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.
Files changed (39) hide show
  1. agent_observatory_cli-0.1.0/LICENSE +21 -0
  2. agent_observatory_cli-0.1.0/PKG-INFO +115 -0
  3. agent_observatory_cli-0.1.0/README.md +79 -0
  4. agent_observatory_cli-0.1.0/agent_observatory_cli.egg-info/PKG-INFO +115 -0
  5. agent_observatory_cli-0.1.0/agent_observatory_cli.egg-info/SOURCES.txt +37 -0
  6. agent_observatory_cli-0.1.0/agent_observatory_cli.egg-info/dependency_links.txt +1 -0
  7. agent_observatory_cli-0.1.0/agent_observatory_cli.egg-info/entry_points.txt +2 -0
  8. agent_observatory_cli-0.1.0/agent_observatory_cli.egg-info/requires.txt +14 -0
  9. agent_observatory_cli-0.1.0/agent_observatory_cli.egg-info/top_level.txt +1 -0
  10. agent_observatory_cli-0.1.0/observatory/__init__.py +5 -0
  11. agent_observatory_cli-0.1.0/observatory/__main__.py +105 -0
  12. agent_observatory_cli-0.1.0/observatory/activity.css +10 -0
  13. agent_observatory_cli-0.1.0/observatory/activity.js +116 -0
  14. agent_observatory_cli-0.1.0/observatory/auto.py +212 -0
  15. agent_observatory_cli-0.1.0/observatory/client.py +253 -0
  16. agent_observatory_cli-0.1.0/observatory/core.py +1654 -0
  17. agent_observatory_cli-0.1.0/observatory/distribution.py +67 -0
  18. agent_observatory_cli-0.1.0/observatory/findings.py +176 -0
  19. agent_observatory_cli-0.1.0/observatory/index.html +84 -0
  20. agent_observatory_cli-0.1.0/observatory/integrations/__init__.py +1 -0
  21. agent_observatory_cli-0.1.0/observatory/integrations/langchain.py +234 -0
  22. agent_observatory_cli-0.1.0/observatory/integrations/openai_agents.py +177 -0
  23. agent_observatory_cli-0.1.0/observatory/local_activity.py +207 -0
  24. agent_observatory_cli-0.1.0/observatory/local_agents.py +394 -0
  25. agent_observatory_cli-0.1.0/observatory/local_runtime.py +49 -0
  26. agent_observatory_cli-0.1.0/observatory/logs.py +109 -0
  27. agent_observatory_cli-0.1.0/observatory/metrics.py +281 -0
  28. agent_observatory_cli-0.1.0/observatory/otlp_proto.py +210 -0
  29. agent_observatory_cli-0.1.0/observatory/server.py +368 -0
  30. agent_observatory_cli-0.1.0/observatory/setup.css +40 -0
  31. agent_observatory_cli-0.1.0/observatory/setup.js +145 -0
  32. agent_observatory_cli-0.1.0/observatory/terminal.py +525 -0
  33. agent_observatory_cli-0.1.0/observatory/terminal_ui.py +1299 -0
  34. agent_observatory_cli-0.1.0/observatory/watch.py +62 -0
  35. agent_observatory_cli-0.1.0/pyproject.toml +49 -0
  36. agent_observatory_cli-0.1.0/setup.cfg +4 -0
  37. agent_observatory_cli-0.1.0/tests/test_observatory.py +366 -0
  38. agent_observatory_cli-0.1.0/tests/test_terminal_search.py +375 -0
  39. 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
+ [![CI](https://github.com/abhishekash/agent-observatory/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/abhishekash/agent-observatory/actions/workflows/ci.yml)
40
+ [![PyPI](https://img.shields.io/pypi/v/agent-observatory-cli)](https://pypi.org/project/agent-observatory-cli/)
41
+ ![Python 3.11+](https://img.shields.io/badge/python-3.11%2B-3776AB?logo=python&logoColor=white)
42
+ ![OpenTelemetry OTLP](https://img.shields.io/badge/OpenTelemetry-OTLP-425CC7?logo=opentelemetry&logoColor=white)
43
+ ![Local first](https://img.shields.io/badge/data-local--first-2E8B57)
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
+ [![CI](https://github.com/abhishekash/agent-observatory/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/abhishekash/agent-observatory/actions/workflows/ci.yml)
4
+ [![PyPI](https://img.shields.io/pypi/v/agent-observatory-cli)](https://pypi.org/project/agent-observatory-cli/)
5
+ ![Python 3.11+](https://img.shields.io/badge/python-3.11%2B-3776AB?logo=python&logoColor=white)
6
+ ![OpenTelemetry OTLP](https://img.shields.io/badge/OpenTelemetry-OTLP-425CC7?logo=opentelemetry&logoColor=white)
7
+ ![Local first](https://img.shields.io/badge/data-local--first-2E8B57)
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
+ [![CI](https://github.com/abhishekash/agent-observatory/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/abhishekash/agent-observatory/actions/workflows/ci.yml)
40
+ [![PyPI](https://img.shields.io/pypi/v/agent-observatory-cli)](https://pypi.org/project/agent-observatory-cli/)
41
+ ![Python 3.11+](https://img.shields.io/badge/python-3.11%2B-3776AB?logo=python&logoColor=white)
42
+ ![OpenTelemetry OTLP](https://img.shields.io/badge/OpenTelemetry-OTLP-425CC7?logo=opentelemetry&logoColor=white)
43
+ ![Local first](https://img.shields.io/badge/data-local--first-2E8B57)
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,2 @@
1
+ [console_scripts]
2
+ agent-observatory = observatory.__main__:main
@@ -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,5 @@
1
+ """Local, framework-independent agent observability service and client."""
2
+
3
+ from .client import Client
4
+
5
+ __all__ = ["Client"]
@@ -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}}