@stjbrown/agent-knowledge 0.1.0-beta.4 → 0.1.0-beta.5

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.
@@ -0,0 +1,163 @@
1
+ # Janet observability design
2
+
3
+ ## Goals
4
+
5
+ Janet is a local CLI agent, not a web application. Observability therefore belongs in the CLI
6
+ runtime and must not require Mastra Studio, a Mastra development server, or any other always-on
7
+ Janet process.
8
+
9
+ The foundation has five constraints:
10
+
11
+ 1. Tracing is strictly off by default.
12
+ 2. Metadata-only capture is the recommended mode.
13
+ 3. Local inspection works without a collector.
14
+ 4. Remote export uses standard OTLP so Phoenix is the first supported backend, not the only one.
15
+ 5. Secrets come from the process environment and are never written to Janet settings.
16
+
17
+ ## Runtime architecture
18
+
19
+ Each interactive or headless Janet process creates one observability runtime during controller
20
+ startup:
21
+
22
+ ```text
23
+ session.sendMessage
24
+ -> Mastra tracing options
25
+ -> Mastra Observability
26
+ -> local Mastra storage exporter -> ~/.agent-knowledge/observability.db
27
+ -> generic OTLP exporter -> Phoenix or another OTLP backend
28
+ ```
29
+
30
+ No observability object or exporter is constructed while capture is off. The ordinary
31
+ `threads.db` continues to hold Janet thread history. Local traces use a separate
32
+ `observability.db`, routed through Mastra composite storage, with a seven-day default retention
33
+ window.
34
+
35
+ Completed spans are flushed before Janet destroys its controller. Export and pruning failures are
36
+ best effort and must not turn a successful Janet response into a failed response.
37
+
38
+ ## Capture modes
39
+
40
+ | Mode | Captured | Excluded |
41
+ |---|---|---|
42
+ | `off` | Nothing | All spans and exports |
43
+ | `metadata` | Timing, hierarchy, model and tool identity, token usage, status, and errors | Prompts, responses, tool arguments, and tool results |
44
+ | `full` | Metadata plus prompt, response, and tool payload content | Nothing beyond Mastra's sensitive-data filtering and serialization limits |
45
+
46
+ Full capture requires a second explicit confirmation in the TUI. Both captured modes exclude
47
+ streaming model-chunk spans and cap serialized string, object, array, and nesting sizes.
48
+
49
+ Project identity is represented by Janet's existing hashed resource ID. Settings and status output
50
+ never show authentication headers. Endpoint status output strips credentials, query parameters,
51
+ and fragments.
52
+
53
+ ## Destinations
54
+
55
+ ### Local history
56
+
57
+ Local history uses Mastra's storage exporter and libSQL. `/traces` lists recent root traces and
58
+ renders their agent, model, and tool hierarchy without printing captured payloads.
59
+
60
+ ### Phoenix
61
+
62
+ Phoenix uses the same generic OTLP/HTTP protobuf path as any other compatible collector. Janet
63
+ adds the Phoenix project name as both an OpenInference resource attribute and the
64
+ `x-project-name` request header. A base collector endpoint such as `http://localhost:6006` is
65
+ normalized by Mastra's OTLP exporter to `/v1/traces`.
66
+
67
+ Phoenix runs separately from Janet. Follow the
68
+ [Phoenix local deployment documentation](https://arize.com/docs/phoenix) to run its collector and
69
+ UI.
70
+
71
+ ### Custom OTLP
72
+
73
+ Custom OTLP accepts any HTTP or HTTPS base endpoint compatible with OTLP/HTTP protobuf. Credentials
74
+ and vendor headers use the standard `OTEL_EXPORTER_OTLP_HEADERS` environment variable. This keeps
75
+ the runtime backend-neutral and avoids storing secrets or adding vendor-specific code to Janet.
76
+
77
+ ## Configuration
78
+
79
+ The TUI is the primary interactive setup:
80
+
81
+ ```text
82
+ /observability
83
+ /observability status
84
+ /observability off
85
+ /traces
86
+ ```
87
+
88
+ The TUI persists only nonsecret preferences in `~/.agent-knowledge/settings.json`. Changes apply
89
+ after restart so a process never has two competing observability lifecycles.
90
+
91
+ Environment variables override saved settings for headless runs and automation:
92
+
93
+ | Variable | Purpose |
94
+ |---|---|
95
+ | `JANET_OBSERVABILITY` | `off`, `metadata`, or `full` |
96
+ | `JANET_OBSERVABILITY_BACKEND` | `local`, `phoenix`, or `otlp` |
97
+ | `JANET_OBSERVABILITY_SAMPLE_RATE` | Number from `0` through `1` |
98
+ | `PHOENIX_COLLECTOR_ENDPOINT` | Phoenix base collector endpoint |
99
+ | `PHOENIX_PROJECT_NAME` | Phoenix project, default `janet` |
100
+ | `OTEL_EXPORTER_OTLP_ENDPOINT` | Generic OTLP base endpoint |
101
+ | `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT` | Trace-specific OTLP endpoint |
102
+ | `OTEL_EXPORTER_OTLP_HEADERS` | Runtime-only comma-separated headers |
103
+
104
+ Precedence is:
105
+
106
+ 1. Janet environment overrides
107
+ 2. Saved Janet settings
108
+ 3. Strictly off defaults
109
+
110
+ Standard `OTEL_*` variables can configure an explicitly enabled run, but cannot enable tracing by
111
+ themselves. Janet does not automatically load a project `.env`.
112
+
113
+ ## Cancellation
114
+
115
+ Cancellation is part of the observability foundation because a trace is not useful if a runaway
116
+ turn cannot be stopped. Keyboard handling is global rather than tied to the focused editor:
117
+
118
+ - Esc or the first Ctrl+C calls `session.abort()` for an active turn.
119
+ - A second Ctrl+C within the double-press window force exits if abort is not completing.
120
+ - `/cancel` uses the same active-turn abort path.
121
+ - A single idle Ctrl+C clears editor input or shows the exit hint; a second exits Janet.
122
+
123
+ ## Verification
124
+
125
+ The automated suite covers:
126
+
127
+ - default-off resolution even when standard OTEL variables exist
128
+ - metadata and full privacy flags
129
+ - malformed and missing configuration
130
+ - separate local trace storage
131
+ - local trace persistence and concurrent Janet processes
132
+ - content-free local trace rendering
133
+ - global cancellation and force-exit behavior
134
+ - endpoint and header redaction
135
+
136
+ An opt-in integration test opens a temporary local collector and verifies a nonempty
137
+ Phoenix-compatible protobuf request, `/v1/traces`, and `x-project-name`:
138
+
139
+ ```bash
140
+ JANET_OTLP_INTEGRATION=1 \
141
+ corepack pnpm --filter @stjbrown/agent-knowledge \
142
+ exec vitest run test/observability-runtime.test.ts
143
+ ```
144
+
145
+ The release test plan in [`TESTING.md`](./TESTING.md) adds a real TUI, Phoenix UI, and clean-install
146
+ pass.
147
+
148
+ ## Evals roadmap
149
+
150
+ Tracing comes first because it supplies the run records needed to design useful evals. The next
151
+ layer should remain backend-neutral:
152
+
153
+ 1. Define a small Janet evaluator interface over completed run records.
154
+ 2. Start with deterministic checks already owned by this project: OKF conformance, citation
155
+ integrity, expected file changes, repeated tool attempts, and successful cancellation.
156
+ 3. Store evaluator name, version, score, label, and explanation as trace metadata or linked score
157
+ records.
158
+ 4. Add a fixture corpus for init, ingest, query, lint, and failure-recovery scenarios.
159
+ 5. Add optional model-graded evaluators only after the deterministic baseline is stable.
160
+ 6. Export the same results to Phoenix or another backend without changing evaluator logic.
161
+
162
+ Tool extensibility is intentionally a separate follow-up. Traces should tell us which capabilities
163
+ Janet lacks before the project commits to a tool-provider interface or bundled defaults.
package/README.md CHANGED
@@ -79,7 +79,9 @@ token-free OKF conformance check before the agent's drift audit, so it is usable
79
79
  |---|---|
80
80
  | `/models` · `/model [id]` | pick a model from an arrow-key list, or switch by id |
81
81
  | `/login <anthropic\|openai-codex> [browser\|device]` · `/logout` · `/auth` | subscription sign-in and status; device mode is available for remote OpenAI login |
82
- | `/help` · `/quit` | help; exit (or double Ctrl+C) |
82
+ | `/observability` · `/traces` | configure opt-in tracing and browse local trace history |
83
+ | `/cancel` | cancel the active turn; Esc or Ctrl+C does the same while Janet is working |
84
+ | `/help` · `/quit` | help; exit (or press Ctrl+C twice) |
83
85
 
84
86
  Just type to talk to Janet; ↑/↓ recalls previous prompts.
85
87
 
@@ -88,6 +90,32 @@ Gemini, via ADC/service account), Amazon Bedrock (AWS credential chain), Anthrop
88
90
  key **or** subscription OAuth), and Google Gemini (API key). Set the choice once (`--model`,
89
91
  `JANET_MODEL`, or the first-run picker) and it persists.
