pi-mono/packages/durable/test/harness-telemetry-options.test.ts
Mario Zechner 2ec55d808d feat: Durable and pi-ai telemetry; Context.telemetry is always a span
- pi-ai: AI_TELEMETRY_SCHEMA; pi.ai.request and pi.ai.poll spans around Models requests via a lazyStream observer
  (no provider changes), first_chunk and block events (never per delta), usage/cost end attributes, provider_error
  status with a bounded message, aborted stays ok; duration, first-chunk, token and cost metrics; option renamed
  telemetryContext -> telemetry (a parent span)
- pi-telemetry: TelemetryContext carries readonly metrics and propagation capabilities on every span
- chord/context: Context.telemetry is always a TelemetrySpan (NOOP default); withTelemetry takes spans
- durable: DURABLE_TELEMETRY_SCHEMA; pi.durable.submit (inputs start their own trace linked to the caller) and
  pi.durable.phase spans for every task phase; stored carriers on submissions and tasks (TaskOptions.trace, links);
  entry, submission, checkpoint, replay and report events after commit; resumed tasks stay in their trace; phase
  duration, active task and report metrics; failed phases carry fixed categories with bounded messages
2026-10-19 06:26:02 +00:00

24 lines
1.2 KiB
TypeScript

import { InMemoryTelemetryContext, NOOP_TELEMETRY_CONTEXT } from "@earendil-works/pi-telemetry";
import { describe, expect, expectTypeOf, it } from "vitest";
import type { HarnessOptions } from "../src/harness/types.ts";
describe("HarnessOptions.telemetry", () => {
it("accepts one adapter with optional propagation and metrics capabilities", () => {
const adapter = new InMemoryTelemetryContext();
const full: Pick<HarnessOptions, "telemetry"> = { telemetry: adapter };
const contextOnly: Pick<HarnessOptions, "telemetry"> = { telemetry: NOOP_TELEMETRY_CONTEXT };
const omitted: Pick<HarnessOptions, "telemetry"> = {};
expect(full.telemetry).toBe(adapter);
expect(contextOnly.telemetry).toBe(NOOP_TELEMETRY_CONTEXT);
expect(omitted.telemetry).toBeUndefined();
expectTypeOf(full.telemetry?.propagation?.inject).toExtend<
((context: NonNullable<HarnessOptions["telemetry"]>) => unknown) | undefined
>();
const compileTimeFailures = () => {
// @ts-expect-error telemetry requires the span-starting context capability
const invalid: Pick<HarnessOptions, "telemetry"> = { telemetry: { counter: adapter.counter.bind(adapter) } };
return invalid;
};
expectTypeOf(compileTimeFailures).toBeFunction();
});
});