UNPKG

eve

Version:

Filesystem-first framework for durable backend AI agents that run anywhere.

120 lines (119 loc) 5.62 kB
import type { ModelMessage, TextStreamPart, ToolSet, TypedToolResult } from "ai"; type ToolResponsePart = Extract<ModelMessage, { role: "tool"; }>["content"][number]; type InlineToolResultPart = Extract<ToolResponsePart, { type: "tool-result"; }>; import type { AssistantStepFinishReason, RuntimeIdentity } from "#protocol/message.js"; import type { RunMode } from "#shared/run-mode.js"; import type { JsonObject } from "#shared/json.js"; import type { HarnessEmitFn, HarnessSession, HarnessToolMap, SessionStateMap, StepInput } from "#harness/types.js"; /** * Tracks emission lifecycle state across harness step invocations. * * Persisted on `session.state` so the state survives when the durable * workflow runtime recreates the harness at each `"use step"` boundary. */ export interface HarnessEmissionState { readonly sessionStarted: boolean; readonly sequence: number; readonly stepIndex: number; readonly turnId: string; } /** Reads the emission state, returning defaults when absent. */ export declare function getHarnessEmissionState(state: SessionStateMap | undefined): HarnessEmissionState; /** * Returns `true` when the harness is **between turns** — either no turn * has started yet (initial state) or the previous turn has emitted its * epilogue (or recoverable failure cascade) and reset. * * Returns `false` while a turn is in progress, including during * tool-loop continuations and runtime-action resumes within the same * turn. Callers that gate per-turn work (eg. lifecycle hook dispatch) * use this predicate to distinguish a fresh delivery from a * continuation of an in-flight turn. * * Implemented over the empty-`turnId` sentinel that `emitTurnEpilogue` * and `emitRecoverableFailedTurn` write — clients should never read * `state.turnId` directly to make this distinction. */ export declare function isHarnessBetweenTurns(session: HarnessSession): boolean; /** * Writes the emission state onto a new copy of the session. */ export declare function setHarnessEmissionState(session: HarnessSession, state: HarnessEmissionState): HarnessSession; /** * Emits `session.started` (once), `turn.started`, and `message.received` at the * beginning of a new turn. Returns updated emission state. */ export declare function emitTurnPreamble(emitFn: HarnessEmitFn, input: StepInput, state: HarnessEmissionState, runtimeIdentity?: RuntimeIdentity): Promise<HarnessEmissionState>; /** * Emits `step.started` for one model call. */ export declare function emitStepStarted(emitFn: HarnessEmitFn, state: HarnessEmissionState, messages?: readonly import("ai").ModelMessage[]): Promise<void>; interface FailedStepPayload { readonly code: string; readonly details?: JsonObject; readonly message: string; } /** * Emits the full terminal failure cascade: `step.failed` → * `turn.failed` → `session.failed`. * * Use this when the session cannot be salvaged (structural config * error, auth misconfig, non-recoverable provider response). The * `session.failed` tail tells adapters the session is dead and no * further follow-up is possible on the same continuation token. */ export declare function emitFailedStep(emitFn: HarnessEmitFn, state: HarnessEmissionState, input: FailedStepPayload & { readonly sessionId: string; }): Promise<void>; /** * Emits the recoverable failure cascade: `step.failed` → * `turn.failed` → `session.waiting`. */ export declare function emitRecoverableFailedTurn(emitFn: HarnessEmitFn, state: HarnessEmissionState, input: FailedStepPayload & { readonly continuationToken: string; }): Promise<HarnessEmissionState>; /** * Returns updated emission state for the next step in the current turn. */ export declare function advanceStep(state: HarnessEmissionState): HarnessEmissionState; /** * Emits `turn.completed` and either `session.waiting` or `session.completed`. * Returns updated emission state with an incremented sequence. */ export declare function emitTurnEpilogue(emitFn: HarnessEmitFn, state: HarnessEmissionState, mode: RunMode, continuationToken: string): Promise<HarnessEmissionState>; /** * Maps an AI SDK finish reason string to the eve-owned * {@link AssistantStepFinishReason} union. Unknown values become `"other"`. */ export declare function normalizeAssistantStepFinishReason(value: string | undefined): AssistantStepFinishReason; /** * Result of consuming one step's `fullStream`. * * Inline results avoid duplicate post-step events. Approval-resume * authorization results also route back to the park detector. */ interface EmittedStreamContent { readonly emittedActionCallIds: ReadonlySet<string>; readonly handledInlineToolResultCallIds: ReadonlySet<string>; readonly invalidInputToolCallIds: ReadonlySet<string>; readonly inlineAuthorizationResults: readonly TypedToolResult<ToolSet>[]; readonly trailingInlineToolResultParts: readonly InlineToolResultPart[]; } interface StreamActionEmissionOptions { readonly excludedActionToolNames: ReadonlySet<string>; readonly tools: HarnessToolMap; } /** * Consumes the AI SDK `fullStream` and emits real-time text and reasoning * events. * * Emits local tool events in source order. Provider calls that arrive in one * stream batch into one request event before their first result. A result * without a streamed call resumes a call from an earlier step. */ export declare function emitStreamContent(emitFn: HarnessEmitFn, state: HarnessEmissionState, fullStream: AsyncIterable<TextStreamPart<ToolSet>>, options?: StreamActionEmissionOptions): Promise<EmittedStreamContent>; export {};