Add Semantic Scholar no-auth chat tools app#7487
Conversation
Greptile SummaryAdds a new standalone Omi plugin (
Confidence Score: 3/5The paper-by-DOI lookup path is broken out of the box — every DOI-based request will return a 404 from Semantic Scholar — so one of the three advertised tools is non-functional as written. The main.py — specifically normalize_identifier (lines 38–42) and the quote call in get_paper (line 124), and the manifest parameter schema (lines 57–81). Important Files Changed
Sequence DiagramsequenceDiagram
participant Omi as Omi Platform
participant App as omi-semantic-scholar-app (FastAPI)
participant SS as Semantic Scholar Graph API
Omi->>App: GET /.well-known/omi-tools.json
App-->>Omi: Tool manifest (3 tools)
Omi->>App: POST /tools/search_semantic_scholar_papers
App->>SS: "GET /paper/search?query=...&limit=...&fields=..."
SS-->>App: "{data: [...papers]}"
App-->>Omi: "ChatToolResponse {result: formatted list}"
Omi->>App: POST /tools/get_semantic_scholar_paper
Note over App: normalize_identifier() strips doi: prefix
Note over App: quote(..., safe="") encodes colon — DOI lookup breaks
App->>SS: "GET /paper/{encoded_id}?fields=..."
SS-->>App: paper detail or 404
App-->>Omi: "ChatToolResponse {result or error}"
Omi->>App: POST /tools/get_semantic_scholar_author_papers
App->>SS: "GET /author/{encoded_id}?fields=name,papers.*"
SS-->>App: "{name, papers: [...]}"
App-->>Omi: "ChatToolResponse {result: sorted paper list}"
Reviews (1): Last reviewed commit: "Add Semantic Scholar no-auth chat tools ..." | Re-trigger Greptile |
| def normalize_identifier(raw: str) -> str: | ||
| value = raw.strip() | ||
| if value.lower().startswith("doi:"): | ||
| value = value[4:] | ||
| return value |
There was a problem hiding this comment.
DOI prefix stripped and colon encoding — DOI lookups always 404
normalize_identifier removes the doi: prefix before the value is passed to the Semantic Scholar API. Semantic Scholar's paper lookup endpoint requires the DOI: prefix to recognize the identifier as a DOI (e.g., /paper/DOI:10.1234%2F5678); without it the raw value 10.1234%2F5678 is treated as an unknown paper ID and the API returns a 404.
Compounding this, quote(..., safe="") on line 124 encodes : to %3A, so even if the prefix were preserved, DOI%3A10.1234%2F5678 may not be matched by the server. The fix is to normalise the prefix to uppercase DOI: (instead of stripping it) and pass safe=":" to quote so that scheme separators are left intact.
| { | ||
| "name": "search_semantic_scholar_papers", | ||
| "description": "Search Semantic Scholar papers by keyword.", | ||
| "endpoint": "/tools/search_semantic_scholar_papers", | ||
| "method": "POST", | ||
| "parameters": { | ||
| "query": "string", | ||
| "max_results": "integer 1-10 (default 5)", | ||
| "min_year": "optional integer", | ||
| }, | ||
| }, | ||
| { | ||
| "name": "get_semantic_scholar_paper", | ||
| "description": "Get details for a paper by Semantic Scholar ID or DOI.", | ||
| "endpoint": "/tools/get_semantic_scholar_paper", | ||
| "method": "POST", | ||
| "parameters": {"paper_id_or_doi": "string"}, | ||
| }, | ||
| { | ||
| "name": "get_semantic_scholar_author_papers", | ||
| "description": "Get recent papers by Semantic Scholar author ID.", | ||
| "endpoint": "/tools/get_semantic_scholar_author_papers", | ||
| "method": "POST", | ||
| "parameters": {"author_id": "string", "max_results": "integer 1-10"}, | ||
| }, |
There was a problem hiding this comment.
Non-standard manifest parameter schema — Omi may not parse tool parameters correctly
Other plugins in this repo (e.g., omi-zomato-app) use a JSON Schema-shaped parameters object with properties, type, description, and required keys. The current manifest uses plain strings as values (e.g., "string", "integer 1-10 (default 5)"). If Omi's tool-calling layer expects JSON Schema, the LLM will not receive accurate type or constraint information for these tools.
| { | |
| "name": "search_semantic_scholar_papers", | |
| "description": "Search Semantic Scholar papers by keyword.", | |
| "endpoint": "/tools/search_semantic_scholar_papers", | |
| "method": "POST", | |
| "parameters": { | |
| "query": "string", | |
| "max_results": "integer 1-10 (default 5)", | |
| "min_year": "optional integer", | |
| }, | |
| }, | |
| { | |
| "name": "get_semantic_scholar_paper", | |
| "description": "Get details for a paper by Semantic Scholar ID or DOI.", | |
| "endpoint": "/tools/get_semantic_scholar_paper", | |
| "method": "POST", | |
| "parameters": {"paper_id_or_doi": "string"}, | |
| }, | |
| { | |
| "name": "get_semantic_scholar_author_papers", | |
| "description": "Get recent papers by Semantic Scholar author ID.", | |
| "endpoint": "/tools/get_semantic_scholar_author_papers", | |
| "method": "POST", | |
| "parameters": {"author_id": "string", "max_results": "integer 1-10"}, | |
| }, | |
| { | |
| "name": "search_semantic_scholar_papers", | |
| "description": "Search Semantic Scholar papers by keyword.", | |
| "endpoint": "/tools/search_semantic_scholar_papers", | |
| "method": "POST", | |
| "parameters": { | |
| "properties": { | |
| "query": {"type": "string", "description": "Keyword search query"}, | |
| "max_results": {"type": "integer", "description": "Number of results to return (1-10, default 5)"}, | |
| "min_year": {"type": "integer", "description": "Optional earliest publication year filter"}, | |
| }, | |
| "required": ["query"], | |
| }, | |
| }, | |
| { | |
| "name": "get_semantic_scholar_paper", | |
| "description": "Get details for a paper by Semantic Scholar ID or DOI.", | |
| "endpoint": "/tools/get_semantic_scholar_paper", | |
| "method": "POST", | |
| "parameters": { | |
| "properties": { | |
| "paper_id_or_doi": {"type": "string", "description": "Semantic Scholar paper ID or DOI (e.g. DOI:10.xxx/xxx)"}, | |
| }, | |
| "required": ["paper_id_or_doi"], | |
| }, | |
| }, | |
| { | |
| "name": "get_semantic_scholar_author_papers", | |
| "description": "Get recent papers by Semantic Scholar author ID.", | |
| "endpoint": "/tools/get_semantic_scholar_author_papers", | |
| "method": "POST", | |
| "parameters": { | |
| "properties": { | |
| "author_id": {"type": "string", "description": "Semantic Scholar author ID"}, | |
| "max_results": {"type": "integer", "description": "Number of papers to return (1-10, default 5)"}, | |
| }, | |
| "required": ["author_id"], | |
| }, | |
| }, |
| class ChatToolResponse(BaseModel): | ||
| """Response model for Omi chat tool endpoints.""" | ||
| result: Optional[str] = None | ||
| error: Optional[str] = None |
There was a problem hiding this comment.
ChatToolResponse allows both fields to be None simultaneously
Both result and error default to None, so it is possible to construct — or accidentally return — ChatToolResponse() with {"result": null, "error": null}. Adding a model validator (e.g., @model_validator(mode="after")) that requires exactly one of the two fields to be set would make the contract explicit and prevent silent empty responses from reaching the Omi platform.
|
Addressed Greptile findings in c2099ae:
Validation:
|
kodjima33
left a comment
There was a problem hiding this comment.
thanks for adding the Semantic Scholar app
/claim #3120
Summary
plugins/omi-semantic-scholar-appintegration with no OAuth/API key requirementsearch_semantic_scholar_papersget_semantic_scholar_paperget_semantic_scholar_author_papersChatToolResponseusingresult/error/.well-known/omi-tools.jsonrequirements.txt,Procfile,railway.toml) and READMEValidation
python3 -m py_compile plugins/omi-semantic-scholar-app/main.py plugins/omi-semantic-scholar-app/models.pyNotes