Revive the reviewed session-telemetry packages from the closed
session-telemetry-otlp-rfc branch (PR #222/#231) on current master, renamed
to @deepseek-ai/dsh-session-telemetry{,-otel} (the SDK component-telemetry
package holds the dsh-telemetry name).
Delta over the branch version: every record now passes a telemetry/redact
waterfall between projection and emit() — the innermost next() applies a
non-configurable conservative credential-shape rule set, listeners stack
stricter rules, a throwing rule withholds the record fail-closed, and the
canonical log is never rewritten. This answers the export-side concern that
closed PR #222; the boundary axiom (our aspect ends at emit(); delivery is
the reporting SDK's) is unchanged, and the runtime-telemetry RFC's outbox /
readCommitted lane is recorded as deferred in the Agent Note.
Covered by seam/redact/OTel-wire unit tiers (100% per-file) and a keyless
Loader-composition e2e that boots the examples fixture against a mock OTLP
collector and pins redaction on the wire plus the untouched canonical log.
26 lines
1.1 KiB
TypeScript
26 lines
1.1 KiB
TypeScript
/**
|
|
* Keyless-self-skipping smoke: ship one real session's records to a live
|
|
* OTLP collector named by $DSH_OTLP_E2E_ENDPOINT and require the SDK's
|
|
* shutdown (flush-and-quiesce) to resolve. Skipped without the endpoint so
|
|
* secretless CI stays green — a CI accommodation, not a cost signal.
|
|
*/
|
|
|
|
import { describe, expect, it } from 'vitest'
|
|
import { Context } from 'cordis'
|
|
import SessionStore, { SessionId } from '@deepseek-ai/dsh-session'
|
|
import TelemetryOtel from '../src/index.ts'
|
|
|
|
describe.skipIf(!process.env.DSH_OTLP_E2E_ENDPOINT)('telemetry-otel e2e (live collector)', () => {
|
|
it('exports a session and quiesces cleanly', async () => {
|
|
const ctx = new Context()
|
|
await ctx.plugin(SessionStore)
|
|
const fiber = await ctx.plugin(TelemetryOtel, {
|
|
exporter: { url: process.env.DSH_OTLP_E2E_ENDPOINT! },
|
|
})
|
|
const session = ctx.sessions.create(SessionId(`e2e-${Date.now()}`), { meta: {} })
|
|
session.append('turn/start', { turn: 1, trigger: { kind: 'message', source: { kind: 'user' } } })
|
|
session.append('turn/end', { turn: 1, reason: { kind: 'completed' } })
|
|
await expect(fiber.dispose()).resolves.not.toThrow()
|
|
})
|
|
})
|