Skip to content

feat: add PDF research agent example using bindufy#328

Merged
raahulrahl merged 5 commits intoGetBindu:mainfrom
ne-ey:add-pdf-research-agent-example
Mar 31, 2026
Merged

feat: add PDF research agent example using bindufy#328
raahulrahl merged 5 commits intoGetBindu:mainfrom
ne-ey:add-pdf-research-agent-example

Conversation

@ne-ey
Copy link
Copy Markdown
Contributor

@ne-ey ne-ey commented Mar 5, 2026

Summary

  • Problem:
    There was no beginner example demonstrating how to build a document research agent that processes PDFs and raw text using Bindu.

  • Why it matters:
    Developers learning Bindu need a clear real-world example showing how an AI agent can be converted into a live service using bindufy().

  • What changed:
    Added a new example agent pdf_research_agent.py under examples/beginner/.
    The agent accepts either a PDF file path or raw document text and returns a structured summary.

  • What did NOT change:
    No changes were made to core Bindu functionality, APIs, storage, or scheduler components.


Change Type

  • Feature
  • Documentation

Scope

  • Documentation
  • CLI / utilities

Linked Issue/PR

None


User-Visible / Behavior Changes

A new beginner example agent is available:

examples/beginner/pdf_research_agent.py

This demonstrates how to:

  • read PDF content using pypdf
  • process document text with an LLM agent
  • expose the agent as a live microservice using bindufy()

Security Impact

New permissions/capabilities? No
Secrets handling changed? No
New network calls? No
Database changes? No
Auth changes? No


Verification

Environment

OS: Windows 11
Python: 3.13
Storage backend: InMemoryStorage
Scheduler backend: InMemoryScheduler

Steps to Test

  1. Run the agent

python pdf_research_agent.py

  1. Send a request using curl

curl -X POST http://localhost:3775/

  1. Retrieve task result using tasks/get.

Expected Behavior

Agent returns a structured summary of the provided document text or PDF content.

Actual Behavior

Agent successfully returns summarized output through the Bindu task system.


Human Verification

Verified scenarios:

  • Agent starts successfully
  • JSON-RPC request accepted
  • Task completes and returns result

Edge cases checked:

  • Raw text input
  • Long document input

Not verified:

  • Very large PDFs

Compatibility / Migration

Backward compatible: Yes


Risks and Mitigations

None


Checklist

  • Tests pass locally
  • Human verification completed
  • Backward compatibility considered

Summary by CodeRabbit

  • New Features

    • Added a PDF Research Agent microservice that extracts text from PDFs and generates structured AI-powered summaries in markdown format. Supports both local PDF file paths and raw text input.
  • Documentation

    • Added comprehensive README with setup instructions, API endpoints, example request payloads, and troubleshooting guidance. Includes environment configuration template.

@ne-ey
Copy link
Copy Markdown
Contributor Author

ne-ey commented Mar 5, 2026

I built this example while learning the Bindu workflow
(bindufy → JSON-RPC message → task lifecycle).

If example agents are not the right direction, I'm happy to
work on an issue instead. I'll take a look through the open issues
and pick something meaningful to contribute.

@ne-ey ne-ey force-pushed the add-pdf-research-agent-example branch from c33d2c4 to a149819 Compare March 5, 2026 13:59
Copy link
Copy Markdown
Member

@Paraschamoli Paraschamoli left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ne-ey use openrouter api key also this is a good agent so don't put it inside beginner make a different folder for it with skill.yaml, readme ,.env.example you can use other agent for refrence

@ne-ey
Copy link
Copy Markdown
Contributor Author

ne-ey commented Mar 20, 2026

@ne-ey use openrouter api key also this is a good agent so don't put it inside beginner make a different folder for it with skill.yaml, readme ,.env.example you can use other agent for refrence

Thanks for the suggestion!! that makes sense, i'll move this out of the beginner folder and restructure it as a proper standalone agent example....and i'll also add the required files and switch to using OPENROUTER
sure i'll take reference from the existing agents in the repo and update this PR accordingly!

@ne-ey
Copy link
Copy Markdown
Contributor Author

ne-ey commented Mar 23, 2026

@Paraschamoli
updated the agent as suggested:

  • moved it out of beginner into a standalone folder
  • added skill.yaml, README, and .env.example
  • switched to OpenRouter

Let me know if anything else needs changes!
Thank you!

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 31, 2026

