You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Aug 6, 2026. It is now read-only.
Repository navigation
Commit 31e4764
Browse filesBrowse the repository at this point in the historyBrowse files
Copy file name to clipboardExpand all lines: packages/agent/README.md
+12-5Lines changed: 12 additions & 5 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -171,6 +171,16 @@ Required environment variables (validated by zod in `src/server/bin.ts`):
171
171
-`POSTHOG_PERSONAL_API_KEY` — API key for PostHog requests
172
172
-`POSTHOG_PROJECT_ID` — numeric project ID
173
173
174
+
Optional run telemetry (the logs pair must both be set, otherwise telemetry stays off):
175
+
176
+
-`POSTHOG_AGENT_OTEL_LOGS_URL` — full OTLP logs URL for run metadata, e.g. `https://us.i.posthog.com/i/v1/logs`
177
+
-`POSTHOG_AGENT_OTEL_LOGS_TOKEN` — project API key of the telemetry project
178
+
-`POSTHOG_AGENT_OTEL_TRACES_URL` — full OTLP traces URL, e.g. `https://us.i.posthog.com/i/v1/traces`; additionally enables one APM trace per run
179
+
180
+
When set, `AgentServer` ships an allowlisted metadata subset of the session log (run/turn/tool lifecycle, usage, error provenance — never message content, tool arguments, or raw error text; see `src/otel-telemetry.ts`) to PostHog Logs, tagged with `service.name=posthog-code-agent` and `run_id`/`task_id`/`team_id`/`user_id`/`distinct_id` resource attributes so cloud runs are filterable per user. With the traces URL set, each run also produces an APM trace (`task_run` root span, a `turn` span per prompt, a `tool_call:<kind>` span per tool call; see `src/otel-trace-builder.ts`), and log records carry the matching trace/span ids so Logs and APM cross-link.
181
+
182
+
The `task_run` root span is ended and exported at the run's in-process terminal point — a background run's prompt settling, a terminal failure, or session cleanup (`close`). It cannot wait for teardown: agent-server is an exec'd process inside the sandbox, so `docker stop` / Modal terminate kill it without SIGTERM ever arriving, and a span still open at that moment is lost. Interactive sessions that end via hard teardown (e.g. inactivity timeout) therefore lose the root span; turn/tool spans and logs still assemble under the same trace id.
183
+
174
184
## Agent SDK
175
185
176
186
The `Agent` class (`src/agent.ts`) is the entrypoint for local/programmatic usage. It handles LLM gateway configuration, log writer setup, and model filtering — then delegates to `createAcpConnection()`.
@@ -209,12 +219,9 @@ Logs serve two purposes: real-time observability and session resume. Every ACP m
209
219
210
220
### Writing logs
211
221
212
-
`SessionLogWriter` (`src/session-log-writer.ts`) is a per-session multiplexer that buffers raw ndJson lines. On flush (auto-scheduled 500ms after writes, or explicit), it dispatches to whichever backend is configured:
213
-
214
-
-**OTEL** (`src/otel-log-writer.ts`) — preferred path. Creates an OpenTelemetry `LoggerProvider` per session with resource attributes (`task_id`, `run_id`, `device_type`) set once and indexed via `resource_fingerprint`. Each ndJson line is emitted as an OTEL log record with an `event_type` attribute (the ACP method name) and exported via OTLP HTTP to PostHog's `/i/v1/agent-logs` endpoint. Batch flush interval defaults to 500ms.
215
-
-**Legacy S3** — falls back to `PostHogAPIClient.appendTaskRunLog()`, which POSTs batched `StoredNotification` entries to the Django API. The API stores them as the task run's `log_url`.
222
+
`SessionLogWriter` (`src/session-log-writer.ts`) is a per-session multiplexer that buffers raw ndJson lines. On flush (auto-scheduled 500ms after writes, or explicit), it POSTs batched `StoredNotification` entries to the Django API via `PostHogAPIClient.appendTaskRunLog()`; the API stores them in S3 as the task run's `log_url`. This S3 log is the source of truth for the full transcript and for session resume.
216
223
217
-
Both backends can be active simultaneously — OTEL for fast indexed queries, S3 for full log download.
224
+
Independently of that flush cycle, the writer tees every parsed non-chunk entry to optional `SessionLogSink`s at append time. In cloud, `OtelRunTelemetry` (`src/otel-telemetry.ts`) is wired as a sink and exports an allowlisted metadata subset (run/turn/tool lifecycle, usage, error provenance — never message content, tool arguments, or raw error text) to PostHog Logs, plus an APM trace per run when configured. See "Optional run telemetry" above for the env vars and behavior. Sink failures can never break S3 log persistence.
'API Error: 400 {"type":"error","error":{"type":"invalid_request_error","message":"prompt is too long: 214431 tokens > 204698 maximum"}}',
45
+
true,
46
+
],
47
+
[
48
+
'API Error: 413 {"error":{"message":"litellm.ContextWindowExceededError: The estimated number of input and maximum output tokens (262334) exceeded this model context window limit (262144)","code":"5021"}}',
49
+
true,
50
+
],
51
+
// Must match without the "API Error: 413" prefix.
52
+
[
53
+
"litellm.ContextWindowExceededError: The estimated number of input and maximum output tokens (262334) exceeded this model context window limit (262144)",
54
+
true,
55
+
],
56
+
// The ACP-wrapped shape the agent-server catch actually sees.
57
+
[
58
+
'Internal error: API Error: 413 {"error":{"message":"exceeded this model context window limit (262144)"}}',
59
+
true,
60
+
],
61
+
// Any gateway 413 means an oversized payload, whatever the body text.
62
+
["API Error: 413 Payload Too Large",true],
63
+
// Pins the 413 matcher's i flag.
64
+
["api error: 413 payload too large",true],
65
+
["API Error: 429 rate limited",false],
66
+
["API Error: 400 invalid request",false],
67
+
["some unrelated failure",false],
68
+
]asconst)("detects %j as %s",(message,expected)=>{
0 commit comments