@tangle-network/agent-runtime 0.75.1 → 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/index.d.ts +87 -140
- package/dist/index.js +110 -141
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -2,11 +2,11 @@ import { AgentProfile, AgentEvalError, AnalystFinding, KnowledgeReadinessReport,
|
|
|
2
2
|
export { AgentEvalError, AgentEvalErrorCode, ConfigError, ControlBudget, ControlDecision, ControlEvalResult, ControlRunResult, ControlStep, DataAcquisitionPlan, JudgeError, KnowledgeReadinessReport, KnowledgeRequirement, NotFoundError, RunRecord, ValidationError } from '@tangle-network/agent-eval';
|
|
3
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
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';
|
|
5
|
-
import { AgentProfile as AgentProfile$1 } from '@tangle-network/agent-interface';
|
|
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
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';
|
|
@@ -675,144 +675,6 @@ declare function defineConversation(input: {
|
|
|
675
675
|
policy: ConversationPolicy;
|
|
676
676
|
}): Conversation;
|
|
677
677
|
|
|
678
|
-
/**
|
|
679
|
-
* `runPersonaConversation` — the persona loop runner: run a WORKER `AgentProfile`
|
|
680
|
-
* (the agent under test) as a multi-round conversation driven by a PERSONA (the
|
|
681
|
-
* simulated user), over the persistent conversation transcript.
|
|
682
|
-
*
|
|
683
|
-
* It is profiles-vs-profiles: the persona is itself a driver `AgentProfile` (an
|
|
684
|
-
* LLM role-playing the user from its facts) — `runConversation` runs the two
|
|
685
|
-
* against each other. Scripted persona turns are kept as a deterministic
|
|
686
|
-
* fast-path. Only the WORKER is metered (it is the side under test); the
|
|
687
|
-
* persona-driver is the test harness, not billed against the agent.
|
|
688
|
-
*
|
|
689
|
-
* `runPersonaDispatch` wraps the runner as a `ProfileDispatchFn` so it drops
|
|
690
|
-
* straight into `runProfileMatrix({ dispatch })` — the same loop serves a single
|
|
691
|
-
* cell and the whole matrix, replacing the per-agent hand-rolled
|
|
692
|
-
* `dispatchWithSurface` bridges.
|
|
693
|
-
*/
|
|
694
|
-
|
|
695
|
-
/** A persona that drives the conversation: either a full driver `AgentProfile`
|
|
696
|
-
* (an LLM user-sim) or a deterministic script of user turns (the fast-path). */
|
|
697
|
-
type PersonaDriver = {
|
|
698
|
-
kind: 'profile';
|
|
699
|
-
profile: AgentProfile;
|
|
700
|
-
} | {
|
|
701
|
-
kind: 'scripted';
|
|
702
|
-
turns: string[];
|
|
703
|
-
};
|
|
704
|
-
interface RunPersonaConversationOptions {
|
|
705
|
-
/** The agent under test. Metered; its rendered prompt leads its turns. */
|
|
706
|
-
worker: AgentProfile;
|
|
707
|
-
/** The simulated user driving the dialogue. */
|
|
708
|
-
persona: PersonaDriver;
|
|
709
|
-
/** Turn an `AgentProfile` into a runnable backend (router / sandbox / fake).
|
|
710
|
-
* Applied to the worker and to a `profile`-kind persona. */
|
|
711
|
-
backendFor: (profile: AgentProfile, role: 'worker' | 'persona') => AgentExecutionBackend;
|
|
712
|
-
/** Render a profile's system prompt — prepended to that profile's messages. */
|
|
713
|
-
systemPromptOf: (profile: AgentProfile) => string;
|
|
714
|
-
/** Speaker-turn cap. Default for a scripted persona = `2 * turns.length`
|
|
715
|
-
* (worker answers each user turn). REQUIRED for a `profile` persona. */
|
|
716
|
-
maxTurns?: number;
|
|
717
|
-
/** Kickoff message routed to the first speaker (the persona). Default 'Begin.' */
|
|
718
|
-
seed?: string;
|
|
719
|
-
/** Content-based "until satisfied" halt, called after every turn. `maxTurns` is the
|
|
720
|
-
* hard ceiling; this is the early stop (the persona declares the goal met / unreachable). */
|
|
721
|
-
haltOn?: HaltPredicate;
|
|
722
|
-
signal?: AbortSignal;
|
|
723
|
-
/** Worker participant / transcript speaker label. Default 'agent'. */
|
|
724
|
-
workerName?: string;
|
|
725
|
-
}
|
|
726
|
-
interface PersonaConversationResult {
|
|
727
|
-
transcript: ConversationTurn[];
|
|
728
|
-
turns: number;
|
|
729
|
-
halted: HaltReason;
|
|
730
|
-
/** Worker-only spend (the side under test). */
|
|
731
|
-
costUsd: number;
|
|
732
|
-
tokensIn: number;
|
|
733
|
-
tokensOut: number;
|
|
734
|
-
}
|
|
735
|
-
/**
|
|
736
|
-
* Run one worker profile against one persona as a multi-round conversation.
|
|
737
|
-
* The persona leads (participant 0): it speaks, the worker answers, repeat,
|
|
738
|
-
* until `maxTurns`. Returns the persistent transcript + worker-only usage.
|
|
739
|
-
*/
|
|
740
|
-
declare function runPersonaConversation(opts: RunPersonaConversationOptions): Promise<PersonaConversationResult>;
|
|
741
|
-
interface RunPersonaConfig<TScenario extends Scenario, TArtifact> {
|
|
742
|
-
/** Turn an `AgentProfile` into a runnable backend (router / sandbox / fake). */
|
|
743
|
-
backendFor: (profile: AgentProfile, role: 'worker' | 'persona') => AgentExecutionBackend;
|
|
744
|
-
/** Render a profile's system prompt. */
|
|
745
|
-
systemPromptOf: (profile: AgentProfile) => string;
|
|
746
|
-
/** The persona driving each scenario — a driver profile or scripted turns. */
|
|
747
|
-
personaOf: (scenario: TScenario) => PersonaDriver;
|
|
748
|
-
/** Build the scored artifact from the finished transcript. */
|
|
749
|
-
artifactOf: (transcript: ConversationTurn[], scenario: TScenario) => TArtifact;
|
|
750
|
-
/** Speaker-turn cap (required when a persona is profile-driven). */
|
|
751
|
-
maxTurns?: (scenario: TScenario) => number;
|
|
752
|
-
seed?: (scenario: TScenario) => string;
|
|
753
|
-
workerName?: string;
|
|
754
|
-
}
|
|
755
|
-
/**
|
|
756
|
-
* Wrap {@link runPersonaConversation} as a `ProfileDispatchFn` for
|
|
757
|
-
* `runProfileMatrix`: the profile axis is the worker-under-test, the scenario
|
|
758
|
-
* axis is the persona, and the runner is the cell. Meters the worker through
|
|
759
|
-
* `ctx.cost` so the matrix's backend-integrity guard sees real usage.
|
|
760
|
-
*/
|
|
761
|
-
declare function runPersonaDispatch<TScenario extends Scenario, TArtifact>(config: RunPersonaConfig<TScenario, TArtifact>): ProfileDispatchFn<TScenario, TArtifact>;
|
|
762
|
-
|
|
763
|
-
/**
|
|
764
|
-
* `evalPersona` — the one-call user-sim product eval. Run a worker `AgentProfile` (the agent under
|
|
765
|
-
* test) against a PERSONA (a simulated user — a scripted script or an LLM driver profile) as a
|
|
766
|
-
* multi-round conversation, with the two seams `runPersonaConversation` otherwise makes you hand-wire
|
|
767
|
-
* defaulted:
|
|
768
|
-
*
|
|
769
|
-
* - `backendFor` defaults to `createOpenAICompatibleBackend({ apiKey, baseUrl, model })` (the
|
|
770
|
-
* OpenAI-compatible router endpoint) for both the worker and a profile-driven persona;
|
|
771
|
-
* - `systemPromptOf` defaults to `p.prompt?.systemPrompt ?? ''`.
|
|
772
|
-
*
|
|
773
|
-
* Either is overridable (tests pass a fake `backendFor` to run offline). `maxTurns` (the hard
|
|
774
|
-
* ceiling) and `haltOn` (the "until satisfied" early stop) pass straight through. Mirrors
|
|
775
|
-
* `supervise()`'s defaulting style: the common case is one call; the raw `runPersonaConversation`
|
|
776
|
-
* seam stays available for full control.
|
|
777
|
-
*
|
|
778
|
-
* The profile here is the authored `AgentProfile` (with `prompt.systemPrompt`), which is why the
|
|
779
|
-
* default `systemPromptOf` can read it. `runPersonaConversation` treats the profile opaquely — only
|
|
780
|
-
* the two callbacks inspect it — so the worker/persona profiles flow straight through.
|
|
781
|
-
*/
|
|
782
|
-
|
|
783
|
-
interface EvalPersonaOptions {
|
|
784
|
-
/** Router (or OpenAI-compatible) endpoint for the DEFAULT backend. Required unless `backendFor`
|
|
785
|
-
* is supplied (tests/advanced override the backend entirely and may omit these). */
|
|
786
|
-
apiKey?: string;
|
|
787
|
-
baseUrl?: string;
|
|
788
|
-
model?: string;
|
|
789
|
-
/** Override the backend seam directly instead of deriving it from `apiKey`/`baseUrl`/`model`
|
|
790
|
-
* (the offline-test path: pass a fake here and the credentials are not needed). */
|
|
791
|
-
backendFor?: (profile: AgentProfile$1, role: 'worker' | 'persona') => AgentExecutionBackend;
|
|
792
|
-
/** Override system-prompt rendering. Default: `p.prompt?.systemPrompt ?? ''`. */
|
|
793
|
-
systemPromptOf?: (profile: AgentProfile$1) => string;
|
|
794
|
-
/** Hard speaker-turn ceiling. REQUIRED for a profile-driven persona; for a scripted persona it
|
|
795
|
-
* defaults to `2 * turns.length`. `maxTurns` is a CEILING, NOT a target — `maxTurns: 0` is zero
|
|
796
|
-
* turns, not run-until-done; `haltOn` is the "until satisfied" knob. */
|
|
797
|
-
maxTurns?: number;
|
|
798
|
-
/** Content-based early stop (the persona declares the goal met / unreachable). */
|
|
799
|
-
haltOn?: HaltPredicate;
|
|
800
|
-
/** Kickoff message to the persona. Default 'Begin.' */
|
|
801
|
-
seed?: string;
|
|
802
|
-
signal?: AbortSignal;
|
|
803
|
-
/** Worker transcript speaker label. Default 'agent'. */
|
|
804
|
-
workerName?: string;
|
|
805
|
-
}
|
|
806
|
-
/** The persona side, authored against the same `AgentProfile` shape as the worker. */
|
|
807
|
-
type EvalPersona = {
|
|
808
|
-
kind: 'scripted';
|
|
809
|
-
turns: string[];
|
|
810
|
-
} | {
|
|
811
|
-
kind: 'profile';
|
|
812
|
-
profile: AgentProfile$1;
|
|
813
|
-
};
|
|
814
|
-
declare function evalPersona(worker: AgentProfile$1, persona: EvalPersona, opts?: EvalPersonaOptions): Promise<PersonaConversationResult>;
|
|
815
|
-
|
|
816
678
|
/**
|
|
817
679
|
* @stable
|
|
818
680
|
*
|
|
@@ -947,6 +809,91 @@ declare class SqlConversationJournal implements ConversationJournal {
|
|
|
947
809
|
declare function runConversation(conversation: Conversation, options: RunConversationOptions): Promise<ConversationResult>;
|
|
948
810
|
declare function runConversationStream(conversation: Conversation, options: RunConversationOptions): AsyncIterable<ConversationStreamEvent>;
|
|
949
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
|
+
|
|
950
897
|
/**
|
|
951
898
|
* @stable
|
|
952
899
|
*
|
|
@@ -1735,4 +1682,4 @@ interface StreamToolLoopOptions<Raw> {
|
|
|
1735
1682
|
* `capped` if it stops for any non-completed reason with calls still pending. */
|
|
1736
1683
|
declare function streamToolLoop<Raw>(opts: StreamToolLoopOptions<Raw>): AsyncGenerator<StreamToolLoopYield<Raw>, void, unknown>;
|
|
1737
1684
|
|
|
1738
|
-
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,
|
|
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
|
@@ -1430,146 +1430,6 @@ function normalizePolicy(policy, participantCount) {
|
|
|
1430
1430
|
return { ...policy, turnOrder };
|
|
1431
1431
|
}
|
|
1432
1432
|
|
|
1433
|
-
// src/conversation/run-persona.ts
|
|
1434
|
-
function withProfilePrompt(inner, systemPrompt, counter) {
|
|
1435
|
-
return {
|
|
1436
|
-
kind: inner.kind,
|
|
1437
|
-
start: inner.start ? (input, ctx) => inner.start(input, ctx) : void 0,
|
|
1438
|
-
resume: inner.resume ? (session, input, ctx) => inner.resume(session, input, ctx) : void 0,
|
|
1439
|
-
stop: inner.stop ? (session, reason) => inner.stop(session, reason) : void 0,
|
|
1440
|
-
async *stream(input, context) {
|
|
1441
|
-
const base = input.messages ?? (input.message ? [{ role: "user", content: input.message }] : []);
|
|
1442
|
-
const messages = base[0]?.role === "system" ? base : [{ role: "system", content: systemPrompt }, ...base];
|
|
1443
|
-
for await (const event of inner.stream({ ...input, messages }, context)) {
|
|
1444
|
-
if (counter && event.type === "llm_call") {
|
|
1445
|
-
counter.tokensIn += event.tokensIn ?? 0;
|
|
1446
|
-
counter.tokensOut += event.tokensOut ?? 0;
|
|
1447
|
-
counter.costUsd += event.costUsd ?? 0;
|
|
1448
|
-
}
|
|
1449
|
-
yield event;
|
|
1450
|
-
}
|
|
1451
|
-
}
|
|
1452
|
-
};
|
|
1453
|
-
}
|
|
1454
|
-
function scriptedPersonaBackend(turns) {
|
|
1455
|
-
let idx = 0;
|
|
1456
|
-
return createIterableBackend({
|
|
1457
|
-
kind: "persona-user",
|
|
1458
|
-
async *stream(_input, context) {
|
|
1459
|
-
const text = turns[idx];
|
|
1460
|
-
if (text === void 0) {
|
|
1461
|
-
throw new Error(
|
|
1462
|
-
`persona-user: ran out of scripted turns at index ${idx} (had ${turns.length})`
|
|
1463
|
-
);
|
|
1464
|
-
}
|
|
1465
|
-
idx += 1;
|
|
1466
|
-
yield {
|
|
1467
|
-
type: "text_delta",
|
|
1468
|
-
task: context.task,
|
|
1469
|
-
session: context.session,
|
|
1470
|
-
text,
|
|
1471
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
1472
|
-
};
|
|
1473
|
-
}
|
|
1474
|
-
});
|
|
1475
|
-
}
|
|
1476
|
-
async function runPersonaConversation(opts) {
|
|
1477
|
-
const counter = { tokensIn: 0, tokensOut: 0, costUsd: 0 };
|
|
1478
|
-
const workerName = opts.workerName ?? "agent";
|
|
1479
|
-
const worker = withProfilePrompt(
|
|
1480
|
-
opts.backendFor(opts.worker, "worker"),
|
|
1481
|
-
opts.systemPromptOf(opts.worker),
|
|
1482
|
-
counter
|
|
1483
|
-
);
|
|
1484
|
-
let persona;
|
|
1485
|
-
let maxTurns;
|
|
1486
|
-
if (opts.persona.kind === "scripted") {
|
|
1487
|
-
if (opts.persona.turns.length === 0) {
|
|
1488
|
-
throw new Error("runPersonaConversation: scripted persona has no turns");
|
|
1489
|
-
}
|
|
1490
|
-
persona = scriptedPersonaBackend(opts.persona.turns);
|
|
1491
|
-
maxTurns = opts.maxTurns ?? 2 * opts.persona.turns.length;
|
|
1492
|
-
} else {
|
|
1493
|
-
persona = withProfilePrompt(
|
|
1494
|
-
opts.backendFor(opts.persona.profile, "persona"),
|
|
1495
|
-
opts.systemPromptOf(opts.persona.profile)
|
|
1496
|
-
);
|
|
1497
|
-
if (opts.maxTurns === void 0) {
|
|
1498
|
-
throw new Error("runPersonaConversation: maxTurns is required for a profile-driven persona");
|
|
1499
|
-
}
|
|
1500
|
-
maxTurns = opts.maxTurns;
|
|
1501
|
-
}
|
|
1502
|
-
const conversation = defineConversation({
|
|
1503
|
-
// Persona leads (participant 0): the seed routes to it, it produces the
|
|
1504
|
-
// user turn, the worker answers, alternate.
|
|
1505
|
-
participants: [
|
|
1506
|
-
{ name: "user", backend: persona },
|
|
1507
|
-
{ name: workerName, backend: worker }
|
|
1508
|
-
],
|
|
1509
|
-
policy: { maxTurns, turnOrder: "alternate", ...opts.haltOn ? { haltOn: opts.haltOn } : {} }
|
|
1510
|
-
});
|
|
1511
|
-
const result = await runConversation(conversation, {
|
|
1512
|
-
seed: opts.seed ?? "Begin.",
|
|
1513
|
-
signal: opts.signal
|
|
1514
|
-
});
|
|
1515
|
-
const costUsd = counter.costUsd > 0 ? counter.costUsd : opts.persona.kind === "scripted" ? result.spentCreditsCents / 100 : 0;
|
|
1516
|
-
return {
|
|
1517
|
-
transcript: result.transcript,
|
|
1518
|
-
turns: result.turns,
|
|
1519
|
-
halted: result.halted,
|
|
1520
|
-
costUsd,
|
|
1521
|
-
tokensIn: counter.tokensIn,
|
|
1522
|
-
tokensOut: counter.tokensOut
|
|
1523
|
-
};
|
|
1524
|
-
}
|
|
1525
|
-
function runPersonaDispatch(config) {
|
|
1526
|
-
return async (worker, scenario, ctx) => {
|
|
1527
|
-
const result = await runPersonaConversation({
|
|
1528
|
-
worker,
|
|
1529
|
-
persona: config.personaOf(scenario),
|
|
1530
|
-
backendFor: config.backendFor,
|
|
1531
|
-
systemPromptOf: config.systemPromptOf,
|
|
1532
|
-
maxTurns: config.maxTurns?.(scenario),
|
|
1533
|
-
seed: config.seed?.(scenario),
|
|
1534
|
-
signal: ctx.signal,
|
|
1535
|
-
workerName: config.workerName
|
|
1536
|
-
});
|
|
1537
|
-
ctx.cost.observe(result.costUsd, "persona-conversation");
|
|
1538
|
-
ctx.cost.observeTokens({ input: result.tokensIn, output: result.tokensOut });
|
|
1539
|
-
return config.artifactOf(result.transcript, scenario);
|
|
1540
|
-
};
|
|
1541
|
-
}
|
|
1542
|
-
|
|
1543
|
-
// src/conversation/eval-persona.ts
|
|
1544
|
-
function evalPersona(worker, persona, opts = {}) {
|
|
1545
|
-
const defaultBackendFor = () => {
|
|
1546
|
-
if (!opts.apiKey || !opts.baseUrl || !opts.model) {
|
|
1547
|
-
throw new Error(
|
|
1548
|
-
"evalPersona: provide opts.{apiKey,baseUrl,model} for the default backend, or opts.backendFor"
|
|
1549
|
-
);
|
|
1550
|
-
}
|
|
1551
|
-
const { apiKey, baseUrl, model } = opts;
|
|
1552
|
-
return () => createOpenAICompatibleBackend({ apiKey, baseUrl, model });
|
|
1553
|
-
};
|
|
1554
|
-
const backendFor = opts.backendFor ?? defaultBackendFor();
|
|
1555
|
-
const systemPromptOf = opts.systemPromptOf ?? ((p) => p.prompt?.systemPrompt ?? "");
|
|
1556
|
-
return runPersonaConversation({
|
|
1557
|
-
// runPersonaConversation types its profile as the benchmark-cell AgentProfile; here it is the
|
|
1558
|
-
// authored AgentProfile (the carrier of prompt.systemPrompt). The runner never inspects the
|
|
1559
|
-
// profile itself — only backendFor/systemPromptOf do, and both are typed for THIS profile — so
|
|
1560
|
-
// the cast at this single boundary is sound.
|
|
1561
|
-
worker,
|
|
1562
|
-
persona,
|
|
1563
|
-
backendFor,
|
|
1564
|
-
systemPromptOf,
|
|
1565
|
-
...opts.maxTurns !== void 0 ? { maxTurns: opts.maxTurns } : {},
|
|
1566
|
-
...opts.haltOn ? { haltOn: opts.haltOn } : {},
|
|
1567
|
-
...opts.seed !== void 0 ? { seed: opts.seed } : {},
|
|
1568
|
-
...opts.signal ? { signal: opts.signal } : {},
|
|
1569
|
-
...opts.workerName !== void 0 ? { workerName: opts.workerName } : {}
|
|
1570
|
-
});
|
|
1571
|
-
}
|
|
1572
|
-
|
|
1573
1433
|
// src/conversation/journal.ts
|
|
1574
1434
|
var InMemoryConversationJournal = class {
|
|
1575
1435
|
entries = /* @__PURE__ */ new Map();
|
|
@@ -1823,6 +1683,116 @@ var SqlConversationJournal = class {
|
|
|
1823
1683
|
}
|
|
1824
1684
|
};
|
|
1825
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
|
+
|
|
1826
1796
|
// src/durable/chat-engine.ts
|
|
1827
1797
|
var encoder = new TextEncoder();
|
|
1828
1798
|
function encodeLine(event) {
|
|
@@ -3521,7 +3491,6 @@ export {
|
|
|
3521
3491
|
defineConversation,
|
|
3522
3492
|
defineRuntimeHooks,
|
|
3523
3493
|
deriveExecutionId,
|
|
3524
|
-
evalPersona,
|
|
3525
3494
|
exportEvalRuns,
|
|
3526
3495
|
getModels,
|
|
3527
3496
|
handleChatTurn,
|