eve 0.14.0 → 0.15.1
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/CHANGELOG.md +23 -0
- package/dist/src/channel/compiled-channel.js +2 -1
- package/dist/src/cli/dev/tui/runner.js +1 -1
- package/dist/src/cli/dev/tui/setup-panel.d.ts +3 -4
- package/dist/src/cli/dev/tui/setup-panel.js +2 -2
- package/dist/src/cli/dev/tui/status-line.d.ts +6 -3
- package/dist/src/cli/dev/tui/status-line.js +1 -1
- package/dist/src/cli/dev/tui/terminal-renderer.js +1 -1
- package/dist/src/cli/dev/tui/vercel-status.d.ts +2 -2
- package/dist/src/cli/dev/tui/vercel-status.js +1 -1
- package/dist/src/cli/run.d.ts +2 -2
- package/dist/src/cli/run.js +2 -2
- package/dist/src/evals/assertions/collector.d.ts +19 -6
- package/dist/src/evals/assertions/collector.js +1 -1
- package/dist/src/evals/assertions/run.d.ts +24 -17
- package/dist/src/evals/assertions/run.js +2 -2
- package/dist/src/evals/assertions/scoped.d.ts +17 -0
- package/dist/src/evals/assertions/scoped.js +1 -0
- package/dist/src/evals/cli/eval.js +1 -1
- package/dist/src/evals/context.d.ts +1 -0
- package/dist/src/evals/context.js +1 -1
- package/dist/src/evals/control-flow.d.ts +9 -0
- package/dist/src/evals/control-flow.js +1 -0
- package/dist/src/evals/define-eval.d.ts +1 -1
- package/dist/src/evals/define-eval.js +1 -1
- package/dist/src/evals/expect/index.d.ts +5 -3
- package/dist/src/evals/expect/index.js +1 -1
- package/dist/src/evals/index.d.ts +2 -2
- package/dist/src/evals/match.d.ts +50 -13
- package/dist/src/evals/match.js +1 -1
- package/dist/src/evals/runner/artifacts.js +1 -1
- package/dist/src/evals/runner/derive-run-facts.js +1 -1
- package/dist/src/evals/runner/execute-eval.js +1 -1
- package/dist/src/evals/runner/execute-task.d.ts +1 -0
- package/dist/src/evals/runner/execute-task.js +1 -1
- package/dist/src/evals/runner/reporters/braintrust.js +1 -1
- package/dist/src/evals/runner/reporters/console.js +1 -1
- package/dist/src/evals/runner/reporters/junit.js +3 -2
- package/dist/src/evals/runner/run-evals.js +1 -1
- package/dist/src/evals/runner/verdict.d.ts +1 -0
- package/dist/src/evals/runner/verdict.js +1 -1
- package/dist/src/evals/session.d.ts +9 -5
- package/dist/src/evals/session.js +1 -1
- package/dist/src/evals/types.d.ts +69 -47
- package/dist/src/execution/workflow-callback-url.d.ts +8 -0
- package/dist/src/execution/workflow-callback-url.js +1 -1
- package/dist/src/execution/workflow-entry.js +1 -1
- package/dist/src/execution/workflow-steps.js +1 -1
- package/dist/src/harness/emission.d.ts +13 -27
- package/dist/src/harness/emission.js +1 -1
- package/dist/src/harness/step-hooks.d.ts +3 -3
- package/dist/src/harness/step-hooks.js +1 -1
- package/dist/src/harness/tool-loop.js +1 -1
- package/dist/src/internal/application/compiled-artifacts.js +1 -1
- package/dist/src/internal/application/package.d.ts +12 -0
- package/dist/src/internal/application/package.js +1 -1
- package/dist/src/internal/application/paths.d.ts +6 -0
- package/dist/src/internal/application/paths.js +1 -1
- package/dist/src/internal/nitro/host/configure-nitro-routes.js +2 -2
- package/dist/src/internal/nitro/host/dev-server-state.d.ts +20 -0
- package/dist/src/internal/nitro/host/dev-server-state.js +1 -0
- package/dist/src/internal/nitro/host/start-development-server.d.ts +12 -5
- package/dist/src/internal/nitro/host/start-development-server.js +2 -2
- package/dist/src/internal/nitro/host/types.d.ts +25 -3
- package/dist/src/internal/nitro/host.d.ts +2 -2
- package/dist/src/internal/nitro/host.js +1 -1
- package/dist/src/internal/workflow/configure-world.d.ts +6 -0
- package/dist/src/internal/workflow/configure-world.js +1 -1
- package/dist/src/internal/workflow/world-compatibility.d.ts +32 -0
- package/dist/src/internal/workflow/world-compatibility.js +1 -0
- package/dist/src/protocol/message.d.ts +7 -5
- package/dist/src/runtime/actions/types.d.ts +10 -11
- package/dist/src/setup/boxes/resolve-provisioning.js +1 -1
- package/dist/src/setup/scaffold/create/project.js +1 -1
- package/dist/src/shared/eve-server-health.d.ts +5 -0
- package/dist/src/shared/eve-server-health.js +1 -0
- package/dist/src/shared/network-address.d.ts +12 -0
- package/dist/src/shared/network-address.js +1 -1
- package/dist/src/shared/result.d.ts +12 -0
- package/dist/src/shared/result.js +1 -0
- package/docs/agent-config.md +13 -3
- package/docs/concepts/execution-model-and-durability.md +1 -1
- package/docs/concepts/sessions-runs-and-streaming.md +1 -1
- package/docs/connections/overview.mdx +40 -2
- package/docs/evals/assertions.mdx +97 -39
- package/docs/evals/cases.mdx +24 -15
- package/docs/evals/judge.mdx +2 -2
- package/docs/evals/overview.mdx +7 -5
- package/docs/evals/reporters.mdx +2 -2
- package/docs/evals/running.mdx +3 -1
- package/docs/evals/targets.mdx +2 -2
- package/docs/guides/auth-and-route-protection.md +48 -1
- package/docs/guides/client/streaming.mdx +1 -1
- package/docs/guides/deployment.md +3 -2
- package/docs/guides/dev-tui.md +1 -1
- package/docs/reference/cli.md +1 -1
- package/docs/tutorial/connect-a-warehouse.mdx +2 -0
- package/package.json +1 -1
|
@@ -3,10 +3,12 @@ import type { StandardSchemaV1 } from "#compiled/@standard-schema/spec/index.js"
|
|
|
3
3
|
import type { HandleMessageStreamEvent, RuntimeIdentity } from "#protocol/message.js";
|
|
4
4
|
import type { SendTurnInput, SessionState } from "#client/types.js";
|
|
5
5
|
import type { InputRequest, InputResponse } from "#runtime/input/types.js";
|
|
6
|
-
import type { JsonObject } from "#shared/json.js";
|
|
6
|
+
import type { JsonObject, JsonValue } from "#shared/json.js";
|
|
7
7
|
import type { AgentModelOptionsDefinition } from "#shared/agent-definition.js";
|
|
8
8
|
import type { EvalReporter } from "#evals/runner/reporters/types.js";
|
|
9
|
-
import type { EveEvalSkillLoadMatchOptions, EveEvalSubagentCallMatchOptions, EveEvalToolCallMatchOptions } from "#evals/match.js";
|
|
9
|
+
import type { EveEvalEventMatch, EveEvalInputRequestMatchOptions, EveEvalSkillLoadMatchOptions, EveEvalSubagentCallMatchOptions, EveEvalToolCallMatchOptions } from "#evals/match.js";
|
|
10
|
+
/** Lifecycle outcome of an eval-observed tool or subagent action. */
|
|
11
|
+
export type EveEvalActionStatus = "pending" | "completed" | "failed" | "rejected";
|
|
10
12
|
/**
|
|
11
13
|
* One tool call extracted from the captured stream, pairing the
|
|
12
14
|
* `actions.requested` request with its matching `action.result`.
|
|
@@ -17,9 +19,9 @@ export interface EveEvalToolCall {
|
|
|
17
19
|
/** Tool input as requested by the model. */
|
|
18
20
|
readonly input: JsonObject;
|
|
19
21
|
/** Tool output from the matching `action.result`; `undefined` when the call never resolved. */
|
|
20
|
-
readonly output:
|
|
21
|
-
/**
|
|
22
|
-
readonly
|
|
22
|
+
readonly output: JsonValue | undefined;
|
|
23
|
+
/** Whether the request is unresolved, completed, failed, or user-rejected. */
|
|
24
|
+
readonly status: EveEvalActionStatus;
|
|
23
25
|
/** Zero-based index of the turn the call happened in. */
|
|
24
26
|
readonly turnIndex: number;
|
|
25
27
|
/** Owning session id, when the runner knows it. */
|
|
@@ -35,9 +37,9 @@ export interface EveEvalSubagentCall {
|
|
|
35
37
|
/** Remote agent URL for remote delegations (`subagent.called` remote metadata). */
|
|
36
38
|
readonly remoteUrl?: string;
|
|
37
39
|
/** Output from the matching `subagent.completed` event; `undefined` when the call never completed. */
|
|
38
|
-
readonly output?:
|
|
39
|
-
/**
|
|
40
|
-
readonly
|
|
40
|
+
readonly output?: JsonValue;
|
|
41
|
+
/** Whether the delegation is unresolved, completed, failed, or rejected. */
|
|
42
|
+
readonly status: EveEvalActionStatus;
|
|
41
43
|
/** Zero-based index of the turn the delegation happened in. */
|
|
42
44
|
readonly turnIndex: number;
|
|
43
45
|
/** Owning session id, when the runner knows it. */
|
|
@@ -74,9 +76,8 @@ export interface EveEvalSessionResult {
|
|
|
74
76
|
*/
|
|
75
77
|
export interface EveEvalTaskResult {
|
|
76
78
|
/**
|
|
77
|
-
* The
|
|
78
|
-
* for reporters and artifacts that log
|
|
79
|
-
* because the runner assigns it after the run completes.
|
|
79
|
+
* The final turn's structured data when present, otherwise its last assistant
|
|
80
|
+
* message. Retained for reporters and artifacts that log one output value.
|
|
80
81
|
*/
|
|
81
82
|
output: unknown;
|
|
82
83
|
/** The agent's last assistant message, or null when none was produced. */
|
|
@@ -131,10 +132,10 @@ export interface Assertion {
|
|
|
131
132
|
/**
|
|
132
133
|
* Handle to a recorded assertion, returned by every `t` assertion method.
|
|
133
134
|
* Chain `gate`/`soft`/`atLeast` to override the recorded severity or
|
|
134
|
-
* threshold
|
|
135
|
-
*
|
|
135
|
+
* threshold. Recorded assertions are finalized by the runner; use `t.require`
|
|
136
|
+
* or a `require*` lookup when later control flow depends on a passing result.
|
|
136
137
|
*/
|
|
137
|
-
export interface AssertionHandle
|
|
138
|
+
export interface AssertionHandle {
|
|
138
139
|
gate(threshold?: number): this;
|
|
139
140
|
soft(threshold?: number): this;
|
|
140
141
|
atLeast(threshold: number): this;
|
|
@@ -153,10 +154,37 @@ export interface AssertionResult {
|
|
|
153
154
|
readonly message?: string;
|
|
154
155
|
readonly metadata?: Readonly<Record<string, unknown>>;
|
|
155
156
|
}
|
|
156
|
-
/**
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
157
|
+
/** Recorded assertions shared by aggregate, session, and turn scopes. */
|
|
158
|
+
export interface EveEvalAssertions {
|
|
159
|
+
succeeded(): AssertionHandle;
|
|
160
|
+
parked(): AssertionHandle;
|
|
161
|
+
messageIncludes(token: string | RegExp): AssertionHandle;
|
|
162
|
+
calledTool(name: string, options?: EveEvalToolCallMatchOptions): AssertionHandle;
|
|
163
|
+
/** Sugar for `calledTool("load_skill", { input: { skill }, ... })`. */
|
|
164
|
+
loadedSkill(skill: string, options?: EveEvalSkillLoadMatchOptions): AssertionHandle;
|
|
165
|
+
notCalledTool(name: string): AssertionHandle;
|
|
166
|
+
/** Asserts that tool requests appeared in order, allowing unrelated requests between them. */
|
|
167
|
+
toolOrder(names: readonly string[]): AssertionHandle;
|
|
168
|
+
usedNoTools(): AssertionHandle;
|
|
169
|
+
maxToolCalls(max: number): AssertionHandle;
|
|
170
|
+
calledSubagent(name: string, options?: EveEvalSubagentCallMatchOptions): AssertionHandle;
|
|
171
|
+
noFailedActions(): AssertionHandle;
|
|
172
|
+
event<TType extends HandleMessageStreamEvent["type"]>(type: TType, options?: Omit<Extract<EveEvalEventMatch, {
|
|
173
|
+
type: TType;
|
|
174
|
+
}>, "type">): AssertionHandle;
|
|
175
|
+
notEvent<TType extends HandleMessageStreamEvent["type"]>(type: TType, options?: Omit<Extract<EveEvalEventMatch, {
|
|
176
|
+
type: TType;
|
|
177
|
+
}>, "type" | "count">): AssertionHandle;
|
|
178
|
+
eventOrder(matchers: readonly EveEvalEventMatch[]): AssertionHandle;
|
|
179
|
+
eventsSatisfy(label: string, predicate: (events: readonly HandleMessageStreamEvent[]) => boolean): AssertionHandle;
|
|
180
|
+
}
|
|
181
|
+
/** Assertions over the final output captured by one session or immutable turn. */
|
|
182
|
+
export interface EveEvalOutputAssertions {
|
|
183
|
+
outputEquals(value: unknown): AssertionHandle;
|
|
184
|
+
outputMatches(schema: StandardSchemaV1): AssertionHandle;
|
|
185
|
+
}
|
|
186
|
+
/** Operations and state shared by the primary eval context and independent sessions. */
|
|
187
|
+
export interface EveEvalSessionDriver {
|
|
160
188
|
/** All events observed on this session so far. */
|
|
161
189
|
readonly events: readonly HandleMessageStreamEvent[];
|
|
162
190
|
/** Input requests left pending by the last parked turn. */
|
|
@@ -165,11 +193,8 @@ export interface EveEvalSession {
|
|
|
165
193
|
readonly state: SessionState;
|
|
166
194
|
/** eve session id after the first successful send. */
|
|
167
195
|
readonly sessionId: string | undefined;
|
|
168
|
-
/**
|
|
169
|
-
|
|
170
|
-
readonly display?: InputRequest["display"];
|
|
171
|
-
readonly toolName?: string;
|
|
172
|
-
}): readonly InputRequest[];
|
|
196
|
+
/** Require exactly one pending input request matching `filter`, or abort dependent control flow. */
|
|
197
|
+
requireInputRequest(filter?: EveEvalInputRequestMatchOptions): InputRequest;
|
|
173
198
|
/** Resolve specific pending requests and run the resumed turn. */
|
|
174
199
|
respond(...responses: InputResponse[]): Promise<EveEvalTurn>;
|
|
175
200
|
/** Resolve every pending request with the same option id. */
|
|
@@ -179,16 +204,22 @@ export interface EveEvalSession {
|
|
|
179
204
|
/** Send one text turn with a local file attached as a data URL. */
|
|
180
205
|
sendFile(text: string, filePath: string, mediaType?: string): Promise<EveEvalTurn>;
|
|
181
206
|
}
|
|
207
|
+
/** Driver for one independent session, exposed by `t.newSession()` and target attachment helpers. */
|
|
208
|
+
export interface EveEvalSession extends EveEvalSessionDriver, EveEvalAssertions, EveEvalOutputAssertions {
|
|
209
|
+
}
|
|
182
210
|
/**
|
|
183
211
|
* One completed eval-driver turn.
|
|
184
212
|
*/
|
|
185
|
-
export interface EveEvalTurn {
|
|
213
|
+
export interface EveEvalTurn extends EveEvalAssertions, EveEvalOutputAssertions {
|
|
186
214
|
readonly data: unknown;
|
|
187
215
|
readonly events: readonly HandleMessageStreamEvent[];
|
|
188
216
|
readonly inputRequests: readonly InputRequest[];
|
|
189
217
|
readonly message: string | undefined;
|
|
218
|
+
readonly sessionId: string;
|
|
190
219
|
readonly status: "completed" | "failed" | "waiting";
|
|
191
220
|
readonly toolCalls: readonly EveEvalToolCall[];
|
|
221
|
+
/** Require exactly one matching tool call, record a gate, and return it for dependent checks. */
|
|
222
|
+
requireToolCall(name: string, options?: Omit<EveEvalToolCallMatchOptions, "count">): EveEvalToolCall;
|
|
192
223
|
expectOk(): this;
|
|
193
224
|
}
|
|
194
225
|
/**
|
|
@@ -232,15 +263,13 @@ export interface JudgeContext {
|
|
|
232
263
|
}
|
|
233
264
|
/**
|
|
234
265
|
* The single context passed to an eval's `test(t)` function. It drives the
|
|
235
|
-
* primary session
|
|
266
|
+
* primary session, carries the run-level
|
|
236
267
|
* and value-level assertion vocabulary, and exposes `judge` for LLM-as-judge.
|
|
237
268
|
*
|
|
238
|
-
*
|
|
239
|
-
*
|
|
240
|
-
* evaluate the supplied value immediately. Use plain `throw` /
|
|
241
|
-
* `turn.expectOk()` for bespoke preconditions that should abort the run.
|
|
269
|
+
* Scoped assertions (`succeeded`, `calledTool`, …) record an entry evaluated
|
|
270
|
+
* after the test body; `check`, `require`, and `judge` evaluate explicit values.
|
|
242
271
|
*/
|
|
243
|
-
export interface EveEvalContext extends
|
|
272
|
+
export interface EveEvalContext extends EveEvalSessionDriver, EveEvalAssertions {
|
|
244
273
|
/** Eval timeout signal. */
|
|
245
274
|
readonly signal: AbortSignal;
|
|
246
275
|
/** Current target under test. */
|
|
@@ -253,24 +282,12 @@ export interface EveEvalContext extends EveEvalSession {
|
|
|
253
282
|
sleep(ms?: number): Promise<void>;
|
|
254
283
|
/** Create an additional independent session against the same target. */
|
|
255
284
|
newSession(): EveEvalSession;
|
|
256
|
-
completed(): AssertionHandle;
|
|
257
|
-
didNotFail(): AssertionHandle;
|
|
258
|
-
waiting(): AssertionHandle;
|
|
259
|
-
messageIncludes(token: string | RegExp): AssertionHandle;
|
|
260
|
-
calledTool(name: string, options?: EveEvalToolCallMatchOptions): AssertionHandle;
|
|
261
|
-
/** Sugar for `calledTool("load_skill", { input: { skill }, ... })`. */
|
|
262
|
-
loadedSkill(skill: string, options?: EveEvalSkillLoadMatchOptions): AssertionHandle;
|
|
263
|
-
notCalledTool(name: string): AssertionHandle;
|
|
264
|
-
toolOrder(names: readonly string[]): AssertionHandle;
|
|
265
|
-
usedNoTools(): AssertionHandle;
|
|
266
|
-
maxToolCalls(max: number): AssertionHandle;
|
|
267
|
-
calledSubagent(name: string, options?: EveEvalSubagentCallMatchOptions): AssertionHandle;
|
|
268
|
-
noFailedActions(): AssertionHandle;
|
|
269
|
-
event(predicate: (events: readonly HandleMessageStreamEvent[]) => boolean, label: string): AssertionHandle;
|
|
270
|
-
outputEquals(value: unknown): AssertionHandle;
|
|
271
|
-
outputMatches(schema: StandardSchemaV1): AssertionHandle;
|
|
272
285
|
/** Apply a value-level assertion (from `eve/evals/expect`) to a value. */
|
|
273
286
|
check(value: unknown, assertion: Assertion): AssertionHandle;
|
|
287
|
+
/** Record an immediate gate and abort dependent control flow when it fails. */
|
|
288
|
+
require<T>(value: T, assertion: Assertion): Promise<T>;
|
|
289
|
+
/** Mark this eval as intentionally skipped and stop executing its test body. */
|
|
290
|
+
skip(reason: string): never;
|
|
274
291
|
/** LLM-as-judge assertions, bound to the resolved judge model. */
|
|
275
292
|
readonly judge: JudgeContext;
|
|
276
293
|
}
|
|
@@ -372,8 +389,9 @@ export type EveEval = EveEvalDefinition & {
|
|
|
372
389
|
* - `"passed"` — no execution error, every gate held, every soft threshold met
|
|
373
390
|
* - `"failed"` — a gate assertion failed or execution errored (timeout, transport, thrown task)
|
|
374
391
|
* - `"scored"` — every gate held but a soft assertion fell below its threshold
|
|
392
|
+
* - `"skipped"` — the test body intentionally called `t.skip(reason)`
|
|
375
393
|
*/
|
|
376
|
-
export type EveEvalVerdict = "passed" | "failed" | "scored";
|
|
394
|
+
export type EveEvalVerdict = "passed" | "failed" | "scored" | "skipped";
|
|
377
395
|
/**
|
|
378
396
|
* Result of executing and asserting one eval.
|
|
379
397
|
*
|
|
@@ -388,6 +406,8 @@ export interface EveEvalResult {
|
|
|
388
406
|
/** Per-eval verdict; see {@link EveEvalVerdict}. */
|
|
389
407
|
readonly verdict: EveEvalVerdict;
|
|
390
408
|
readonly error?: string;
|
|
409
|
+
/** Why the eval intentionally skipped, present only for a `"skipped"` verdict. */
|
|
410
|
+
readonly skipReason?: string;
|
|
391
411
|
readonly startedAt: string;
|
|
392
412
|
readonly completedAt: string;
|
|
393
413
|
}
|
|
@@ -405,6 +425,8 @@ export interface EveEvalRunSummary {
|
|
|
405
425
|
readonly failed: number;
|
|
406
426
|
/** Evals with verdict `"scored"` (below-threshold soft assertions only). */
|
|
407
427
|
readonly scored: number;
|
|
428
|
+
/** Evals intentionally skipped by their test body. */
|
|
429
|
+
readonly skipped: number;
|
|
408
430
|
/** The execution-error subset of `failed` (timeouts, connection failures, exceptions). */
|
|
409
431
|
readonly errored: number;
|
|
410
432
|
}
|
|
@@ -6,6 +6,14 @@
|
|
|
6
6
|
* agent.
|
|
7
7
|
*/
|
|
8
8
|
export declare function resolveVercelProductionCallbackBaseUrl(): string | null;
|
|
9
|
+
/**
|
|
10
|
+
* Resolves the origin used for framework-owned workflow callbacks.
|
|
11
|
+
*
|
|
12
|
+
* Workflow metadata falls back to port 3000 when its optional local port
|
|
13
|
+
* discovery is unavailable. eve already configures the local world with the
|
|
14
|
+
* active dev-server origin, so prefer that value before the metadata fallback.
|
|
15
|
+
*/
|
|
16
|
+
export declare function resolveWorkflowCallbackBaseUrl(metadataUrl: string): string;
|
|
9
17
|
/**
|
|
10
18
|
* Builds a framework-owned callback URL from a resolved callback origin.
|
|
11
19
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
function resolveVercelProductionCallbackBaseUrl(){return process.env.VERCEL_ENV===`production`&&process.env.VERCEL_PROJECT_PRODUCTION_URL?`https://${process.env.VERCEL_PROJECT_PRODUCTION_URL}`:null}function createWorkflowCallbackUrl(e,t){let n=new URL(t,e),r=process.env.VERCEL_AUTOMATION_BYPASS_SECRET?.trim();return r&&n.searchParams.set(`x-vercel-protection-bypass`,r),n.toString()}export{createWorkflowCallbackUrl,resolveVercelProductionCallbackBaseUrl};
|
|
1
|
+
function resolveVercelProductionCallbackBaseUrl(){return process.env.VERCEL_ENV===`production`&&process.env.VERCEL_PROJECT_PRODUCTION_URL?`https://${process.env.VERCEL_PROJECT_PRODUCTION_URL}`:null}function resolveWorkflowCallbackBaseUrl(e){let t=process.env.WORKFLOW_LOCAL_BASE_URL?.trim()||void 0;return(resolveVercelProductionCallbackBaseUrl()??t??e).replace(/\/$/,``)}function createWorkflowCallbackUrl(e,t){let n=new URL(t,e),r=process.env.VERCEL_AUTOMATION_BYPASS_SECRET?.trim();return r&&n.searchParams.set(`x-vercel-protection-bypass`,r),n.toString()}export{createWorkflowCallbackUrl,resolveVercelProductionCallbackBaseUrl,resolveWorkflowCallbackBaseUrl};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{accumulateRuntimeActionResults}from"#harness/runtime-actions.js";import{dispatchRuntimeActionsStep}from"#execution/dispatch-runtime-actions-step.js";import{
|
|
1
|
+
import{accumulateRuntimeActionResults}from"#harness/runtime-actions.js";import{dispatchRuntimeActionsStep}from"#execution/dispatch-runtime-actions-step.js";import{resolveWorkflowCallbackBaseUrl}from"#execution/workflow-callback-url.js";import{normalizeSerializableError,rebuildSerializableError}from"#execution/workflow-errors.js";import{dispatchTurnStep,emitTerminalSessionFailureStep,routeProxiedDeliverStep,runProxyInputRequestStep}from"#execution/workflow-steps.js";import{createHook,getWorkflowMetadata,getWritable}from"#compiled/@workflow/core/index.js";import{coalesceDeliveries}from"#harness/messages.js";import{readChannelRequestId,readRootSessionId}from"#execution/eve-workflow-attributes.js";import{notifyDelegatedParentStep}from"#execution/delegated-parent-notification.js";import{createDelegatedSubagentErrorResult,createDelegatedSubagentSuccessResult}from"#execution/delegated-parent-result.js";import{createSessionStep}from"#execution/create-session-step.js";import{dispatchWorkflowRuntimeActionsStep}from"#execution/dispatch-workflow-runtime-actions-step.js";import{fireSessionCallbackStep}from"#execution/session-callback-step.js";import{claimHookOwnership,closeHookIterator,disposeHook}from"#execution/hook-ownership.js";async function workflowEntry(e){"use workflow";let{workflowRunId:t}=getWorkflowMetadata(),n=e.serializedContext[`eve.continuationToken`]||``,i=e.serializedContext[`eve.mode`],a=e.serializedContext[`eve.capabilities`],s=e.serializedContext[`eve.bundle`];e.serializedContext[`eve.sessionId`]=t;let c=getWritable();try{let r=readRootSessionId(e.serializedContext),{state:o}=await createSessionStep({compiledArtifactsSource:s.source,continuationToken:n,nodeId:s.nodeId,outputSchema:e.input.outputSchema,rootSessionId:r,sessionId:t});return await runDriverLoop({capabilities:a,driverWritable:c,initialInput:{kind:`deliver`,payloads:[{message:e.input.message,context:e.input.context,outputSchema:e.input.outputSchema}],requestId:readChannelRequestId(e.serializedContext)},mode:i,serializedContext:e.serializedContext,sessionState:o})}catch(t){throw await emitTerminalSessionFailureStep({error:normalizeSerializableError(t),parentWritable:c,serializedContext:e.serializedContext}),await fireSessionCallbackStep({error:normalizeSerializableError(t),serializedContext:e.serializedContext,status:`failed`}),await notifyDelegatedParentStep({result:createDelegatedSubagentErrorResult(e.serializedContext,t),serializedContext:e.serializedContext}),t}}async function runDriverLoop(e){let r=createHook({token:`${e.sessionState.sessionId}:auth`}),i=r[Symbol.asyncIterator](),a=0,nextTurnCompletionToken=()=>`${e.sessionState.sessionId}:turn-completion:${String(a++)}`,o=``,s,c,l=null,u=[],getNextPromise=()=>{if(c===void 0)throw Error(`Cannot wait for deliveries before a continuation token is available.`);return l??=c.next(),l},consumeNext=()=>{l=null},closeParkHook=async()=>{let e=c,t=s;if(s=void 0,c=void 0,l=null,e!==void 0)try{await closeHookIterator(e)}catch(e){if(t!==void 0)try{await disposeHook(t)}catch{}throw e}t!==void 0&&await disposeHook(t)},rekeyHook=async e=>{if(!e||s!==void 0&&e===o)return;let t=createHook({token:e});await claimHookOwnership(t);try{await closeParkHook()}catch(e){try{await disposeHook(t)}catch{}throw e}o=e,s=t,c=t[Symbol.asyncIterator](),l=null};try{e.sessionState.continuationToken&&await rekeyHook(e.sessionState.continuationToken);let r=await dispatchAndAwaitTurn({capabilities:e.capabilities,completionToken:nextTurnCompletionToken(),delivery:e.initialInput,mode:e.mode,parentWritable:e.driverWritable,serializedContext:e.serializedContext,sessionState:e.sessionState});if(r.kind===`done`)return await finalizeDone({action:r,driverWritable:e.driverWritable});if(!r.sessionState.continuationToken)throw Error("Cannot park: no continuation token available. The channel must post the first message during the initial turn (anchoring the session) or `send()` must be called with an explicit continuationToken.");for(await rekeyHook(r.sessionState.continuationToken);;)switch(r.kind){case`done`:return await finalizeDone({action:r,driverWritable:e.driverWritable});case`dispatch-workflow-runtime-actions`:case`dispatch-runtime-actions`:{let i=await(r.kind===`dispatch-workflow-runtime-actions`?dispatchWorkflowRuntimeActionsStep:dispatchRuntimeActionsStep)({callbackBaseUrl:resolveWorkflowCallbackBaseUrl(getWorkflowMetadata().url),parentWritable:e.driverWritable,serializedContext:r.serializedContext,sessionState:r.sessionState}),a=await waitForPendingRuntimeActionResults({bufferedDeliveries:u,consumeNext,getNextPromise,initialResults:i.results,parentWritable:e.driverWritable,pendingActionKeys:r.pendingActionKeys,rekeyHook,serializedContext:r.serializedContext,sessionState:i.sessionState});if(a===null)return{output:``};r=await dispatchAndAwaitTurn({capabilities:e.capabilities,completionToken:nextTurnCompletionToken(),delivery:{kind:`runtime-action-result`,results:a.results},mode:e.mode,parentWritable:e.driverWritable,serializedContext:a.serializedContext,sessionState:a.sessionState}),await rekeyHook(r.sessionState.continuationToken);break}case`park`:{if(r.authorizationNames&&r.authorizationNames.length>0){let t=r.authorizationNames.length,n=[];for(;n.length<t;){let e=await i.next();if(e.done)break;e.value.kind===`deliver`&&n.push(...e.value.payloads)}r=await dispatchAndAwaitTurn({capabilities:e.capabilities,completionToken:nextTurnCompletionToken(),delivery:{kind:`deliver`,payloads:n},mode:e.mode,parentWritable:e.driverWritable,serializedContext:r.serializedContext,sessionState:r.sessionState}),await rekeyHook(r.sessionState.continuationToken);break}let t=await waitForNextDeliver({bufferedDeliveries:u,consumeNext,getNextPromise});if(t===null)return{output:``};let n=await routeDeliverForChildren({auth:t.auth,parentWritable:e.driverWritable,payloads:t.payloads,sessionState:r.sessionState});if(n===void 0)continue;r=await dispatchAndAwaitTurn({capabilities:e.capabilities,completionToken:nextTurnCompletionToken(),delivery:{auth:t.auth,kind:`deliver`,payloads:[n],requestId:t.requestId},mode:e.mode,parentWritable:e.driverWritable,serializedContext:r.serializedContext,sessionState:r.sessionState}),await rekeyHook(r.sessionState.continuationToken);break}}}finally{await closeParkHook(),await closeHookIterator(i),await disposeHook(r)}}async function finalizeDone(e){let{output:t,serializedContext:n}=e.action,r=e.action.isError===!0;return await fireSessionCallbackStep({error:r?t:void 0,output:r?void 0:t,serializedContext:n,status:r?`failed`:`completed`}),await notifyDelegatedParentStep({result:r?createDelegatedSubagentErrorResult(n,t):createDelegatedSubagentSuccessResult(n,t),serializedContext:n}),{output:t}}async function dispatchAndAwaitTurn(e){let t=createHook({token:e.completionToken}),n=t.token;try{await dispatchTurnStep({capabilities:e.capabilities,completionToken:n,delivery:e.delivery,mode:e.mode,parentWritable:e.parentWritable,serializedContext:e.serializedContext,sessionState:e.sessionState});let r=await awaitHookPayload(t);if(r.kind===`turn-error`)throw rebuildSerializableError(r.error);return r.action}finally{await disposeHook(t)}}async function awaitHookPayload(e){for await(let t of e)return t;throw Error(`Turn completion hook closed before delivering a result.`)}async function waitForPendingRuntimeActionResults(t){let n=t.sessionState,r=t.serializedContext,i=await accumulateRuntimeActionResults({bufferedDeliveries:t.bufferedDeliveries,async getNext(){for(;;){let e=await t.getNextPromise();if(t.consumeNext(),e.done)return null;let i=e.value;if(i.kind===`deliver`){let e=await routeDeliverForChildren({auth:i.auth,parentWritable:t.parentWritable,payloads:i.payloads,sessionState:n});if(e===void 0)continue;return{kind:`deliver`,value:{...i,payloads:[e]}}}if(i.kind===`runtime-action-result`)return{kind:`runtime-action-result`,results:i.results};let a=await runProxyInputRequestStep({hookPayload:i,parentWritable:t.parentWritable,serializedContext:r,sessionState:n});n=a.sessionState,r=a.serializedContext,await t.rekeyHook(n.continuationToken)}},initialResults:t.initialResults,pendingActionKeys:t.pendingActionKeys});return i===null?null:{results:i,serializedContext:r,sessionState:n}}async function routeDeliverForChildren(e){let t=coalescePayloads(e.payloads);return e.sessionState.hasProxyInputRequests?(await routeProxiedDeliverStep({auth:e.auth,parentWritable:e.parentWritable,payload:t,sessionState:e.sessionState})).remainder:t}async function waitForNextDeliver(e){if(e.bufferedDeliveries.length>0)return coalesceDeliveries(e.bufferedDeliveries.splice(0));for(;;){let t=await e.getNextPromise();if(e.consumeNext(),t.done)return null;if(t.value.kind!==`deliver`)continue;let n=t.value;for(;;){let t=await takeReadyPayload(e.getNextPromise());if(t===NO_READY_MESSAGE||(e.consumeNext(),t.done))break;t.value.kind===`deliver`&&(n=coalesceDeliveries([n,t.value]))}return n}}function coalescePayloads(e){if(e.length===0)return{};if(e.length===1)return e[0]??{};let t={},n=[];for(let r of e){for(let[e,n]of Object.entries(r))e!==`inputResponses`&&n!==void 0&&(t[e]=n);r.inputResponses!==void 0&&n.push(...r.inputResponses)}return n.length>0&&(t.inputResponses=n),t}const NO_READY_MESSAGE=Symbol(`no-ready-message`);async function takeReadyPayload(e){return await Promise.resolve(),await Promise.race([e,Promise.resolve(NO_READY_MESSAGE)])}export{workflowEntry};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createLogger,formatError}from"#internal/logging.js";import{callAdapterEventHandler,defaultDeliverResult}from"#channel/adapter.js";import{AuthKey,CapabilitiesKey,ContinuationTokenKey,ModeKey}from"#context/keys.js";import{createAuthorizationCompletedEvent,createSessionFailedEvent,encodeMessageStreamEvent,timestampHandleMessageStreamEvent}from"#protocol/message.js";import{BundleKey,ChannelKey}from"#runtime/sessions/runtime-context-keys.js";import{getHarnessEmissionState}from"#harness/emission.js";import{createDurableSessionState,readDurableSession}from"#execution/durable-session-store.js";import{hydrateDurableSession,refreshSessionFromTurnAgent}from"#execution/session.js";import{deserializeContext,serializeContext}from"#context/serialize.js";import{resumeHook}from"#internal/workflow/runtime.js";import{buildAdapterContext}from"#channel/adapter-context.js";import{getPendingRuntimeActionBatch}from"#harness/runtime-actions.js";import{createWorkflowRuntime,startWorkflowPreferLatest}from"#execution/workflow-runtime.js";import{getPendingWorkflowInterrupt}from"#harness/workflow-interrupt-state.js";import{getRuntimeActionKeysFromWorkflowInterrupt,isWorkflowRuntimeActionInterrupt}from"#harness/workflow-runtime-action-state.js";import{upsertProxyInputRequests}from"#harness/proxy-input-requests.js";import{setChannelContext}from"#execution/channel-context.js";import{CallbackBaseUrlKey,PendingAuthorizationResultKey,clearPendingAuthorization,getPendingAuthorization}from"#harness/authorization.js";import{createTurnWorkflowInput}from"#execution/durable-session-migrations/turn-workflow.js";import{coalesceTurnInputs}from"#harness/messages.js";import{buildTurnAttributes,readRootSessionId}from"#execution/eve-workflow-attributes.js";import{normalizeEveAttributes}from"#runtime/attributes/normalize.js";import{dispatchStreamEventHooks}from"#context/hook-lifecycle.js";import{dispatchDynamicInstructionEvent}from"#context/dynamic-instruction-lifecycle.js";import{dispatchDynamicSkillEvent}from"#context/dynamic-skill-lifecycle.js";import{dispatchDynamicToolEvent}from"#context/dynamic-tool-lifecycle.js";import{runStep,withContextScope}from"#context/run-step.js";import{hasPendingInputBatch}from"#harness/input-requests.js";import{getRuntimeActionRequestKey}from"#runtime/actions/keys.js";import{createExecutionNodeStep}from"#execution/node-step.js";import{emitProxiedInputRequest,routeDeliverPayload}from"#execution/subagent-hitl-proxy.js";import{turnWorkflow}from"#execution/turn-workflow.js";async function turnStep(e){"use step";let t=e,o=await readDurableSession(t.sessionState),l=await deserializeContext(t.serializedContext),f=l.require(ChannelKey),p=l.require(BundleKey);try{let{getWorkflowMetadata:e}=await import(`#compiled/@workflow/core/index.js`),t=e();typeof t.url==`string`&&l.set(CallbackBaseUrlKey,t.url.replace(/\/$/,``))}catch{}let m=getPendingAuthorization(o.state),h;if(m&&t.input?.kind===`deliver`){let e=[],n=[],r=[];for(let i of t.input.payloads){let t=i.authorizationCallback;if(t){let r=m.challenges.find(e=>e.name===t.connectionName);r&&(e.push({name:r.name,resume:r.resume,callback:t.callback,hookUrl:r.hookUrl}),n.push({name:r.name,authorization:r.challenge}))}else r.push(i)}e.length>0&&(l.set(PendingAuthorizationResultKey,e),o={...o,state:clearPendingAuthorization(o.state,e.map(e=>e.name))},h=n,t=r.length>0?{...t,input:{...t.input,payloads:r}}:{...t,input:void 0})}t.input?.kind===`deliver`&&t.input.auth!==void 0&&l.set(AuthKey,t.input.auth??null);let g=hydrateDurableSession({compactionOverrides:{thresholdPercent:p.resolvedAgent.config.compaction?.thresholdPercent},durable:o,turnAgent:p.turnAgent}),_=buildAdapterContext(f,l),v;if(t.input?.kind===`deliver`){let e=[];for(let n of t.input.payloads){let t=f.deliver?await f.deliver(n,_):defaultDeliverResult(n);t!=null&&e.push(t)}v=e.length===0?void 0:e.reduce(coalesceTurnInputs)}else t.input?.kind===`runtime-action-result`&&(v={runtimeActionResults:t.input.results});if(t.input?.kind===`deliver`&&setChannelContext(l,{...f,state:{..._.state}}),t.input?.kind===`deliver`&&v===void 0){let e=reconcileSessionContinuationToken(l,g),n=serializeContext(l),r=e===g?t.sessionState:createDurableSessionState({session:e});return{action:`park`,...derivePendingState(e),serializedContext:n,sessionState:r}}let y=t.parentWritable.getWriter(),b=p.hookRegistry,x=p.resolvedAgent.dynamicInstructionsResolvers??[],S=p.resolvedAgent.dynamicSkillResolvers??[],C=p.resolvedAgent.dynamicToolResolvers??[],emit=async e=>{let t=await callAdapterEventHandler(f,e,_);return setChannelContext(l,{...f,state:{..._.state}}),await y.write(encodeMessageStreamEvent(timestampHandleMessageStreamEvent(t))),t},handleEvent=async(e,t)=>{let n=await emit(e);await dispatchStreamEventHooks({ctx:l,registry:b,event:n}),await dispatchDynamicToolEvent({ctx:l,resolvers:C,event:n,messages:t??[]}),await dispatchDynamicSkillEvent({ctx:l,resolvers:S,event:n,messages:t??[]}),await dispatchDynamicInstructionEvent({ctx:l,resolvers:x,event:n,messages:t??[]})},w=l.require(ModeKey),T=await runStep(l,g,async e=>{let t=resolveEffectiveOutputSchema({agentOutputSchema:p.turnAgent.outputSchema,input:v,mode:w,session:e});if(h){let e=getHarnessEmissionState(t.state);for(let{name:t,authorization:n}of h)await handleEvent(createAuthorizationCompletedEvent({authorization:n,name:t,outcome:`authorized`,sequence:e.sequence,stepIndex:e.stepIndex,turnId:e.turnId}))}let n=l.get(CapabilitiesKey);return(async(e,t)=>{let r=refreshSessionFromTurnAgent({compactionOverrides:{thresholdPercent:p.resolvedAgent.config.compaction?.thresholdPercent},session:e,turnAgent:p.turnAgent});return createExecutionNodeStep({capabilities:n,createRuntime:createWorkflowRuntime,handleEvent,mode:w,modelResolutionScope:{moduleMap:p.moduleMap,nodeId:p.nodeId},node:p.graph.root})(r,t)})(t,v)}),E=reconcileSessionContinuationToken(l,T.session),D=serializeContext(l);T={...T,session:E};let O=createDurableSessionState({session:T.session});if(T.next!==null&&typeof T.next==`object`&&`done`in T.next)return await y.close(),{action:`done`,output:T.next.output,isError:T.next.isError,serializedContext:D,sessionState:O};if(T.next===null){y.releaseLock();let e=getPendingWorkflowInterrupt(T.session.state);return e!==void 0&&isWorkflowRuntimeActionInterrupt(e.interrupt)?{action:`dispatch-workflow-runtime-actions`,pendingRuntimeActionKeys:getRuntimeActionKeysFromWorkflowInterrupt(e.interrupt),serializedContext:D,sessionState:O}:{action:`park`,...derivePendingState(T.session),serializedContext:D,sessionState:O}}return y.releaseLock(),{action:`continue`,serializedContext:D,sessionState:O}}function derivePendingState(e){let t=getPendingRuntimeActionBatch(e.state),n=getPendingAuthorization(e.state),r={authorizationNames:n?.challenges.map(e=>e.name),hasPendingAuthorization:n!==void 0,hasPendingInputBatch:hasPendingInputBatch(e.state)};return t===void 0?r:{...r,pendingRuntimeActionKeys:t.actions.map(e=>getRuntimeActionRequestKey(e))}}function reconcileSessionContinuationToken(e,t){let n=e.get(ContinuationTokenKey);return n===void 0||n===t.continuationToken?t:{...t,continuationToken:n}}function resolveEffectiveOutputSchema(e){let{agentOutputSchema:t,input:n,mode:r,session:i}=e;return n?.outputSchema===void 0?r===`task`&&i.outputSchema===void 0&&t!==void 0?{...i,outputSchema:t}:i:{...i,outputSchema:n.outputSchema}}const log=createLogger(`execution.workflow-entry`);async function emitTerminalSessionFailureStep(e){"use step";let r=formatError(e.error),i=typeof r.name==`string`?r.name:`WORKFLOW_EXECUTION_FAILED`,a=typeof r.message==`string`?r.message:String(e.error),o=e.serializedContext[`eve.sessionId`]??``;log.error(`workflow loop threw — emitting terminal session.failed`,{sessionId:o,errorId:typeof r.errorId==`string`?r.errorId:void 0,code:i,message:a,detail:typeof r.detail==`string`?r.detail:void 0});let s=createSessionFailedEvent({code:i,details:r,message:a,sessionId:o});try{let t=await deserializeContext(e.serializedContext),r=t.get(ChannelKey);r!==void 0&&await callAdapterEventHandler(r,s,buildAdapterContext(r,t))}catch(e){log.error(`adapter failed to handle terminal session.failed event`,{errorId:typeof r.errorId==`string`?r.errorId:void 0,sessionId:o,error:e})}try{let t=e.parentWritable.getWriter();try{await t.write(encodeMessageStreamEvent(timestampHandleMessageStreamEvent(s)))}finally{t.releaseLock()}}catch(e){log.error(`failed to write terminal session.failed event to durable stream`,{errorId:typeof r.errorId==`string`?r.errorId:void 0,sessionId:o,error:e})}}async function runProxyInputRequestStep(e){"use step";let t=await readDurableSession(e.sessionState),r=await deserializeContext(e.serializedContext),i=r.require(ChannelKey),a=buildAdapterContext(i,r),o=r.require(ModeKey),c=r.require(BundleKey),l=hydrateDurableSession({compactionOverrides:{thresholdPercent:c.resolvedAgent.config.compaction?.thresholdPercent},durable:t,turnAgent:c.turnAgent}),u=e.parentWritable.getWriter(),d;try{let emit=async e=>{let t=await callAdapterEventHandler(i,e,a);await u.write(encodeMessageStreamEvent(timestampHandleMessageStreamEvent(t)))};d=await withContextScope(r,l,async t=>{let n=await emitProxiedInputRequest({emit,hookPayload:e.hookPayload,mode:o,session:t});return{result:n.entries,session:n.session}})}finally{u.releaseLock()}return setChannelContext(r,{...i,state:{...a.state}}),{serializedContext:serializeContext(r),sessionState:createDurableSessionState({session:reconcileSessionContinuationToken(r,upsertProxyInputRequests({entries:d.result,forChildContinuationToken:e.hookPayload.childContinuationToken,session:d.session}))})}}async function routeProxiedDeliverStep(e){"use step";let t=await readDurableSession(e.sessionState),n=routeDeliverPayload({payload:e.payload,state:t.state});for(let t of n.forChildren)await resumeHook(t.childContinuationToken,{auth:e.auth,kind:`deliver`,payloads:[t.payload]});return{remainder:n.forSelf}}async function dispatchTurnStep(e){"use step";return{runId:(await startWorkflowPreferLatest(turnWorkflow,[createTurnWorkflowInput(e)],{allowReservedAttributes:!0,attributes:normalizeEveAttributes(buildTurnAttributes({parentSessionId:e.sessionState.sessionId,requestId:e.delivery.kind===`deliver`?e.delivery.requestId:void 0,rootSessionId:readRootSessionId(e.serializedContext)??e.sessionState.sessionId}))})).runId}}export{dispatchTurnStep,emitTerminalSessionFailureStep,reconcileSessionContinuationToken,resolveEffectiveOutputSchema,routeProxiedDeliverStep,runProxyInputRequestStep,turnStep};
|
|
1
|
+
import{createLogger,formatError}from"#internal/logging.js";import{callAdapterEventHandler,defaultDeliverResult}from"#channel/adapter.js";import{AuthKey,CapabilitiesKey,ContinuationTokenKey,ModeKey}from"#context/keys.js";import{createAuthorizationCompletedEvent,createSessionFailedEvent,encodeMessageStreamEvent,timestampHandleMessageStreamEvent}from"#protocol/message.js";import{BundleKey,ChannelKey}from"#runtime/sessions/runtime-context-keys.js";import{getHarnessEmissionState}from"#harness/emission.js";import{createDurableSessionState,readDurableSession}from"#execution/durable-session-store.js";import{hydrateDurableSession,refreshSessionFromTurnAgent}from"#execution/session.js";import{deserializeContext,serializeContext}from"#context/serialize.js";import{resumeHook}from"#internal/workflow/runtime.js";import{buildAdapterContext}from"#channel/adapter-context.js";import{getPendingRuntimeActionBatch}from"#harness/runtime-actions.js";import{createWorkflowRuntime,startWorkflowPreferLatest}from"#execution/workflow-runtime.js";import{getPendingWorkflowInterrupt}from"#harness/workflow-interrupt-state.js";import{getRuntimeActionKeysFromWorkflowInterrupt,isWorkflowRuntimeActionInterrupt}from"#harness/workflow-runtime-action-state.js";import{upsertProxyInputRequests}from"#harness/proxy-input-requests.js";import{resolveWorkflowCallbackBaseUrl}from"#execution/workflow-callback-url.js";import{setChannelContext}from"#execution/channel-context.js";import{CallbackBaseUrlKey,PendingAuthorizationResultKey,clearPendingAuthorization,getPendingAuthorization}from"#harness/authorization.js";import{createTurnWorkflowInput}from"#execution/durable-session-migrations/turn-workflow.js";import{coalesceTurnInputs}from"#harness/messages.js";import{buildTurnAttributes,readRootSessionId}from"#execution/eve-workflow-attributes.js";import{normalizeEveAttributes}from"#runtime/attributes/normalize.js";import{dispatchStreamEventHooks}from"#context/hook-lifecycle.js";import{dispatchDynamicInstructionEvent}from"#context/dynamic-instruction-lifecycle.js";import{dispatchDynamicSkillEvent}from"#context/dynamic-skill-lifecycle.js";import{dispatchDynamicToolEvent}from"#context/dynamic-tool-lifecycle.js";import{runStep,withContextScope}from"#context/run-step.js";import{hasPendingInputBatch}from"#harness/input-requests.js";import{getRuntimeActionRequestKey}from"#runtime/actions/keys.js";import{createExecutionNodeStep}from"#execution/node-step.js";import{emitProxiedInputRequest,routeDeliverPayload}from"#execution/subagent-hitl-proxy.js";import{turnWorkflow}from"#execution/turn-workflow.js";async function turnStep(e){"use step";let t=e,o=await readDurableSession(t.sessionState),l=await deserializeContext(t.serializedContext),f=l.require(ChannelKey),p=l.require(BundleKey);try{let{getWorkflowMetadata:e}=await import(`#compiled/@workflow/core/index.js`),t=e();typeof t.url==`string`&&l.set(CallbackBaseUrlKey,resolveWorkflowCallbackBaseUrl(t.url))}catch{}let m=getPendingAuthorization(o.state),h;if(m&&t.input?.kind===`deliver`){let e=[],n=[],r=[];for(let i of t.input.payloads){let t=i.authorizationCallback;if(t){let r=m.challenges.find(e=>e.name===t.connectionName);r&&(e.push({name:r.name,resume:r.resume,callback:t.callback,hookUrl:r.hookUrl}),n.push({name:r.name,authorization:r.challenge}))}else r.push(i)}e.length>0&&(l.set(PendingAuthorizationResultKey,e),o={...o,state:clearPendingAuthorization(o.state,e.map(e=>e.name))},h=n,t=r.length>0?{...t,input:{...t.input,payloads:r}}:{...t,input:void 0})}t.input?.kind===`deliver`&&t.input.auth!==void 0&&l.set(AuthKey,t.input.auth??null);let g=hydrateDurableSession({compactionOverrides:{thresholdPercent:p.resolvedAgent.config.compaction?.thresholdPercent},durable:o,turnAgent:p.turnAgent}),_=buildAdapterContext(f,l),v;if(t.input?.kind===`deliver`){let e=[];for(let n of t.input.payloads){let t=f.deliver?await f.deliver(n,_):defaultDeliverResult(n);t!=null&&e.push(t)}v=e.length===0?void 0:e.reduce(coalesceTurnInputs)}else t.input?.kind===`runtime-action-result`&&(v={runtimeActionResults:t.input.results});if(t.input?.kind===`deliver`&&setChannelContext(l,{...f,state:{..._.state}}),t.input?.kind===`deliver`&&v===void 0){let e=reconcileSessionContinuationToken(l,g),n=serializeContext(l),r=e===g?t.sessionState:createDurableSessionState({session:e});return{action:`park`,...derivePendingState(e),serializedContext:n,sessionState:r}}let y=t.parentWritable.getWriter(),b=p.hookRegistry,x=p.resolvedAgent.dynamicInstructionsResolvers??[],S=p.resolvedAgent.dynamicSkillResolvers??[],C=p.resolvedAgent.dynamicToolResolvers??[],emit=async e=>{let t=await callAdapterEventHandler(f,e,_);return setChannelContext(l,{...f,state:{..._.state}}),await y.write(encodeMessageStreamEvent(timestampHandleMessageStreamEvent(t))),t},handleEvent=async(e,t)=>{let n=await emit(e);await dispatchStreamEventHooks({ctx:l,registry:b,event:n}),await dispatchDynamicToolEvent({ctx:l,resolvers:C,event:n,messages:t??[]}),await dispatchDynamicSkillEvent({ctx:l,resolvers:S,event:n,messages:t??[]}),await dispatchDynamicInstructionEvent({ctx:l,resolvers:x,event:n,messages:t??[]})},w=l.require(ModeKey),T=await runStep(l,g,async e=>{let t=resolveEffectiveOutputSchema({agentOutputSchema:p.turnAgent.outputSchema,input:v,mode:w,session:e});if(h){let e=getHarnessEmissionState(t.state);for(let{name:t,authorization:n}of h)await handleEvent(createAuthorizationCompletedEvent({authorization:n,name:t,outcome:`authorized`,sequence:e.sequence,stepIndex:e.stepIndex,turnId:e.turnId}))}let n=l.get(CapabilitiesKey);return(async(e,t)=>{let r=refreshSessionFromTurnAgent({compactionOverrides:{thresholdPercent:p.resolvedAgent.config.compaction?.thresholdPercent},session:e,turnAgent:p.turnAgent});return createExecutionNodeStep({capabilities:n,createRuntime:createWorkflowRuntime,handleEvent,mode:w,modelResolutionScope:{moduleMap:p.moduleMap,nodeId:p.nodeId},node:p.graph.root})(r,t)})(t,v)}),E=reconcileSessionContinuationToken(l,T.session),D=serializeContext(l);T={...T,session:E};let O=createDurableSessionState({session:T.session});if(T.next!==null&&typeof T.next==`object`&&`done`in T.next)return await y.close(),{action:`done`,output:T.next.output,isError:T.next.isError,serializedContext:D,sessionState:O};if(T.next===null){y.releaseLock();let e=getPendingWorkflowInterrupt(T.session.state);return e!==void 0&&isWorkflowRuntimeActionInterrupt(e.interrupt)?{action:`dispatch-workflow-runtime-actions`,pendingRuntimeActionKeys:getRuntimeActionKeysFromWorkflowInterrupt(e.interrupt),serializedContext:D,sessionState:O}:{action:`park`,...derivePendingState(T.session),serializedContext:D,sessionState:O}}return y.releaseLock(),{action:`continue`,serializedContext:D,sessionState:O}}function derivePendingState(e){let t=getPendingRuntimeActionBatch(e.state),n=getPendingAuthorization(e.state),r={authorizationNames:n?.challenges.map(e=>e.name),hasPendingAuthorization:n!==void 0,hasPendingInputBatch:hasPendingInputBatch(e.state)};return t===void 0?r:{...r,pendingRuntimeActionKeys:t.actions.map(e=>getRuntimeActionRequestKey(e))}}function reconcileSessionContinuationToken(e,t){let n=e.get(ContinuationTokenKey);return n===void 0||n===t.continuationToken?t:{...t,continuationToken:n}}function resolveEffectiveOutputSchema(e){let{agentOutputSchema:t,input:n,mode:r,session:i}=e;return n?.outputSchema===void 0?r===`task`&&i.outputSchema===void 0&&t!==void 0?{...i,outputSchema:t}:i:{...i,outputSchema:n.outputSchema}}const log=createLogger(`execution.workflow-entry`);async function emitTerminalSessionFailureStep(e){"use step";let r=formatError(e.error),i=typeof r.name==`string`?r.name:`WORKFLOW_EXECUTION_FAILED`,a=typeof r.message==`string`?r.message:String(e.error),o=e.serializedContext[`eve.sessionId`]??``;log.error(`workflow loop threw — emitting terminal session.failed`,{sessionId:o,errorId:typeof r.errorId==`string`?r.errorId:void 0,code:i,message:a,detail:typeof r.detail==`string`?r.detail:void 0});let s=createSessionFailedEvent({code:i,details:r,message:a,sessionId:o});try{let t=await deserializeContext(e.serializedContext),r=t.get(ChannelKey);r!==void 0&&await callAdapterEventHandler(r,s,buildAdapterContext(r,t))}catch(e){log.error(`adapter failed to handle terminal session.failed event`,{errorId:typeof r.errorId==`string`?r.errorId:void 0,sessionId:o,error:e})}try{let t=e.parentWritable.getWriter();try{await t.write(encodeMessageStreamEvent(timestampHandleMessageStreamEvent(s)))}finally{t.releaseLock()}}catch(e){log.error(`failed to write terminal session.failed event to durable stream`,{errorId:typeof r.errorId==`string`?r.errorId:void 0,sessionId:o,error:e})}}async function runProxyInputRequestStep(e){"use step";let t=await readDurableSession(e.sessionState),r=await deserializeContext(e.serializedContext),i=r.require(ChannelKey),a=buildAdapterContext(i,r),o=r.require(ModeKey),c=r.require(BundleKey),l=hydrateDurableSession({compactionOverrides:{thresholdPercent:c.resolvedAgent.config.compaction?.thresholdPercent},durable:t,turnAgent:c.turnAgent}),u=e.parentWritable.getWriter(),d;try{let emit=async e=>{let t=await callAdapterEventHandler(i,e,a);await u.write(encodeMessageStreamEvent(timestampHandleMessageStreamEvent(t)))};d=await withContextScope(r,l,async t=>{let n=await emitProxiedInputRequest({emit,hookPayload:e.hookPayload,mode:o,session:t});return{result:n.entries,session:n.session}})}finally{u.releaseLock()}return setChannelContext(r,{...i,state:{...a.state}}),{serializedContext:serializeContext(r),sessionState:createDurableSessionState({session:reconcileSessionContinuationToken(r,upsertProxyInputRequests({entries:d.result,forChildContinuationToken:e.hookPayload.childContinuationToken,session:d.session}))})}}async function routeProxiedDeliverStep(e){"use step";let t=await readDurableSession(e.sessionState),n=routeDeliverPayload({payload:e.payload,state:t.state});for(let t of n.forChildren)await resumeHook(t.childContinuationToken,{auth:e.auth,kind:`deliver`,payloads:[t.payload]});return{remainder:n.forSelf}}async function dispatchTurnStep(e){"use step";return{runId:(await startWorkflowPreferLatest(turnWorkflow,[createTurnWorkflowInput(e)],{allowReservedAttributes:!0,attributes:normalizeEveAttributes(buildTurnAttributes({parentSessionId:e.sessionState.sessionId,requestId:e.delivery.kind===`deliver`?e.delivery.requestId:void 0,rootSessionId:readRootSessionId(e.serializedContext)??e.sessionState.sessionId}))})).runId}}export{dispatchTurnStep,emitTerminalSessionFailureStep,reconcileSessionContinuationToken,resolveEffectiveOutputSchema,routeProxiedDeliverStep,runProxyInputRequestStep,turnStep};
|
|
@@ -8,7 +8,7 @@ type InlineToolResultPart = Extract<ToolResponsePart, {
|
|
|
8
8
|
import type { AssistantStepFinishReason, RuntimeIdentity } from "#protocol/message.js";
|
|
9
9
|
import type { RunMode } from "#shared/run-mode.js";
|
|
10
10
|
import type { JsonObject } from "#shared/json.js";
|
|
11
|
-
import type { HarnessEmitFn, HarnessSession, SessionStateMap, StepInput } from "#harness/types.js";
|
|
11
|
+
import type { HarnessEmitFn, HarnessSession, HarnessToolMap, SessionStateMap, StepInput } from "#harness/types.js";
|
|
12
12
|
/**
|
|
13
13
|
* Tracks emission lifecycle state across harness step invocations.
|
|
14
14
|
*
|
|
@@ -91,41 +91,27 @@ export declare function normalizeAssistantStepFinishReason(value: string | undef
|
|
|
91
91
|
/**
|
|
92
92
|
* Result of consuming one step's `fullStream`.
|
|
93
93
|
*
|
|
94
|
-
*
|
|
95
|
-
*
|
|
96
|
-
*
|
|
97
|
-
* `emitStepActions` skips these to avoid double-emission.
|
|
98
|
-
*
|
|
99
|
-
* `inlineToolResultParts` holds the same tool-results in
|
|
100
|
-
* `ToolResultPart` shape. The AI SDK omits them from
|
|
101
|
-
* `stepResult.response.messages` on the approval-resume path, so the
|
|
102
|
-
* harness splices them into persisted history to keep the prior turn's
|
|
103
|
-
* `tool_use` block balanced with a matching `tool_result` on replay.
|
|
104
|
-
*
|
|
105
|
-
* `inlineAuthorizationResults` holds approval-resume tool-results whose
|
|
106
|
-
* output is an {@link AuthorizationSignal}. These are surfaced into
|
|
107
|
-
* `stepResult.toolResults` for the park detector instead of being emitted
|
|
108
|
-
* as plain `action.result` events.
|
|
94
|
+
* Inline results avoid duplicate post-step events. Approval-resume results
|
|
95
|
+
* also repair persisted history or route authorization back to the park
|
|
96
|
+
* detector.
|
|
109
97
|
*/
|
|
110
98
|
interface EmittedStreamContent {
|
|
99
|
+
readonly emittedActionCallIds: ReadonlySet<string>;
|
|
111
100
|
readonly handledInlineToolResultCallIds: ReadonlySet<string>;
|
|
112
101
|
readonly inlineAuthorizationResults: readonly TypedToolResult<ToolSet>[];
|
|
113
102
|
readonly inlineToolResultParts: readonly InlineToolResultPart[];
|
|
114
103
|
}
|
|
104
|
+
interface StreamActionEmissionOptions {
|
|
105
|
+
readonly excludedActionToolNames: ReadonlySet<string>;
|
|
106
|
+
readonly tools: HarnessToolMap;
|
|
107
|
+
}
|
|
115
108
|
/**
|
|
116
109
|
* Consumes the AI SDK `fullStream` and emits real-time text and reasoning
|
|
117
110
|
* events.
|
|
118
111
|
*
|
|
119
|
-
*
|
|
120
|
-
*
|
|
121
|
-
*
|
|
122
|
-
* the AI SDK enqueues the executed tool-result onto the same step's
|
|
123
|
-
* stream before the next LLM call. Emitting `action.result` inline keeps
|
|
124
|
-
* it ahead of the message events that depend on it.
|
|
125
|
-
*
|
|
126
|
-
* Tool-call, tool-approval-request, and non-resumed tool-result events
|
|
127
|
-
* are still emitted by `emitStepActions` from the `onStepFinish`
|
|
128
|
-
* callback so the existing single-step batch ordering is preserved.
|
|
112
|
+
* Emits local and provider tool results in source order. A result without a
|
|
113
|
+
* streamed call resumes a call from an earlier step. `emitStepActions` emits
|
|
114
|
+
* the remaining events.
|
|
129
115
|
*/
|
|
130
|
-
export declare function emitStreamContent(emitFn: HarnessEmitFn, state: HarnessEmissionState, fullStream: AsyncIterable<TextStreamPart<ToolSet
|
|
116
|
+
export declare function emitStreamContent(emitFn: HarnessEmitFn, state: HarnessEmissionState, fullStream: AsyncIterable<TextStreamPart<ToolSet>>, options?: StreamActionEmissionOptions): Promise<EmittedStreamContent>;
|
|
131
117
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{toError}from"#shared/errors.js";import{createActionResultEvent,createActionsRequestedEvent,createMessageAppendedEvent,createMessageCompletedEvent,createMessageReceivedEvent,createReasoningAppendedEvent,createReasoningCompletedEvent,createSessionCompletedEvent,createSessionFailedEvent,createSessionStartedEvent,createSessionWaitingEvent,createStepFailedEvent,createStepStartedEvent,createTurnCompletedEvent,createTurnFailedEvent,createTurnStartedEvent}from"#protocol/message.js";import{contextStorage}from"#context/container.js";import{resolveToolCallInputObject}from"#harness/runtime-actions.js";import{isAuthorizationSignal,isPendingAuthorizationToolOutput}from"#harness/authorization.js";import{hasEmptyDeliverySentinel}from"#shared/empty-delivery.js";import{createRuntimeToolResultFromStepResult,createRuntimeToolResultFromValue}from"#harness/action-result-helpers.js";import{readToolInterrupt}from"#harness/tool-interrupts.js";const HARNESS_EMISSION_STATE_KEY=`eve.harness.emission`,DEFAULT_EMISSION_STATE={sessionStarted:!1,sequence:0,stepIndex:0,turnId:``};function getHarnessEmissionState(e){return e?.[HARNESS_EMISSION_STATE_KEY]??DEFAULT_EMISSION_STATE}function isHarnessBetweenTurns(e){return getHarnessEmissionState(e.state).turnId===``}function setHarnessEmissionState(e,t){return{...e,state:{...e.state,[HARNESS_EMISSION_STATE_KEY]:t}}}async function emitTurnPreamble(e,t,n,r){let i=`turn_${n.sequence}`;return n.sessionStarted||await e(createSessionStartedEvent({runtime:r})),await e(createTurnStartedEvent({sequence:n.sequence,turnId:i})),t.message!==void 0&&await e(createMessageReceivedEvent({message:t.message,sequence:n.sequence,turnId:i})),{sessionStarted:!0,sequence:n.sequence,stepIndex:0,turnId:i}}async function emitStepStarted(e,t,n){await e(createStepStartedEvent({sequence:t.sequence,stepIndex:t.stepIndex,turnId:t.turnId}),n)}async function emitStepAndTurnFailed(e,t,n){await e(createStepFailedEvent({...n,sequence:t.sequence,stepIndex:t.stepIndex,turnId:t.turnId})),await e(createTurnFailedEvent({...n,sequence:t.sequence,turnId:t.turnId}))}async function emitFailedStep(e,t,n){await emitStepAndTurnFailed(e,t,n),await e(createSessionFailedEvent(n))}async function emitRecoverableFailedTurn(e,t,n){return await emitStepAndTurnFailed(e,t,n),await e(createSessionWaitingEvent()),{sessionStarted:t.sessionStarted,sequence:t.sequence+1,stepIndex:0,turnId:``}}function advanceStep(e){return{...e,stepIndex:e.stepIndex+1}}async function emitTurnEpilogue(e,t,n){return await e(createTurnCompletedEvent({sequence:t.sequence,turnId:t.turnId})),n===`conversation`?await e(createSessionWaitingEvent()):await e(createSessionCompletedEvent()),{sessionStarted:t.sessionStarted,sequence:t.sequence+1,stepIndex:0,turnId:``}}function normalizeAssistantStepFinishReason(e){switch(e){case`content-filter`:case`error`:case`length`:case`stop`:case`tool-calls`:return e;default:return`other`}}async function emitStreamContent(a,o,s){let
|
|
1
|
+
import{toError}from"#shared/errors.js";import{createActionResultEvent,createActionsRequestedEvent,createMessageAppendedEvent,createMessageCompletedEvent,createMessageReceivedEvent,createReasoningAppendedEvent,createReasoningCompletedEvent,createSessionCompletedEvent,createSessionFailedEvent,createSessionStartedEvent,createSessionWaitingEvent,createStepFailedEvent,createStepStartedEvent,createTurnCompletedEvent,createTurnFailedEvent,createTurnStartedEvent}from"#protocol/message.js";import{contextStorage}from"#context/container.js";import{createRuntimeActionRequestFromToolCall,resolveToolCallInputObject}from"#harness/runtime-actions.js";import{isAuthorizationSignal,isPendingAuthorizationToolOutput}from"#harness/authorization.js";import{hasEmptyDeliverySentinel}from"#shared/empty-delivery.js";import{createRuntimeToolResultFromStepResult,createRuntimeToolResultFromValue}from"#harness/action-result-helpers.js";import{readToolInterrupt}from"#harness/tool-interrupts.js";const HARNESS_EMISSION_STATE_KEY=`eve.harness.emission`,DEFAULT_EMISSION_STATE={sessionStarted:!1,sequence:0,stepIndex:0,turnId:``};function getHarnessEmissionState(e){return e?.[HARNESS_EMISSION_STATE_KEY]??DEFAULT_EMISSION_STATE}function isHarnessBetweenTurns(e){return getHarnessEmissionState(e.state).turnId===``}function setHarnessEmissionState(e,t){return{...e,state:{...e.state,[HARNESS_EMISSION_STATE_KEY]:t}}}async function emitTurnPreamble(e,t,n,r){let i=`turn_${n.sequence}`;return n.sessionStarted||await e(createSessionStartedEvent({runtime:r})),await e(createTurnStartedEvent({sequence:n.sequence,turnId:i})),t.message!==void 0&&await e(createMessageReceivedEvent({message:t.message,sequence:n.sequence,turnId:i})),{sessionStarted:!0,sequence:n.sequence,stepIndex:0,turnId:i}}async function emitStepStarted(e,t,n){await e(createStepStartedEvent({sequence:t.sequence,stepIndex:t.stepIndex,turnId:t.turnId}),n)}async function emitStepAndTurnFailed(e,t,n){await e(createStepFailedEvent({...n,sequence:t.sequence,stepIndex:t.stepIndex,turnId:t.turnId})),await e(createTurnFailedEvent({...n,sequence:t.sequence,turnId:t.turnId}))}async function emitFailedStep(e,t,n){await emitStepAndTurnFailed(e,t,n),await e(createSessionFailedEvent(n))}async function emitRecoverableFailedTurn(e,t,n){return await emitStepAndTurnFailed(e,t,n),await e(createSessionWaitingEvent()),{sessionStarted:t.sessionStarted,sequence:t.sequence+1,stepIndex:0,turnId:``}}function advanceStep(e){return{...e,stepIndex:e.stepIndex+1}}async function emitTurnEpilogue(e,t,n){return await e(createTurnCompletedEvent({sequence:t.sequence,turnId:t.turnId})),n===`conversation`?await e(createSessionWaitingEvent()):await e(createSessionCompletedEvent()),{sessionStarted:t.sessionStarted,sequence:t.sequence+1,stepIndex:0,turnId:``}}function normalizeAssistantStepFinishReason(e){switch(e){case`content-filter`:case`error`:case`length`:case`stop`:case`tool-calls`:return e;default:return`other`}}async function emitStreamContent(a,o,s,c){let l=``,u=``,d=`stop`,f,p=new Set,m=new Set,h=new Set,g=new Set,_=[],v=[],flushCurrentMessage=async()=>{u.length!==0&&(await a(createMessageCompletedEvent({finishReason:`tool-calls`,message:u,sequence:o.sequence,stepIndex:o.stepIndex,turnId:o.turnId})),u=``)},emitActionRequest=async e=>{m.has(e.callId)||(u.trim().length>0&&await flushCurrentMessage(),m.add(e.callId),await a(createActionsRequestedEvent({actions:[e],sequence:o.sequence,stepIndex:o.stepIndex,turnId:o.turnId})))},emitProviderToolCall=async e=>{await emitActionRequest({callId:e.toolCallId,input:resolveToolCallInputObject(e.input,{callId:e.toolCallId,toolName:e.toolName}),kind:`tool-call`,toolName:e.toolName})},emitActionResult=async e=>{h.has(e.callId)||(h.add(e.callId),await a(createActionResultEvent({result:e,sequence:o.sequence,stepIndex:o.stepIndex,turnId:o.turnId})))},emitToolCall=async e=>{if(!(c===void 0||e.invalid===!0||c.excludedActionToolNames.has(e.toolName)))try{await emitActionRequest(createRuntimeActionRequestFromToolCall({toolCall:e,tools:c.tools}))}catch(e){if(e instanceof TypeError)return;throw e}};for await(let t of s)if(f===void 0)switch(t.type){case`reasoning-delta`:l+=t.text,await a(createReasoningAppendedEvent({reasoningDelta:t.text,reasoningSoFar:l,sequence:o.sequence,stepIndex:o.stepIndex,turnId:o.turnId}));break;case`text-delta`:l.trim().length>0&&(await a(createReasoningCompletedEvent({reasoning:l,sequence:o.sequence,stepIndex:o.stepIndex,turnId:o.turnId})),l=``),u+=t.text,await a(createMessageAppendedEvent({messageDelta:t.text,messageSoFar:u,sequence:o.sequence,stepIndex:o.stepIndex,turnId:o.turnId}));break;case`tool-call`:{let e=t;p.add(e.toolCallId),e.providerExecuted===!0?await emitProviderToolCall(e):await emitToolCall(e);break}case`tool-result`:{let e=t;if(e.preliminary===!0)break;if(e.providerExecuted===!0){await emitProviderToolCall({input:`input`in e?e.input:void 0,toolCallId:e.toolCallId,toolName:e.toolName}),await emitActionResult(createRuntimeToolResultFromStepResult(e));break}if(p.has(t.toolCallId)){if(isInlineAuthorizationToolResult(e))break;m.has(t.toolCallId)&&(await emitActionResult(createRuntimeToolResultFromStepResult(e)),g.add(t.toolCallId));break}if(await flushCurrentMessage(),isInlineAuthorizationToolResult(e)){g.add(t.toolCallId),_.push(e);break}await emitActionResult(createRuntimeToolResultFromStepResult(e)),g.add(t.toolCallId);let n=e.output;v.push({type:`tool-result`,toolCallId:e.toolCallId,toolName:e.toolName,output:typeof n==`string`?{type:`text`,value:n}:{type:`json`,value:n??null}});break}case`tool-error`:{let n=t;n.providerExecuted===!0?(await emitProviderToolCall(n),await emitActionResult(createRuntimeToolResultFromValue({callId:n.toolCallId,isError:!0,output:toError(n.error),toolName:n.toolName}))):m.has(n.toolCallId)&&(await emitActionResult(createRuntimeToolResultFromValue({callId:n.toolCallId,isError:!0,output:toError(n.error),toolName:n.toolName})),g.add(n.toolCallId));break}case`finish-step`:d=normalizeAssistantStepFinishReason(t.finishReason);break;case`error`:f=toError(t.error);break;default:break}if(f!==void 0)throw f;return l.trim().length>0&&await a(createReasoningCompletedEvent({reasoning:l,sequence:o.sequence,stepIndex:o.stepIndex,turnId:o.turnId})),d!==`tool-calls`&&hasEmptyDeliverySentinel(u)?await a(createMessageCompletedEvent({finishReason:d,message:null,sequence:o.sequence,stepIndex:o.stepIndex,turnId:o.turnId})):u.trim().length>0&&await a(createMessageCompletedEvent({finishReason:d,message:u,sequence:o.sequence,stepIndex:o.stepIndex,turnId:o.turnId})),{emittedActionCallIds:m,handledInlineToolResultCallIds:g,inlineAuthorizationResults:_,inlineToolResultParts:v}}function isInlineAuthorizationToolResult(e){if(isPendingAuthorizationToolOutput(e.output))return!0;let t=contextStorage.getStore();if(t===void 0)return!1;let n=readToolInterrupt(t,e.toolCallId);return n!==void 0&&isAuthorizationSignal(n)}export{advanceStep,emitFailedStep,emitRecoverableFailedTurn,emitStepStarted,emitStreamContent,emitTurnEpilogue,emitTurnPreamble,getHarnessEmissionState,isHarnessBetweenTurns,normalizeAssistantStepFinishReason,setHarnessEmissionState};
|
|
@@ -84,11 +84,11 @@ export declare function buildStepHooks(input: StepHooksInput): StepHooks;
|
|
|
84
84
|
* arguments — the runtime event stream only sees successfully parsed
|
|
85
85
|
* tool calls.
|
|
86
86
|
*
|
|
87
|
-
* `handledInlineToolResultCallIds`
|
|
88
|
-
*
|
|
89
|
-
* This skips them to avoid double-emission.
|
|
87
|
+
* `handledInlineToolResultCallIds` contains results emitted by
|
|
88
|
+
* `emitStreamContent` or sent to authorization. Skip them here.
|
|
90
89
|
*/
|
|
91
90
|
export declare function emitStepActions(emitFn: HarnessEmitFn, state: HarnessEmissionState, step: HarnessStepResult, options: {
|
|
91
|
+
readonly emittedActionCallIds?: ReadonlySet<string>;
|
|
92
92
|
readonly excludedActionToolNames: ReadonlySet<string>;
|
|
93
93
|
readonly handledInlineToolResultCallIds?: ReadonlySet<string>;
|
|
94
94
|
readonly tools: ToolLoopHarnessConfig["tools"];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createActionResultEvent,createActionsRequestedEvent,createStepCompletedEvent}from"#protocol/message.js";import{contextStorage}from"#context/container.js";import{emitStepStarted,normalizeAssistantStepFinishReason}from"#harness/emission.js";import{createRuntimeActionRequestFromToolCall}from"#harness/runtime-actions.js";import{isAuthorizationSignal,isPendingAuthorizationToolOutput}from"#harness/authorization.js";import{createRuntimeToolResultFromMessagePart,createRuntimeToolResultFromStepResult}from"#harness/action-result-helpers.js";import{readToolInterrupt}from"#harness/tool-interrupts.js";import{extractToolApprovalInputRequests}from"#harness/input-extraction.js";import{applyConversationCacheControl,mergeGatewayAutoCaching}from"#harness/prompt-cache.js";function buildStepHooks(e){let t=e.session,n=e.emit,r;return{onStepFinish:async e=>{r(e)},prepareStep:async({messages:r})=>{let a=r;n&&e.emitStepStarted!==!1&&await emitStepStarted(n,e.emissionState,r),e.cachePath.kind===`anthropic-direct`&&e.marker&&(a=applyConversationCacheControl([...r],e.marker));let o={messages:a};return e.cachePath.kind===`gateway-auto`&&(o.providerOptions=mergeGatewayAutoCaching(t.agent.modelReference.providerOptions)),o},stepResult:new Promise(e=>{r=e})}}async function emitStepActions(r,i,s,c){let l=new Set(s.toolCalls.filter(isProviderExecutedToolCall).map(e=>e.toolCallId)),u=new Set([...l,...extractToolApprovalInputRequests({content:s.content??[]}).map(e=>e.action.callId),...s.toolCalls.filter(isInvalidToolCall).map(e=>e.toolCallId)]),isExcluded=(e,t)=>u.has(e)||c.excludedActionToolNames.has(t),d=s.toolCalls.filter(e=>!isExcluded(e.toolCallId,e.toolName)).map(e=>createRuntimeActionRequestFromToolCall({toolCall:e,tools:c.tools}));d.length>0&&await r(createActionsRequestedEvent({actions:d,sequence:i.sequence,stepIndex:i.stepIndex,turnId:i.turnId}));let f=c.handledInlineToolResultCallIds,p=new Map(s.toolResults.map(e=>[e.toolCallId,e.output]));for(let t of reconcileToolResults(s)){if(isExcluded(t.callId,t.toolName)||f?.has(t.callId))continue;let n=p.get(t.callId);shouldSkipAuthorizationActionResult(t.callId,n)||await r(createActionResultEvent({result:t,sequence:i.sequence,stepIndex:i.stepIndex,turnId:i.turnId}))}await r(createStepCompletedEvent({finishReason:normalizeAssistantStepFinishReason(s.finishReason),sequence:i.sequence,stepIndex:i.stepIndex,turnId:i.turnId,usage:extractStepUsage(s.usage)}))}function isInvalidToolCall(e){return e.invalid===!0}function isProviderExecutedToolCall(e){return e.providerExecuted===!0}function reconcileToolResults(e){let t=new Map;for(let n of e.toolResults)n.providerExecuted!==!0&&t.set(n.toolCallId,createRuntimeToolResultFromStepResult(n));for(let n of extractToolResultParts(e.response.messages))n.providerExecuted!==!0&&(t.has(n.toolCallId)||t.set(n.toolCallId,createRuntimeToolResultFromMessagePart(n)));return[...t.values()]}function shouldSkipAuthorizationActionResult(e,t){if(t!==void 0&&isPendingAuthorizationToolOutput(t))return!0;let n=contextStorage.getStore();if(n===void 0)return!1;let i=readToolInterrupt(n,e);return i!==void 0&&isAuthorizationSignal(i)}function extractToolResultParts(e){let t=[];for(let n of e)if(!(n.role!==`tool`||!Array.isArray(n.content)))for(let e of n.content)e.type===`tool-result`&&t.push(e);return t}function extractStepUsage(e){if(e===void 0)return;let t={};return e.inputTokens!==void 0&&(t.inputTokens=e.inputTokens),e.outputTokens!==void 0&&(t.outputTokens=e.outputTokens),e.inputTokenDetails?.cacheReadTokens!==void 0&&(t.cacheReadTokens=e.inputTokenDetails.cacheReadTokens),e.inputTokenDetails?.cacheWriteTokens!==void 0&&(t.cacheWriteTokens=e.inputTokenDetails.cacheWriteTokens),Object.keys(t).length>0?t:void 0}export{buildStepHooks,emitStepActions,isInvalidToolCall};
|
|
1
|
+
import{createActionResultEvent,createActionsRequestedEvent,createStepCompletedEvent}from"#protocol/message.js";import{contextStorage}from"#context/container.js";import{emitStepStarted,normalizeAssistantStepFinishReason}from"#harness/emission.js";import{createRuntimeActionRequestFromToolCall}from"#harness/runtime-actions.js";import{isAuthorizationSignal,isPendingAuthorizationToolOutput}from"#harness/authorization.js";import{createRuntimeToolResultFromMessagePart,createRuntimeToolResultFromStepResult}from"#harness/action-result-helpers.js";import{readToolInterrupt}from"#harness/tool-interrupts.js";import{extractToolApprovalInputRequests}from"#harness/input-extraction.js";import{applyConversationCacheControl,mergeGatewayAutoCaching}from"#harness/prompt-cache.js";function buildStepHooks(e){let t=e.session,n=e.emit,r;return{onStepFinish:async e=>{r(e)},prepareStep:async({messages:r})=>{let a=r;n&&e.emitStepStarted!==!1&&await emitStepStarted(n,e.emissionState,r),e.cachePath.kind===`anthropic-direct`&&e.marker&&(a=applyConversationCacheControl([...r],e.marker));let o={messages:a};return e.cachePath.kind===`gateway-auto`&&(o.providerOptions=mergeGatewayAutoCaching(t.agent.modelReference.providerOptions)),o},stepResult:new Promise(e=>{r=e})}}async function emitStepActions(r,i,s,c){let l=new Set(s.toolCalls.filter(isProviderExecutedToolCall).map(e=>e.toolCallId)),u=new Set([...l,...extractToolApprovalInputRequests({content:s.content??[]}).map(e=>e.action.callId),...s.toolCalls.filter(isInvalidToolCall).map(e=>e.toolCallId)]),isExcluded=(e,t)=>u.has(e)||c.excludedActionToolNames.has(t),d=s.toolCalls.filter(e=>!isExcluded(e.toolCallId,e.toolName)&&!c.emittedActionCallIds?.has(e.toolCallId)).map(e=>createRuntimeActionRequestFromToolCall({toolCall:e,tools:c.tools}));d.length>0&&await r(createActionsRequestedEvent({actions:d,sequence:i.sequence,stepIndex:i.stepIndex,turnId:i.turnId}));let f=c.handledInlineToolResultCallIds,p=new Map(s.toolResults.map(e=>[e.toolCallId,e.output]));for(let t of reconcileToolResults(s)){if(isExcluded(t.callId,t.toolName)||f?.has(t.callId))continue;let n=p.get(t.callId);shouldSkipAuthorizationActionResult(t.callId,n)||await r(createActionResultEvent({result:t,sequence:i.sequence,stepIndex:i.stepIndex,turnId:i.turnId}))}await r(createStepCompletedEvent({finishReason:normalizeAssistantStepFinishReason(s.finishReason),sequence:i.sequence,stepIndex:i.stepIndex,turnId:i.turnId,usage:extractStepUsage(s.usage)}))}function isInvalidToolCall(e){return e.invalid===!0}function isProviderExecutedToolCall(e){return e.providerExecuted===!0}function reconcileToolResults(e){let t=new Map;for(let n of e.toolResults)n.providerExecuted!==!0&&t.set(n.toolCallId,createRuntimeToolResultFromStepResult(n));for(let n of extractToolResultParts(e.response.messages))n.providerExecuted!==!0&&(t.has(n.toolCallId)||t.set(n.toolCallId,createRuntimeToolResultFromMessagePart(n)));return[...t.values()]}function shouldSkipAuthorizationActionResult(e,t){if(t!==void 0&&isPendingAuthorizationToolOutput(t))return!0;let n=contextStorage.getStore();if(n===void 0)return!1;let i=readToolInterrupt(n,e);return i!==void 0&&isAuthorizationSignal(i)}function extractToolResultParts(e){let t=[];for(let n of e)if(!(n.role!==`tool`||!Array.isArray(n.content)))for(let e of n.content)e.type===`tool-result`&&t.push(e);return t}function extractStepUsage(e){if(e===void 0)return;let t={};return e.inputTokens!==void 0&&(t.inputTokens=e.inputTokens),e.outputTokens!==void 0&&(t.outputTokens=e.outputTokens),e.inputTokenDetails?.cacheReadTokens!==void 0&&(t.cacheReadTokens=e.inputTokenDetails.cacheReadTokens),e.inputTokenDetails?.cacheWriteTokens!==void 0&&(t.cacheWriteTokens=e.inputTokenDetails.cacheWriteTokens),Object.keys(t).length>0?t:void 0}export{buildStepHooks,emitStepActions,isInvalidToolCall};
|