Skip to content

Single paper recommendation

This tool is used to return recommendations for a single paper.

SinglePaperRecInput

Bases: BaseModel

Input schema for single paper recommendation tool.

Source code in aiagents4pharma/talk2scholars/tools/s2/single_paper_rec.py
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
class SinglePaperRecInput(BaseModel):
    """Input schema for single paper recommendation tool."""

    paper_id: str = Field(
        description="Semantic Scholar Paper ID to get recommendations for (40-character string)"
    )
    limit: int = Field(
        default=5,
        description="Maximum number of recommendations to return",
        ge=1,
        le=500,
    )
    year: Optional[str] = Field(
        default=None,
        description="Year range in format: YYYY for specific year, "
        "YYYY- for papers after year, -YYYY for papers before year, or YYYY:YYYY for range",
    )
    tool_call_id: Annotated[str, InjectedToolCallId]
    model_config = {"arbitrary_types_allowed": True}

get_single_paper_recommendations(paper_id, tool_call_id, limit=5, year=None)

Get recommendations for on a single paper using its Semantic Scholar ID. No other ID types are supported.

Parameters:

Name Type Description Default
paper_id str

The Semantic Scholar Paper ID to get recommendations for.

required
tool_call_id Annotated[str, InjectedToolCallId]

The tool call ID.

required
limit int

The maximum number of recommendations to return. Defaults to 2.

5
year str

Year range for papers.

None
Supports formats like "2024-", "-2024", "2024

2025". Defaults to None.

required

Returns:

Type Description
Command[Any]

Dict[str, Any]: The recommendations and related information.

Source code in aiagents4pharma/talk2scholars/tools/s2/single_paper_rec.py
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
@tool(args_schema=SinglePaperRecInput, parse_docstring=True)
def get_single_paper_recommendations(
    paper_id: str,
    tool_call_id: Annotated[str, InjectedToolCallId],
    limit: int = 5,
    year: Optional[str] = None,
) -> Command[Any]:
    """
    Get recommendations for on a single paper using its Semantic Scholar ID.
    No other ID types are supported.

    Args:
        paper_id (str): The Semantic Scholar Paper ID to get recommendations for.
        tool_call_id (Annotated[str, InjectedToolCallId]): The tool call ID.
        limit (int, optional): The maximum number of recommendations to return. Defaults to 2.
        year (str, optional): Year range for papers.
        Supports formats like "2024-", "-2024", "2024:2025". Defaults to None.

    Returns:
        Dict[str, Any]: The recommendations and related information.
    """
    logger.info(
        "Starting single paper recommendations search with paper ID: %s", paper_id
    )

    endpoint = f"{cfg.api_endpoint}/{paper_id}"
    params = {
        "limit": min(limit, 500),  # Max 500 per API docs
        "fields": ",".join(cfg.api_fields),
        "from": cfg.recommendation_params.from_pool,
    }

    # Add year parameter if provided
    if year:
        params["year"] = year

    response = requests.get(endpoint, params=params, timeout=cfg.request_timeout)
    data = response.json()
    response = requests.get(endpoint, params=params, timeout=10)
    # print(f"API Response Status: {response.status_code}")
    logging.info(
        "API Response Status for recommendations of paper %s: %s",
        paper_id,
        response.status_code,
    )
    if response.status_code != 200:
        raise ValueError("Invalid paper ID or API error.")
    # print(f"Request params: {params}")
    logging.info("Request params: %s", params)

    data = response.json()
    recommendations = data.get("recommendedPapers", [])

    if not recommendations:
        return Command(
            update={
                "papers": {},
                "messages": [
                    ToolMessage(
                        content=f"No recommendations found for {paper_id}.",
                        tool_call_id=tool_call_id,
                    )
                ],
            }
        )

    # Extract paper ID and title from recommendations
    filtered_papers = {
        paper["paperId"]: {
            # "semantic_scholar_id": paper["paperId"],  # Store Semantic Scholar ID
            "Title": paper.get("title", "N/A"),
            "Abstract": paper.get("abstract", "N/A"),
            "Year": paper.get("year", "N/A"),
            "Citation Count": paper.get("citationCount", "N/A"),
            "URL": paper.get("url", "N/A"),
            # "arXiv_ID": paper.get("externalIds", {}).get(
            #     "ArXiv", "N/A"
            # ),  # Extract arXiv ID
        }
        for paper in recommendations
        if paper.get("title") and paper.get("authors")
    }

    # Prepare content with top 3 paper titles and years
    top_papers = list(filtered_papers.values())[:3]
    top_papers_info = "\n".join(
        [
            f"{i+1}. {paper['Title']} ({paper['Year']})"
            for i, paper in enumerate(top_papers)
        ]
    )

    logger.info("Filtered %d papers", len(filtered_papers))

    content = (
        "Recommendations based on single paper were successful. "
        "Papers are attached as an artifact."
    )
    content += " Here is a summary of the recommendations:\n"
    content += f"Number of papers found: {len(filtered_papers)}\n"
    content += f"Query Paper ID: {paper_id}\n"
    content += f"Year: {year}\n" if year else ""
    content += "Top papers:\n" + top_papers_info

    return Command(
        update={
            "papers": filtered_papers,  # Now sending the dictionary directly
            "last_displayed_papers": "papers",
            "messages": [
                ToolMessage(
                    content=content,
                    tool_call_id=tool_call_id,
                    artifact=filtered_papers,
                )
            ],
        }
    )