@tangle-network/agent-runtime 0.75.0 → 0.76.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/agent.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as _tangle_network_agent_eval from '@tangle-network/agent-eval';
2
2
  import { TraceAnalystKindSpec, AnalystFinding } from '@tangle-network/agent-eval';
3
3
  import { A as ArtifactKind, C as CandidateGenerator, P as PromotionGate } from './generator-YkAQrOoD.js';
4
- import { a as RuntimeStreamEvent, S as SandboxClient, b as OutputAdapter, A as AgentRunSpec } from './types-YimN9PQP.js';
4
+ import { a as RuntimeStreamEvent, S as SandboxClient, b as OutputAdapter, A as AgentRunSpec } from './types-B-jWSfcu.js';
5
5
  import { A as AgentSurfaces } from './improvement-adapter-CioiEE2z.js';
6
6
  export { C as CreateSurfaceImprovementAdapterOpts, D as DraftPatchInput, a as DraftPatchOutput, R as ResolvedSurface, S as SurfaceImprovementEdit, b as SurfaceValidationIssue, c as createSurfaceImprovementAdapter, r as renderSurfaceIssues, d as resolveSubjectPath, v as validateSurfaces } from './improvement-adapter-CioiEE2z.js';
7
7
  import { K as KnowledgeAdapter, a as RunAnalystLoopResult } from './types-BC3bZpH0.js';
@@ -1,5 +1,5 @@
1
1
  import { TraceAnalystByteBudgets, TraceAnalysisStore } from '@tangle-network/agent-eval';
2
- import { I as Iteration } from './types-YimN9PQP.js';
2
+ import { I as Iteration } from './types-B-jWSfcu.js';
3
3
  import { R as RunAnalystLoopOpts, a as RunAnalystLoopResult } from './types-BC3bZpH0.js';
4
4
  export { A as AnalystLoopEvent, b as AnalystRegistryLike, c as AnalystRegistryStreamingLike, d as AutoApplyPolicy, F as FindingsStoreLike, I as ImprovementAdapter, e as ImprovementEditBatch, f as ImprovementReport, K as KnowledgeAdapter, g as KnowledgeProposalBatch, h as KnowledgeReport } from './types-BC3bZpH0.js';
5
5
  import '@tangle-network/sandbox';
@@ -1,7 +1,7 @@
1
- import { m as ExecutorFactory, E as ExecutorRegistry, l as DeliverableSpec, i as Spend, d as Agent, j as Scope, e as ResultBlobStore, B as Budget } from './worktree-CtuEQ7bZ.js';
1
+ import { m as ExecutorFactory, E as ExecutorRegistry, l as DeliverableSpec, i as Spend, d as Agent, j as Scope, e as ResultBlobStore, B as Budget } from './worktree-CDxqwxGo.js';
2
2
  import { AgentProfile } from '@tangle-network/agent-interface';
3
3
  import { U as UiLens, a as UiFinding, C as CoderTask } from './substrate-rNj6TDc3.js';
4
- import { e as LoopTraceEmitter, c as LoopTraceEvent, S as SandboxClient, A as AgentRunSpec, E as ExecCtx } from './types-YimN9PQP.js';
4
+ import { e as LoopTraceEmitter, c as LoopTraceEvent, S as SandboxClient, A as AgentRunSpec, E as ExecCtx } from './types-B-jWSfcu.js';
5
5
  import { SandboxEvent, SandboxInstance, BackendType } from '@tangle-network/sandbox';
6
6
  import { AgentEvalError } from '@tangle-network/agent-eval';
7
7
  import { O as OtelExporter } from './otel-export-BKmNwiCb.js';
package/dist/index.d.ts CHANGED
@@ -1,23 +1,23 @@
1
1
  import { AgentProfile, AgentEvalError, AnalystFinding, KnowledgeReadinessReport, RunRecord, ControlEvalResult, KnowledgeRequirement } from '@tangle-network/agent-eval';
2
2
  export { AgentEvalError, AgentEvalErrorCode, ConfigError, ControlBudget, ControlDecision, ControlEvalResult, ControlRunResult, ControlStep, DataAcquisitionPlan, JudgeError, KnowledgeReadinessReport, KnowledgeRequirement, NotFoundError, RunRecord, ValidationError } from '@tangle-network/agent-eval';