📝 Walkthrough

Walkthrough

Added a complete new PDF Research Agent example service featuring environment configuration, comprehensive documentation, Python implementation with PDF text extraction and LLM summarization via OpenRouter, and a skill definition for microservice integration.

Changes

Cohort / File(s) Summary
Configuration & Documentation
examples/pdf_research_agent/.env.example, examples/pdf_research_agent/README.md
Environment variable template for OpenRouter API key and detailed service documentation covering setup, usage, endpoints, error handling, and troubleshooting.
Service Implementation
examples/pdf_research_agent/pdf_research_agent.py
Core HTTP service handler that reads PDF files or raw text, extracts content with error handling, truncates large documents, and invokes an Agent configured with OpenRouter for structured markdown summarization.
Skill Definition
examples/pdf_research_agent/skills/pdf-research-skill/skill.yaml
Bindu microservice skill configuration declaring input/output modes, model selection, PDF extraction strategy, and JSON-RPC transport metadata.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 Hoppy hops with PDFs in sight,

A research agent shining bright,

Text extracted, summaries told,

Knowledge wrapped in markdown gold!

From OpenRouter's wisdom flows,

Where every document grows and glows.

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat: add PDF research agent example using bindufy' clearly and specifically describes the main change: adding a new PDF research agent example that uses the bindufy framework.
Description check ✅ Passed The description covers all major required sections: problem, why it matters, what changed, change type, scope, user-visible changes, security impact, verification steps, human verification, compatibility, and checklist. All critical sections are present and adequately completed.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands and usage tips.

Added comprehensive README for PDF Research Agent detailing features, installation, usage, and configuration.
Removed comments and unnecessary lines from the .env.example file, retaining only the OPENROUTER_API_KEY variable.
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 8

🧹 Nitpick comments (1)
examples/pdf_research_agent/pdf_research_agent.py (1)

23-27: Make the skill path independent of the caller's working directory.

"skills/pdf-research-skill" only resolves when the process starts from this folder. Running the script from repo root breaks skill discovery even though the script path itself is valid.

Suggested refactor
 from bindu.penguin.bindufy import bindufy
 from agno.agent import Agent
 from agno.models.openrouter import OpenRouter
 from dotenv import load_dotenv
+from pathlib import Path
 import os
