komodor-agentops 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- komodor_agentops-0.1.0/LICENSE +53 -0
- komodor_agentops-0.1.0/PKG-INFO +218 -0
- komodor_agentops-0.1.0/README.md +183 -0
- komodor_agentops-0.1.0/pyproject.toml +71 -0
- komodor_agentops-0.1.0/setup.cfg +4 -0
- komodor_agentops-0.1.0/src/komodor_agentops/__init__.py +92 -0
- komodor_agentops-0.1.0/src/komodor_agentops/adapters/__init__.py +1 -0
- komodor_agentops-0.1.0/src/komodor_agentops/adapters/adk/__init__.py +4 -0
- komodor_agentops-0.1.0/src/komodor_agentops/adapters/adk/a2a_adapter.py +313 -0
- komodor_agentops-0.1.0/src/komodor_agentops/adapters/adk/adapter.py +453 -0
- komodor_agentops-0.1.0/src/komodor_agentops/adapters/agno/__init__.py +13 -0
- komodor_agentops-0.1.0/src/komodor_agentops/adapters/agno/a2a_adapter.py +275 -0
- komodor_agentops-0.1.0/src/komodor_agentops/adapters/claude_code/__init__.py +36 -0
- komodor_agentops-0.1.0/src/komodor_agentops/adapters/claude_code/a2a_adapter.py +658 -0
- komodor_agentops-0.1.0/src/komodor_agentops/adapters/claude_code/agent.py +127 -0
- komodor_agentops-0.1.0/src/komodor_agentops/adapters/claude_code/hook.py +260 -0
- komodor_agentops-0.1.0/src/komodor_agentops/adapters/claude_code/hook_payload.py +32 -0
- komodor_agentops-0.1.0/src/komodor_agentops/adapters/claude_code/hook_types.py +15 -0
- komodor_agentops-0.1.0/src/komodor_agentops/adapters/claude_code/install.py +137 -0
- komodor_agentops-0.1.0/src/komodor_agentops/adapters/claude_code/instrumented_query.py +110 -0
- komodor_agentops-0.1.0/src/komodor_agentops/adapters/claude_code/sdk_hooks.py +473 -0
- komodor_agentops-0.1.0/src/komodor_agentops/adapters/claude_code/session_snapshot.py +177 -0
- komodor_agentops-0.1.0/src/komodor_agentops/adapters/claude_code/usage.py +296 -0
- komodor_agentops-0.1.0/src/komodor_agentops/adapters/langchain/__init__.py +4 -0
- komodor_agentops-0.1.0/src/komodor_agentops/adapters/langchain/callbacks.py +168 -0
- komodor_agentops-0.1.0/src/komodor_agentops/adapters/langchain/context_callbacks.py +130 -0
- komodor_agentops-0.1.0/src/komodor_agentops/adapters/langchain/usage.py +146 -0
- komodor_agentops-0.1.0/src/komodor_agentops/adapters/nanobot/__init__.py +15 -0
- komodor_agentops-0.1.0/src/komodor_agentops/adapters/nanobot/hook.py +159 -0
- komodor_agentops-0.1.0/src/komodor_agentops/adapters/nanobot/patches.py +103 -0
- komodor_agentops-0.1.0/src/komodor_agentops/adapters/nanobot/skills.py +47 -0
- komodor_agentops-0.1.0/src/komodor_agentops/adapters/nanobot/telemetry.py +125 -0
- komodor_agentops-0.1.0/src/komodor_agentops/artifacts.py +64 -0
- komodor_agentops-0.1.0/src/komodor_agentops/client.py +180 -0
- komodor_agentops-0.1.0/src/komodor_agentops/config.py +63 -0
- komodor_agentops-0.1.0/src/komodor_agentops/core/__init__.py +30 -0
- komodor_agentops-0.1.0/src/komodor_agentops/core/agent_spec_file.py +247 -0
- komodor_agentops-0.1.0/src/komodor_agentops/core/auth.py +17 -0
- komodor_agentops-0.1.0/src/komodor_agentops/core/context.py +131 -0
- komodor_agentops-0.1.0/src/komodor_agentops/core/errors.py +34 -0
- komodor_agentops-0.1.0/src/komodor_agentops/core/events.py +89 -0
- komodor_agentops-0.1.0/src/komodor_agentops/core/hooks.py +47 -0
- komodor_agentops-0.1.0/src/komodor_agentops/core/observe.py +78 -0
- komodor_agentops-0.1.0/src/komodor_agentops/core/rpc.py +21 -0
- komodor_agentops-0.1.0/src/komodor_agentops/core/secrets.py +210 -0
- komodor_agentops-0.1.0/src/komodor_agentops/core/skills.py +254 -0
- komodor_agentops-0.1.0/src/komodor_agentops/core/transport.py +482 -0
- komodor_agentops-0.1.0/src/komodor_agentops/core/types.py +222 -0
- komodor_agentops-0.1.0/src/komodor_agentops/core/usage.py +176 -0
- komodor_agentops-0.1.0/src/komodor_agentops/github.py +99 -0
- komodor_agentops-0.1.0/src/komodor_agentops/grade_context.py +45 -0
- komodor_agentops-0.1.0/src/komodor_agentops/knowledge.py +134 -0
- komodor_agentops-0.1.0/src/komodor_agentops/observability.py +338 -0
- komodor_agentops-0.1.0/src/komodor_agentops/py.typed +0 -0
- komodor_agentops-0.1.0/src/komodor_agentops/runtime.py +206 -0
- komodor_agentops-0.1.0/src/komodor_agentops/schemas/agent-spec.schema.json +115 -0
- komodor_agentops-0.1.0/src/komodor_agentops/shipper/__init__.py +60 -0
- komodor_agentops-0.1.0/src/komodor_agentops/shipper/queue.py +59 -0
- komodor_agentops-0.1.0/src/komodor_agentops/shipper/retry.py +52 -0
- komodor_agentops-0.1.0/src/komodor_agentops/shipper/sender.py +139 -0
- komodor_agentops-0.1.0/src/komodor_agentops/worker/__init__.py +21 -0
- komodor_agentops-0.1.0/src/komodor_agentops/worker/_async.py +17 -0
- komodor_agentops-0.1.0/src/komodor_agentops/worker/a2a/__init__.py +0 -0
- komodor_agentops-0.1.0/src/komodor_agentops/worker/a2a/executor.py +313 -0
- komodor_agentops-0.1.0/src/komodor_agentops/worker/a2a/server.py +104 -0
- komodor_agentops-0.1.0/src/komodor_agentops/worker/a2a/streaming.py +23 -0
- komodor_agentops-0.1.0/src/komodor_agentops/worker/bootstrap.py +101 -0
- komodor_agentops-0.1.0/src/komodor_agentops/worker/builtin_use_cases.py +104 -0
- komodor_agentops-0.1.0/src/komodor_agentops/worker/channel/__init__.py +0 -0
- komodor_agentops-0.1.0/src/komodor_agentops/worker/channel/listener.py +144 -0
- komodor_agentops-0.1.0/src/komodor_agentops/worker/hooks/__init__.py +0 -0
- komodor_agentops-0.1.0/src/komodor_agentops/worker/hooks/heartbeat.py +103 -0
- komodor_agentops-0.1.0/src/komodor_agentops/worker/hooks/reporter.py +159 -0
- komodor_agentops-0.1.0/src/komodor_agentops/worker/local.py +332 -0
- komodor_agentops-0.1.0/src/komodor_agentops/worker/logging_bridge.py +42 -0
- komodor_agentops-0.1.0/src/komodor_agentops/worker/orchestrator.py +584 -0
- komodor_agentops-0.1.0/src/komodor_agentops/worker/result.py +57 -0
- komodor_agentops-0.1.0/src/komodor_agentops/worker/server.py +315 -0
- komodor_agentops-0.1.0/src/komodor_agentops/worker/snapshot.py +34 -0
- komodor_agentops-0.1.0/src/komodor_agentops/worker/stream/__init__.py +0 -0
- komodor_agentops-0.1.0/src/komodor_agentops/worker/stream/server.py +88 -0
- komodor_agentops-0.1.0/src/komodor_agentops.egg-info/PKG-INFO +218 -0
- komodor_agentops-0.1.0/src/komodor_agentops.egg-info/SOURCES.txt +122 -0
- komodor_agentops-0.1.0/src/komodor_agentops.egg-info/dependency_links.txt +1 -0
- komodor_agentops-0.1.0/src/komodor_agentops.egg-info/entry_points.txt +4 -0
- komodor_agentops-0.1.0/src/komodor_agentops.egg-info/requires.txt +29 -0
- komodor_agentops-0.1.0/src/komodor_agentops.egg-info/top_level.txt +1 -0
- komodor_agentops-0.1.0/tests/test_a2a_server.py +518 -0
- komodor_agentops-0.1.0/tests/test_adk_e2e.py +154 -0
- komodor_agentops-0.1.0/tests/test_adk_llm_events.py +162 -0
- komodor_agentops-0.1.0/tests/test_adk_session_events.py +137 -0
- komodor_agentops-0.1.0/tests/test_adk_tool_events.py +178 -0
- komodor_agentops-0.1.0/tests/test_artifact_client.py +49 -0
- komodor_agentops-0.1.0/tests/test_builtin_use_cases.py +90 -0
- komodor_agentops-0.1.0/tests/test_channel_listener.py +261 -0
- komodor_agentops-0.1.0/tests/test_claude_code.py +1322 -0
- komodor_agentops-0.1.0/tests/test_claude_worker_real_sdk.py +200 -0
- komodor_agentops-0.1.0/tests/test_client.py +122 -0
- komodor_agentops-0.1.0/tests/test_context.py +55 -0
- komodor_agentops-0.1.0/tests/test_dependencies.py +80 -0
- komodor_agentops-0.1.0/tests/test_errors.py +74 -0
- komodor_agentops-0.1.0/tests/test_flush.py +131 -0
- komodor_agentops-0.1.0/tests/test_flush_pump.py +62 -0
- komodor_agentops-0.1.0/tests/test_hooks_reporter.py +181 -0
- komodor_agentops-0.1.0/tests/test_knowledge_client.py +22 -0
- komodor_agentops-0.1.0/tests/test_logging_bridge.py +111 -0
- komodor_agentops-0.1.0/tests/test_new_worker.py +145 -0
- komodor_agentops-0.1.0/tests/test_observe.py +117 -0
- komodor_agentops-0.1.0/tests/test_orchestrator_channel.py +711 -0
- komodor_agentops-0.1.0/tests/test_public_import.py +11 -0
- komodor_agentops-0.1.0/tests/test_redaction.py +97 -0
- komodor_agentops-0.1.0/tests/test_reporter_run_lifecycle.py +112 -0
- komodor_agentops-0.1.0/tests/test_result_task.py +46 -0
- komodor_agentops-0.1.0/tests/test_rpc.py +30 -0
- komodor_agentops-0.1.0/tests/test_secrets.py +256 -0
- komodor_agentops-0.1.0/tests/test_session_snapshot.py +543 -0
- komodor_agentops-0.1.0/tests/test_skills.py +188 -0
- komodor_agentops-0.1.0/tests/test_stream_server.py +87 -0
- komodor_agentops-0.1.0/tests/test_telemetry.py +680 -0
- komodor_agentops-0.1.0/tests/test_transport_auth.py +121 -0
- komodor_agentops-0.1.0/tests/test_types.py +471 -0
- komodor_agentops-0.1.0/tests/test_usage_collection.py +86 -0
- komodor_agentops-0.1.0/tests/test_worker_local.py +122 -0
- komodor_agentops-0.1.0/tests/test_worker_seams.py +286 -0
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
Komodor AgentOps License
|
|
2
|
+
|
|
3
|
+
The Komodor AgentOps SDK, together with its associated libraries, documentation,
|
|
4
|
+
and files (the "Software"), is provided by Komodor Ltd. ("Komodor") for integration
|
|
5
|
+
with the Komodor service (the "Service"). By installing, copying, or using the
|
|
6
|
+
Software, you agree to these terms.
|
|
7
|
+
|
|
8
|
+
© 2020 - Komodor Ltd.
|
|
9
|
+
|
|
10
|
+
Grant. Subject to your compliance with these terms, Komodor grants you a
|
|
11
|
+
non-exclusive, non-transferable, non-sublicensable, worldwide, revocable, and
|
|
12
|
+
limited license to (a) install and use the Software to develop, test, and operate
|
|
13
|
+
integrations of your applications and services with the Service, or to use
|
|
14
|
+
applications and services that embed the Software, and (b) reproduce
|
|
15
|
+
and distribute verbatim copies of the Software, but only as embedded within your own
|
|
16
|
+
applications, services, or container images, and not on a standalone basis. No
|
|
17
|
+
separate agreement with Komodor is required; anyone who obtains the Software
|
|
18
|
+
receives this license. If you have a separate written agreement with Komodor
|
|
19
|
+
covering the Software, that agreement controls to the extent of any conflict.
|
|
20
|
+
|
|
21
|
+
You may develop and operate your own software that imports, calls, subclasses,
|
|
22
|
+
configures, or otherwise depends on the Software through its published interfaces;
|
|
23
|
+
doing so is permitted use and does not, by itself, create a modified version or
|
|
24
|
+
derivative work of the Software.
|
|
25
|
+
|
|
26
|
+
Restrictions. You shall not: (a) distribute the Software on a standalone basis, or
|
|
27
|
+
resell, lease, or sublicense it; (b) offer the Software itself, or substantially its
|
|
28
|
+
standalone functionality, to third parties as a hosted or managed service — this
|
|
29
|
+
does not restrict you from operating or offering your own applications or services
|
|
30
|
+
that embed the Software; (c) modify the Software or create a derivative work of its
|
|
31
|
+
files or code; (d) remove, alter, or obscure any copyright, license, or proprietary
|
|
32
|
+
notice, all of which you must retain in every copy you distribute; or (e) claim any
|
|
33
|
+
proprietary interest in the Software, or contest or infringe Komodor's intellectual
|
|
34
|
+
property rights in it.
|
|
35
|
+
|
|
36
|
+
Ownership. The Software is licensed, not sold. Komodor retains all right, title, and
|
|
37
|
+
interest in and to the Software and all intellectual property rights in it. No
|
|
38
|
+
rights are granted except as expressly stated here, and no patent rights are
|
|
39
|
+
granted. This license does not permit use of Komodor's names or trademarks, except
|
|
40
|
+
for reasonable and customary use in describing the origin of the Software.
|
|
41
|
+
|
|
42
|
+
Termination. This license terminates automatically if you breach it and do not cure
|
|
43
|
+
the breach within thirty (30) days of Komodor's written notice. On termination you
|
|
44
|
+
must stop installing, using, and distributing the Software, except that copies
|
|
45
|
+
already embedded in products you distributed to end users before termination may
|
|
46
|
+
remain in use. The Restrictions and this "No warranty; no liability" section survive termination.
|
|
47
|
+
|
|
48
|
+
No warranty; no liability. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
|
49
|
+
KIND, EXPRESS OR IMPLIED, INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY,
|
|
50
|
+
FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND NON-INFRINGEMENT. IN NO EVENT SHALL
|
|
51
|
+
KOMODOR OR THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER
|
|
52
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT, OR OTHERWISE, ARISING FROM, OUT
|
|
53
|
+
OF, OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: komodor-agentops
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Python SDK for AgentOps observability.
|
|
5
|
+
Author: Komodor Ltd.
|
|
6
|
+
License-Expression: LicenseRef-Komodor-Proprietary
|
|
7
|
+
Project-URL: Homepage, https://agentops.komodor.com
|
|
8
|
+
Requires-Python: >=3.11
|
|
9
|
+
Description-Content-Type: text/markdown
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Requires-Dist: agentops-otel~=0.1.0
|
|
12
|
+
Requires-Dist: agentops-rpc~=0.1.0
|
|
13
|
+
Requires-Dist: a2a-sdk[http-server]<2,>=1.0
|
|
14
|
+
Requires-Dist: croniter>=2.0
|
|
15
|
+
Requires-Dist: fastapi>=0.136.1
|
|
16
|
+
Requires-Dist: httpx
|
|
17
|
+
Requires-Dist: pydantic>=2.0
|
|
18
|
+
Requires-Dist: pydantic-settings>=2.0
|
|
19
|
+
Requires-Dist: python-frontmatter>=1.2.0
|
|
20
|
+
Requires-Dist: pyyaml>=6.0.3
|
|
21
|
+
Requires-Dist: uvicorn[standard]>=0.46.0
|
|
22
|
+
Provides-Extra: server
|
|
23
|
+
Provides-Extra: langchain
|
|
24
|
+
Requires-Dist: langchain-core; extra == "langchain"
|
|
25
|
+
Provides-Extra: claude-code
|
|
26
|
+
Requires-Dist: claude-agent-sdk>=0.1.81; extra == "claude-code"
|
|
27
|
+
Provides-Extra: adk
|
|
28
|
+
Requires-Dist: google-adk[extensions]>=2.2.0; extra == "adk"
|
|
29
|
+
Provides-Extra: agno
|
|
30
|
+
Requires-Dist: agno<3,>=2.6; extra == "agno"
|
|
31
|
+
Requires-Dist: anthropic>=0.40; extra == "agno"
|
|
32
|
+
Provides-Extra: all
|
|
33
|
+
Requires-Dist: komodor-agentops[adk,agno,claude-code,langchain]; extra == "all"
|
|
34
|
+
Dynamic: license-file
|
|
35
|
+
|
|
36
|
+
# komodor-agentops
|
|
37
|
+
|
|
38
|
+
Python SDK for AgentOps observability, including the worker runtime, with
|
|
39
|
+
optional extras for framework integrations (LangChain, Claude Agent SDK, ADK,
|
|
40
|
+
Agno).
|
|
41
|
+
|
|
42
|
+
## Install
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
pip install komodor-agentops
|
|
46
|
+
|
|
47
|
+
# With framework adapters
|
|
48
|
+
pip install komodor-agentops[langchain]
|
|
49
|
+
pip install komodor-agentops[claude-code]
|
|
50
|
+
pip install komodor-agentops[adk]
|
|
51
|
+
pip install komodor-agentops[agno]
|
|
52
|
+
pip install komodor-agentops[all] # Everything
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Quick Start
|
|
56
|
+
|
|
57
|
+
### @observe() decorator
|
|
58
|
+
|
|
59
|
+
Wrap functions to emit span events automatically:
|
|
60
|
+
|
|
61
|
+
```python
|
|
62
|
+
from komodor_agentops import observe
|
|
63
|
+
|
|
64
|
+
@observe(name="summarize", as_type="llm")
|
|
65
|
+
async def summarize(text: str) -> str:
|
|
66
|
+
...
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### AgentOps client (lightweight event buffer)
|
|
70
|
+
|
|
71
|
+
```python
|
|
72
|
+
from komodor_agentops import AgentOps
|
|
73
|
+
|
|
74
|
+
client = AgentOps(agent_id="my-agent", endpoint="http://localhost:8000")
|
|
75
|
+
await client.log("Processing started", run_id="run_1")
|
|
76
|
+
await client.flush()
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### TransportClient (full controlplane client)
|
|
80
|
+
|
|
81
|
+
For direct controlplane interaction (heartbeat, run lifecycle, event ingest):
|
|
82
|
+
|
|
83
|
+
```python
|
|
84
|
+
from komodor_agentops import TransportClient, AgentSpec
|
|
85
|
+
|
|
86
|
+
agent = AgentSpec(agent_id="my-agent", agent_card={"name": "My Agent"})
|
|
87
|
+
async with TransportClient(endpoint="http://localhost:8000", worker_id="wrk_1", agent=agent) as ops:
|
|
88
|
+
await ops.heartbeat()
|
|
89
|
+
run = await ops.start_run_direct("run_1", input_payload={"prompt": "hello"})
|
|
90
|
+
await ops.emit_span_start(run_id="run_1", span_id="s1", name="tool", span_kind="tool")
|
|
91
|
+
await ops.emit_span_end(run_id="run_1", span_id="s1", name="tool", span_kind="tool")
|
|
92
|
+
await ops.complete_run("run_1", output={"result": "done"})
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### AgentOpsWorker (unified server)
|
|
96
|
+
|
|
97
|
+
Run a worker with A2A protocol + AgentOps streaming:
|
|
98
|
+
|
|
99
|
+
```python
|
|
100
|
+
from pathlib import Path
|
|
101
|
+
|
|
102
|
+
from komodor_agentops import AgentOpsWorker, AgentSpec, A2AMessage, A2ATask
|
|
103
|
+
|
|
104
|
+
spec = AgentSpec.from_dir(
|
|
105
|
+
Path(__file__).parent,
|
|
106
|
+
agent_card={"skills": [{"id": "search", "name": "search"}]},
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
async def handler(message: A2AMessage) -> A2ATask:
|
|
110
|
+
return A2ATask(id=message.task_id, status={"state": "completed"})
|
|
111
|
+
|
|
112
|
+
worker = AgentOpsWorker(agent=spec, handler=handler)
|
|
113
|
+
await worker.serve(host="0.0.0.0", port=8010)
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
The standard AgentOps agent layout is:
|
|
117
|
+
|
|
118
|
+
```text
|
|
119
|
+
my_agent/
|
|
120
|
+
agent-spec.yaml
|
|
121
|
+
agent.md
|
|
122
|
+
worker.py
|
|
123
|
+
skills/
|
|
124
|
+
triage.md
|
|
125
|
+
rca/SKILL.md
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
`AgentSpec.from_dir(Path(__file__).parent, ...)` requires `agent-spec.yaml`, then loads `agent.md` and `skills/` automatically. The worker registers loaded skills during heartbeat, and SDK-owned LLM adapters can prepend the agent context at invocation time.
|
|
129
|
+
|
|
130
|
+
```yaml
|
|
131
|
+
schema_version: 1
|
|
132
|
+
agent_id: my-agent
|
|
133
|
+
name: My Agent
|
|
134
|
+
description: Does useful work.
|
|
135
|
+
owner: AgentOps
|
|
136
|
+
repo: https://github.com/komodorio/agentops
|
|
137
|
+
source_path: packages/workers/my_agent
|
|
138
|
+
labels:
|
|
139
|
+
category: example
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
To make a worker available in the AgentOps Chat UI, advertise chat capability on its agent card:
|
|
143
|
+
|
|
144
|
+
```python
|
|
145
|
+
spec = AgentSpec(
|
|
146
|
+
agent_id="my-chat-agent",
|
|
147
|
+
agent_card={
|
|
148
|
+
"name": "My Chat Agent",
|
|
149
|
+
"capabilities": {"chat": True, "ask": True, "streaming": True},
|
|
150
|
+
},
|
|
151
|
+
)
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
Control plane chat sessions invoke the selected worker over A2A with input data that includes `messages` (conversation history), `model`, and `prompt` (latest user text). A2A message parts use the proto-style shape accepted by `AgentOpsWorker`, such as `{"text": "..."}` and `{"data": {...}}`.
|
|
155
|
+
|
|
156
|
+
## Framework Adapters
|
|
157
|
+
|
|
158
|
+
### LangChain
|
|
159
|
+
|
|
160
|
+
```python
|
|
161
|
+
from komodor_agentops.langchain import KomodorCallbackHandler
|
|
162
|
+
|
|
163
|
+
handler = KomodorCallbackHandler(ops=transport_client, controlplane_run_id="run_1")
|
|
164
|
+
chain.invoke(input, config={"callbacks": [handler]})
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### Claude Code
|
|
168
|
+
|
|
169
|
+
Install hooks that forward Claude Code events to the controlplane:
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
install-cc-hooks --endpoint http://localhost:8000
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
SDK hooks for `claude-agent-sdk`:
|
|
176
|
+
|
|
177
|
+
```python
|
|
178
|
+
from komodor_agentops.claude_code.sdk_hooks import agent_ops_hooks_for_run
|
|
179
|
+
|
|
180
|
+
hooks = agent_ops_hooks_for_run("run_1")
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
## Architecture
|
|
184
|
+
|
|
185
|
+
```
|
|
186
|
+
komodor-agentops
|
|
187
|
+
agentops-rpc, agentops-otel (wire types + OTel bootstrap)
|
|
188
|
+
fastapi, uvicorn, a2a-sdk (worker/server runtime)
|
|
189
|
+
httpx, pydantic, pydantic-settings, croniter, pyyaml, python-frontmatter
|
|
190
|
+
|
|
|
191
|
+
+-- [langchain] -> langchain-core
|
|
192
|
+
+-- [claude-code] -> claude-agent-sdk
|
|
193
|
+
+-- [adk] -> google-adk
|
|
194
|
+
+-- [agno] -> agno, anthropic
|
|
195
|
+
+-- [server] -> no-op alias (kept so existing [server] refs resolve)
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
## Package Structure
|
|
199
|
+
|
|
200
|
+
```
|
|
201
|
+
src/komodor_agentops/
|
|
202
|
+
__init__.py # Public API
|
|
203
|
+
_client.py # Event buffer + flush
|
|
204
|
+
_transport.py # Full controlplane HTTP client
|
|
205
|
+
_context.py # TraceContext + ContextVar
|
|
206
|
+
_events.py # AgentOpsEvent dataclass
|
|
207
|
+
_flush.py # Async event batching
|
|
208
|
+
_observe.py # @observe() decorator
|
|
209
|
+
_rpc.py # JSON-RPC helpers
|
|
210
|
+
_types.py # Internal SDK types (AgentSpec, RunJob, etc.)
|
|
211
|
+
worker.py # AgentOpsWorker facade
|
|
212
|
+
py.typed # PEP 561 marker
|
|
213
|
+
a2a/ # A2A protocol bridge
|
|
214
|
+
stream/ # SSE/JSON-RPC streaming
|
|
215
|
+
hooks/ # Reporter + heartbeat
|
|
216
|
+
langchain/ # LangChain callback handler
|
|
217
|
+
claude_code/ # Claude Code integration
|
|
218
|
+
```
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
# komodor-agentops
|
|
2
|
+
|
|
3
|
+
Python SDK for AgentOps observability, including the worker runtime, with
|
|
4
|
+
optional extras for framework integrations (LangChain, Claude Agent SDK, ADK,
|
|
5
|
+
Agno).
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
pip install komodor-agentops
|
|
11
|
+
|
|
12
|
+
# With framework adapters
|
|
13
|
+
pip install komodor-agentops[langchain]
|
|
14
|
+
pip install komodor-agentops[claude-code]
|
|
15
|
+
pip install komodor-agentops[adk]
|
|
16
|
+
pip install komodor-agentops[agno]
|
|
17
|
+
pip install komodor-agentops[all] # Everything
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Quick Start
|
|
21
|
+
|
|
22
|
+
### @observe() decorator
|
|
23
|
+
|
|
24
|
+
Wrap functions to emit span events automatically:
|
|
25
|
+
|
|
26
|
+
```python
|
|
27
|
+
from komodor_agentops import observe
|
|
28
|
+
|
|
29
|
+
@observe(name="summarize", as_type="llm")
|
|
30
|
+
async def summarize(text: str) -> str:
|
|
31
|
+
...
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### AgentOps client (lightweight event buffer)
|
|
35
|
+
|
|
36
|
+
```python
|
|
37
|
+
from komodor_agentops import AgentOps
|
|
38
|
+
|
|
39
|
+
client = AgentOps(agent_id="my-agent", endpoint="http://localhost:8000")
|
|
40
|
+
await client.log("Processing started", run_id="run_1")
|
|
41
|
+
await client.flush()
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### TransportClient (full controlplane client)
|
|
45
|
+
|
|
46
|
+
For direct controlplane interaction (heartbeat, run lifecycle, event ingest):
|
|
47
|
+
|
|
48
|
+
```python
|
|
49
|
+
from komodor_agentops import TransportClient, AgentSpec
|
|
50
|
+
|
|
51
|
+
agent = AgentSpec(agent_id="my-agent", agent_card={"name": "My Agent"})
|
|
52
|
+
async with TransportClient(endpoint="http://localhost:8000", worker_id="wrk_1", agent=agent) as ops:
|
|
53
|
+
await ops.heartbeat()
|
|
54
|
+
run = await ops.start_run_direct("run_1", input_payload={"prompt": "hello"})
|
|
55
|
+
await ops.emit_span_start(run_id="run_1", span_id="s1", name="tool", span_kind="tool")
|
|
56
|
+
await ops.emit_span_end(run_id="run_1", span_id="s1", name="tool", span_kind="tool")
|
|
57
|
+
await ops.complete_run("run_1", output={"result": "done"})
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### AgentOpsWorker (unified server)
|
|
61
|
+
|
|
62
|
+
Run a worker with A2A protocol + AgentOps streaming:
|
|
63
|
+
|
|
64
|
+
```python
|
|
65
|
+
from pathlib import Path
|
|
66
|
+
|
|
67
|
+
from komodor_agentops import AgentOpsWorker, AgentSpec, A2AMessage, A2ATask
|
|
68
|
+
|
|
69
|
+
spec = AgentSpec.from_dir(
|
|
70
|
+
Path(__file__).parent,
|
|
71
|
+
agent_card={"skills": [{"id": "search", "name": "search"}]},
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
async def handler(message: A2AMessage) -> A2ATask:
|
|
75
|
+
return A2ATask(id=message.task_id, status={"state": "completed"})
|
|
76
|
+
|
|
77
|
+
worker = AgentOpsWorker(agent=spec, handler=handler)
|
|
78
|
+
await worker.serve(host="0.0.0.0", port=8010)
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
The standard AgentOps agent layout is:
|
|
82
|
+
|
|
83
|
+
```text
|
|
84
|
+
my_agent/
|
|
85
|
+
agent-spec.yaml
|
|
86
|
+
agent.md
|
|
87
|
+
worker.py
|
|
88
|
+
skills/
|
|
89
|
+
triage.md
|
|
90
|
+
rca/SKILL.md
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
`AgentSpec.from_dir(Path(__file__).parent, ...)` requires `agent-spec.yaml`, then loads `agent.md` and `skills/` automatically. The worker registers loaded skills during heartbeat, and SDK-owned LLM adapters can prepend the agent context at invocation time.
|
|
94
|
+
|
|
95
|
+
```yaml
|
|
96
|
+
schema_version: 1
|
|
97
|
+
agent_id: my-agent
|
|
98
|
+
name: My Agent
|
|
99
|
+
description: Does useful work.
|
|
100
|
+
owner: AgentOps
|
|
101
|
+
repo: https://github.com/komodorio/agentops
|
|
102
|
+
source_path: packages/workers/my_agent
|
|
103
|
+
labels:
|
|
104
|
+
category: example
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
To make a worker available in the AgentOps Chat UI, advertise chat capability on its agent card:
|
|
108
|
+
|
|
109
|
+
```python
|
|
110
|
+
spec = AgentSpec(
|
|
111
|
+
agent_id="my-chat-agent",
|
|
112
|
+
agent_card={
|
|
113
|
+
"name": "My Chat Agent",
|
|
114
|
+
"capabilities": {"chat": True, "ask": True, "streaming": True},
|
|
115
|
+
},
|
|
116
|
+
)
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Control plane chat sessions invoke the selected worker over A2A with input data that includes `messages` (conversation history), `model`, and `prompt` (latest user text). A2A message parts use the proto-style shape accepted by `AgentOpsWorker`, such as `{"text": "..."}` and `{"data": {...}}`.
|
|
120
|
+
|
|
121
|
+
## Framework Adapters
|
|
122
|
+
|
|
123
|
+
### LangChain
|
|
124
|
+
|
|
125
|
+
```python
|
|
126
|
+
from komodor_agentops.langchain import KomodorCallbackHandler
|
|
127
|
+
|
|
128
|
+
handler = KomodorCallbackHandler(ops=transport_client, controlplane_run_id="run_1")
|
|
129
|
+
chain.invoke(input, config={"callbacks": [handler]})
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### Claude Code
|
|
133
|
+
|
|
134
|
+
Install hooks that forward Claude Code events to the controlplane:
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
install-cc-hooks --endpoint http://localhost:8000
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
SDK hooks for `claude-agent-sdk`:
|
|
141
|
+
|
|
142
|
+
```python
|
|
143
|
+
from komodor_agentops.claude_code.sdk_hooks import agent_ops_hooks_for_run
|
|
144
|
+
|
|
145
|
+
hooks = agent_ops_hooks_for_run("run_1")
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
## Architecture
|
|
149
|
+
|
|
150
|
+
```
|
|
151
|
+
komodor-agentops
|
|
152
|
+
agentops-rpc, agentops-otel (wire types + OTel bootstrap)
|
|
153
|
+
fastapi, uvicorn, a2a-sdk (worker/server runtime)
|
|
154
|
+
httpx, pydantic, pydantic-settings, croniter, pyyaml, python-frontmatter
|
|
155
|
+
|
|
|
156
|
+
+-- [langchain] -> langchain-core
|
|
157
|
+
+-- [claude-code] -> claude-agent-sdk
|
|
158
|
+
+-- [adk] -> google-adk
|
|
159
|
+
+-- [agno] -> agno, anthropic
|
|
160
|
+
+-- [server] -> no-op alias (kept so existing [server] refs resolve)
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
## Package Structure
|
|
164
|
+
|
|
165
|
+
```
|
|
166
|
+
src/komodor_agentops/
|
|
167
|
+
__init__.py # Public API
|
|
168
|
+
_client.py # Event buffer + flush
|
|
169
|
+
_transport.py # Full controlplane HTTP client
|
|
170
|
+
_context.py # TraceContext + ContextVar
|
|
171
|
+
_events.py # AgentOpsEvent dataclass
|
|
172
|
+
_flush.py # Async event batching
|
|
173
|
+
_observe.py # @observe() decorator
|
|
174
|
+
_rpc.py # JSON-RPC helpers
|
|
175
|
+
_types.py # Internal SDK types (AgentSpec, RunJob, etc.)
|
|
176
|
+
worker.py # AgentOpsWorker facade
|
|
177
|
+
py.typed # PEP 561 marker
|
|
178
|
+
a2a/ # A2A protocol bridge
|
|
179
|
+
stream/ # SSE/JSON-RPC streaming
|
|
180
|
+
hooks/ # Reporter + heartbeat
|
|
181
|
+
langchain/ # LangChain callback handler
|
|
182
|
+
claude_code/ # Claude Code integration
|
|
183
|
+
```
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "komodor-agentops"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "Python SDK for AgentOps observability."
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
license = "LicenseRef-Komodor-Proprietary"
|
|
7
|
+
license-files = ["LICENSE"]
|
|
8
|
+
authors = [{ name = "Komodor Ltd." }]
|
|
9
|
+
requires-python = ">=3.11"
|
|
10
|
+
dependencies = [
|
|
11
|
+
"agentops-otel~=0.1.0",
|
|
12
|
+
"agentops-rpc~=0.1.0",
|
|
13
|
+
"a2a-sdk[http-server]>=1.0,<2",
|
|
14
|
+
"croniter>=2.0",
|
|
15
|
+
"fastapi>=0.136.1",
|
|
16
|
+
"httpx",
|
|
17
|
+
"pydantic>=2.0",
|
|
18
|
+
"pydantic-settings>=2.0",
|
|
19
|
+
"python-frontmatter>=1.2.0",
|
|
20
|
+
"pyyaml>=6.0.3",
|
|
21
|
+
"uvicorn[standard]>=0.46.0",
|
|
22
|
+
]
|
|
23
|
+
|
|
24
|
+
[project.urls]
|
|
25
|
+
Homepage = "https://agentops.komodor.com"
|
|
26
|
+
|
|
27
|
+
[project.optional-dependencies]
|
|
28
|
+
server = [] # kept as no-op alias so [server] refs resolve
|
|
29
|
+
langchain = [
|
|
30
|
+
"langchain-core",
|
|
31
|
+
]
|
|
32
|
+
claude-code = [
|
|
33
|
+
"claude-agent-sdk>=0.1.81",
|
|
34
|
+
]
|
|
35
|
+
adk = [
|
|
36
|
+
"google-adk[extensions]>=2.2.0",
|
|
37
|
+
]
|
|
38
|
+
agno = [
|
|
39
|
+
"agno>=2.6,<3",
|
|
40
|
+
"anthropic>=0.40",
|
|
41
|
+
]
|
|
42
|
+
all = [
|
|
43
|
+
"komodor-agentops[langchain,claude-code,adk,agno]",
|
|
44
|
+
]
|
|
45
|
+
|
|
46
|
+
[project.scripts]
|
|
47
|
+
install-cc-hooks = "komodor_agentops.adapters.claude_code.install:cli"
|
|
48
|
+
komodor-cc-hook = "komodor_agentops.adapters.claude_code.hook:main"
|
|
49
|
+
agentops-run-worker = "komodor_agentops.worker.local:cli"
|
|
50
|
+
|
|
51
|
+
[build-system]
|
|
52
|
+
requires = ["setuptools>=77"]
|
|
53
|
+
build-backend = "setuptools.build_meta"
|
|
54
|
+
|
|
55
|
+
[tool.setuptools.package-dir]
|
|
56
|
+
"" = "src"
|
|
57
|
+
|
|
58
|
+
[tool.setuptools.packages.find]
|
|
59
|
+
where = ["src"]
|
|
60
|
+
|
|
61
|
+
[tool.setuptools.package-data]
|
|
62
|
+
"komodor_agentops" = ["schemas/*.json"]
|
|
63
|
+
|
|
64
|
+
[tool.uv.sources]
|
|
65
|
+
agentops-otel = { workspace = true }
|
|
66
|
+
agentops-rpc = { workspace = true }
|
|
67
|
+
|
|
68
|
+
[dependency-groups]
|
|
69
|
+
dev = [
|
|
70
|
+
"respx>=0.23.1",
|
|
71
|
+
]
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
from agentops_rpc import (
|
|
2
|
+
GRADER_CAPABILITY,
|
|
3
|
+
REVIEW_CAPABILITY,
|
|
4
|
+
USE_CASE_INPUT_KEY,
|
|
5
|
+
A2AMessage,
|
|
6
|
+
A2AMessagePart,
|
|
7
|
+
A2ATask,
|
|
8
|
+
GradeContext,
|
|
9
|
+
GradeResult,
|
|
10
|
+
RunJob,
|
|
11
|
+
UseCase,
|
|
12
|
+
)
|
|
13
|
+
from komodor_agentops.artifacts import ArtifactClient, get_artifact_client
|
|
14
|
+
from komodor_agentops.client import AgentOpsClient as AgentOps
|
|
15
|
+
from komodor_agentops.client import get_client
|
|
16
|
+
from komodor_agentops.core.context import TraceContext
|
|
17
|
+
from komodor_agentops.core.events import AgentOpsEvent
|
|
18
|
+
from komodor_agentops.core.observe import observe
|
|
19
|
+
from komodor_agentops.core.secrets import apply_secret_to_env, get_run_secrets, get_secret
|
|
20
|
+
from komodor_agentops.core.skills import AgentMarkdown
|
|
21
|
+
from komodor_agentops.core.transport import AgentOpsClient as TransportClient
|
|
22
|
+
from komodor_agentops.core.types import AgentSpec
|
|
23
|
+
from komodor_agentops.core.usage import drain_usage, record_usage, reset_usage, usage_from_anthropic_response
|
|
24
|
+
from komodor_agentops.github import (
|
|
25
|
+
GitHubIntegrationError,
|
|
26
|
+
github_api_get,
|
|
27
|
+
github_api_patch,
|
|
28
|
+
github_api_post,
|
|
29
|
+
github_graphql,
|
|
30
|
+
github_installation_token,
|
|
31
|
+
)
|
|
32
|
+
from komodor_agentops.grade_context import fetch_grade_context
|
|
33
|
+
from komodor_agentops.worker import (
|
|
34
|
+
AgentOpsWorker,
|
|
35
|
+
collect_env_secrets,
|
|
36
|
+
fetch_controlplane_secrets,
|
|
37
|
+
load_env_files,
|
|
38
|
+
run_worker_once,
|
|
39
|
+
run_worker_once_sync,
|
|
40
|
+
)
|
|
41
|
+
from komodor_agentops.worker.a2a.streaming import stream_status_text
|
|
42
|
+
from komodor_agentops.worker.result import DESCRIPTIVE_OUTPUT_KEY, result_task
|
|
43
|
+
from komodor_agentops.worker.server import create_worker_app, event_sink_from_client, register_worker_endpoint
|
|
44
|
+
|
|
45
|
+
__all__ = [
|
|
46
|
+
"ArtifactClient",
|
|
47
|
+
"get_artifact_client",
|
|
48
|
+
"AgentOps",
|
|
49
|
+
"AgentMarkdown",
|
|
50
|
+
"AgentOpsEvent",
|
|
51
|
+
"AgentOpsWorker",
|
|
52
|
+
"A2AMessage",
|
|
53
|
+
"A2AMessagePart",
|
|
54
|
+
"A2ATask",
|
|
55
|
+
"AgentSpec",
|
|
56
|
+
"DESCRIPTIVE_OUTPUT_KEY",
|
|
57
|
+
"GRADER_CAPABILITY",
|
|
58
|
+
"REVIEW_CAPABILITY",
|
|
59
|
+
"USE_CASE_INPUT_KEY",
|
|
60
|
+
"GitHubIntegrationError",
|
|
61
|
+
"GradeContext",
|
|
62
|
+
"GradeResult",
|
|
63
|
+
"fetch_grade_context",
|
|
64
|
+
"RunJob",
|
|
65
|
+
"UseCase",
|
|
66
|
+
"apply_secret_to_env",
|
|
67
|
+
"collect_env_secrets",
|
|
68
|
+
"fetch_controlplane_secrets",
|
|
69
|
+
"TraceContext",
|
|
70
|
+
"TransportClient",
|
|
71
|
+
"create_worker_app",
|
|
72
|
+
"event_sink_from_client",
|
|
73
|
+
"get_client",
|
|
74
|
+
"get_run_secrets",
|
|
75
|
+
"github_api_get",
|
|
76
|
+
"github_api_patch",
|
|
77
|
+
"github_api_post",
|
|
78
|
+
"github_graphql",
|
|
79
|
+
"github_installation_token",
|
|
80
|
+
"get_secret",
|
|
81
|
+
"load_env_files",
|
|
82
|
+
"observe",
|
|
83
|
+
"record_usage",
|
|
84
|
+
"register_worker_endpoint",
|
|
85
|
+
"result_task",
|
|
86
|
+
"reset_usage",
|
|
87
|
+
"run_worker_once",
|
|
88
|
+
"run_worker_once_sync",
|
|
89
|
+
"drain_usage",
|
|
90
|
+
"stream_status_text",
|
|
91
|
+
"usage_from_anthropic_response",
|
|
92
|
+
]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Adapter modules for third-party agent frameworks."""
|