3
- import { f as AgentBackendInput, g as AgentExecutionBackend, O as OpenAIChatTool, h as OpenAIChatToolChoice, i as AgentBackendContext, a as RuntimeStreamEvent, K as KnowledgeReadinessDecision, j as RunAgentTaskOptions, k as AgentTaskRunResult, l as RunAgentTaskStreamOptions, m as AgentRuntimeEvent, n as AgentTaskStatus, o as RuntimeSessionStore, p as RuntimeSession, R as RuntimeHooks } from './types-YimN9PQP.js';
4
- export { q as AgentAdapter, r as AgentKnowledgeProvider, s as AgentRuntimeEventSink, t as AgentTaskContext, u as AgentTaskSpec, B as BackendErrorDetail, v as RuntimeDecisionEvidenceRef, w as RuntimeDecisionKind, x as RuntimeDecisionPoint, y as RuntimeHookContext, z as RuntimeHookErrorContext, C as RuntimeHookEvent, D as RuntimeHookPhase, F as RuntimeHookTarget, G as RuntimeRunHandle, H as RuntimeRunPersistenceAdapter, J as RuntimeRunRow, M as composeRuntimeHooks, N as defineRuntimeHooks, P as notifyRuntimeDecisionPoint, Q as notifyRuntimeHookEvent, T as startRuntimeRun } from './types-YimN9PQP.js';
5
- import { AgentProfile as AgentProfile$1 } from '@tangle-network/agent-interface';
3
+ import { f as AgentBackendInput, g as AgentExecutionBackend, O as OpenAIChatTool, h as OpenAIChatToolChoice, i as OpenAIChatResponseFormat, j as AgentBackendContext, a as RuntimeStreamEvent, K as KnowledgeReadinessDecision, k as RunAgentTaskOptions, l as AgentTaskRunResult, m as RunAgentTaskStreamOptions, n as AgentRuntimeEvent, o as AgentTaskStatus, p as RuntimeSessionStore, q as RuntimeSession, R as RuntimeHooks } from './types-B-jWSfcu.js';
4
+ export { r as AgentAdapter, s as AgentKnowledgeProvider, t as AgentRuntimeEventSink, u as AgentTaskContext, v as AgentTaskSpec, B as BackendErrorDetail, w as RuntimeDecisionEvidenceRef, x as RuntimeDecisionKind, y as RuntimeDecisionPoint, z as RuntimeHookContext, C as RuntimeHookErrorContext, D as RuntimeHookEvent, F as RuntimeHookPhase, G as RuntimeHookTarget, H as RuntimeRunHandle, J as RuntimeRunPersistenceAdapter, M as RuntimeRunRow, N as composeRuntimeHooks, P as defineRuntimeHooks, Q as notifyRuntimeDecisionPoint, T as notifyRuntimeHookEvent, U as startRuntimeRun } from './types-B-jWSfcu.js';
6
5
  import { Scenario, ProfileDispatchFn } from '@tangle-network/agent-eval/campaign';
7
6
  import { C as CandidateGenerator } from './mcp-serve-verifier-CT1KLTG_.js';
8
7
  export { A as AgenticGeneratorOptions, I as ImprovementDriverOptions, M as McpServeSpec, V as Verifier, a as VerifyResult, b as agenticGenerator, c as commandVerifier, i as improvementDriver, m as mcpServeVerifier } from './mcp-serve-verifier-CT1KLTG_.js';
9
8
  import { Scenario as Scenario$1, SurfaceProposer, JudgeConfig, MutableSurface, DispatchContext, SelfImproveBudget, SelfImproveLlm, SelfImproveResult } from '@tangle-network/agent-eval/contract';
9
+ import { AgentProfile as AgentProfile$1 } from '@tangle-network/agent-interface';
10
10
  import { S as SurfaceImprovementEdit } from './improvement-adapter-CioiEE2z.js';
11
11
  import { I as ImprovementAdapter } from './types-BC3bZpH0.js';
12
- export { D as DELEGATED_LOOP_MODES, a as DelegatedLoopMode, b as DelegatedLoopRegistry, c as DelegatedLoopResult, d as DelegatedLoopRunner, L as LoopRunnerCliArgs, e as LoopRunnerCliResult, R as ResearchLoopResult, f as ResearchLoopRunnerOptions, g as RunDelegatedLoopOptions, V as VetoedFact, W as WorktreeLoopRunnerOptions, h as auditLoopRunner, i as isDelegatedLoopMode, p as parseLoopRunnerArgv, r as researchLoopRunner, j as runDelegatedLoop, k as runLoopRunnerCli, s as selfImproveLoopRunner, w as worktreeLoopRunner } from './loop-runner-bin-BPthX22l.js';
13
- export { m as mcpToolsForRuntimeMcp, a as mcpToolsForRuntimeMcpSubset } from './openai-tools-D-VCAEmw.js';
12
+ export { D as DELEGATED_LOOP_MODES, a as DelegatedLoopMode, b as DelegatedLoopRegistry, c as DelegatedLoopResult, d as DelegatedLoopRunner, L as LoopRunnerCliArgs, e as LoopRunnerCliResult, R as ResearchLoopResult, f as ResearchLoopRunnerOptions, g as RunDelegatedLoopOptions, V as VetoedFact, W as WorktreeLoopRunnerOptions, h as auditLoopRunner, i as isDelegatedLoopMode, p as parseLoopRunnerArgv, r as researchLoopRunner, j as runDelegatedLoop, k as runLoopRunnerCli, s as selfImproveLoopRunner, w as worktreeLoopRunner } from './loop-runner-bin-Dbtg787n.js';
13
+ export { m as mcpToolsForRuntimeMcp, a as mcpToolsForRuntimeMcpSubset } from './openai-tools-D5tcirFF.js';
14
14
  export { E as EvalRunEvent, a as EvalRunGeneration, b as EvalRunsExportConfig, c as EvalRunsExportResult, I as INTELLIGENCE_WIRE_VERSION, L as LoopSpanNode, d as OtelAttribute, e as OtelExportConfig, O as OtelExporter, f as OtelSpan, g as buildLoopOtelSpans, h as buildLoopSpanNodes, i as createOtelExporter, j as exportEvalRuns, l as loopEventToOtelSpan } from './otel-export-BKmNwiCb.js';
15
15
  import '@tangle-network/sandbox';
16
16
  import './local-harness-BE_h8szs.js';
17
17
  import 'node:child_process';
18
18
  import './kb-gate-CuzMYGYM.js';
19
- import './worktree-CtuEQ7bZ.js';
20
- import './worktree-fanout-Cdez8GR7.js';
19
+ import './worktree-CDxqwxGo.js';
20
+ import './worktree-fanout-CljF1L2v.js';
21
21
 
22
22
  /**
23
23
  * @stable
@@ -136,6 +136,10 @@ declare function createOpenAICompatibleBackend<TInput extends AgentBackendInput
136
136
  * `'auto'`).
137
137
  */
138
138
  toolChoice?: OpenAIChatToolChoice;