@@
 config = {
@@
-     "skills": ["skills/pdf-research-skill"],
+    "skills": [str(Path(__file__).resolve().parent / "skills" / "pdf-research-skill")],

Also applies to: 81-92

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@examples/pdf_research_agent/pdf_research_agent.py` around lines 23 - 27,
Replace hard-coded relative skill paths with paths resolved from the script
location: compute base_dir = os.path.dirname(__file__) (or
os.path.abspath(os.path.dirname(__file__))) and build the skill path via
os.path.join(base_dir, "skills", "pdf-research-skill") and use that value
wherever the literal "skills/pdf-research-skill" appears (e.g., the
bindufy/Agent skill registration at top of file and the other occurrences around
lines 81-92) so skill discovery works regardless of the current working
directory.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@examples/pdf_research_agent/pdf_research_agent.py`:
- Around line 129-133: The handler is incorrectly inferring failures by
inspecting document_text prefixes; update _read_content to return a structured
result (e.g., a tuple or dataclass like (success: bool, content: str, error:
Optional[str])) or throw an exception on failure, and change the caller in
pdf_research_agent.py to check the structured success flag (or catch the
exception) instead of testing document_text.startswith("[" or "Error");
reference the _read_content function and the document_text variable so you
locate and replace the sentinel-string logic with a clear success/error check
and return the real document content unchanged when success is true.
- Around line 35-45: The _read_content function currently opens arbitrary host
PDF paths; change it to disallow arbitrary paths by requiring PDFs live only
under a controlled directory (configured via an env var like SAFE_PDF_DIR) or by
banning path inputs entirely and accepting uploaded file content/bytes instead.
Implement path validation in _read_content using os.path.abspath and
os.path.commonpath to ensure the resolved file is inside SAFE_PDF_DIR, and
return/raise a clear error if the check fails; if you prefer uploads, change the
API to accept file bytes and parse those with PdfReader. Apply the same
validation/behavior to the other PDF-reading call sites referenced (the blocks
handling PDF paths around the other pdf-reading code), and ensure any logging or
forwarding to OpenRouter only happens after path validation or after using
uploaded content.
- Around line 37-53: The code currently treats any ".pdf" path that doesn't
exist as raw text because the os.path.isfile() check prevents entering the PDF
branch; update the logic handling 'source' so that if
source.strip().endswith(".pdf") but not os.path.isfile(source.strip()) you
return or raise a clear file-not-found error instead of returning the path
string. Locate the PDF handling block (the if source.strip().endswith(".pdf")
and os.path.isfile(...) check and the final "return source" fallback) and change
it to first detect a ".pdf" path, then if the file is missing return a message
like "PDF file '<path>' not found" (or raise FileNotFoundError) before
attempting to import/use PdfReader or falling back to treating the input as raw
text.

In `@examples/pdf_research_agent/README.md`:
- Around line 22-25: Update the startup instructions in the README so the
initial directory is examples/pdf_research_agent (not just examples) and update
the subsequent run commands and the relative skills/pdf-research-skill path so
they resolve from that directory; specifically edit the "Clone and Navigate"
step and the two run command blocks referenced around lines 22–25 and 47–54 to
use cd examples/pdf_research_agent and ensure the config relative path points to
skills/pdf-research-skill (from that directory).
- Around line 105-117: The README has multiple anonymous markdown code fences
(the ASCII architecture diagram and several error-output samples) that trigger
markdownlint MD040; update each of those triple-backtick fences to include the
language hint "text" (e.g., change ``` to ```text) so the diagram and outputs
are explicitly marked as plain text—apply this change to the ASCII architecture
diagram block shown in the diff and to the other anonymous fences containing
error-output or sample text elsewhere in the README.
- Around line 210-215: Update the "## 🛡️ Security & Privacy" section so it does
not claim protections the example does not implement: remove or revise the
bullets "Content Filtering", "Input Validation", and "Output Sanitization" and
instead state the actual protections provided (e.g., "Text-only processing, no
file storage") and an explicit disclaimer that the example forwards user input
to the model and does not perform comprehensive input validation, content
filtering, or output sanitization; reference the example script
pdf_research_agent.py (and its main/handler functions) in the disclaimer so
readers know where to add those protections if desired.

In `@examples/pdf_research_agent/skills/pdf-research-skill/skill.yaml`:
- Around line 74-77: Update the transport.port entry in the skill manifest so it
matches the actual service port used by the agent (change the transport.port
value from 3775 to 3773) to align the skill.yaml with the example code and
README; look for the transport block (the "transport:" key and its children
"protocol", "endpoint", "port") in skill.yaml and set port to 3773 so consumers
hit the correct endpoint.
- Around line 27-29: The manifest advertises application/pdf but the runtime
handler in examples/pdf_research_agent/pdf_research_agent.py only accepts plain
text (raw text or a server-local path string); either remove "application/pdf"
from input_modes in skill.yaml so it only lists "text/plain", or implement true
PDF binary handling in the handler (update the request parsing and the function
that processes inputs in pdf_research_agent.py to accept and stream/parse
application/pdf payloads). Ensure the chosen change is applied consistently by
editing input_modes in skill.yaml or by adding PDF binary parsing logic in the
handler so the manifest matches the actual accepted payload shape.

---

Nitpick comments:
In `@examples/pdf_research_agent/pdf_research_agent.py`:
- Around line 23-27: Replace hard-coded relative skill paths with paths resolved
from the script location: compute base_dir = os.path.dirname(__file__) (or
os.path.abspath(os.path.dirname(__file__))) and build the skill path via
os.path.join(base_dir, "skills", "pdf-research-skill") and use that value
wherever the literal "skills/pdf-research-skill" appears (e.g., the
bindufy/Agent skill registration at top of file and the other occurrences around
lines 81-92) so skill discovery works regardless of the current working
directory.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 7d45e6b3-d3e2-47c9-88ae-47d2112eefaa

📥 Commits

Reviewing files that changed from the base of the PR and between 3835fe2 and e5e105c.

📒 Files selected for processing (4)
  • examples/pdf_research_agent/.env.example
  • examples/pdf_research_agent/README.md
  • examples/pdf_research_agent/pdf_research_agent.py
  • examples/pdf_research_agent/skills/pdf-research-skill/skill.yaml

Comment on lines +35 to +45
def _read_content(source: str) -> str:
"""Return plain text from a PDF file path, or the source string itself."""
if source.strip().endswith(".pdf") and os.path.isfile(source.strip()):
try:
from pypdf import PdfReader # optional dependency
reader = PdfReader(source.strip())
pages = [page.extract_text() or "" for page in reader.pages]
text = "\n\n".join(pages)
if len(text.strip()) < 100:
return f"PDF file '{source.strip()}' appears to be empty or contains very little text."
return text
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Don't let callers choose arbitrary server-side PDF paths.

_read_content() opens any user-supplied .pdf on the host, and the extracted text is then sent to OpenRouter while auth is disabled. That is local file exfiltration, not just a convenience feature. Restrict path mode to a safe directory or allowlist, or require uploaded content instead of raw paths.

Also applies to: 69-72, 92-98

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@examples/pdf_research_agent/pdf_research_agent.py` around lines 35 - 45, The
_read_content function currently opens arbitrary host PDF paths; change it to
disallow arbitrary paths by requiring PDFs live only under a controlled
directory (configured via an env var like SAFE_PDF_DIR) or by banning path
inputs entirely and accepting uploaded file content/bytes instead. Implement
path validation in _read_content using os.path.abspath and os.path.commonpath to
ensure the resolved file is inside SAFE_PDF_DIR, and return/raise a clear error
if the check fails; if you prefer uploads, change the API to accept file bytes
and parse those with PdfReader. Apply the same validation/behavior to the other
PDF-reading call sites referenced (the blocks handling PDF paths around the
other pdf-reading code), and ensure any logging or forwarding to OpenRouter only
happens after path validation or after using uploaded content.

Comment on lines +37 to +53
if source.strip().endswith(".pdf") and os.path.isfile(source.strip()):
try:
from pypdf import PdfReader # optional dependency
reader = PdfReader(source.strip())
pages = [page.extract_text() or "" for page in reader.pages]
text = "\n\n".join(pages)
if len(text.strip()) < 100:
return f"PDF file '{source.strip()}' appears to be empty or contains very little text."
return text
except ImportError:
return (
f"[pypdf not installed — cannot read '{source.strip()}'. "
"Run: uv add pypdf]"
)
except Exception as e:
return f"Error reading PDF '{source.strip()}': {str(e)}"
return source # treat as raw document text
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Return a file-not-found error instead of summarizing the path string.

When the input ends with .pdf but the file does not exist, the os.path.isfile() guard skips the PDF branch and returns the literal path as raw text. A typo like /tmp/missing.pdf will be “summarized” instead of producing the documented file-read error.

Suggested fix
 def _read_content(source: str) -> str:
     """Return plain text from a PDF file path, or the source string itself."""
-    if source.strip().endswith(".pdf") and os.path.isfile(source.strip()):
+    candidate = source.strip()
+    if candidate.lower().endswith(".pdf"):
+        if not os.path.isfile(candidate):
+            return f"Error reading PDF '{candidate}': file does not exist."
         try:
             from pypdf import PdfReader  # optional dependency
-            reader = PdfReader(source.strip())
+            reader = PdfReader(candidate)
             pages = [page.extract_text() or "" for page in reader.pages]
             text = "\n\n".join(pages)
             if len(text.strip()) < 100:
-                return f"PDF file '{source.strip()}' appears to be empty or contains very little text."
+                return f"PDF file '{candidate}' appears to be empty or contains very little text."
             return text
         except ImportError:
             return (
-                f"[pypdf not installed — cannot read '{source.strip()}'. "
+                f"[pypdf not installed — cannot read '{candidate}'. "
                 "Run: uv add pypdf]"
             )
         except Exception as e:
-            return f"Error reading PDF '{source.strip()}': {str(e)}"
+            return f"Error reading PDF '{candidate}': {e!s}"
     return source  # treat as raw document text
🧰 Tools
🪛 Ruff (0.15.7)

[warning] 51-51: Do not catch blind exception: Exception

(BLE001)


[warning] 52-52: Use explicit conversion flag

Replace with conversion flag

(RUF010)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@examples/pdf_research_agent/pdf_research_agent.py` around lines 37 - 53, The
code currently treats any ".pdf" path that doesn't exist as raw text because the
os.path.isfile() check prevents entering the PDF branch; update the logic
handling 'source' so that if source.strip().endswith(".pdf") but not
os.path.isfile(source.strip()) you return or raise a clear file-not-found error
instead of returning the path string. Locate the PDF handling block (the if
source.strip().endswith(".pdf") and os.path.isfile(...) check and the final
"return source" fallback) and change it to first detect a ".pdf" path, then if
the file is missing return a message like "PDF file '<path>' not found" (or
raise FileNotFoundError) before attempting to import/use PdfReader or falling
back to treating the input as raw text.

Comment on lines +129 to +133
document_text = _read_content(user_input)

# Check if document processing failed
if document_text.startswith("[") or document_text.startswith("Error"):
return document_text
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Don't infer internal failures from user text prefixes.

A real document that starts with [Draft] or Error analysis... will be returned unsummarized because the handler treats those prefixes as processing errors. _read_content() should return structured status instead of sentinel strings.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@examples/pdf_research_agent/pdf_research_agent.py` around lines 129 - 133,
The handler is incorrectly inferring failures by inspecting document_text
prefixes; update _read_content to return a structured result (e.g., a tuple or
dataclass like (success: bool, content: str, error: Optional[str])) or throw an
exception on failure, and change the caller in pdf_research_agent.py to check
the structured success flag (or catch the exception) instead of testing
document_text.startswith("[" or "Error"); reference the _read_content function
and the document_text variable so you locate and replace the sentinel-string
logic with a clear success/error check and return the real document content
unchanged when success is true.

Comment on lines +22 to +25
### 1. Clone and Navigate
```bash
cd examples
```
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

The startup steps land in the wrong directory.

After cd examples, both run commands miss the script. The relative skills/pdf-research-skill path in the config also only resolves when the current directory is examples/pdf_research_agent.

Suggested README fix
 ### 1. Clone and Navigate
 ```bash
-cd examples
+cd examples/pdf_research_agent
</details>


Also applies to: 47-54

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against the current code and only fix it if needed.

In @examples/pdf_research_agent/README.md around lines 22 - 25, Update the
startup instructions in the README so the initial directory is
examples/pdf_research_agent (not just examples) and update the subsequent run
commands and the relative skills/pdf-research-skill path so they resolve from
that directory; specifically edit the "Clone and Navigate" step and the two run
command blocks referenced around lines 22–25 and 47–54 to use cd
examples/pdf_research_agent and ensure the config relative path points to
skills/pdf-research-skill (from that directory).


</details>

<!-- fingerprinting:phantom:medusa:grasshopper:d61549d5-677b-496f-93f2-bf000b710cd4 -->

<!-- This is an auto-generated comment by CodeRabbit -->

Comment on lines +105 to +117
```
┌─────────────────┐ ┌─────────────────────┐ ┌─────────────────────┐
│ Client │───▶│ Bindu Core │───▶│ PDF Agent │
│ (Postman) │ │ (A2A Protocol) │ │ (Agno + OpenRouter)│
└─────────────────┘ └─────────────────────┘ └─────────────────────┘
│ │
▼ ▼
┌─────────────┐ ┌─────────────────┐
│ DID │ │ PDF Parser │
│ Auth │ │ Text Extract │
│ Storage │ │ Summary Gen │
└─────────────┘ └─────────────────┘
```
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add language hints to the plain-text fences.

markdownlint MD040 is firing on these anonymous blocks. text is enough for the architecture diagram and the error-output samples.

Suggested README fix
-```
+```text
-```
+```text
</details>


Also applies to: 193-195, 198-200, 203-205

<details>
<summary>🧰 Tools</summary>

<details>
<summary>🪛 markdownlint-cli2 (0.22.0)</summary>

[warning] 105-105: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

</details>

</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against the current code and only fix it if needed.

In @examples/pdf_research_agent/README.md around lines 105 - 117, The README has
multiple anonymous markdown code fences (the ASCII architecture diagram and
several error-output samples) that trigger markdownlint MD040; update each of
those triple-backtick fences to include the language hint "text" (e.g., change
totext) so the diagram and outputs are explicitly marked as plain
text—apply this change to the ASCII architecture diagram block shown in the diff
and to the other anonymous fences containing error-output or sample text
elsewhere in the README.


</details>

<!-- fingerprinting:phantom:medusa:grasshopper:d61549d5-677b-496f-93f2-bf000b710cd4 -->

<!-- This is an auto-generated comment by CodeRabbit -->

Comment on lines +210 to +215
## 🛡️ Security & Privacy

- **Data Privacy**: Text-only processing, no file storage
- **Content Filtering**: Educational-appropriate content filtering
- **Input Validation**: Enabled for all inputs
- **Output Sanitization**: Enabled for safe responses
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Don't claim security controls the example doesn't implement.

This example does not perform content filtering, output sanitization, or comprehensive input validation in examples/pdf_research_agent/pdf_research_agent.py; it mostly forwards user input to the model. Leaving these bullets here advertises protections that do not exist.

Suggested README fix
 ## 🛡️ Security & Privacy
 
 - **Data Privacy**: Text-only processing, no file storage
-- **Content Filtering**: Educational-appropriate content filtering
-- **Input Validation**: Enabled for all inputs
-- **Output Sanitization**: Enabled for safe responses
+- **Input Handling**: Basic empty-input and file-read checks only
+- **Authentication**: Disabled by default for local development
+- **Production Hardening**: Add auth, path restrictions, validation, and output checks before deployment
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@examples/pdf_research_agent/README.md` around lines 210 - 215, Update the "##
🛡️ Security & Privacy" section so it does not claim protections the example
does not implement: remove or revise the bullets "Content Filtering", "Input
Validation", and "Output Sanitization" and instead state the actual protections
provided (e.g., "Text-only processing, no file storage") and an explicit
disclaimer that the example forwards user input to the model and does not
perform comprehensive input validation, content filtering, or output
sanitization; reference the example script pdf_research_agent.py (and its
main/handler functions) in the disclaimer so readers know where to add those
protections if desired.

Comment on lines +27 to +29
input_modes:
- text/plain # Raw document text pasted directly
- application/pdf # Local PDF file path resolved server-side
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Advertise only the input mode the handler actually supports.

The service currently accepts a text message containing either raw text or a server-local path string. There is no binary application/pdf handling in examples/pdf_research_agent/pdf_research_agent.py, so clients following this manifest will send the wrong payload shape.

Suggested manifest fix
 input_modes:
-  - text/plain         # Raw document text pasted directly
-  - application/pdf    # Local PDF file path resolved server-side
+  - text/plain         # Raw document text or a server-local PDF path string
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
input_modes:
- text/plain # Raw document text pasted directly
- application/pdf # Local PDF file path resolved server-side
input_modes:
- text/plain # Raw document text or a server-local PDF path string
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@examples/pdf_research_agent/skills/pdf-research-skill/skill.yaml` around
lines 27 - 29, The manifest advertises application/pdf but the runtime handler
in examples/pdf_research_agent/pdf_research_agent.py only accepts plain text
(raw text or a server-local path string); either remove "application/pdf" from
input_modes in skill.yaml so it only lists "text/plain", or implement true PDF
binary handling in the handler (update the request parsing and the function that
processes inputs in pdf_research_agent.py to accept and stream/parse
application/pdf payloads). Ensure the chosen change is applied consistently by
editing input_modes in skill.yaml or by adding PDF binary parsing logic in the
handler so the manifest matches the actual accepted payload shape.

Comment on lines +74 to +77
transport:
protocol: A2A (JSON-RPC over HTTP)
endpoint: POST /
port: 3775
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Sync the declared port with the actual service.

transport.port still says 3775, but the example code and README both start the agent on 3773. Consumers using this manifest will hit the wrong endpoint.

Suggested manifest fix
   transport:
     protocol: A2A (JSON-RPC over HTTP)
     endpoint: POST /
-    port: 3775
+    port: 3773
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
transport:
protocol: A2A (JSON-RPC over HTTP)
endpoint: POST /
port: 3775
transport:
protocol: A2A (JSON-RPC over HTTP)
endpoint: POST /
port: 3773
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@examples/pdf_research_agent/skills/pdf-research-skill/skill.yaml` around
lines 74 - 77, Update the transport.port entry in the skill manifest so it
matches the actual service port used by the agent (change the transport.port
value from 3775 to 3773) to align the skill.yaml with the example code and
README; look for the transport block (the "transport:" key and its children
"protocol", "endpoint", "port") in skill.yaml and set port to 3773 so consumers
hit the correct endpoint.

@raahulrahl raahulrahl merged commit 0526d56 into GetBindu:main Mar 31, 2026
3 of 5 checks passed
@ne-ey
Copy link
Copy Markdown
Contributor Author

ne-ey commented Mar 31, 2026

@raahulrahl Thank you for merging the pull request. I’m currently occupied with college commitments, so I’m unable to look into the issue right now. I’ll review and address it in the next few days.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants