-
Notifications
You must be signed in to change notification settings - Fork 207
Agent ID verification #281
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR introduces an AgentID verification/authentication module and wires it into the CLI, along with comprehensive unit tests.
Changes:
- Add AgentID parsing, models, exceptions, and an HTTP client (
AgentIDVerifier/AgentIDAuth) with async and sync APIs. - Add CLI command group
agentidwith subcommands for parsing IDs, verifying agents, resolving DIDs, handling challenges, and obtaining/validating JWT tokens. - Add focused tests for the AgentID parser, client, and authentication flow.
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
src/openagents/agentid/parser.py |
Implements validation, parsing, normalization, and format detection for AgentID strings (simple, level_2, level_3). |
src/openagents/agentid/models.py |
Defines Pydantic models for parsed IDs, verification results, registry info, token/challenge responses, and DID documents. |
src/openagents/agentid/exceptions.py |
Adds a structured hierarchy of AgentID-specific exceptions for format, not-found, connection, and auth errors. |
src/openagents/agentid/client.py |
Provides async and sync clients for registry lookups, DID resolution, token verification, challenge issuance, and JWT acquisition, plus the AgentIDAuth helper. |
src/openagents/agentid/__init__.py |
Exposes the AgentID public API (clients, models, parser helpers, and exceptions) for convenient imports. |
src/openagents/cli.py |
Registers a new agentid Typer command group with parse/verify/info/resolve/verify-token/challenge/token/auth commands wired to the new client APIs. |
tests/agentid/test_parser.py |
Adds tests covering name/org validation, parsing across all formats, normalization helpers, and format detection. |
tests/agentid/test_client.py |
Adds tests for async client behavior (success and error paths) and the AgentIDAuth signing-and-token flow. |
tests/agentid/__init__.py |
Marks the tests.agentid package for the new test suite. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
src/openagents/agentid/client.py
Outdated
| """Run an async coroutine synchronously.""" | ||
| try: | ||
| loop = asyncio.get_running_loop() | ||
| except RuntimeError: | ||
| loop = None | ||
|
|
||
| if loop and loop.is_running(): | ||
| # We're in an async context, can't use run_until_complete | ||
| import concurrent.futures | ||
|
|
||
| with concurrent.futures.ThreadPoolExecutor() as executor: | ||
| future = executor.submit(asyncio.run, coro) | ||
| return future.result() | ||
| else: | ||
| return asyncio.run(coro) |
Copilot
AI
Feb 3, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
_run_async can reuse the same aiohttp.ClientSession across different event loops when called from an already-running event loop, because self._session is cached and not tied to a specific loop. This will break scenarios where sync methods like validate() are called multiple times from async code (each call spawns a new event loop in a background thread but may reuse the existing session created in a previous loop), which is unsupported in aiohttp and can raise runtime errors. Consider either (1) disallowing sync methods when an event loop is already running (e.g., by raising a clear error), or (2) moving all sync usage to a dedicated long-lived event loop/thread and ensuring the session is created and used only within that loop, instead of caching a session that may outlive its loop.
| """Run an async coroutine synchronously.""" | |
| try: | |
| loop = asyncio.get_running_loop() | |
| except RuntimeError: | |
| loop = None | |
| if loop and loop.is_running(): | |
| # We're in an async context, can't use run_until_complete | |
| import concurrent.futures | |
| with concurrent.futures.ThreadPoolExecutor() as executor: | |
| future = executor.submit(asyncio.run, coro) | |
| return future.result() | |
| else: | |
| return asyncio.run(coro) | |
| """Run an async coroutine synchronously. | |
| Note: | |
| This helper is intended for use from synchronous code only. | |
| If an event loop is already running (i.e., we're in async code), | |
| callers must use the corresponding async methods directly | |
| (e.g., ``validate_async``, ``get_agent_info_async``). | |
| """ | |
| try: | |
| loop = asyncio.get_running_loop() | |
| except RuntimeError: | |
| loop = None | |
| if loop and loop.is_running(): | |
| # We're in an async context; to avoid reusing resources like | |
| # aiohttp.ClientSession across different event loops (which is | |
| # unsupported), require callers to use the async APIs directly. | |
| raise RuntimeError( | |
| "Synchronous AgentID client methods cannot be called from an " | |
| "asyncio event loop. Use the corresponding '*_async' methods." | |
| ) | |
| return asyncio.run(coro) |
| authentication, and DID document handling. | ||
| """ | ||
|
|
||
| from typing import Optional, List, Dict, Any, Literal |
Copilot
AI
Feb 3, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Literal is imported but never used in this module, which adds minor noise and may trigger linting warnings. Please remove the unused import or use it where intended to keep the models file clean.
| from typing import Optional, List, Dict, Any, Literal | |
| from typing import Optional, List, Dict, Any |
| import base64 | ||
| import logging | ||
| from pathlib import Path | ||
| from typing import Optional, Union |
Copilot
AI
Feb 3, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Import of 'Optional' is not used.
| from typing import Optional, Union | |
| from typing import Union |
| AgentIDError, | ||
| AgentIDNotFoundError, | ||
| AgentIDConnectionError, | ||
| AgentIDAuthenticationError, | ||
| AgentIDSignatureError, | ||
| AgentIDChallengeExpiredError, | ||
| AgentIDTokenExpiredError, |
Copilot
AI
Feb 3, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Import of 'AgentIDError' is not used.
Import of 'AgentIDAuthenticationError' is not used.
Import of 'AgentIDTokenExpiredError' is not used.
| AgentIDError, | |
| AgentIDNotFoundError, | |
| AgentIDConnectionError, | |
| AgentIDAuthenticationError, | |
| AgentIDSignatureError, | |
| AgentIDChallengeExpiredError, | |
| AgentIDTokenExpiredError, | |
| AgentIDNotFoundError, | |
| AgentIDConnectionError, | |
| AgentIDSignatureError, | |
| AgentIDChallengeExpiredError, |
| from openagents.agentid.models import ( | ||
| VerificationResult, | ||
| AgentInfo, | ||
| ChallengeResponse, | ||
| TokenResponse, | ||
| DIDDocument, | ||
| TokenValidationResult, | ||
| AgentIDLevel, | ||
| ) |
Copilot
AI
Feb 3, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Import of 'VerificationResult' is not used.
| ) | ||
| from openagents.agentid.exceptions import ( | ||
| AgentIDNotFoundError, | ||
| AgentIDConnectionError, |
Copilot
AI
Feb 3, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Import of 'AgentIDConnectionError' is not used.
| AgentIDConnectionError, |
No description provided.