import type * as memory from "#instrumentation/memory.js"; import type { InstrumentationStateSlot } from "#instrumentation/state.js"; import type { RuntimeTraceContext } from "#protocol/message.js"; import type { ChannelAudience } from "#shared/channel-audience.js"; import type { InstrumentationDecision } from "#shared/instrumentation-decision.js"; import type { TraceCaptureContext, TraceCapturePolicy } from "#shared/trace-policy.js"; /** * Stable eve identity for one model attempt. Retries share `stepIndex` and * differ by `attemptIndex`, so `step.attempt.*` fires once per attempt while * protocol `step.*` events and the resolver hook fire once per step. */ export interface InstrumentationAttemptScope { readonly traceSessionId?: string; readonly channelAudience?: ChannelAudience; readonly attemptId: string; readonly attemptIndex: number; readonly functionId?: string; readonly rootSessionId?: string; readonly sessionId: string; readonly stepIndex: number; readonly turnId: string; } /** The model SDK operation an attempt runs through. */ export interface InstrumentationOperationRef { readonly modelId: string; readonly operationId: string; readonly provider: string; } export interface InstrumentationModelRef { readonly modelId: string; readonly provider: string; } /** Token usage for one model call. A field is absent when the provider omits it. */ export interface InstrumentationUsage { /** Provider-reported cost in US dollars. Absent when the provider omits pricing. */ readonly costUsd?: number; readonly inputTokenDetails?: { readonly cacheReadTokens?: number; readonly cacheWriteTokens?: number; }; readonly inputTokens?: number; readonly outputTokens?: number; } /** Final model input for one call. Message shape stays opaque to this layer. */ export interface InstrumentationModelInput { readonly instructions?: unknown; readonly messages: readonly unknown[]; readonly tools?: readonly unknown[]; } /** * The model response parts eve records. A kind outside this union is dropped * when the bridge maps a response, so widening the union is what makes a new * kind reachable by a provider. */ export type InstrumentationContentPart = { readonly type: "text"; readonly text: string; } | { readonly type: "reasoning"; readonly text: string; } | { readonly type: "tool-call"; readonly callId: string; readonly input: unknown; readonly toolName: string; } | { readonly type: "tool-result"; readonly callId: string; readonly input: unknown; readonly output: unknown; readonly toolName: string; } | { readonly type: "tool-error"; readonly callId: string; readonly error: unknown; readonly input: unknown; readonly toolName: string; }; /** * How one tool call ended. * * `type` survives a provider that declined content, so whether the tool errored * is answerable without seeing what it returned. */ export type InstrumentationToolOutput = { readonly type: "result"; readonly output?: unknown; } | { readonly type: "error"; readonly error?: unknown; }; /** * Every event carries an `idempotencyKey` naming the operation it is about: a * start and its terminal share one, and two operations never collide. * * Every part is identity eve reconstructs on replay — session and turn ids, * `scope.attemptId` (itself `session:turn:step:attempt`), AI SDK step number, * and durable runtime-action call ids. A provider writing rows can use the key * as its row id and be idempotent by construction. */ export declare function sessionIdempotencyKey(sessionId: string): string; export declare function turnIdempotencyKey(sessionId: string, turnId: string): string; export declare function attemptIdempotencyKey(scope: InstrumentationAttemptScope): string; /** Identifies one provider call, including retries, within an AI SDK step. */ export declare function modelCallIdempotencyKey(scope: InstrumentationAttemptScope, stepNumber: number, callIndex: number): string; export declare function toolCallIdempotencyKey(scope: InstrumentationAttemptScope, callId: string, stepNumber: number): string; export declare function inputIdempotencyKey(sessionId: string, turnId: string, requestId: string): string; export declare function channelDeliveryIdempotencyKey(sessionId: string, deliveryId: string): string; export interface InstrumentationChannelDeliveryRef { readonly channelAudience?: ChannelAudience; readonly channelKind: string; readonly channelName: string; readonly deliveryId: string; readonly requestId?: string; readonly requestTraceContext?: InstrumentationTraceContext; } /** Known framework delivery input; adapter-specific fields are never projected. */ export interface InstrumentationChannelDeliveryInput { readonly context?: readonly string[]; readonly inputResponses?: readonly InstrumentationInputResponse[]; readonly message?: unknown; readonly outputSchema?: unknown; } interface InstrumentationChannelDeliveryScope { readonly traceSessionId?: string; readonly agentName?: string; readonly delivery: InstrumentationChannelDeliveryRef; readonly idempotencyKey: string; readonly rootSessionId: string; readonly sequence?: number; readonly sessionId: string; readonly traceSeed?: InstrumentationTraceSeed; readonly turnId?: string; } export interface InstrumentationChannelDeliveryStartedEvent extends InstrumentationChannelDeliveryScope { readonly parentTraceContext?: InstrumentationTraceContext; readonly type: "channel.delivery.started"; /** Content. Absent unless this provider's trace policy records this direction. */ readonly input?: InstrumentationChannelDeliveryInput; } export type InstrumentationChannelDeliveryOutcome = "cancelled" | "completed" | "failed"; export interface InstrumentationChannelDeliveryTerminalEvent extends InstrumentationChannelDeliveryScope { readonly type: "channel.delivery.cancelled" | "channel.delivery.completed" | "channel.delivery.failed"; /** Content. Absent unless this provider's trace policy records this direction. */ readonly error?: unknown; readonly errorCode?: string; readonly outcome: InstrumentationChannelDeliveryOutcome; } /** Framework-owned reason an agent suspended for user input. */ export type InstrumentationInputKind = "question" | "session-limit" | "tool-approval"; export interface InstrumentationInputOption { readonly description?: string; readonly id: string; readonly label: string; readonly style?: "danger" | "default" | "primary"; } /** User-facing input request content projected without runtime-owned types. */ export interface InstrumentationInputRequest { readonly allowFreeform?: boolean; readonly display?: "confirmation" | "select" | "text"; readonly options?: readonly InstrumentationInputOption[]; readonly prompt: string; } /** User response content projected without runtime-owned types. */ export interface InstrumentationInputResponse { readonly optionId?: string; readonly text?: string; } export type InstrumentationInputOutcome = "answered" | "approved" | "cancelled" | "denied" | "failed" | "ignored" | "invalid"; export interface InstrumentationInputRequestedEvent { readonly type: "input.requested"; readonly action: { readonly callId: string; readonly name: string; }; readonly idempotencyKey: string; readonly kind: InstrumentationInputKind; /** Content. Absent unless this provider's trace policy records this direction. */ readonly request?: InstrumentationInputRequest; readonly requestId: string; readonly scope: InstrumentationAttemptScope; } export interface InstrumentationInputResolvedEvent { readonly type: "input.resolved"; readonly error?: unknown; readonly idempotencyKey: string; readonly kind: InstrumentationInputKind; readonly outcome: InstrumentationInputOutcome; readonly requestId: string; /** Content. Absent unless this provider's trace policy records this direction. */ readonly response?: InstrumentationInputResponse; readonly scope: InstrumentationAttemptScope; } /** Runtime action call IDs are durable and unique within one session. */ export declare function actionIdempotencyKey(sessionId: string, turnId: string, callId: string): string; export interface InstrumentationStepAttemptStartedEvent { readonly type: "step.attempt.started"; readonly idempotencyKey: string; readonly operation: InstrumentationOperationRef; readonly runtimeContext?: Readonly>; readonly scope: InstrumentationAttemptScope; } export interface InstrumentationSessionStartedEvent { readonly traceSessionId?: string; readonly type: "session.started"; readonly agentName?: string; readonly channelKind?: string; readonly channelType?: string; readonly channelAudience?: ChannelAudience; readonly idempotencyKey: string; readonly parentLineage?: InstrumentationParentLineage; readonly parentTraceContext?: InstrumentationTraceContext; readonly rootSessionId: string; readonly scheduleId?: string; readonly sessionId: string; readonly title?: string; readonly traceSeed?: InstrumentationTraceSeed; } export type InstrumentationTraceContext = RuntimeTraceContext; export interface InstrumentationTraceSeed extends InstrumentationTraceContext { readonly decision?: InstrumentationDecision; } export declare const INSTRUMENTATION_PRINCIPAL_TYPES: readonly ["anonymous", "app", "local-dev", "none", "other", "runtime", "service", "unknown", "user"]; export type InstrumentationPrincipalType = (typeof INSTRUMENTATION_PRINCIPAL_TYPES)[number]; export declare function isInstrumentationPrincipalType(value: unknown): value is InstrumentationPrincipalType; export interface InstrumentationPrincipalSummary { readonly id?: string; readonly type: InstrumentationPrincipalType; } /** * Which tool call dispatched a subagent child. The trace structure alone * cannot say: one turn's children all parent to the same window. */ export interface InstrumentationParentLineage { readonly callId: string; readonly sessionId: string; readonly subagentName?: string; readonly turnId: string; } /** * A session transition that carries no failure. * * `session.waiting` sits here rather than with the failed shape because it is * not terminal: the session suspends awaiting input or approval and may resume * with a new turn. */ export interface InstrumentationSessionSettledEvent { readonly type: "session.completed" | "session.waiting"; readonly idempotencyKey: string; readonly sessionId: string; readonly turnId?: string; } export interface InstrumentationSessionFailedEvent { readonly type: "session.failed"; /** Content. Absent unless this provider's trace policy records this direction. */ readonly error?: unknown; readonly idempotencyKey: string; readonly sessionId: string; readonly turnId?: string; } export type InstrumentationSessionTransitionEvent = InstrumentationSessionSettledEvent | InstrumentationSessionFailedEvent; export interface InstrumentationTurnStartedEvent { readonly traceSessionId?: string; readonly type: "turn.started"; readonly agentName?: string; readonly currentPrincipal?: InstrumentationPrincipalSummary; readonly idempotencyKey: string; readonly initiatorPrincipal?: InstrumentationPrincipalSummary; readonly parentLineage?: InstrumentationParentLineage; readonly parentTraceContext?: InstrumentationTraceContext; readonly rootSessionId: string; readonly sequence: number; readonly sessionId: string; readonly turnId: string; } /** * A turn that ended without a failure. * * `turn.cancelled` sits here rather than with the failed shape because * cancellation is not an error: the harness settles a cancelled turn as * `turn.cancelled` → `session.waiting`, with no failure surfaced anywhere. */ export interface InstrumentationTurnSettledEvent { readonly type: "turn.cancelled" | "turn.completed"; readonly idempotencyKey: string; readonly sessionId: string; readonly turnId: string; } export interface InstrumentationTurnFailedEvent { readonly type: "turn.failed"; /** Content. Absent unless this provider's trace policy records this direction. */ readonly error?: unknown; readonly idempotencyKey: string; readonly sessionId: string; readonly turnId: string; } export type InstrumentationTurnTerminalEvent = InstrumentationTurnSettledEvent | InstrumentationTurnFailedEvent; export interface InstrumentationStepAttemptCompletedEvent { readonly type: "step.attempt.completed"; readonly idempotencyKey: string; readonly scope: InstrumentationAttemptScope; } export interface InstrumentationStepAttemptFailedEvent { readonly type: "step.attempt.failed"; /** Content. Absent unless this provider's trace policy records this direction. */ readonly error?: unknown; readonly idempotencyKey: string; readonly scope: InstrumentationAttemptScope; } export type InstrumentationStepAttemptTerminalEvent = InstrumentationStepAttemptCompletedEvent | InstrumentationStepAttemptFailedEvent; /** * Provider metadata for one completed attempt, as reported by the AI SDK * (`StepResult.providerMetadata`). Carries Vercel AI Gateway cost data when * the request went through the gateway; absent for other providers. */ export interface InstrumentationStepAttemptMetadataEvent { readonly type: "step.attempt.metadata"; readonly idempotencyKey: string; readonly scope: InstrumentationAttemptScope; readonly providerMetadata: Readonly>; } export interface InstrumentationModelCallStartedEvent { readonly type: "model.call.started"; readonly idempotencyKey: string; /** Content. Absent unless this provider's trace policy records this direction. */ readonly input?: InstrumentationModelInput; readonly model: InstrumentationModelRef; readonly runtimeContext?: Readonly>; readonly scope: InstrumentationAttemptScope; } export interface InstrumentationModelCallCompletedEvent { readonly type: "model.call.completed"; /** Content. Absent unless this provider's trace policy records this direction. */ readonly content?: readonly InstrumentationContentPart[]; readonly finishReason: string; readonly idempotencyKey: string; readonly responseModelId?: string; readonly responseId?: string; readonly scope: InstrumentationAttemptScope; readonly usage: InstrumentationUsage; } export interface InstrumentationModelCallFailedEvent { readonly type: "model.call.failed"; /** Content. Absent unless this provider's trace policy records this direction. */ readonly error?: unknown; readonly idempotencyKey: string; readonly scope: InstrumentationAttemptScope; } export type InstrumentationModelCallTerminalEvent = InstrumentationModelCallCompletedEvent | InstrumentationModelCallFailedEvent; /** How eve runs the tool call. */ export type InstrumentationToolCallKind = "load-skill" | "remote-agent-call" | "subagent-call" | "tool-call"; export interface InstrumentationToolCallStartedEvent { /** Durable dispatch metadata, when this call is owned by eve's tool loop. */ readonly kind?: InstrumentationToolCallKind; readonly isWorkflowTool?: boolean; readonly frameworkTool?: boolean; readonly startedAtMs?: number; readonly type: "tool.call.started"; readonly callId: string; readonly idempotencyKey: string; readonly input: unknown; readonly scope: InstrumentationAttemptScope; readonly toolName: string; } export interface InstrumentationToolCallCompletedEvent { readonly outcome?: InstrumentationToolCallOutcome; readonly usage?: InstrumentationUsage; readonly acceptedAtMs?: number; readonly completedAtMs?: number; readonly type: "tool.call.completed"; /** How long the tool's `execute` ran, in milliseconds, when the publisher measured it. */ readonly durationMs?: number; readonly idempotencyKey: string; readonly output: InstrumentationToolOutput; readonly scope: InstrumentationAttemptScope; } export interface InstrumentationToolCallFailedEvent { readonly outcome?: Exclude; readonly usage?: InstrumentationUsage; readonly acceptedAtMs?: number; readonly errorCode?: string; readonly completedAtMs?: number; readonly type: "tool.call.failed"; /** Content. Absent unless this provider's trace policy records this direction. */ readonly error?: unknown; readonly idempotencyKey: string; readonly scope: InstrumentationAttemptScope; } export type InstrumentationToolCallTerminalEvent = InstrumentationToolCallCompletedEvent | InstrumentationToolCallFailedEvent; export type InstrumentationToolCallOutcome = "abandoned" | "cancelled" | "completed" | "failed" | "rejected"; /** The second argument to every handler. */ export interface InstrumentationHandlerContext { /** Durable state scoped to this provider and this operation. */ readonly state: InstrumentationStateSlot; } /** * The AI SDK can omit a model terminal when an incomplete stream closes. A * handler can use `ctx.state` for durable correlation when a terminal arrives, * but providers must scope live resources to the attempt and release anything * still open when the step attempt terminates. */ export type InstrumentationEventHandler = (event: TEvent, ctx: InstrumentationHandlerContext) => void | PromiseLike; /** Internal normalized provider shape consumed by the instrumentation bus. */ export interface InstrumentationProviderDefinition { readonly name: string; /** Durable state identity, separate from the human-readable log name. */ readonly stateNamespace?: string; /** Internal provider-specific projection applied after capture filtering. */ readonly projectEvent?: (event: InstrumentationEvent) => InstrumentationEvent | PromiseLike; /** Provider-specific event admission and directional content policy. */ readonly tracePolicy?: TraceCapturePolicy; readonly events?: { readonly "channel.delivery.started"?: InstrumentationEventHandler; readonly "channel.delivery.cancelled"?: InstrumentationEventHandler; readonly "channel.delivery.completed"?: InstrumentationEventHandler; readonly "channel.delivery.failed"?: InstrumentationEventHandler; readonly "step.attempt.started"?: InstrumentationEventHandler; readonly "step.attempt.completed"?: InstrumentationEventHandler; readonly "step.attempt.failed"?: InstrumentationEventHandler; readonly "step.attempt.metadata"?: InstrumentationEventHandler; readonly "model.call.started"?: InstrumentationEventHandler; readonly "model.call.completed"?: InstrumentationEventHandler; readonly "model.call.failed"?: InstrumentationEventHandler; readonly "memory.operation.started"?: InstrumentationEventHandler; readonly "memory.operation.completed"?: InstrumentationEventHandler; readonly "memory.operation.failed"?: InstrumentationEventHandler; readonly "input.requested"?: InstrumentationEventHandler; readonly "input.resolved"?: InstrumentationEventHandler; readonly "session.completed"?: InstrumentationEventHandler; readonly "session.failed"?: InstrumentationEventHandler; readonly "session.started"?: InstrumentationEventHandler; readonly "session.waiting"?: InstrumentationEventHandler; readonly "tool.call.started"?: InstrumentationEventHandler; readonly "tool.call.completed"?: InstrumentationEventHandler; readonly "tool.call.failed"?: InstrumentationEventHandler; readonly "turn.cancelled"?: InstrumentationEventHandler; readonly "turn.completed"?: InstrumentationEventHandler; readonly "turn.failed"?: InstrumentationEventHandler; readonly "turn.started"?: InstrumentationEventHandler; }; /** Drains anything buffered. Driven by the runtime, not by the bus. */ readonly flush?: () => void | PromiseLike; /** Releases resources when the process is going away. */ readonly shutdown?: () => void | PromiseLike; } type InstrumentationProviderInput = Omit & { readonly name?: string; }; export interface InstrumentationDispatchGroups { readonly serialBefore?: readonly InstrumentationProviderDefinition[]; readonly parallel?: readonly InstrumentationProviderDefinition[]; readonly serialAfter?: readonly InstrumentationProviderDefinition[]; } export type InstrumentationHooksInput = readonly InstrumentationProviderInput[] | InstrumentationDispatchGroups; /** Events that pair a start with its terminal under one `idempotencyKey`. */ export type InstrumentationCorrelatedEvent = InstrumentationChannelDeliveryStartedEvent | InstrumentationChannelDeliveryTerminalEvent | InstrumentationInputRequestedEvent | InstrumentationInputResolvedEvent | memory.InstrumentationMemoryOperationStartedEvent | memory.InstrumentationMemoryOperationTerminalEvent | InstrumentationModelCallStartedEvent | InstrumentationModelCallTerminalEvent | InstrumentationToolCallStartedEvent | InstrumentationToolCallTerminalEvent; export type InstrumentationPointEvent = InstrumentationStepAttemptStartedEvent | InstrumentationStepAttemptMetadataEvent | InstrumentationStepAttemptTerminalEvent | InstrumentationSessionStartedEvent | InstrumentationSessionTransitionEvent | InstrumentationTurnStartedEvent | InstrumentationTurnTerminalEvent; export type InstrumentationEvent = InstrumentationCorrelatedEvent | InstrumentationPointEvent; /** Trusted framework operation for activating context around AI SDK execution. */ export type InstrumentationContextRunner = (operation: InstrumentationExecutionOperation, execute: () => PromiseLike) => PromiseLike; /** Stable identity supplied only to a trusted framework context runner. */ export type InstrumentationExecutionOperation = { readonly idempotencyKey: string; readonly scope: InstrumentationAttemptScope; readonly type: "tool.call"; readonly callId?: string; readonly toolName?: string; readonly input?: unknown; readonly frameworkTool?: boolean; readonly startedAtMs?: number; readonly completedAtMs?: number; readonly failed?: boolean; } | { readonly idempotencyKey: string; readonly scope: InstrumentationAttemptScope; readonly type: "model.call"; } | memory.InstrumentationMemoryExecutionOperation; /** Provider-neutral hook operations consumed by the AI SDK bridge. */ export interface InstrumentationHooks { /** * Whether any provider admitted by this bound trace requests content. * * False means nothing downstream can read what was said, so the publisher * should not serialize it in the first place. This is the only way the * projection is skipped rather than merely withheld. */ readonly capturesContent: boolean; /** Input-content demand for publishers that can project directions separately. */ readonly capturesInputs?: boolean; /** Output-content demand for publishers that can project directions separately. */ readonly capturesOutputs?: boolean; readonly forTrace?: (trace: TraceCaptureContext) => InstrumentationHooks; publish(event: InstrumentationEvent): Promise; } export interface CreateInstrumentationHooksOptions { readonly handlerTimeoutMs?: number; } /** Creates failure-isolated hooks backed by normalized dispatch groups. */ export declare function createInstrumentationHooks(input: InstrumentationHooksInput, options?: CreateInstrumentationHooksOptions): InstrumentationHooks; export {};