139
+ /**
140
+ * OpenAI Chat Completions `response_format`. Omit for provider default text.
141
+ */
142
+ responseFormat?: OpenAIChatResponseFormat;
139
143
  fetchImpl?: typeof fetch;
140
144
  retry?: BackendRetryPolicy;
141
145
  }): AgentExecutionBackend<TInput>;
@@ -671,144 +675,6 @@ declare function defineConversation(input: {
671
675
  policy: ConversationPolicy;
672
676
  }): Conversation;
673
677
 
674
- /**
675
- * `runPersonaConversation` — the persona loop runner: run a WORKER `AgentProfile`
676
- * (the agent under test) as a multi-round conversation driven by a PERSONA (the
677
- * simulated user), over the persistent conversation transcript.
678
- *
679
- * It is profiles-vs-profiles: the persona is itself a driver `AgentProfile` (an
680
- * LLM role-playing the user from its facts) — `runConversation` runs the two
681
- * against each other. Scripted persona turns are kept as a deterministic
682
- * fast-path. Only the WORKER is metered (it is the side under test); the
683
- * persona-driver is the test harness, not billed against the agent.
684
- *
685
- * `runPersonaDispatch` wraps the runner as a `ProfileDispatchFn` so it drops
686
- * straight into `runProfileMatrix({ dispatch })` — the same loop serves a single
687
- * cell and the whole matrix, replacing the per-agent hand-rolled
688
- * `dispatchWithSurface` bridges.
689
- */
690
-
691
- /** A persona that drives the conversation: either a full driver `AgentProfile`
692
- * (an LLM user-sim) or a deterministic script of user turns (the fast-path). */
693
- type PersonaDriver = {
694
- kind: 'profile';
695
- profile: AgentProfile;
696
- } | {
697
- kind: 'scripted';
698
- turns: string[];
699
- };
700
- interface RunPersonaConversationOptions {
701
- /** The agent under test. Metered; its rendered prompt leads its turns. */
702
- worker: AgentProfile;
703
- /** The simulated user driving the dialogue. */
704
- persona: PersonaDriver;
705
- /** Turn an `AgentProfile` into a runnable backend (router / sandbox / fake).
706
- * Applied to the worker and to a `profile`-kind persona. */
707
- backendFor: (profile: AgentProfile, role: 'worker' | 'persona') => AgentExecutionBackend;
708
- /** Render a profile's system prompt — prepended to that profile's messages. */
709
- systemPromptOf: (profile: AgentProfile) => string;
710
- /** Speaker-turn cap. Default for a scripted persona = `2 * turns.length`
711
- * (worker answers each user turn). REQUIRED for a `profile` persona. */
712
- maxTurns?: number;
713
- /** Kickoff message routed to the first speaker (the persona). Default 'Begin.' */
714
- seed?: string;
715
- /** Content-based "until satisfied" halt, called after every turn. `maxTurns` is the
716
- * hard ceiling; this is the early stop (the persona declares the goal met / unreachable). */
717
- haltOn?: HaltPredicate;
718
- signal?: AbortSignal;
719
- /** Worker participant / transcript speaker label. Default 'agent'. */
720
- workerName?: string;
721
- }
722
- interface PersonaConversationResult {
723
- transcript: ConversationTurn[];
724
- turns: number;
725
- halted: HaltReason;
726
- /** Worker-only spend (the side under test). */
727
- costUsd: number;
728
- tokensIn: number;
729
- tokensOut: number;
730
- }
731
- /**
732
- * Run one worker profile against one persona as a multi-round conversation.
733
- * The persona leads (participant 0): it speaks, the worker answers, repeat,
734
- * until `maxTurns`. Returns the persistent transcript + worker-only usage.
735
- */
736
- declare function runPersonaConversation(opts: RunPersonaConversationOptions): Promise<PersonaConversationResult>;
737
- interface RunPersonaConfig<TScenario extends Scenario, TArtifact> {
738
- /** Turn an `AgentProfile` into a runnable backend (router / sandbox / fake). */
739
- backendFor: (profile: AgentProfile, role: 'worker' | 'persona') => AgentExecutionBackend;
740
- /** Render a profile's system prompt. */
741
- systemPromptOf: (profile: AgentProfile) => string;
742
- /** The persona driving each scenario — a driver profile or scripted turns. */
743
- personaOf: (scenario: TScenario) => PersonaDriver;
744
- /** Build the scored artifact from the finished transcript. */
745
- artifactOf: (transcript: ConversationTurn[], scenario: TScenario) => TArtifact;
746
- /** Speaker-turn cap (required when a persona is profile-driven). */
747
- maxTurns?: (scenario: TScenario) => number;
748
- seed?: (scenario: TScenario) => string;
749
- workerName?: string;
750
- }
751
- /**
752
- * Wrap {@link runPersonaConversation} as a `ProfileDispatchFn` for
753
- * `runProfileMatrix`: the profile axis is the worker-under-test, the scenario
754
- * axis is the persona, and the runner is the cell. Meters the worker through
755
- * `ctx.cost` so the matrix's backend-integrity guard sees real usage.
756
- */
757
- declare function runPersonaDispatch<TScenario extends Scenario, TArtifact>(config: RunPersonaConfig<TScenario, TArtifact>): ProfileDispatchFn<TScenario, TArtifact>;
758
-
759
- /**
760
- * `evalPersona` — the one-call user-sim product eval. Run a worker `AgentProfile` (the agent under
761
- * test) against a PERSONA (a simulated user — a scripted script or an LLM driver profile) as a
762
- * multi-round conversation, with the two seams `runPersonaConversation` otherwise makes you hand-wire
763
- * defaulted:
764
- *
765
- * - `backendFor` defaults to `createOpenAICompatibleBackend({ apiKey, baseUrl, model })` (the
766
- * OpenAI-compatible router endpoint) for both the worker and a profile-driven persona;
767
- * - `systemPromptOf` defaults to `p.prompt?.systemPrompt ?? ''`.
768
- *
769
- * Either is overridable (tests pass a fake `backendFor` to run offline). `maxTurns` (the hard
770
- * ceiling) and `haltOn` (the "until satisfied" early stop) pass straight through. Mirrors
771
- * `supervise()`'s defaulting style: the common case is one call; the raw `runPersonaConversation`
772
- * seam stays available for full control.
773
- *
774
- * The profile here is the authored `AgentProfile` (with `prompt.systemPrompt`), which is why the
775
- * default `systemPromptOf` can read it. `runPersonaConversation` treats the profile opaquely — only
776
- * the two callbacks inspect it — so the worker/persona profiles flow straight through.
777
- */
778
-
779
- interface EvalPersonaOptions {
780
- /** Router (or OpenAI-compatible) endpoint for the DEFAULT backend. Required unless `backendFor`
781
- * is supplied (tests/advanced override the backend entirely and may omit these). */
782
- apiKey?: string;
783
- baseUrl?: string;
784
- model?: string;
785
- /** Override the backend seam directly instead of deriving it from `apiKey`/`baseUrl`/`model`
786
- * (the offline-test path: pass a fake here and the credentials are not needed). */
787
- backendFor?: (profile: AgentProfile$1, role: 'worker' | 'persona') => AgentExecutionBackend;
788
- /** Override system-prompt rendering. Default: `p.prompt?.systemPrompt ?? ''`. */
789
- systemPromptOf?: (profile: AgentProfile$1) => string;
790
- /** Hard speaker-turn ceiling. REQUIRED for a profile-driven persona; for a scripted persona it
791
- * defaults to `2 * turns.length`. `maxTurns` is a CEILING, NOT a target — `maxTurns: 0` is zero
792
- * turns, not run-until-done; `haltOn` is the "until satisfied" knob. */
793
- maxTurns?: number;
794
- /** Content-based early stop (the persona declares the goal met / unreachable). */
795
- haltOn?: HaltPredicate;
796
- /** Kickoff message to the persona. Default 'Begin.' */
797
- seed?: string;
798
- signal?: AbortSignal;
799
- /** Worker transcript speaker label. Default 'agent'. */
800
- workerName?: string;
801
- }
802
- /** The persona side, authored against the same `AgentProfile` shape as the worker. */
803
- type EvalPersona = {
804
- kind: 'scripted';
805
- turns: string[];
806
- } | {
807
- kind: 'profile';
808
- profile: AgentProfile$1;
809
- };
810
- declare function evalPersona(worker: AgentProfile$1, persona: EvalPersona, opts?: EvalPersonaOptions): Promise<PersonaConversationResult>;
811
-
812
678
  /**
813
679
  * @stable
814
680
  *
@@ -943,6 +809,91 @@ declare class SqlConversationJournal implements ConversationJournal {
943
809
  declare function runConversation(conversation: Conversation, options: RunConversationOptions): Promise<ConversationResult>;
944
810
  declare function runConversationStream(conversation: Conversation, options: RunConversationOptions): AsyncIterable<ConversationStreamEvent>;
945
811
 
812
+ /**
813
+ * `runPersonaConversation` — the persona loop runner: run a WORKER `AgentProfile`
814
+ * (the agent under test) as a multi-round conversation driven by a PERSONA (the
815
+ * simulated user), over the persistent conversation transcript.
816
+ *
817
+ * It is profiles-vs-profiles: the persona is itself a driver `AgentProfile` (an
818
+ * LLM role-playing the user from its facts) — `runConversation` runs the two
819
+ * against each other. Scripted persona turns are kept as a deterministic
820
+ * fast-path. Only the WORKER is metered (it is the side under test); the
821
+ * persona-driver is the test harness, not billed against the agent.
822
+ *
823
+ * `runPersonaDispatch` wraps the runner as a `ProfileDispatchFn` so it drops
824
+ * straight into `runProfileMatrix({ dispatch })` — the same loop serves a single
825
+ * cell and the whole matrix, replacing the per-agent hand-rolled
826
+ * `dispatchWithSurface` bridges.
827
+ */
828
+
829
+ /** A persona that drives the conversation: either a full driver `AgentProfile`
830
+ * (an LLM user-sim) or a deterministic script of user turns (the fast-path). */
831
+ type PersonaDriver = {
832
+ kind: 'profile';
833
+ profile: AgentProfile;
834
+ } | {
835
+ kind: 'scripted';
836
+ turns: string[];
837
+ };
838
+ interface RunPersonaConversationOptions {
839
+ /** The agent under test. Metered; its rendered prompt leads its turns. */
840
+ worker: AgentProfile;
841
+ /** The simulated user driving the dialogue. */
842
+ persona: PersonaDriver;
843
+ /** Turn an `AgentProfile` into a runnable backend (router / sandbox / fake).
844
+ * Applied to the worker and to a `profile`-kind persona. */
845
+ backendFor: (profile: AgentProfile, role: 'worker' | 'persona') => AgentExecutionBackend;
846
+ /** Render a profile's system prompt — prepended to that profile's messages. */
847
+ systemPromptOf: (profile: AgentProfile) => string;
848
+ /** Speaker-turn cap. Default for a scripted persona = `2 * turns.length`
849
+ * (worker answers each user turn). REQUIRED for a `profile` persona. */
850
+ maxTurns?: number;
851
+ /** Kickoff message routed to the first speaker (the persona). Default 'Begin.' */
852
+ seed?: string;
853
+ /** Content-based "until satisfied" halt, called after every turn. `maxTurns` is the
854
+ * hard ceiling; this is the early stop (the persona declares the goal met / unreachable). */
855
+ haltOn?: HaltPredicate;
856
+ signal?: AbortSignal;
857
+ /** Worker participant / transcript speaker label. Default 'agent'. */
858
+ workerName?: string;
859
+ }
860
+ interface PersonaConversationResult {
861
+ transcript: ConversationTurn[];
862
+ turns: number;
863
+ halted: HaltReason;
864
+ /** Worker-only spend (the side under test). */
865
+ costUsd: number;
866
+ tokensIn: number;
867
+ tokensOut: number;
868
+ }
869
+ /**
870
+ * Run one worker profile against one persona as a multi-round conversation.
871
+ * The persona leads (participant 0): it speaks, the worker answers, repeat,
872
+ * until `maxTurns`. Returns the persistent transcript + worker-only usage.
873
+ */
874
+ declare function runPersonaConversation(opts: RunPersonaConversationOptions): Promise<PersonaConversationResult>;
875
+ interface RunPersonaConfig<TScenario extends Scenario, TArtifact> {
876
+ /** Turn an `AgentProfile` into a runnable backend (router / sandbox / fake). */
877
+ backendFor: (profile: AgentProfile, role: 'worker' | 'persona') => AgentExecutionBackend;
878
+ /** Render a profile's system prompt. */
879
+ systemPromptOf: (profile: AgentProfile) => string;
880
+ /** The persona driving each scenario — a driver profile or scripted turns. */
881
+ personaOf: (scenario: TScenario) => PersonaDriver;
882
+ /** Build the scored artifact from the finished transcript. */
883
+ artifactOf: (transcript: ConversationTurn[], scenario: TScenario) => TArtifact;
884
+ /** Speaker-turn cap (required when a persona is profile-driven). */
885
+ maxTurns?: (scenario: TScenario) => number;
886
+ seed?: (scenario: TScenario) => string;
887
+ workerName?: string;
888
+ }
889
+ /**
890
+ * Wrap {@link runPersonaConversation} as a `ProfileDispatchFn` for
891
+ * `runProfileMatrix`: the profile axis is the worker-under-test, the scenario
892
+ * axis is the persona, and the runner is the cell. Meters the worker through
893
+ * `ctx.cost` so the matrix's backend-integrity guard sees real usage.
894
+ */
895
+ declare function runPersonaDispatch<TScenario extends Scenario, TArtifact>(config: RunPersonaConfig<TScenario, TArtifact>): ProfileDispatchFn<TScenario, TArtifact>;
896
+
946
897
  /**
947
898
  * @stable
948
899
  *
@@ -1731,4 +1682,4 @@ interface StreamToolLoopOptions<Raw> {
1731
1682
  * `capped` if it stops for any non-completed reason with calls still pending. */
