agent-observatory-cli 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.
- agent_observatory_cli-0.1.0/LICENSE +21 -0
- agent_observatory_cli-0.1.0/PKG-INFO +115 -0
- agent_observatory_cli-0.1.0/README.md +79 -0
- agent_observatory_cli-0.1.0/agent_observatory_cli.egg-info/PKG-INFO +115 -0
- agent_observatory_cli-0.1.0/agent_observatory_cli.egg-info/SOURCES.txt +37 -0
- agent_observatory_cli-0.1.0/agent_observatory_cli.egg-info/dependency_links.txt +1 -0
- agent_observatory_cli-0.1.0/agent_observatory_cli.egg-info/entry_points.txt +2 -0
- agent_observatory_cli-0.1.0/agent_observatory_cli.egg-info/requires.txt +14 -0
- agent_observatory_cli-0.1.0/agent_observatory_cli.egg-info/top_level.txt +1 -0
- agent_observatory_cli-0.1.0/observatory/__init__.py +5 -0
- agent_observatory_cli-0.1.0/observatory/__main__.py +105 -0
- agent_observatory_cli-0.1.0/observatory/activity.css +10 -0
- agent_observatory_cli-0.1.0/observatory/activity.js +116 -0
- agent_observatory_cli-0.1.0/observatory/auto.py +212 -0
- agent_observatory_cli-0.1.0/observatory/client.py +253 -0
- agent_observatory_cli-0.1.0/observatory/core.py +1654 -0
- agent_observatory_cli-0.1.0/observatory/distribution.py +67 -0
- agent_observatory_cli-0.1.0/observatory/findings.py +176 -0
- agent_observatory_cli-0.1.0/observatory/index.html +84 -0
- agent_observatory_cli-0.1.0/observatory/integrations/__init__.py +1 -0
- agent_observatory_cli-0.1.0/observatory/integrations/langchain.py +234 -0
- agent_observatory_cli-0.1.0/observatory/integrations/openai_agents.py +177 -0
- agent_observatory_cli-0.1.0/observatory/local_activity.py +207 -0
- agent_observatory_cli-0.1.0/observatory/local_agents.py +394 -0
- agent_observatory_cli-0.1.0/observatory/local_runtime.py +49 -0
- agent_observatory_cli-0.1.0/observatory/logs.py +109 -0
- agent_observatory_cli-0.1.0/observatory/metrics.py +281 -0
- agent_observatory_cli-0.1.0/observatory/otlp_proto.py +210 -0
- agent_observatory_cli-0.1.0/observatory/server.py +368 -0
- agent_observatory_cli-0.1.0/observatory/setup.css +40 -0
- agent_observatory_cli-0.1.0/observatory/setup.js +145 -0
- agent_observatory_cli-0.1.0/observatory/terminal.py +525 -0
- agent_observatory_cli-0.1.0/observatory/terminal_ui.py +1299 -0
- agent_observatory_cli-0.1.0/observatory/watch.py +62 -0
- agent_observatory_cli-0.1.0/pyproject.toml +49 -0
- agent_observatory_cli-0.1.0/setup.cfg +4 -0
- agent_observatory_cli-0.1.0/tests/test_observatory.py +366 -0
- agent_observatory_cli-0.1.0/tests/test_terminal_search.py +375 -0
- agent_observatory_cli-0.1.0/tests/test_terminal_usability.py +221 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 abhishekash
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: agent-observatory-cli
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Local agent trace receiver and investigation dashboard
|
|
5
|
+
License-Expression: MIT
|
|
6
|
+
Project-URL: Repository, https://github.com/abhishekash/agent-observatory
|
|
7
|
+
Project-URL: Issues, https://github.com/abhishekash/agent-observatory/issues
|
|
8
|
+
Keywords: agents,observability,opentelemetry,otlp,tracing
|
|
9
|
+
Classifier: Development Status :: 3 - Alpha
|
|
10
|
+
Classifier: Environment :: Console
|
|
11
|
+
Classifier: Framework :: AsyncIO
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: Operating System :: OS Independent
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
19
|
+
Classifier: Topic :: Software Development :: Debuggers
|
|
20
|
+
Classifier: Topic :: System :: Monitoring
|
|
21
|
+
Requires-Python: >=3.11
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
License-File: LICENSE
|
|
24
|
+
Requires-Dist: textual<9,>=8.2
|
|
25
|
+
Provides-Extra: auto
|
|
26
|
+
Requires-Dist: opentelemetry-sdk<2,>=1.27; extra == "auto"
|
|
27
|
+
Requires-Dist: opentelemetry-exporter-otlp-proto-http<2,>=1.27; extra == "auto"
|
|
28
|
+
Requires-Dist: openinference-instrumentation-openai>=0.1; extra == "auto"
|
|
29
|
+
Requires-Dist: openinference-instrumentation-anthropic>=0.1; extra == "auto"
|
|
30
|
+
Requires-Dist: openinference-instrumentation-langchain>=0.1; extra == "auto"
|
|
31
|
+
Provides-Extra: langchain
|
|
32
|
+
Requires-Dist: langchain-core<2,>=0.3.9; extra == "langchain"
|
|
33
|
+
Provides-Extra: openai-agents
|
|
34
|
+
Requires-Dist: openai-agents<2,>=0.1.0; extra == "openai-agents"
|
|
35
|
+
Dynamic: license-file
|
|
36
|
+
|
|
37
|
+
# Agent Observatory
|
|
38
|
+
|
|
39
|
+
[](https://github.com/abhishekash/agent-observatory/actions/workflows/ci.yml)
|
|
40
|
+
[](https://pypi.org/project/agent-observatory-cli/)
|
|
41
|
+

|
|
42
|
+

|
|
43
|
+

|
|
44
|
+
|
|
45
|
+
**See what your agents are doing, live.** Agent Observatory watches local Codex and Claude Code sessions, receives OpenTelemetry from instrumented agents, and brings tasks, tool calls, MCP, traces, tokens, errors, and host activity into one terminal cockpit and local web dashboard.
|
|
46
|
+
|
|
47
|
+
<p align="center">
|
|
48
|
+
<img src="media/terminal-demo.gif" alt="Animated preview of the Agent Observatory terminal cockpit with agents, MCP calls, traces, and host processes" width="960">
|
|
49
|
+
</p>
|
|
50
|
+
|
|
51
|
+
<p align="center"><em>Short demo using synthetic example data. No real session logs or user prompts are included.</em></p>
|
|
52
|
+
|
|
53
|
+
## Start in one command
|
|
54
|
+
|
|
55
|
+
Requires Python 3.11+. Install [uv](https://docs.astral.sh/uv/getting-started/installation/) if needed, then:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
uv tool install agent-observatory-cli
|
|
59
|
+
agent-observatory
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Or install it into the active Python environment with `python -m pip install agent-observatory-cli`.
|
|
63
|
+
|
|
64
|
+
The terminal cockpit discovers recent local Codex and Claude Code sessions automatically. Press **b** to open the local web dashboard. It listens on `127.0.0.1:14318`.
|
|
65
|
+
|
|
66
|
+
Already cloned the repository? Run the installer for your shell:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
./scripts/install.sh
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
```powershell
|
|
73
|
+
.\scripts\install.ps1
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
These install the checkout as an isolated uv tool. Re-run the script after pulling an update. No administrator access is needed.
|
|
77
|
+
|
|
78
|
+
## What you get
|
|
79
|
+
|
|
80
|
+
- **Agents:** distinct sessions, project, current task, model, recent actions, and activity state.
|
|
81
|
+
- **Activity:** readable user/assistant messages, shell commands, file changes, browser events, model use, and tool results.
|
|
82
|
+
- **MCP:** server and tool calls with readable arguments and results, an Errors filter, latency, and direct links to the execution span.
|
|
83
|
+
- **Traces:** parent/child spans, model usage, errors, and evidence for each operation.
|
|
84
|
+
- **Host:** known local agent processes and basic resource use, shown separately from sessions.
|
|
85
|
+
- **Web dashboard:** searchable live activity with the same local receiver.
|
|
86
|
+
|
|
87
|
+
The cockpit adapts from compact terminals to wide workspaces. Search stays with each view, **Enter** inspects a row, **e** expands the details, and **Esc** returns to the list. Drag to highlight inspector text and press **Ctrl+C** to copy it; **c** copies the current details. Activity, MCP Calls, and Traces include **Older / Newer / Latest** controls for stored history, and **Alt+Left** returns from a linked trace to the event you were reading.
|
|
88
|
+
|
|
89
|
+
The receiver stores data in a local SQLite file. Native session capture is bounded and redacts recognizable credentials on a best-effort basis. Choose metadata-only capture with `--metadata-only`. See [Privacy and capture boundaries](docs/privacy.md).
|
|
90
|
+
|
|
91
|
+
## Connect other agents
|
|
92
|
+
|
|
93
|
+
Send OpenTelemetry traces, logs, and metrics over OTLP/HTTP, or use the Python and JavaScript clients:
|
|
94
|
+
|
|
95
|
+
- [Python setup and automatic SDK capture](docs/python.md)
|
|
96
|
+
- [Node.js client](docs/javascript.md)
|
|
97
|
+
- [OTLP, receiver, and deployment configuration](docs/receiver.md)
|
|
98
|
+
- [Complete usage guide and examples](docs/usage.md)
|
|
99
|
+
|
|
100
|
+
## Develop
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
git clone https://github.com/abhishekash/agent-observatory.git
|
|
104
|
+
cd agent-observatory
|
|
105
|
+
uv tool install --editable .
|
|
106
|
+
python -m unittest discover -s tests -v
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Contributions and bug reports are welcome. See [CONTRIBUTING.md](CONTRIBUTING.md) and [open an issue](https://github.com/abhishekash/agent-observatory/issues).
|
|
110
|
+
|
|
111
|
+
Maintainers can follow the [PyPI publishing guide](docs/publishing.md) to release a version with Trusted Publishing.
|
|
112
|
+
|
|
113
|
+
## License
|
|
114
|
+
|
|
115
|
+
Agent Observatory is distributed under the [MIT License](LICENSE).
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# Agent Observatory
|
|
2
|
+
|
|
3
|
+
[](https://github.com/abhishekash/agent-observatory/actions/workflows/ci.yml)
|
|
4
|
+
[](https://pypi.org/project/agent-observatory-cli/)
|
|
5
|
+

|
|
6
|
+

|
|
7
|
+

|
|
8
|
+
|
|
9
|
+
**See what your agents are doing, live.** Agent Observatory watches local Codex and Claude Code sessions, receives OpenTelemetry from instrumented agents, and brings tasks, tool calls, MCP, traces, tokens, errors, and host activity into one terminal cockpit and local web dashboard.
|
|
10
|
+
|
|
11
|
+
<p align="center">
|
|
12
|
+
<img src="media/terminal-demo.gif" alt="Animated preview of the Agent Observatory terminal cockpit with agents, MCP calls, traces, and host processes" width="960">
|
|
13
|
+
</p>
|
|
14
|
+
|
|
15
|
+
<p align="center"><em>Short demo using synthetic example data. No real session logs or user prompts are included.</em></p>
|
|
16
|
+
|
|
17
|
+
## Start in one command
|
|
18
|
+
|
|
19
|
+
Requires Python 3.11+. Install [uv](https://docs.astral.sh/uv/getting-started/installation/) if needed, then:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
uv tool install agent-observatory-cli
|
|
23
|
+
agent-observatory
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Or install it into the active Python environment with `python -m pip install agent-observatory-cli`.
|
|
27
|
+
|
|
28
|
+
The terminal cockpit discovers recent local Codex and Claude Code sessions automatically. Press **b** to open the local web dashboard. It listens on `127.0.0.1:14318`.
|
|
29
|
+
|
|
30
|
+
Already cloned the repository? Run the installer for your shell:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
./scripts/install.sh
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
```powershell
|
|
37
|
+
.\scripts\install.ps1
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
These install the checkout as an isolated uv tool. Re-run the script after pulling an update. No administrator access is needed.
|
|
41
|
+
|
|
42
|
+
## What you get
|
|
43
|
+
|
|
44
|
+
- **Agents:** distinct sessions, project, current task, model, recent actions, and activity state.
|
|
45
|
+
- **Activity:** readable user/assistant messages, shell commands, file changes, browser events, model use, and tool results.
|
|
46
|
+
- **MCP:** server and tool calls with readable arguments and results, an Errors filter, latency, and direct links to the execution span.
|
|
47
|
+
- **Traces:** parent/child spans, model usage, errors, and evidence for each operation.
|
|
48
|
+
- **Host:** known local agent processes and basic resource use, shown separately from sessions.
|
|
49
|
+
- **Web dashboard:** searchable live activity with the same local receiver.
|
|
50
|
+
|
|
51
|
+
The cockpit adapts from compact terminals to wide workspaces. Search stays with each view, **Enter** inspects a row, **e** expands the details, and **Esc** returns to the list. Drag to highlight inspector text and press **Ctrl+C** to copy it; **c** copies the current details. Activity, MCP Calls, and Traces include **Older / Newer / Latest** controls for stored history, and **Alt+Left** returns from a linked trace to the event you were reading.
|
|
52
|
+
|
|
53
|
+
The receiver stores data in a local SQLite file. Native session capture is bounded and redacts recognizable credentials on a best-effort basis. Choose metadata-only capture with `--metadata-only`. See [Privacy and capture boundaries](docs/privacy.md).
|
|
54
|
+
|
|
55
|
+
## Connect other agents
|
|
56
|
+
|
|
57
|
+
Send OpenTelemetry traces, logs, and metrics over OTLP/HTTP, or use the Python and JavaScript clients:
|
|
58
|
+
|
|
59
|
+
- [Python setup and automatic SDK capture](docs/python.md)
|
|
60
|
+
- [Node.js client](docs/javascript.md)
|
|
61
|
+
- [OTLP, receiver, and deployment configuration](docs/receiver.md)
|
|
62
|
+
- [Complete usage guide and examples](docs/usage.md)
|
|
63
|
+
|
|
64
|
+
## Develop
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
git clone https://github.com/abhishekash/agent-observatory.git
|
|
68
|
+
cd agent-observatory
|
|
69
|
+
uv tool install --editable .
|
|
70
|
+
python -m unittest discover -s tests -v
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Contributions and bug reports are welcome. See [CONTRIBUTING.md](CONTRIBUTING.md) and [open an issue](https://github.com/abhishekash/agent-observatory/issues).
|
|
74
|
+
|
|
75
|
+
Maintainers can follow the [PyPI publishing guide](docs/publishing.md) to release a version with Trusted Publishing.
|
|
76
|
+
|
|
77
|
+
## License
|
|
78
|
+
|
|
79
|
+
Agent Observatory is distributed under the [MIT License](LICENSE).
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: agent-observatory-cli
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Local agent trace receiver and investigation dashboard
|
|
5
|
+
License-Expression: MIT
|
|
6
|
+
Project-URL: Repository, https://github.com/abhishekash/agent-observatory
|
|
7
|
+
Project-URL: Issues, https://github.com/abhishekash/agent-observatory/issues
|
|
8
|
+
Keywords: agents,observability,opentelemetry,otlp,tracing
|
|
9
|
+
Classifier: Development Status :: 3 - Alpha
|
|
10
|
+
Classifier: Environment :: Console
|
|
11
|
+
Classifier: Framework :: AsyncIO
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: Operating System :: OS Independent
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
19
|
+
Classifier: Topic :: Software Development :: Debuggers
|
|
20
|
+
Classifier: Topic :: System :: Monitoring
|
|
21
|
+
Requires-Python: >=3.11
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
License-File: LICENSE
|
|
24
|
+
Requires-Dist: textual<9,>=8.2
|
|
25
|
+
Provides-Extra: auto
|
|
26
|
+
Requires-Dist: opentelemetry-sdk<2,>=1.27; extra == "auto"
|
|
27
|
+
Requires-Dist: opentelemetry-exporter-otlp-proto-http<2,>=1.27; extra == "auto"
|
|
28
|
+
Requires-Dist: openinference-instrumentation-openai>=0.1; extra == "auto"
|
|
29
|
+
Requires-Dist: openinference-instrumentation-anthropic>=0.1; extra == "auto"
|
|
30
|
+
Requires-Dist: openinference-instrumentation-langchain>=0.1; extra == "auto"
|
|
31
|
+
Provides-Extra: langchain
|
|
32
|
+
Requires-Dist: langchain-core<2,>=0.3.9; extra == "langchain"
|
|
33
|
+
Provides-Extra: openai-agents
|
|
34
|
+
Requires-Dist: openai-agents<2,>=0.1.0; extra == "openai-agents"
|
|
35
|
+
Dynamic: license-file
|
|
36
|
+
|
|
37
|
+
# Agent Observatory
|
|
38
|
+
|
|
39
|
+
[](https://github.com/abhishekash/agent-observatory/actions/workflows/ci.yml)
|
|
40
|
+
[](https://pypi.org/project/agent-observatory-cli/)
|
|
41
|
+

|
|
42
|
+

|
|
43
|
+

|
|
44
|
+
|
|
45
|
+
**See what your agents are doing, live.** Agent Observatory watches local Codex and Claude Code sessions, receives OpenTelemetry from instrumented agents, and brings tasks, tool calls, MCP, traces, tokens, errors, and host activity into one terminal cockpit and local web dashboard.
|
|
46
|
+
|
|
47
|
+
<p align="center">
|
|
48
|
+
<img src="media/terminal-demo.gif" alt="Animated preview of the Agent Observatory terminal cockpit with agents, MCP calls, traces, and host processes" width="960">
|
|
49
|
+
</p>
|
|
50
|
+
|
|
51
|
+
<p align="center"><em>Short demo using synthetic example data. No real session logs or user prompts are included.</em></p>
|
|
52
|
+
|
|
53
|
+
## Start in one command
|
|
54
|
+
|
|
55
|
+
Requires Python 3.11+. Install [uv](https://docs.astral.sh/uv/getting-started/installation/) if needed, then:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
uv tool install agent-observatory-cli
|
|
59
|
+
agent-observatory
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Or install it into the active Python environment with `python -m pip install agent-observatory-cli`.
|
|
63
|
+
|
|
64
|
+
The terminal cockpit discovers recent local Codex and Claude Code sessions automatically. Press **b** to open the local web dashboard. It listens on `127.0.0.1:14318`.
|
|
65
|
+
|
|
66
|
+
Already cloned the repository? Run the installer for your shell:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
./scripts/install.sh
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
```powershell
|
|
73
|
+
.\scripts\install.ps1
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
These install the checkout as an isolated uv tool. Re-run the script after pulling an update. No administrator access is needed.
|
|
77
|
+
|
|
78
|
+
## What you get
|
|
79
|
+
|
|
80
|
+
- **Agents:** distinct sessions, project, current task, model, recent actions, and activity state.
|
|
81
|
+
- **Activity:** readable user/assistant messages, shell commands, file changes, browser events, model use, and tool results.
|
|
82
|
+
- **MCP:** server and tool calls with readable arguments and results, an Errors filter, latency, and direct links to the execution span.
|
|
83
|
+
- **Traces:** parent/child spans, model usage, errors, and evidence for each operation.
|
|
84
|
+
- **Host:** known local agent processes and basic resource use, shown separately from sessions.
|
|
85
|
+
- **Web dashboard:** searchable live activity with the same local receiver.
|
|
86
|
+
|
|
87
|
+
The cockpit adapts from compact terminals to wide workspaces. Search stays with each view, **Enter** inspects a row, **e** expands the details, and **Esc** returns to the list. Drag to highlight inspector text and press **Ctrl+C** to copy it; **c** copies the current details. Activity, MCP Calls, and Traces include **Older / Newer / Latest** controls for stored history, and **Alt+Left** returns from a linked trace to the event you were reading.
|
|
88
|
+
|
|
89
|
+
The receiver stores data in a local SQLite file. Native session capture is bounded and redacts recognizable credentials on a best-effort basis. Choose metadata-only capture with `--metadata-only`. See [Privacy and capture boundaries](docs/privacy.md).
|
|
90
|
+
|
|
91
|
+
## Connect other agents
|
|
92
|
+
|
|
93
|
+
Send OpenTelemetry traces, logs, and metrics over OTLP/HTTP, or use the Python and JavaScript clients:
|
|
94
|
+
|
|
95
|
+
- [Python setup and automatic SDK capture](docs/python.md)
|
|
96
|
+
- [Node.js client](docs/javascript.md)
|
|
97
|
+
- [OTLP, receiver, and deployment configuration](docs/receiver.md)
|
|
98
|
+
- [Complete usage guide and examples](docs/usage.md)
|
|
99
|
+
|
|
100
|
+
## Develop
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
git clone https://github.com/abhishekash/agent-observatory.git
|
|
104
|
+
cd agent-observatory
|
|
105
|
+
uv tool install --editable .
|
|
106
|
+
python -m unittest discover -s tests -v
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Contributions and bug reports are welcome. See [CONTRIBUTING.md](CONTRIBUTING.md) and [open an issue](https://github.com/abhishekash/agent-observatory/issues).
|
|
110
|
+
|
|
111
|
+
Maintainers can follow the [PyPI publishing guide](docs/publishing.md) to release a version with Trusted Publishing.
|
|
112
|
+
|
|
113
|
+
## License
|
|
114
|
+
|
|
115
|
+
Agent Observatory is distributed under the [MIT License](LICENSE).
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
README.md
|
|
3
|
+
pyproject.toml
|
|
4
|
+
agent_observatory_cli.egg-info/PKG-INFO
|
|
5
|
+
agent_observatory_cli.egg-info/SOURCES.txt
|
|
6
|
+
agent_observatory_cli.egg-info/dependency_links.txt
|
|
7
|
+
agent_observatory_cli.egg-info/entry_points.txt
|
|
8
|
+
agent_observatory_cli.egg-info/requires.txt
|
|
9
|
+
agent_observatory_cli.egg-info/top_level.txt
|
|
10
|
+
observatory/__init__.py
|
|
11
|
+
observatory/__main__.py
|
|
12
|
+
observatory/activity.css
|
|
13
|
+
observatory/activity.js
|
|
14
|
+
observatory/auto.py
|
|
15
|
+
observatory/client.py
|
|
16
|
+
observatory/core.py
|
|
17
|
+
observatory/distribution.py
|
|
18
|
+
observatory/findings.py
|
|
19
|
+
observatory/index.html
|
|
20
|
+
observatory/local_activity.py
|
|
21
|
+
observatory/local_agents.py
|
|
22
|
+
observatory/local_runtime.py
|
|
23
|
+
observatory/logs.py
|
|
24
|
+
observatory/metrics.py
|
|
25
|
+
observatory/otlp_proto.py
|
|
26
|
+
observatory/server.py
|
|
27
|
+
observatory/setup.css
|
|
28
|
+
observatory/setup.js
|
|
29
|
+
observatory/terminal.py
|
|
30
|
+
observatory/terminal_ui.py
|
|
31
|
+
observatory/watch.py
|
|
32
|
+
observatory/integrations/__init__.py
|
|
33
|
+
observatory/integrations/langchain.py
|
|
34
|
+
observatory/integrations/openai_agents.py
|
|
35
|
+
tests/test_observatory.py
|
|
36
|
+
tests/test_terminal_search.py
|
|
37
|
+
tests/test_terminal_usability.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
textual<9,>=8.2
|
|
2
|
+
|
|
3
|
+
[auto]
|
|
4
|
+
opentelemetry-sdk<2,>=1.27
|
|
5
|
+
opentelemetry-exporter-otlp-proto-http<2,>=1.27
|
|
6
|
+
openinference-instrumentation-openai>=0.1
|
|
7
|
+
openinference-instrumentation-anthropic>=0.1
|
|
8
|
+
openinference-instrumentation-langchain>=0.1
|
|
9
|
+
|
|
10
|
+
[langchain]
|
|
11
|
+
langchain-core<2,>=0.3.9
|
|
12
|
+
|
|
13
|
+
[openai-agents]
|
|
14
|
+
openai-agents<2,>=0.1.0
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
observatory
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import argparse
|
|
4
|
+
import json
|
|
5
|
+
import os
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
|
|
8
|
+
from .core import Store, normalize_native
|
|
9
|
+
from .server import serve
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def main():
|
|
13
|
+
parser = argparse.ArgumentParser(prog="python -m observatory",
|
|
14
|
+
description="Start the terminal cockpit with no subcommand, or choose a command below.")
|
|
15
|
+
parser.add_argument("--db", default="observatory.db")
|
|
16
|
+
sub = parser.add_subparsers(dest="command")
|
|
17
|
+
cockpit = sub.add_parser("cockpit", help="one-command terminal dashboard and optional agent launch")
|
|
18
|
+
cockpit.add_argument("--port", type=int, default=14318, help="local receiver port (default: 14318)")
|
|
19
|
+
cockpit.add_argument("--endpoint", default=os.environ.get("OBSERVATORY_ENDPOINT"),
|
|
20
|
+
help="connect to an existing receiver instead of starting one")
|
|
21
|
+
cockpit.add_argument("--service", default=os.environ.get("OTEL_SERVICE_NAME", "my-agent"))
|
|
22
|
+
cockpit.add_argument("--python", help="Python executable in the agent's environment")
|
|
23
|
+
cockpit.add_argument("--module", action="store_true", help="run the agent as a Python module")
|
|
24
|
+
cockpit.add_argument("--capture-content", action="store_true", help="include prompts and model responses")
|
|
25
|
+
cockpit.add_argument("--new-window", action="store_true", help="open the cockpit in a new terminal window")
|
|
26
|
+
cockpit.add_argument("--once", action="store_true", help="print one snapshot and exit")
|
|
27
|
+
cockpit.add_argument("--no-local-agents", dest="local_agents", action="store_false",
|
|
28
|
+
help="disable local Codex / Claude Code session discovery in a receiver started here")
|
|
29
|
+
cockpit.add_argument("--metadata-only", action="store_true", help="omit native session text, commands and outputs")
|
|
30
|
+
cockpit.add_argument("target", nargs="?", help="optional Python agent script or module to launch")
|
|
31
|
+
cockpit.add_argument("arguments", nargs=argparse.REMAINDER, help="arguments passed to the agent")
|
|
32
|
+
server = sub.add_parser("serve", help="run local dashboard and OTLP/HTTP receiver")
|
|
33
|
+
server.add_argument("--host", default="127.0.0.1")
|
|
34
|
+
server.add_argument("--port", type=int, default=4318)
|
|
35
|
+
server.add_argument("--token", default=os.environ.get("OBSERVATORY_TOKEN"),
|
|
36
|
+
help="optional bearer token (or OBSERVATORY_TOKEN environment variable)")
|
|
37
|
+
server.add_argument("--watch-jsonl", type=Path, action="append", default=[],
|
|
38
|
+
help="tail a harness JSONL file as spans are written; repeatable")
|
|
39
|
+
server.add_argument("--watch-service", default="agent-harness")
|
|
40
|
+
server.add_argument("--retention-days", type=float,
|
|
41
|
+
help="delete complete traces and telemetry older than this many days")
|
|
42
|
+
server.add_argument("--no-local-agents", dest="local_agents", action="store_false",
|
|
43
|
+
help="disable automatic local Codex / Claude Code session discovery")
|
|
44
|
+
server.add_argument("--metadata-only", action="store_true", help="omit native session text, commands and outputs")
|
|
45
|
+
launcher = sub.add_parser("run", help="automatically capture model calls from a Python agent")
|
|
46
|
+
launcher.add_argument("--endpoint", default=os.environ.get("OBSERVATORY_ENDPOINT", "http://127.0.0.1:4318"),
|
|
47
|
+
help="dashboard address (or OBSERVATORY_ENDPOINT)")
|
|
48
|
+
launcher.add_argument("--service", default=os.environ.get("OTEL_SERVICE_NAME", "my-agent"),
|
|
49
|
+
help="name shown in the dashboard")
|
|
50
|
+
launcher.add_argument("--module", action="store_true", help="run an importable module instead of a script")
|
|
51
|
+
launcher.add_argument("--capture-content", action="store_true", help="include prompts and model responses")
|
|
52
|
+
launcher.add_argument("target", help="your agent's Python script or module")
|
|
53
|
+
launcher.add_argument("arguments", nargs=argparse.REMAINDER, help="arguments passed to your agent")
|
|
54
|
+
importer = sub.add_parser("import-jsonl", help="import agent-harness span JSONL")
|
|
55
|
+
importer.add_argument("path", type=Path)
|
|
56
|
+
importer.add_argument("--service", default="agent-harness")
|
|
57
|
+
evaluations = sub.add_parser("import-evals", help="join agent-evals results.json outcomes to traces")
|
|
58
|
+
evaluations.add_argument("path", type=Path)
|
|
59
|
+
prune = sub.add_parser("prune", help="delete telemetry older than the retention period")
|
|
60
|
+
prune.add_argument("--older-than-days", type=float, required=True)
|
|
61
|
+
args = parser.parse_args()
|
|
62
|
+
if args.command in {None, "cockpit"}:
|
|
63
|
+
from .terminal import CockpitError, run_cockpit
|
|
64
|
+
options = {key: getattr(args, key) for key in ("port", "endpoint", "service", "python", "module", "capture_content", "new_window", "once", "target", "arguments", "local_agents", "metadata_only")} if args.command else {
|
|
65
|
+
"endpoint": os.environ.get("OBSERVATORY_ENDPOINT"),
|
|
66
|
+
"service": os.environ.get("OTEL_SERVICE_NAME", "my-agent"),
|
|
67
|
+
}
|
|
68
|
+
try:
|
|
69
|
+
run_cockpit(db_path=args.db, **options)
|
|
70
|
+
except CockpitError as exc:
|
|
71
|
+
parser.exit(2, f"Observatory: {exc}\n")
|
|
72
|
+
elif args.command == "serve":
|
|
73
|
+
serve(args.db, args.host, args.port, args.token, args.watch_jsonl,
|
|
74
|
+
args.watch_service, args.retention_days, args.local_agents, args.metadata_only)
|
|
75
|
+
elif args.command == "run":
|
|
76
|
+
from .auto import SetupError, run_agent
|
|
77
|
+
try:
|
|
78
|
+
run_agent(args.target, args.arguments, endpoint=args.endpoint, service=args.service,
|
|
79
|
+
module=args.module, capture_content=args.capture_content)
|
|
80
|
+
except SetupError as exc:
|
|
81
|
+
parser.exit(2, f"Observatory: {exc}\n")
|
|
82
|
+
except KeyboardInterrupt:
|
|
83
|
+
parser.exit(130)
|
|
84
|
+
elif args.command == "import-jsonl":
|
|
85
|
+
spans = []
|
|
86
|
+
with args.path.open(encoding="utf-8") as stream:
|
|
87
|
+
for number, line in enumerate(stream, 1):
|
|
88
|
+
if line.strip():
|
|
89
|
+
try:
|
|
90
|
+
spans.append(normalize_native(json.loads(line), args.service))
|
|
91
|
+
except (ValueError, KeyError, TypeError) as exc:
|
|
92
|
+
parser.error(f"{args.path}:{number}: {exc}")
|
|
93
|
+
print(f"Imported {Store(args.db).ingest(spans)} spans")
|
|
94
|
+
elif args.command == "import-evals":
|
|
95
|
+
payload = json.loads(args.path.read_text(encoding="utf-8"))
|
|
96
|
+
if not isinstance(payload, dict) or not isinstance(payload.get("results"), list):
|
|
97
|
+
parser.error("expected results.json with a results array")
|
|
98
|
+
print(f"Imported {Store(args.db).ingest_outcomes(payload['results'], source=str(args.path))} outcomes")
|
|
99
|
+
else:
|
|
100
|
+
deleted = Store(args.db).prune(args.older_than_days)
|
|
101
|
+
print(json.dumps(deleted, sort_keys=True))
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
if __name__ == "__main__":
|
|
105
|
+
main()
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
.live-work{margin:22px 0 28px;padding:24px;border-color:#344b66;background:linear-gradient(145deg,#142235,#111b2c)}
|
|
2
|
+
.work-heading,.work-session-head,.work-toolbar,.work-event-top,.work-evidence{display:flex;align-items:center;gap:12px;justify-content:space-between}
|
|
3
|
+
.work-heading h1{margin:7px 0 0;font-size:27px;letter-spacing:-.03em}.work-live{color:#99e9c3;background:#183a32;border:1px solid #28584a;padding:7px 12px;border-radius:30px;font-size:12px;white-space:nowrap}.work-live:before{content:'●';margin-right:7px}.work-live.paused{color:#efcb80;background:#3b3020;border-color:#6d5834}.work-note{font-size:12px;margin-bottom:20px}
|
|
4
|
+
.work-stats{display:grid;grid-template-columns:1fr 1fr 2fr 1fr;gap:10px}.work-stat{padding:14px;border:1px solid #2b3e55;border-radius:10px;background:#111d2d;display:flex;flex-direction:column;gap:7px}.work-stat span{font-size:11px}.work-stat strong{font-size:19px;font-variant-numeric:tabular-nums}
|
|
5
|
+
.work-sessions{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px;margin:16px 0}.work-session{border:1px solid #2e425b;border-radius:10px;background:#162437;padding:14px;min-width:0}.work-session-head{font-size:12px}.work-presence{display:inline-block;margin-top:9px;color:#99a8bb;font-size:10px;letter-spacing:.03em}.work-presence.recent{color:#91e5b8}.work-task{font-size:13px;line-height:1.5;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;margin:8px 0}.work-model{font:11px ui-monospace,monospace}.work-last{font-size:11px;color:#9db9da;margin-top:9px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
|
6
|
+
.work-toolbar{margin:20px 0 12px;justify-content:flex-start;flex-wrap:wrap}.work-toolbar input{flex:1;min-width:220px}.work-toolbar select{max-width:180px}.work-categories{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:14px}.work-layout{display:grid;grid-template-columns:minmax(0,1.1fr) minmax(0,1fr);gap:14px}.work-feed{max-height:540px;overflow:auto;display:flex;flex-direction:column;gap:5px}.work-event{display:flex;align-items:center;gap:10px;text-align:left;width:100%;padding:12px 10px;border:1px solid transparent;border-radius:9px;background:#142135;color:#dce8f7}.work-event:hover{background:#1d304b}.work-event.selected{background:#223957;border-color:#5276a1}.work-event.error{border-left:3px solid #e88e99}.work-symbol{width:28px;flex-shrink:0;color:#8ab6ed;font:18px ui-monospace,monospace;text-align:center}.work-event-content{min-width:0;flex:1}.work-event-top{justify-content:flex-start;font-size:11px;gap:7px}.work-event-top strong{color:#c8ddf7;max-width:120px;overflow:hidden;text-overflow:ellipsis}.work-result{font-size:9px;text-transform:uppercase;color:#8ed5b0;letter-spacing:.04em}.error .work-result{color:#ff9ca8}.work-subject{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-size:12px;margin-top:5px}.work-event time{font:10px ui-monospace,monospace;white-space:nowrap}
|
|
7
|
+
.work-inspector{border:1px solid #30435b;background:#0e1929;border-radius:11px;padding:18px;min-width:0;max-height:540px;overflow:auto}.work-inspector h2{font-size:17px;line-height:1.4;overflow-wrap:anywhere;margin:8px 0 12px}.work-evidence{justify-content:flex-start;flex-wrap:wrap;color:#9aafc9;font-size:10px;border-bottom:1px solid #263a52;padding-bottom:13px}.work-detail h3{font-size:10px;text-transform:uppercase;letter-spacing:.1em;color:#88a6cd;margin:16px 0 7px}.work-detail pre,.work-content{white-space:pre-wrap;overflow-wrap:anywhere;font:11px/1.6 ui-monospace,monospace;color:#c5d6ed;background:#111e30;border:1px solid #23374e;padding:12px;border-radius:7px;max-height:300px;overflow:auto}.work-provenance,.work-footer{font-size:10px;line-height:1.6;margin-top:15px}.work-empty{padding:35px 16px;color:#9baac0;font-size:13px}.work-inspector>.refresh{margin-top:14px}
|
|
8
|
+
.work-expand{border:0;background:transparent;color:#9cbff0;font-size:11px;padding:8px 0;cursor:pointer}.work-machine{margin-top:12px;border:1px solid #2b4059;border-radius:8px;padding:12px;overflow:auto}.work-machine summary{cursor:pointer;color:#a9bed9;font-size:12px}.work-processes{width:100%;border-collapse:collapse;margin-top:12px;font-size:11px;text-align:left}.work-processes th,.work-processes td{border-bottom:1px solid #263a52;padding:8px}.work-processes th{color:#94b2d8;font-weight:500}
|
|
9
|
+
@media(max-width:1100px){.work-layout{grid-template-columns:1fr}.work-feed{max-height:360px}.work-stats{grid-template-columns:1fr 1fr}.work-sessions{grid-template-columns:1fr}.work-heading{align-items:flex-start}.work-heading h1{font-size:23px}}
|
|
10
|
+
@media(max-width:600px){.live-work{padding:14px}.work-heading{flex-direction:column}.work-toolbar input{min-width:100%}.work-event-top .muted{display:none}.work-stat strong{font-size:16px}}
|