feat: add source field to session_start telemetry#968
Conversation
|
This PR doesn't fully meet our contributing guidelines and PR template. What needs to be fixed:
Please edit this PR description to address the above within 2 hours, or it will be automatically closed. If you believe this was flagged incorrectly, please let a maintainer know. |
There was a problem hiding this comment.
Claude Code Review
This repository is configured for manual code reviews. Comment @claude review to trigger a review and subscribe this PR to future pushes, or @claude review once for a one-time review.
Tip: disable this comment in your organization's Code Review settings.
|
👋 This PR was automatically closed by our quality checks. Common reasons:
If you believe this was a mistake, please open an issue explaining your intended contribution and a maintainer will help you. |
dev-punia-altimate
left a comment
There was a problem hiding this comment.
🤖 Code Review — OpenCodeReview (Gemini) — 1 finding(s)
- 1 anchored to a line (posted inline when the comment stream is on)
- 0 without a line anchor
All findings (full text)
1. packages/opencode/src/session/index.ts (L227-L229)
[🔵 LOW] Here you can use Info.shape.metadata to reuse the type definition and maintain consistency with how permission is defined, avoiding duplicate Zod schema declarations.
Suggested change:
permission: Info.shape.permission,
workspaceID: WorkspaceID.zod.optional(),
metadata: Info.shape.metadata,
| permission: Info.shape.permission, | ||
| workspaceID: WorkspaceID.zod.optional(), | ||
| metadata: z.record(z.string(), z.unknown()).optional(), |
There was a problem hiding this comment.
[🔵 LOW] Here you can use Info.shape.metadata to reuse the type definition and maintain consistency with how permission is defined, avoiding duplicate Zod schema declarations.
Suggested change:
| permission: Info.shape.permission, | |
| workspaceID: WorkspaceID.zod.optional(), | |
| metadata: z.record(z.string(), z.unknown()).optional(), | |
| permission: Info.shape.permission, | |
| workspaceID: WorkspaceID.zod.optional(), | |
| metadata: Info.shape.metadata, |
There was a problem hiding this comment.
Done in 6c60c31 — the create schema now uses Info.shape.metadata, matching the permission: Info.shape.permission pattern.
🤖 Code Review — OpenCodeReview (Gemini) — No Issues FoundNo supported files changed. |
|
Aligning the platform-team telemetry work on this One thing our #970 added after AI review that's worth carrying over — normalize + allowlist the value so a stray env/flag can't inflate the dimension's cardinality: const KNOWN_SOURCES = new Set(["cli", "datamates", "poweruser", "vscode"])
export function setSource(s: string): void {
const normalized = (s ?? "").trim().toLowerCase()
clientSource = KNOWN_SOURCES.has(normalized) ? normalized : "cli"
}(The per-session read at |
Deep review — telemetry
|
|
👋 This PR was automatically closed by our quality checks. Common reasons:
If you believe this was a mistake, please open an issue explaining your intended contribution and a maintainer will help you. |
Pushed fixes for the review findings (
|
Code Review SummaryStatus: No Issues Found | Recommendation: Merge Files Reviewed (10 files)
Notes:
Previous Review Summaries (2 snapshots, latest commit 1c1c100)Current summary above is authoritative. Previous snapshots are kept for context only. Previous review (commit 1c1c100)Status: No Issues Found | Recommendation: Merge Files Reviewed (8 files)
Notes:
Migration is backward-compatible (nullable Previous review (commit 531d617)Status: No Issues Found | Recommendation: Merge Files Reviewed (8 files)
Notes:
Migration is backward-compatible (nullable Reviewed by glm-5.2 · Input: 31K · Output: 4.6K · Cached: 251.7K Review guidance: REVIEW.md from base branch |
Adds source: string to the session_start event type definition and populates it with Flag.ALTIMATE_CLI_CLIENT at the call site. Defaults to "cli" for terminal invocations; overridden to "vscode" when the VS Code extension spawns the server via ALTIMATE_CLI_CLIENT env var.
…sion metadata)
- Add optional metadata column to SessionTable (JSON blob, backward-compatible)
- Add metadata field to Session.Info schema, fromRow, toRow, create, and createNext
- Add source?: string to session_start event type in telemetry/index.ts
- In prompt.ts session_start emit, override source with session.metadata?.source
when present, falling back to Flag.ALTIMATE_CLI_CLIENT for sessions without it
VS Code extensions (datamates, poweruser) can now pass { metadata: { source: "datamates" } }
in POST /session to produce distinguishable session_start telemetry even though both
extensions share the same altimate serve process. The global source injection in
toAppInsightsEnvelopes() (clientSource) is unchanged and still covers all other events.
Resolves review findings on the telemetry `source` field: - Read `Flag.ALTIMATE_CLI_CLIENT` live at envelope-build time instead of a hardcoded `clientSource = "cli"` set only inside the prompt flow. Events emitted before the first prompt (startup, connection setup, standalone CLI subcommands) are now labelled with the real client instead of defaulting to `"cli"`. Removes the now-redundant `clientSource` variable, `setSource()`, and its call in `session/prompt.ts`. - Type-guard `session.metadata?.source` in the `session_start` emit (was an unchecked `as string`) so malformed client JSON falls back to the flag instead of being routed to `measurements` downstream. - Document `Session.Info.metadata` as an intentional open extension point. - Add tests: telemetry envelope `source` behaviour (env-flag default, `"cli"` fallback, per-event override, non-string routing contract) and session `metadata` round-trip through `create` -> `get`. Comments clarified per Codex review: events that carry their own `source` field (session_start, and pre-existing `skill_*`/connections events) override the injected process-level value. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
531d617 to
1c1c100
Compare
|
👋 This PR was automatically closed by our quality checks. Common reasons:
If you believe this was a mistake, please open an issue explaining your intended contribution and a maintainer will help you. |
There was a problem hiding this comment.
1. Session.fork doesn't carry the new source label.
This PR threads metadata through Session.create → createNext, but Session.fork (packages/opencode/src/session/index.ts, ~L256) still calls createNext({ directory, workspaceID, title }) without it. Normal sessions now carry their source (datamates / poweruser), but forked sessions get metadata: undefined and their session_start falls back to the process-level Flag.ALTIMATE_CLI_CLIENT ("cli"). createNext already accepts metadata, so the fix is a one-line pass-through — either inherit original.metadata or accept an optional metadata on the fork request. Worth a test pinning whichever behavior is intended.
2. The generated SDK / OpenAPI artifacts weren't regenerated.
The PR adds metadata to the Session.create request schema (which POST /session validates against), but the committed client is now out of sync:
packages/sdk/js/src/v2/gen/types.gen.ts—Sessionhas nometadata, andSessionCreateData.bodystill allows onlyparentID/title/permission/workspaceID.packages/sdk/openapi.json— the/sessionPOST body wasn't updated.
This self-corrects on the next SDK rebuild (packages/sdk/js/script/build.ts runs bun dev generate), but as committed, consumers of the generated types can't send metadata. Regenerate + commit the artifacts; optionally add a CI check that fails on schema/client drift.
…ema reuse - `Session.fork` now inherits `original.metadata`, so forked sessions keep the origin (`source`) of the session they were forked from instead of falling back to the process-level `Flag.ALTIMATE_CLI_CLIENT` in their `session_start` telemetry. Adds a fork-inherits-metadata test. - Regenerate the committed SDK/OpenAPI artifacts for the new `metadata` field: `packages/sdk/openapi.json` (`Session`, `GlobalSession`, and the `/session` POST body) and `packages/sdk/js/src/v2/gen/types.gen.ts` (`Session`, `GlobalSession`, `SessionCreateData.body`). Applied only the `metadata` delta — verified byte-for-byte against the real `@hey-api/openapi-ts` output — to avoid importing unrelated pre-existing spec drift. - Reuse `Info.shape.metadata` in the `Session.create` request schema instead of re-declaring the Zod record, matching the `permission` pattern. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
👋 This PR was automatically closed by our quality checks. Common reasons:
If you believe this was a mistake, please open an issue explaining your intended contribution and a maintainer will help you. |
Addressed all review comments (
|
Merge the 5 commits on `main` since this branch was cut (bearer-auth remote MCP #793, session_start `source` telemetry #968, aireceipts CI #992, REVIEW.md docs #983/#984) into the upstream OpenCode v1.17.9 bridge branch. 9 conflicts resolved: - `altimate/telemetry/index.ts` — keep upstream `InstallationVersion`; re-add #968's `Flag`/`source` (per-session client label). - `session/index.ts` — keep upstream `permission` readonly cast AND #968's `metadata: row.metadata`. Session `metadata` already exists upstream (core `SessionTable`, upstream PR #23068), so #968's persistence layer is redundant. - `session/session.sql.ts` — accept upstream deletion (persistence moved to `@opencode-ai/core`); dropped #968's duplicate migration `20260626041744_elite_malcolm_colcord` (would crash "duplicate column: metadata" against upstream's `20260511173437_session-metadata`). - `test/session/session.test.ts` — keep upstream Effect harness (main's metadata cases were the redundant old-harness variant). - `config/config.ts` — take upstream (schema relocated to core Effect Schema); re-apply #793's `headersCommand`/`oauth` normalize passthrough. - `mcp/index.ts` — re-port #793 (bearer-auth) onto upstream's Effect-based MCP rewrite: `resolveHeadersCommand` (execFile, no shell), case-insensitive `mergeHeaders`, lenient `listTools` retry, OAuth auto-disable folded into upstream's `supportsOAuth`, `maskString` on failures. Adapted `Either`→`Result` (effect 4.0.0-beta.74). - `core/v1/config/mcp.ts` — add `headersCommand` to the Effect Schema `Remote` struct as a mutable non-empty string-array record (`Schema.mutable(...).check (Schema.isNonEmpty())`), so `DeepMutable`-wrapped consumers type-check. - `test/mcp/headers.test.ts`, `test/mcp/mcp-bearer-auth.test.ts` — re-expressed #793's schema/integration tests against the Effect Schema and `it.instance` harness (Zod `safeParse` → `Schema.decodeUnknownSync`). - SDK artifacts kept at the upstream-HEAD baseline (regenerated by CI/release). Verification: all 13 packages typecheck clean (`bun turbo typecheck`); MCP + session + telemetry suites 194/194; bearer-auth + headers 32/32. Zero conflict markers. Marker guard non-strict pass (CI mode for upstream-merge PRs). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
First stable 0.9.x on npm `latest` — brings the upstream OpenCode v1.4.0→v1.17.9 bridge merge, bearer-auth remote MCP (#793), session_start `source` telemetry (#968), and the MCP permission-check security fix to stable users upgrading from 0.8.10. Adds the v0.9.1 adversarial suite (headersCommand shell-injection safety, MCP tolerant-retry gate precision, hostile session.metadata). See CHANGELOG.md. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Summary
sourceto every telemetry event by injecting it globally intoAppInsightsEnvelopes(), matching the existingcli_versioninjection patternsourceas a module-level variable (clientSource); callers set it once at startup viaTelemetry.setSource()session/prompt.ts, callsTelemetry.setSource(Flag.ALTIMATE_CLI_CLIENT)at init — defaults to"cli"for terminal invocationsSource values
"cli"altimatein terminal"vscode"ALTIMATE_CLI_CLIENT=vscodeenv var, injected in companion PR AltimateAI/vscode-altimate-mcp-server#386)Why global injection (not per-event type)
cli_versionis already injected globally into every App Insights event envelope.sourcefollows the same pattern — zero per-event-type changes needed, and all 30+ event types get the field automatically.Requested by @saravmajestic via harness