1732
1683
  declare function streamToolLoop<Raw>(opts: StreamToolLoopOptions<Raw>): AsyncGenerator<StreamToolLoopYield<Raw>, void, unknown>;
1733
1684
 
1734
- export { AgentBackendContext, AgentBackendInput, AgentExecutionBackend, AgentRuntimeEvent, AgentTaskRunResult, AgentTaskStatus, type AuthSource, type BackendCallPolicy, BackendTransportError, CandidateGenerator, type ChatStreamEvent, type ChatTurnHooks, type ChatTurnIdentity, type ChatTurnProducer, type ChatTurnResult, type CircuitBreakerConfig, CircuitBreakerState, CircuitOpenError, type Conversation, type ConversationDriveState, type ConversationJournal, type ConversationJournalEntry, type ConversationParticipant, type ConversationPolicy, type ConversationResult, type ConversationStreamEvent, type ConversationTurn, type D1DatabaseLike, type D1StmtLike, DEFAULT_MAX_DEPTH, DEFAULT_ROUTER_BASE_URL, DeadlineExceededError, type EvalPersonaOptions, FORWARD_HEADERS, FileConversationJournal, type ForwardHeaderName, type HaltContext, type HaltPredicate, type HaltReason, type HaltSignal, type ImproveOptions, type ImproveResult, type ImproveSurface, InMemoryConversationJournal, InMemoryRuntimeSessionStore, type ModelInfo, OpenAIChatTool, OpenAIChatToolChoice, type PersonaConversationResult, type PersonaDriver, PlannerError, type PropagatedHeaders, type ReflectiveGeneratorOptions, type ResolvedChatModel, type RetryBackoff, type RetryableErrorPredicate, type RouterEnv, type RunChatTurnInput, type RunConversationOptions, type RunPersonaConfig, type RunPersonaConversationOptions, type RunToolLoopOptions, type RuntimeEventCollector, RuntimeHooks, RuntimeRunStateError, RuntimeSessionStore, RuntimeStreamEvent, type RuntimeStreamEventCollector, type RuntimeTelemetryOptions, type SanitizedKnowledgeReadinessReport, type SqlAdapter, SqlConversationJournal, type StreamToolLoopOptions, type StreamToolLoopYield, type ToolCallOutcome, type ToolLoopAssistantToolCall, type ToolLoopCall, type ToolLoopEvent, type ToolLoopMessage, type ToolLoopResult, type ToolLoopStopReason, type TurnOrder, applyRunRecordDefaults, buildForwardHeaders, cleanModelId, computeBackoff, createConversationBackend, createIterableBackend, createOpenAICompatibleBackend, createRuntimeEventCollector, createRuntimeStreamEventCollector, createSandboxPromptBackend, d1ToSqlAdapter, decideKnowledgeReadiness, defaultIsRetryable, defineConversation, deriveExecutionId, evalPersona, getModels, handleChatTurn, improve, isDepthExceeded, makePerAttemptSignal, mcpBuildPrompt, readDepth, readinessServerSentEvent, reflectiveGenerator, resolveChatModel, resolveRouterBaseUrl, runAgentTask, runAgentTaskStream, runConversation, runConversationStream, runPersonaConversation, runPersonaDispatch, runToolLoop, runtimeStreamServerSentEvent, sanitizeAgentRuntimeEvent, sanitizeKnowledgeReadinessReport, sanitizeRuntimeStreamEvent, sleep, slugifySpeaker, streamToolLoop, toolBuildPrompt, turnId, validateChatModelId };
1685
+ export { AgentBackendContext, AgentBackendInput, AgentExecutionBackend, AgentRuntimeEvent, AgentTaskRunResult, AgentTaskStatus, type AuthSource, type BackendCallPolicy, BackendTransportError, CandidateGenerator, type ChatStreamEvent, type ChatTurnHooks, type ChatTurnIdentity, type ChatTurnProducer, type ChatTurnResult, type CircuitBreakerConfig, CircuitBreakerState, CircuitOpenError, type Conversation, type ConversationDriveState, type ConversationJournal, type ConversationJournalEntry, type ConversationParticipant, type ConversationPolicy, type ConversationResult, type ConversationStreamEvent, type ConversationTurn, type D1DatabaseLike, type D1StmtLike, DEFAULT_MAX_DEPTH, DEFAULT_ROUTER_BASE_URL, DeadlineExceededError, FORWARD_HEADERS, FileConversationJournal, type ForwardHeaderName, type HaltContext, type HaltPredicate, type HaltReason, type HaltSignal, type ImproveOptions, type ImproveResult, type ImproveSurface, InMemoryConversationJournal, InMemoryRuntimeSessionStore, type ModelInfo, OpenAIChatResponseFormat, OpenAIChatTool, OpenAIChatToolChoice, type PersonaConversationResult, type PersonaDriver, PlannerError, type PropagatedHeaders, type ReflectiveGeneratorOptions, type ResolvedChatModel, type RetryBackoff, type RetryableErrorPredicate, type RouterEnv, type RunChatTurnInput, type RunConversationOptions, type RunPersonaConfig, type RunPersonaConversationOptions, type RunToolLoopOptions, type RuntimeEventCollector, RuntimeHooks, RuntimeRunStateError, RuntimeSessionStore, RuntimeStreamEvent, type RuntimeStreamEventCollector, type RuntimeTelemetryOptions, type SanitizedKnowledgeReadinessReport, type SqlAdapter, SqlConversationJournal, type StreamToolLoopOptions, type StreamToolLoopYield, type ToolCallOutcome, type ToolLoopAssistantToolCall, type ToolLoopCall, type ToolLoopEvent, type ToolLoopMessage, type ToolLoopResult, type ToolLoopStopReason, type TurnOrder, applyRunRecordDefaults, buildForwardHeaders, cleanModelId, computeBackoff, createConversationBackend, createIterableBackend, createOpenAICompatibleBackend, createRuntimeEventCollector, createRuntimeStreamEventCollector, createSandboxPromptBackend, d1ToSqlAdapter, decideKnowledgeReadiness, defaultIsRetryable, defineConversation, deriveExecutionId, getModels, handleChatTurn, improve, isDepthExceeded, makePerAttemptSignal, mcpBuildPrompt, readDepth, readinessServerSentEvent, reflectiveGenerator, resolveChatModel, resolveRouterBaseUrl, runAgentTask, runAgentTaskStream, runConversation, runConversationStream, runPersonaConversation, runPersonaDispatch, runToolLoop, runtimeStreamServerSentEvent, sanitizeAgentRuntimeEvent, sanitizeKnowledgeReadinessReport, sanitizeRuntimeStreamEvent, sleep, slugifySpeaker, streamToolLoop, toolBuildPrompt, turnId, validateChatModelId };
package/dist/index.js CHANGED
@@ -208,6 +208,9 @@ function createOpenAICompatibleBackend(options) {
208
208
  bodyPayload.tools = options.tools;
209
209
  if (options.toolChoice !== void 0) bodyPayload.tool_choice = options.toolChoice;
210
210
  }