90
92
 
93
+ **Observability.** Tracing is strictly off by default. Run `/observability` to choose local trace
94
+ history, Phoenix, or a custom OTLP endpoint. Metadata-only capture records timing, model and tool
95
+ activity, token usage, status, and errors without prompt or response bodies. Full capture requires
96
+ an explicit warning and confirmation. Settings take effect after restarting Janet.
97
+
98
+ Local history is stored separately at `~/.agent-knowledge/observability.db` and can be inspected
99
+ with `/traces`. Phoenix runs as a separate local or remote service; Janet sends it standard
100
+ OTLP/HTTP protobuf traces and does not run a web or development server. Custom OTLP supports other
101
+ compatible collectors and backends.
102
+
103
+ Headless runs and automation can use environment configuration:
104
+
105
+ ```bash
106
+ JANET_OBSERVABILITY=metadata \
107
+ JANET_OBSERVABILITY_BACKEND=phoenix \
108
+ PHOENIX_COLLECTOR_ENDPOINT=http://localhost:6006 \
109
+ PHOENIX_PROJECT_NAME=janet \
110
+ janet query "What happened?" --print
111
+ ```
112
+
113
+ Use `JANET_OBSERVABILITY_BACKEND=otlp` with `OTEL_EXPORTER_OTLP_ENDPOINT` for a custom collector.
114
+ Authentication headers can be supplied with `OTEL_EXPORTER_OTLP_HEADERS`; Janet never writes them
115
+ to `settings.json`. Standard `OTEL_*` variables configure an explicitly enabled run but do not
116
+ enable tracing on their own. Janet also does not load a project's `.env` automatically. See
117
+ [`OBSERVABILITY.md`](./OBSERVABILITY.md) for the architecture, privacy model, and eval roadmap.
118
+
91
119
  Janet is built on [Mastra](https://mastra.ai) and lives in
92
120
  [`packages/janet`](https://github.com/stjbrown/agent-knowledge/tree/janet-agent/packages/janet)
93
121
  (published as `@stjbrown/agent-knowledge`, bins `janet` + `ding`). She also reports lifecycle state