211
+ if (options.responseFormat !== void 0) {
212
+ bodyPayload.response_format = options.responseFormat;
213
+ }
211
214
  const requestBody = JSON.stringify(bodyPayload);
212
215
  let response;
213
216
  let lastStatus = 0;
@@ -1427,146 +1430,6 @@ function normalizePolicy(policy, participantCount) {
1427
1430
  return { ...policy, turnOrder };
1428
1431
  }
1429
1432
 
1430
- // src/conversation/run-persona.ts
1431
- function withProfilePrompt(inner, systemPrompt, counter) {
1432
- return {
1433
- kind: inner.kind,
1434
- start: inner.start ? (input, ctx) => inner.start(input, ctx) : void 0,
1435
- resume: inner.resume ? (session, input, ctx) => inner.resume(session, input, ctx) : void 0,
1436
- stop: inner.stop ? (session, reason) => inner.stop(session, reason) : void 0,
1437
- async *stream(input, context) {
1438
- const base = input.messages ?? (input.message ? [{ role: "user", content: input.message }] : []);
1439
- const messages = base[0]?.role === "system" ? base : [{ role: "system", content: systemPrompt }, ...base];
1440
- for await (const event of inner.stream({ ...input, messages }, context)) {
1441
- if (counter && event.type === "llm_call") {
1442
- counter.tokensIn += event.tokensIn ?? 0;
1443
- counter.tokensOut += event.tokensOut ?? 0;
1444
- counter.costUsd += event.costUsd ?? 0;
1445
- }
1446
- yield event;
1447
- }
1448
- }
1449
- };
1450
- }
1451
- function scriptedPersonaBackend(turns) {
1452
- let idx = 0;
1453
- return createIterableBackend({
1454
- kind: "persona-user",
1455
- async *stream(_input, context) {
1456
- const text = turns[idx];
1457
- if (text === void 0) {
1458
- throw new Error(
1459
- `persona-user: ran out of scripted turns at index ${idx} (had ${turns.length})`
1460
- );
1461
- }
1462
- idx += 1;
1463
- yield {
1464
- type: "text_delta",
1465
- task: context.task,
1466
- session: context.session,
1467
- text,
1468
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
1469
- };
1470
- }
1471
- });
1472
- }
1473
- async function runPersonaConversation(opts) {
1474
- const counter = { tokensIn: 0, tokensOut: 0, costUsd: 0 };
1475
- const workerName = opts.workerName ?? "agent";
1476
- const worker = withProfilePrompt(
1477
- opts.backendFor(opts.worker, "worker"),
1478
- opts.systemPromptOf(opts.worker),
1479
- counter
1480
- );
1481
- let persona;
1482
- let maxTurns;
1483
- if (opts.persona.kind === "scripted") {
1484
- if (opts.persona.turns.length === 0) {
1485
- throw new Error("runPersonaConversation: scripted persona has no turns");
1486
- }
1487
- persona = scriptedPersonaBackend(opts.persona.turns);
1488
- maxTurns = opts.maxTurns ?? 2 * opts.persona.turns.length;
1489
- } else {
1490
- persona = withProfilePrompt(
1491
- opts.backendFor(opts.persona.profile, "persona"),
1492
- opts.systemPromptOf(opts.persona.profile)
1493
- );
1494
- if (opts.maxTurns === void 0) {
1495
- throw new Error("runPersonaConversation: maxTurns is required for a profile-driven persona");
1496
- }
1497
- maxTurns = opts.maxTurns;
1498
- }
1499
- const conversation = defineConversation({
1500
- // Persona leads (participant 0): the seed routes to it, it produces the
1501
- // user turn, the worker answers, alternate.
1502
- participants: [
1503
- { name: "user", backend: persona },
1504
- { name: workerName, backend: worker }
1505
- ],
1506
- policy: { maxTurns, turnOrder: "alternate", ...opts.haltOn ? { haltOn: opts.haltOn } : {} }
1507
- });
1508
- const result = await runConversation(conversation, {
1509
- seed: opts.seed ?? "Begin.",
1510
- signal: opts.signal
1511
- });
1512
- const costUsd = counter.costUsd > 0 ? counter.costUsd : opts.persona.kind === "scripted" ? result.spentCreditsCents / 100 : 0;
1513
- return {
1514
- transcript: result.transcript,
1515
- turns: result.turns,
1516
- halted: result.halted,
1517
- costUsd,
1518
- tokensIn: counter.tokensIn,
1519
- tokensOut: counter.tokensOut
1520
- };
1521
- }
1522
- function runPersonaDispatch(config) {
1523
- return async (worker, scenario, ctx) => {
1524
- const result = await runPersonaConversation({
1525
- worker,
1526
- persona: config.personaOf(scenario),
1527
- backendFor: config.backendFor,
1528
- systemPromptOf: config.systemPromptOf,
1529
- maxTurns: config.maxTurns?.(scenario),
1530
- seed: config.seed?.(scenario),
1531
- signal: ctx.signal,
1532
- workerName: config.workerName
1533
- });
1534
- ctx.cost.observe(result.costUsd, "persona-conversation");
1535
- ctx.cost.observeTokens({ input: result.tokensIn, output: result.tokensOut });
1536
- return config.artifactOf(result.transcript, scenario);
1537
- };
1538
- }
1539
-
1540
- // src/conversation/eval-persona.ts
1541
- function evalPersona(worker, persona, opts = {}) {
1542
- const defaultBackendFor = () => {
1543
- if (!opts.apiKey || !opts.baseUrl || !opts.model) {
1544
- throw new Error(
1545
- "evalPersona: provide opts.{apiKey,baseUrl,model} for the default backend, or opts.backendFor"
1546
- );
1547
- }
1548
- const { apiKey, baseUrl, model } = opts;
1549
- return () => createOpenAICompatibleBackend({ apiKey, baseUrl, model });
1550
- };
1551
- const backendFor = opts.backendFor ?? defaultBackendFor();
1552
- const systemPromptOf = opts.systemPromptOf ?? ((p) => p.prompt?.systemPrompt ?? "");
1553
- return runPersonaConversation({
1554
- // runPersonaConversation types its profile as the benchmark-cell AgentProfile; here it is the
1555
- // authored AgentProfile (the carrier of prompt.systemPrompt). The runner never inspects the
1556
- // profile itself — only backendFor/systemPromptOf do, and both are typed for THIS profile — so
1557
- // the cast at this single boundary is sound.
1558
- worker,
1559
- persona,
1560
- backendFor,
1561
- systemPromptOf,
1562
- ...opts.maxTurns !== void 0 ? { maxTurns: opts.maxTurns } : {},
1563
- ...opts.haltOn ? { haltOn: opts.haltOn } : {},
1564
- ...opts.seed !== void 0 ? { seed: opts.seed } : {},
1565
- ...opts.signal ? { signal: opts.signal } : {},
1566
- ...opts.workerName !== void 0 ? { workerName: opts.workerName } : {}
1567
- });
1568
- }
1569
-
1570
1433
  // src/conversation/journal.ts
1571
1434
  var InMemoryConversationJournal = class {
1572
1435
  entries = /* @__PURE__ */ new Map();
@@ -1820,6 +1683,116 @@ var SqlConversationJournal = class {
1820
1683
  }
1821
1684
  };
1822
1685
 
1686
+ // src/conversation/run-persona.ts
1687
+ function withProfilePrompt(inner, systemPrompt, counter) {
1688
+ return {
1689
+ kind: inner.kind,
1690
+ start: inner.start ? (input, ctx) => inner.start(input, ctx) : void 0,
1691
+ resume: inner.resume ? (session, input, ctx) => inner.resume(session, input, ctx) : void 0,
1692
+ stop: inner.stop ? (session, reason) => inner.stop(session, reason) : void 0,
1693
+ async *stream(input, context) {
1694
+ const base = input.messages ?? (input.message ? [{ role: "user", content: input.message }] : []);
1695
+ const messages = base[0]?.role === "system" ? base : [{ role: "system", content: systemPrompt }, ...base];
1696
+ for await (const event of inner.stream({ ...input, messages }, context)) {
1697
+ if (counter && event.type === "llm_call") {
1698
+ counter.tokensIn += event.tokensIn ?? 0;
1699
+ counter.tokensOut += event.tokensOut ?? 0;
1700
+ counter.costUsd += event.costUsd ?? 0;
1701
+ }
1702
+ yield event;
1703
+ }
1704
+ }
1705
+ };
1706
+ }
1707
+ function scriptedPersonaBackend(turns) {
1708
+ let idx = 0;
1709
+ return createIterableBackend({
1710
+ kind: "persona-user",
1711
+ async *stream(_input, context) {
1712
+ const text = turns[idx];
1713
+ if (text === void 0) {
1714
+ throw new Error(
1715
+ `persona-user: ran out of scripted turns at index ${idx} (had ${turns.length})`
1716
+ );
1717
+ }
1718
+ idx += 1;
1719
+ yield {
1720
+ type: "text_delta",
1721
+ task: context.task,
1722
+ session: context.session,
1723
+ text,
1724
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
1725
+ };
1726
+ }
1727
+ });
1728
+ }
1729
+ async function runPersonaConversation(opts) {
1730
+ const counter = { tokensIn: 0, tokensOut: 0, costUsd: 0 };
1731
+ const workerName = opts.workerName ?? "agent";
1732
+ const worker = withProfilePrompt(
1733
+ opts.backendFor(opts.worker, "worker"),
1734
+ opts.systemPromptOf(opts.worker),
1735
+ counter
1736
+ );
1737
+ let persona;
1738
+ let maxTurns;
1739
+ if (opts.persona.kind === "scripted") {
1740
+ if (opts.persona.turns.length === 0) {
1741
+ throw new Error("runPersonaConversation: scripted persona has no turns");
1742
+ }
1743
+ persona = scriptedPersonaBackend(opts.persona.turns);
1744
+ maxTurns = opts.maxTurns ?? 2 * opts.persona.turns.length;
1745
+ } else {
1746
+ persona = withProfilePrompt(
1747
+ opts.backendFor(opts.persona.profile, "persona"),
1748
+ opts.systemPromptOf(opts.persona.profile)
1749
+ );
1750
+ if (opts.maxTurns === void 0) {
1751
+ throw new Error("runPersonaConversation: maxTurns is required for a profile-driven persona");
1752
+ }
1753
+ maxTurns = opts.maxTurns;
1754
+ }
1755
+ const conversation = defineConversation({
1756
+ // Persona leads (participant 0): the seed routes to it, it produces the
1757
+ // user turn, the worker answers, alternate.
1758
+ participants: [
1759
+ { name: "user", backend: persona },
1760
+ { name: workerName, backend: worker }
1761
+ ],
1762
+ policy: { maxTurns, turnOrder: "alternate", ...opts.haltOn ? { haltOn: opts.haltOn } : {} }
1763
+ });
1764
+ const result = await runConversation(conversation, {
1765
+ seed: opts.seed ?? "Begin.",
1766
+ signal: opts.signal
1767
+ });
1768
+ const costUsd = counter.costUsd > 0 ? counter.costUsd : opts.persona.kind === "scripted" ? result.spentCreditsCents / 100 : 0;
1769
+ return {
1770
+ transcript: result.transcript,
1771
+ turns: result.turns,
1772
+ halted: result.halted,
1773
+ costUsd,
1774
+ tokensIn: counter.tokensIn,
1775
+ tokensOut: counter.tokensOut
1776
+ };
1777
+ }
1778
+ function runPersonaDispatch(config) {
1779
+ return async (worker, scenario, ctx) => {
1780
+ const result = await runPersonaConversation({
1781
+ worker,
1782
+ persona: config.personaOf(scenario),
1783
+ backendFor: config.backendFor,
1784
+ systemPromptOf: config.systemPromptOf,
1785
+ maxTurns: config.maxTurns?.(scenario),
1786
+ seed: config.seed?.(scenario),
1787
+ signal: ctx.signal,
1788
+ workerName: config.workerName
1789
+ });
1790
+ ctx.cost.observe(result.costUsd, "persona-conversation");
1791
+ ctx.cost.observeTokens({ input: result.tokensIn, output: result.tokensOut });
1792
+ return config.artifactOf(result.transcript, scenario);
1793
+ };
1794
+ }
1795
+
1823
1796
  // src/durable/chat-engine.ts
1824
1797
  var encoder = new TextEncoder();
1825
1798
  function encodeLine(event) {
@@ -3518,7 +3491,6 @@ export {
3518
3491
  defineConversation,
3519
3492
  defineRuntimeHooks,
3520
3493
  deriveExecutionId,
3521
- evalPersona,
3522
3494
  exportEvalRuns,
3523
3495
  getModels,
3524
3496
  handleChatTurn,