eve 0.42.0 → 0.44.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/CHANGELOG.md +34 -0
- package/dist/src/channel/adapter.d.ts +2 -1
- package/dist/src/channel/forwarded-principal.d.ts +4 -4
- package/dist/src/channel/instrumentation.js +1 -1
- package/dist/src/cli/commands/registry-project.d.ts +3 -0
- package/dist/src/cli/commands/registry-project.js +2 -1
- package/dist/src/cli/commands/registry.d.ts +2 -0
- package/dist/src/cli/commands/registry.js +1 -1
- package/dist/src/cli/dev/tui/traces/trace-view.js +1 -1
- package/dist/src/compiled/.vendor-stamp.json +1 -1
- package/dist/src/compiled/jsonc-parser/index.d.ts +19 -0
- package/dist/src/compiler/extension-compatibility.d.ts +7 -5
- package/dist/src/compiler/extension-compatibility.js +1 -1
- package/dist/src/compiler/manifest.d.ts +3 -0
- package/dist/src/compiler/manifest.js +1 -1
- package/dist/src/compiler/normalize-manifest.js +1 -1
- package/dist/src/compiler/normalize-tool.js +1 -1
- package/dist/src/context/build-dynamic-tools.d.ts +5 -5
- package/dist/src/context/build-dynamic-tools.js +1 -1
- package/dist/src/context/dynamic-subagent-lifecycle.js +1 -1
- package/dist/src/context/dynamic-tool-lifecycle.d.ts +8 -27
- package/dist/src/context/dynamic-tool-lifecycle.js +1 -1
- package/dist/src/context/keys.d.ts +10 -14
- package/dist/src/context/keys.js +1 -1
- package/dist/src/context/provider.d.ts +5 -1
- package/dist/src/context/run-step.d.ts +3 -2
- package/dist/src/context/run-step.js +1 -1
- package/dist/src/execution/agent-handle-dispatch.d.ts +3 -0
- package/dist/src/execution/agent-handle-dispatch.js +1 -1
- package/dist/src/execution/delegation-tool.d.ts +9 -1
- package/dist/src/execution/delegation-tool.js +1 -1
- package/dist/src/execution/dispatch-runtime-actions-shared.d.ts +14 -1
- package/dist/src/execution/dispatch-runtime-actions-shared.js +1 -1
- package/dist/src/execution/dispatch-runtime-actions-step.js +1 -1
- package/dist/src/execution/history-view.d.ts +9 -0
- package/dist/src/execution/history-view.js +1 -0
- package/dist/src/execution/next-driver-action.d.ts +33 -1
- package/dist/src/execution/node-step.d.ts +5 -2
- package/dist/src/execution/node-step.js +1 -1
- package/dist/src/execution/remote-agent-dispatch.d.ts +2 -0
- package/dist/src/execution/remote-agent-dispatch.js +1 -1
- package/dist/src/execution/session-callback-step.d.ts +2 -2
- package/dist/src/execution/session-callback-step.js +1 -1
- package/dist/src/execution/tasks/child/steps.js +1 -1
- package/dist/src/execution/tasks/child/update.d.ts +2 -2
- package/dist/src/execution/tasks/child/update.js +1 -1
- package/dist/src/execution/tasks/child/workflow.js +1 -1
- package/dist/src/execution/tasks/parent/agent-views.d.ts +2 -1
- package/dist/src/execution/tasks/parent/agent-views.js +1 -1
- package/dist/src/execution/tasks/parent/continuation-dispatch.d.ts +6 -0
- package/dist/src/execution/tasks/parent/continuation-dispatch.js +1 -1
- package/dist/src/execution/tasks/parent/control-shared.d.ts +1 -1
- package/dist/src/execution/tasks/parent/control-shared.js +1 -1
- package/dist/src/execution/tasks/parent/delegate.d.ts +20 -6
- package/dist/src/execution/tasks/parent/delegate.js +1 -1
- package/dist/src/execution/tasks/parent/dispatch-task-step.js +1 -1
- package/dist/src/execution/tasks/parent/dispatch.d.ts +13 -1
- package/dist/src/execution/tasks/parent/dispatch.js +1 -1
- package/dist/src/execution/tasks/parent/hitl-proxy-steps.js +1 -1
- package/dist/src/execution/tasks/parent/tool-execution.d.ts +46 -0
- package/dist/src/execution/tasks/parent/tool-execution.js +1 -0
- package/dist/src/execution/tool-auth.d.ts +12 -3
- package/dist/src/execution/tool-auth.js +1 -1
- package/dist/src/execution/turn-cancellation-control.js +1 -1
- package/dist/src/execution/turn-workflow.js +1 -1
- package/dist/src/execution/wire/session-inbox-wire.v1.js +1 -1
- package/dist/src/execution/workflow-steps.d.ts +1 -54
- package/dist/src/execution/workflow-steps.js +1 -1
- package/dist/src/execution/workflow-trace-context.js +1 -1
- package/dist/src/harness/advertised-tools.js +1 -1
- package/dist/src/harness/background-tools.d.ts +37 -0
- package/dist/src/harness/background-tools.js +1 -0
- package/dist/src/harness/channel-delivery-instrumentation.js +1 -1
- package/dist/src/harness/execute-tool.d.ts +10 -1
- package/dist/src/harness/handles/transitions.d.ts +36 -0
- package/dist/src/harness/handles/transitions.js +1 -1
- package/dist/src/harness/instrumentation/lifecycle.d.ts +4 -0
- package/dist/src/harness/instrumentation/native-events.d.ts +2 -0
- package/dist/src/harness/instrumentation/native-events.js +1 -1
- package/dist/src/harness/messages.d.ts +2 -0
- package/dist/src/harness/messages.js +1 -1
- package/dist/src/harness/prepare-trace-context.d.ts +2 -0
- package/dist/src/harness/prepare-trace-context.js +1 -1
- package/dist/src/harness/tool-loop.js +2 -2
- package/dist/src/harness/tools.d.ts +5 -1
- package/dist/src/harness/tools.js +1 -1
- package/dist/src/harness/types.d.ts +13 -0
- package/dist/src/internal/application/package.js +1 -1
- package/dist/src/internal/authored-definition/schema-backed.js +1 -1
- package/dist/src/internal/authored-module-loader.js +1 -1
- package/dist/src/internal/workflow-bundle/dynamic-capability-transform-plugin.js +1 -1
- package/dist/src/internal/workflow-bundle/dynamic-tool-ast-references.d.ts +13 -0
- package/dist/src/internal/workflow-bundle/dynamic-tool-transform.d.ts +7 -31
- package/dist/src/internal/workflow-bundle/dynamic-tool-transform.js +4 -4
- package/dist/src/packages/eve-catalog/src/index.js +1 -1
- package/dist/src/public/channels/chat-sdk/audience.d.ts +2 -0
- package/dist/src/public/channels/chat-sdk/audience.js +1 -0
- package/dist/src/public/channels/chat-sdk/chatSdkChannel.d.ts +2 -0
- package/dist/src/public/channels/chat-sdk/chatSdkChannel.js +2 -2
- package/dist/src/public/channels/discord/audience.d.ts +5 -0
- package/dist/src/public/channels/discord/audience.js +1 -0
- package/dist/src/public/channels/discord/discordChannel.d.ts +2 -0
- package/dist/src/public/channels/discord/discordChannel.js +1 -1
- package/dist/src/public/channels/discord/inbound.d.ts +1 -0
- package/dist/src/public/channels/discord/inbound.js +1 -1
- package/dist/src/public/channels/discord/index.d.ts +1 -0
- package/dist/src/public/channels/eve.d.ts +7 -7
- package/dist/src/public/channels/eve.js +1 -1
- package/dist/src/public/channels/index.d.ts +3 -2
- package/dist/src/public/channels/slack/slackChannel.d.ts +4 -0
- package/dist/src/public/channels/slack/slackChannel.js +1 -1
- package/dist/src/public/channels/teams/index.d.ts +1 -0
- package/dist/src/public/channels/teams/teamsChannel.js +1 -1
- package/dist/src/public/channels/telegram/audience.d.ts +3 -0
- package/dist/src/public/channels/telegram/audience.js +1 -0
- package/dist/src/public/channels/telegram/index.d.ts +1 -0
- package/dist/src/public/channels/telegram/telegramChannel.js +1 -1
- package/dist/src/public/channels/twilio/twilioChannel.d.ts +2 -0
- package/dist/src/public/channels/twilio/twilioChannel.js +1 -1
- package/dist/src/public/definitions/channel.d.ts +1 -0
- package/dist/src/public/definitions/remote-agent.d.ts +7 -5
- package/dist/src/public/definitions/tool.d.ts +23 -0
- package/dist/src/public/definitions/tool.js +1 -1
- package/dist/src/public/instrumentation/otel.d.ts +6 -10
- package/dist/src/public/instrumentation/otel.js +1 -1
- package/dist/src/public/tools/approval/approval-helpers.js +1 -1
- package/dist/src/public/tools/index.d.ts +1 -1
- package/dist/src/runtime/framework-tools/connection-search-dynamic.js +2 -2
- package/dist/src/runtime/framework-tools/subagent/local.d.ts +41 -0
- package/dist/src/runtime/framework-tools/subagent/local.js +1 -0
- package/dist/src/runtime/framework-tools/subagent/remote.d.ts +23 -0
- package/dist/src/runtime/framework-tools/subagent/remote.js +1 -0
- package/dist/src/runtime/framework-tools/tasks.d.ts +11 -2
- package/dist/src/runtime/framework-tools/tasks.js +1 -1
- package/dist/src/runtime/resolve-tool.js +1 -1
- package/dist/src/runtime/session-callback-route.js +1 -1
- package/dist/src/setup/integrations/linq/management.d.ts +5 -0
- package/dist/src/setup/integrations/linq/management.js +1 -0
- package/dist/src/setup/integrations/linq/setup.d.ts +5 -1
- package/dist/src/setup/integrations/linq/setup.js +3 -3
- package/dist/src/setup/scaffold/create/add-to-project.js +1 -1
- package/dist/src/setup/scaffold/create/project.js +4 -10
- package/dist/src/setup/scaffold/create/web-template.d.ts +2 -2
- package/dist/src/setup/scaffold/create/web-template.js +374 -2
- package/dist/src/setup/scaffold/update/channels.d.ts +1 -1
- package/dist/src/setup/scaffold/update/channels.js +2 -2
- package/dist/src/setup/scaffold/update/package-json.d.ts +0 -2
- package/dist/src/setup/scaffold/update/package-json.js +1 -1
- package/dist/src/setup/scaffold/workspace-root.d.ts +0 -1
- package/dist/src/setup/scaffold/workspace-root.js +1 -1
- package/dist/src/shared/channel-audience.d.ts +7 -0
- package/dist/src/shared/channel-audience.js +1 -0
- package/dist/src/shared/channel-definition.d.ts +2 -1
- package/dist/src/shared/durable-dynamic-tool-callbacks.d.ts +34 -0
- package/dist/src/shared/durable-dynamic-tool-callbacks.js +1 -0
- package/dist/src/shared/dynamic-tool-definition.d.ts +2 -4
- package/dist/src/shared/empty-delivery.js +1 -1
- package/dist/src/shared/history-view.d.ts +22 -0
- package/dist/src/shared/history-view.js +1 -0
- package/dist/src/shared/json.d.ts +2 -0
- package/dist/src/shared/json.js +1 -1
- package/dist/src/shared/tool-definition.d.ts +4 -1
- package/dist/src/shared/tool-task.d.ts +107 -0
- package/dist/src/shared/tool-task.js +1 -0
- package/dist/src/tasks/delivery-context.d.ts +12 -0
- package/dist/src/tasks/delivery-context.js +17 -0
- package/dist/src/tasks/json.d.ts +25 -10
- package/dist/src/tasks/json.js +1 -1
- package/dist/src/tasks/session-index.d.ts +5 -3
- package/dist/src/tasks/session-index.js +1 -1
- package/dist/src/tasks/transitions.d.ts +40 -5
- package/dist/src/tasks/transitions.js +1 -1
- package/dist/src/tasks/types.d.ts +46 -4
- package/dist/src/tasks/types.js +1 -1
- package/dist/src/tracing/agent-action-instrumentation.js +1 -1
- package/dist/src/tracing/agent-approval-instrumentation.js +1 -1
- package/dist/src/tracing/agent-channel-delivery-instrumentation.js +1 -1
- package/dist/src/tracing/agent-otel-provider.d.ts +2 -0
- package/dist/src/tracing/agent-otel-provider.js +2 -2
- package/dist/src/tracing/agent-otel-session-context.d.ts +2 -0
- package/dist/src/tracing/agent-otel-session-context.js +1 -1
- package/dist/src/tracing/agent-trace-context-store.js +1 -1
- package/dist/src/tracing/agent-trace-state.d.ts +3 -0
- package/dist/src/tracing/channel-audience-context.d.ts +4 -0
- package/dist/src/tracing/channel-audience-context.js +1 -0
- package/dist/src/tracing/content-attributes.js +1 -1
- package/dist/src/tracing/content-span-processor.d.ts +7 -7
- package/dist/src/tracing/content-span-processor.js +1 -1
- package/dist/src/tracing/install-instrumentation-runtime.js +1 -1
- package/dist/src/tracing/local-instrumentation-runtime.d.ts +3 -0
- package/dist/src/tracing/local-instrumentation-runtime.js +1 -1
- package/dist/src/tracing/local-traces.d.ts +1 -10
- package/dist/src/tracing/local-traces.js +1 -1
- package/dist/src/tracing/otel-declaration.d.ts +34 -27
- package/dist/src/tracing/otel-declaration.js +1 -1
- package/dist/src/tracing/sampled-trace.d.ts +2 -0
- package/dist/src/tracing/sampled-trace.js +1 -0
- package/dist/src/tracing/span-export-policy.d.ts +41 -0
- package/dist/src/tracing/span-export-policy.js +1 -0
- package/dist/src/tracing/suppress-tracing.d.ts +2 -0
- package/dist/src/tracing/suppress-tracing.js +1 -0
- package/docs/channels/custom.mdx +2 -0
- package/docs/channels/linq.mdx +1 -1
- package/docs/getting-started.mdx +36 -36
- package/docs/guides/auth-and-route-protection.md +6 -2
- package/docs/guides/dynamic-capabilities.md +12 -10
- package/docs/guides/instrumentation.md +2 -0
- package/docs/guides/remote-agents.md +10 -2
- package/docs/tools/overview.mdx +19 -0
- package/docs/tutorial/ship-it.mdx +1 -1
- package/package.json +1 -1
|
@@ -16,6 +16,8 @@ export interface JsonObject {
|
|
|
16
16
|
* JSON-serializable values that can safely cross workflow and step boundaries.
|
|
17
17
|
*/
|
|
18
18
|
export type JsonValue = JsonArray | JsonObject | JsonPrimitive;
|
|
19
|
+
/** Compares two already-validated JSON structures by value. */
|
|
20
|
+
export declare function jsonValuesEqual(left: unknown, right: unknown): boolean;
|
|
19
21
|
/**
|
|
20
22
|
* Returns the normalized JSON value for one runtime payload.
|
|
21
23
|
*
|
package/dist/src/shared/json.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
const INVALID_JSON_VALUE_CANDIDATE=Symbol(`invalid-json-value-candidate`);function parseJsonValue(t){let n=normalizeJsonValueCandidate(t);if(n===INVALID_JSON_VALUE_CANDIDATE)throw TypeError(`Expected a JSON-serializable value.`);return n}function parseJsonObject(e){let t=parseJsonValue(e);if(!isJsonObjectValue(t))throw TypeError(`Expected a JSON-serializable object.`);return t}function normalizeJsonValueCandidate(t,n=new WeakSet){if(t===null||typeof t==`boolean`||typeof t==`string`)return t;if(typeof t==`number`)return Number.isFinite(t)?t:INVALID_JSON_VALUE_CANDIDATE;if(Array.isArray(t)){let r=[];for(let i of t){let t=normalizeJsonValueCandidate(i,n);if(t===INVALID_JSON_VALUE_CANDIDATE)return INVALID_JSON_VALUE_CANDIDATE;r.push(t)}return r}if(typeof t!=`object`||t===void 0||!isPlainObject(t)||n.has(t))return INVALID_JSON_VALUE_CANDIDATE;n.add(t);let r={};for(let[i,a]of Object.entries(t)){if(a===void 0)continue;let t=normalizeJsonValueCandidate(a,n);if(t===INVALID_JSON_VALUE_CANDIDATE)return INVALID_JSON_VALUE_CANDIDATE;r[i]=t}return n.delete(t),r}function isJsonObjectValue(e){return e!==null&&!Array.isArray(e)&&typeof e==`object`}function isPlainObject(e){let t=Object.getPrototypeOf(e);return t===null||t===Object.prototype}export{isJsonObjectValue,parseJsonObject,parseJsonValue};
|
|
1
|
+
function jsonValuesEqual(e,t){if(e===t)return!0;if(Array.isArray(e)||Array.isArray(t))return Array.isArray(e)&&Array.isArray(t)&&e.length===t.length&&e.every((e,n)=>jsonValuesEqual(e,t[n]));if(e===null||t===null||typeof e!=`object`||typeof t!=`object`)return!1;let n=Object.entries(e),r=t;return n.length===Object.keys(r).length&&n.every(([e,t])=>Object.hasOwn(r,e)&&jsonValuesEqual(t,r[e]))}const INVALID_JSON_VALUE_CANDIDATE=Symbol(`invalid-json-value-candidate`);function parseJsonValue(t){let n=normalizeJsonValueCandidate(t);if(n===INVALID_JSON_VALUE_CANDIDATE)throw TypeError(`Expected a JSON-serializable value.`);return n}function parseJsonObject(e){let t=parseJsonValue(e);if(!isJsonObjectValue(t))throw TypeError(`Expected a JSON-serializable object.`);return t}function normalizeJsonValueCandidate(t,n=new WeakSet){if(t===null||typeof t==`boolean`||typeof t==`string`)return t;if(typeof t==`number`)return Number.isFinite(t)?t:INVALID_JSON_VALUE_CANDIDATE;if(Array.isArray(t)){let r=[];for(let i of t){let t=normalizeJsonValueCandidate(i,n);if(t===INVALID_JSON_VALUE_CANDIDATE)return INVALID_JSON_VALUE_CANDIDATE;r.push(t)}return r}if(typeof t!=`object`||t===void 0||!isPlainObject(t)||n.has(t))return INVALID_JSON_VALUE_CANDIDATE;n.add(t);let r={};for(let[i,a]of Object.entries(t)){if(a===void 0)continue;let t=normalizeJsonValueCandidate(a,n);if(t===INVALID_JSON_VALUE_CANDIDATE)return INVALID_JSON_VALUE_CANDIDATE;r[i]=t}return n.delete(t),r}function isJsonObjectValue(e){return e!==null&&!Array.isArray(e)&&typeof e==`object`}function isPlainObject(e){let t=Object.getPrototypeOf(e);return t===null||t===Object.prototype}export{isJsonObjectValue,jsonValuesEqual,parseJsonObject,parseJsonValue};
|
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
import type { ToolExecutionOptions } from "ai";
|
|
2
2
|
import type { StandardJSONSchemaV1, StandardSchemaV1 } from "#compiled/@standard-schema/spec/index.js";
|
|
3
3
|
import type { JsonObject } from "#shared/json.js";
|
|
4
|
+
import type { TaskExec } from "#shared/tool-task.js";
|
|
4
5
|
/**
|
|
5
6
|
* Options forwarded from the AI SDK to the tool's {@link ToolDefinition.execute}
|
|
6
7
|
* function. These are the same options the SDK passes to every tool call.
|
|
7
8
|
*/
|
|
8
9
|
export type ToolExecuteOptions = Omit<ToolExecutionOptions<unknown>, "context">;
|
|
9
|
-
export type ToolExecuteFn<TInput = unknown, TOutput = unknown> = (input: TInput, options: ToolExecuteOptions) => Promise<TOutput> | TOutput | AsyncIterable<TOutput>;
|
|
10
|
+
export type ToolExecuteFn<TInput = unknown, TOutput = unknown> = (input: TInput, options: ToolExecuteOptions, task?: TaskExec) => Promise<TOutput> | TOutput | AsyncIterable<TOutput>;
|
|
11
|
+
export type ToolExecution = "background";
|
|
10
12
|
interface ToolDefinitionBase {
|
|
11
13
|
readonly description: string;
|
|
14
|
+
readonly execution?: ToolExecution;
|
|
12
15
|
}
|
|
13
16
|
/**
|
|
14
17
|
* Internal/compiled tool definition shape. Carries `name` because the
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import type { BackgroundTask } from "#execution/tasks/parent/delegate.js";
|
|
2
|
+
import type { BackgroundToolCall } from "#harness/background-tools.js";
|
|
3
|
+
import type { HarnessSession } from "#harness/types.js";
|
|
4
|
+
import type { JsonObject, JsonValue } from "#shared/json.js";
|
|
5
|
+
declare const TASK_DELEGATED_KIND = "eve:task-delegated";
|
|
6
|
+
/** Private address an executor uses to report lifecycle changes to its owning task. */
|
|
7
|
+
export interface TaskBinding {
|
|
8
|
+
readonly taskId: string;
|
|
9
|
+
readonly token: string;
|
|
10
|
+
readonly url?: string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Opaque, task-private address used to control an external executor. `data`
|
|
14
|
+
* means nothing to the task layer beyond deep equality (replay idempotency);
|
|
15
|
+
* only the executor `kind` that wrote it may parse it (e.g. cancel routing).
|
|
16
|
+
*/
|
|
17
|
+
export interface TaskExecutorBinding {
|
|
18
|
+
readonly kind: string;
|
|
19
|
+
readonly data: JsonObject;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* What the model sees as this call's tool output when work is delegated: the
|
|
23
|
+
* author-supplied data plus `status: "working"` and the `taskId` it can poll
|
|
24
|
+
* or cancel. It acknowledges delegation — it is not the task's result, which
|
|
25
|
+
* arrives later through task completion.
|
|
26
|
+
*/
|
|
27
|
+
export type TaskReceipt<TData extends JsonObject = JsonObject> = TData & {
|
|
28
|
+
readonly status: "working";
|
|
29
|
+
readonly taskId: string;
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Sentinel returned by a background tool after an external executor accepts
|
|
33
|
+
* responsibility for the task. Returning it ends `execute`; it does not
|
|
34
|
+
* complete the durable task.
|
|
35
|
+
*/
|
|
36
|
+
export interface TaskDelegated<TData extends JsonObject = JsonObject> {
|
|
37
|
+
readonly kind: typeof TASK_DELEGATED_KIND;
|
|
38
|
+
readonly executor: TaskExecutorBinding;
|
|
39
|
+
readonly receipt: TaskReceipt<TData>;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Commands an in-process executor may report to its task via
|
|
43
|
+
* {@link TaskExec.send}. Deliberately narrower than the task run's full
|
|
44
|
+
* command surface — bind, ready, and input routing stay runtime-owned.
|
|
45
|
+
*/
|
|
46
|
+
export type TaskSendCommand = {
|
|
47
|
+
readonly kind: "update";
|
|
48
|
+
readonly message: string;
|
|
49
|
+
} | {
|
|
50
|
+
readonly kind: "complete";
|
|
51
|
+
readonly data: JsonValue;
|
|
52
|
+
} | {
|
|
53
|
+
readonly kind: "fail";
|
|
54
|
+
readonly data: JsonValue;
|
|
55
|
+
} | {
|
|
56
|
+
readonly kind: "cancel";
|
|
57
|
+
};
|
|
58
|
+
/** Task capability passed only to tools declared with `execution: "background"`. */
|
|
59
|
+
export interface TaskExec {
|
|
60
|
+
/**
|
|
61
|
+
* The sibling background calls admitted in the same step. The only view a
|
|
62
|
+
* tool has of what launched alongside it, for enforcing batch-wide
|
|
63
|
+
* invariants before delegating.
|
|
64
|
+
*/
|
|
65
|
+
readonly batch: readonly BackgroundToolCall[];
|
|
66
|
+
/**
|
|
67
|
+
* The task-private address for reporting lifecycle changes back to this
|
|
68
|
+
* task. Hand it to the external executor so completion routes to the task
|
|
69
|
+
* directly instead of through the (already finished) tool call.
|
|
70
|
+
*/
|
|
71
|
+
readonly binding: TaskBinding;
|
|
72
|
+
/**
|
|
73
|
+
* Snapshot of the harness session at step start, for reading context.
|
|
74
|
+
* Mutating it changes nothing durable: session writes belong to the
|
|
75
|
+
* runtime, keyed off the executor binding at step commit.
|
|
76
|
+
*/
|
|
77
|
+
readonly session: HarnessSession;
|
|
78
|
+
/**
|
|
79
|
+
* Delivers progress or a terminal command to this task's inbox from the same
|
|
80
|
+
* process, for executors that outlive `execute` in-memory (e.g. a callback firing
|
|
81
|
+
* after delegation). Call it only after `execute` returned `delegated(...)`
|
|
82
|
+
* — the runtime settles non-delegated returns itself, and a second terminal
|
|
83
|
+
* command is refused. Not restart-safe: an in-process callback dies with
|
|
84
|
+
* the process; the persisted executor binding remains the durable
|
|
85
|
+
* cancellation path. Throws when the task no longer accepts commands
|
|
86
|
+
* (already terminal).
|
|
87
|
+
*/
|
|
88
|
+
readonly send: (command: TaskSendCommand) => Promise<void>;
|
|
89
|
+
/** The durable task backing this call; its identity outlives `execute`. */
|
|
90
|
+
readonly task: BackgroundTask;
|
|
91
|
+
/**
|
|
92
|
+
* Builds the `TaskDelegated` sentinel to return from `execute`. Centralizes
|
|
93
|
+
* receipt stamping so every receipt carries this task's `taskId` and
|
|
94
|
+
* `status: "working"` — tools cannot mint receipts for tasks they don't own.
|
|
95
|
+
*/
|
|
96
|
+
delegated<TData extends JsonObject>(input: {
|
|
97
|
+
readonly executor: TaskExecutorBinding;
|
|
98
|
+
readonly receipt: TData;
|
|
99
|
+
}): TaskDelegated<TData>;
|
|
100
|
+
}
|
|
101
|
+
export declare function createTaskDelegated<TData extends JsonObject>(input: {
|
|
102
|
+
readonly binding: TaskBinding;
|
|
103
|
+
readonly executor: TaskExecutorBinding;
|
|
104
|
+
readonly receipt: TData;
|
|
105
|
+
}): TaskDelegated<TData>;
|
|
106
|
+
export declare function isTaskDelegated(value: unknown): value is TaskDelegated;
|
|
107
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const TASK_DELEGATED_KIND=`eve:task-delegated`;function createTaskDelegated(e){return{executor:e.executor,kind:TASK_DELEGATED_KIND,receipt:{...e.receipt,status:`working`,taskId:e.binding.taskId}}}function isTaskDelegated(e){return typeof e==`object`&&!!e&&`kind`in e&&e.kind===TASK_DELEGATED_KIND}export{createTaskDelegated,isTaskDelegated};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { SessionStateMap } from "#harness/types.js";
|
|
2
|
+
export declare const TASK_DELIVERY_CONTEXT_LABEL = "[Task state]";
|
|
3
|
+
export declare const TASK_DELIVERY_PENDING_INSTRUCTION = "Background task control: incomplete cohort\nThis framework-authored instruction overrides any earlier instruction to report, summarize, acknowledge, or otherwise handle background results.\n\nThe accompanying [Task state] message is runtime-authored and lists tasks started by the same parent turn. At least one of those tasks is still pending, so the combined report is not ready.\n\nAction:\n- You may call tools only if the newly delivered task result requires immediate action.\n- Otherwise, take no action.\n\nDelivery:\n- Do not report completed tasks or partial results.\n- Do not provide progress, status, an acknowledgement, or a waiting message.\n- After any necessary tool calls, your entire final text response must be exactly <eve-empty-delivery/> and no other text.\n\nIncorrect: \"Two of three tasks have completed.\"\nIncorrect: \"Still waiting for the remaining task.\"\nCorrect: <eve-empty-delivery/>";
|
|
4
|
+
export declare const TASK_DELIVERY_SETTLED_INSTRUCTION = "Background task reporting\nThis turn was triggered by background task activity. The accompanying [Task state] message is runtime-authored and lists tasks started by the same parent turn, all settled, with every available terminal output. Do not reply with <eve-empty-delivery/>. Send one user-facing response that combines their useful results.";
|
|
5
|
+
/** Returns model context and cohort phase for tasks started by the same parent turn as this delivery. */
|
|
6
|
+
export declare function resolveTaskDeliveryContext(input: {
|
|
7
|
+
readonly state: SessionStateMap | undefined;
|
|
8
|
+
readonly taskDeliveryId: string;
|
|
9
|
+
}): {
|
|
10
|
+
readonly context: string;
|
|
11
|
+
readonly phase: "pending" | "settled";
|
|
12
|
+
} | undefined;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import{getSessionTaskIndex}from"#tasks/session-index.js";import{EMPTY_DELIVERY_SENTINEL}from"#shared/empty-delivery.js";const TASK_DELIVERY_CONTEXT_LABEL=`[Task state]`,TASK_DELIVERY_PENDING_INSTRUCTION=`Background task control: incomplete cohort
|
|
2
|
+
This framework-authored instruction overrides any earlier instruction to report, summarize, acknowledge, or otherwise handle background results.
|
|
3
|
+
|
|
4
|
+
The accompanying ${TASK_DELIVERY_CONTEXT_LABEL} message is runtime-authored and lists tasks started by the same parent turn. At least one of those tasks is still pending, so the combined report is not ready.
|
|
5
|
+
|
|
6
|
+
Action:
|
|
7
|
+
- You may call tools only if the newly delivered task result requires immediate action.
|
|
8
|
+
- Otherwise, take no action.
|
|
9
|
+
|
|
10
|
+
Delivery:
|
|
11
|
+
- Do not report completed tasks or partial results.
|
|
12
|
+
- Do not provide progress, status, an acknowledgement, or a waiting message.
|
|
13
|
+
- After any necessary tool calls, your entire final text response must be exactly ${EMPTY_DELIVERY_SENTINEL} and no other text.
|
|
14
|
+
|
|
15
|
+
Incorrect: "Two of three tasks have completed."
|
|
16
|
+
Incorrect: "Still waiting for the remaining task."
|
|
17
|
+
Correct: ${EMPTY_DELIVERY_SENTINEL}`,TASK_DELIVERY_SETTLED_INSTRUCTION=`Background task reporting\nThis turn was triggered by background task activity. The accompanying ${TASK_DELIVERY_CONTEXT_LABEL} message is runtime-authored and lists tasks started by the same parent turn, all settled, with every available terminal output. Do not reply with ${EMPTY_DELIVERY_SENTINEL}. Send one user-facing response that combines their useful results.`;function resolveTaskDeliveryContext(t){let n=getSessionTaskIndex(t.state),r=n.find(e=>t.taskDeliveryId.startsWith(`${e.taskId}:`));if(r===void 0)return;let i=n.filter(e=>e.createdByTurnId===r.createdByTurnId),a=i.every(e=>e.terminalView!==void 0),o=i.map(e=>({name:e.metadata.name,output:a?e.terminalView?.lastOutput:void 0,status:e.terminalView?.status??`pending`,taskId:e.taskId}));return{context:`${TASK_DELIVERY_CONTEXT_LABEL}\n${JSON.stringify({tasks:o})}`,phase:a?`settled`:`pending`}}export{TASK_DELIVERY_CONTEXT_LABEL,TASK_DELIVERY_PENDING_INSTRUCTION,TASK_DELIVERY_SETTLED_INSTRUCTION,resolveTaskDeliveryContext};
|
package/dist/src/tasks/json.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import type { JsonValue } from "#shared/json.js";
|
|
|
3
3
|
import type { TaskView } from "#tasks/types.js";
|
|
4
4
|
/** Model-visible task shape. Unlisted private fields are stripped by zod. */
|
|
5
5
|
declare const taskViewJsonSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
6
|
-
metadata: z.ZodObject<{
|
|
6
|
+
metadata: z.ZodUnion<readonly [z.ZodObject<{
|
|
7
7
|
agentId: z.ZodString;
|
|
8
8
|
kind: z.ZodLiteral<"subagent">;
|
|
9
9
|
mode: z.ZodEnum<{
|
|
@@ -11,11 +11,14 @@ declare const taskViewJsonSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
11
11
|
remote: "remote";
|
|
12
12
|
}>;
|
|
13
13
|
name: z.ZodString;
|
|
14
|
-
}, z.core.$strip
|
|
14
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
15
|
+
kind: z.ZodString;
|
|
16
|
+
name: z.ZodString;
|
|
17
|
+
}, z.core.$strip>]>;
|
|
15
18
|
taskId: z.ZodString;
|
|
16
19
|
status: z.ZodLiteral<"working">;
|
|
17
20
|
}, z.core.$strip>, z.ZodObject<{
|
|
18
|
-
metadata: z.ZodObject<{
|
|
21
|
+
metadata: z.ZodUnion<readonly [z.ZodObject<{
|
|
19
22
|
agentId: z.ZodString;
|
|
20
23
|
kind: z.ZodLiteral<"subagent">;
|
|
21
24
|
mode: z.ZodEnum<{
|
|
@@ -23,12 +26,15 @@ declare const taskViewJsonSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
23
26
|
remote: "remote";
|
|
24
27
|
}>;
|
|
25
28
|
name: z.ZodString;
|
|
26
|
-
}, z.core.$strip
|
|
29
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
30
|
+
kind: z.ZodString;
|
|
31
|
+
name: z.ZodString;
|
|
32
|
+
}, z.core.$strip>]>;
|
|
27
33
|
taskId: z.ZodString;
|
|
28
34
|
inputRequests: z.ZodReadonly<z.ZodArray<z.ZodType<JsonValue, unknown, z.core.$ZodTypeInternals<JsonValue, unknown>>>>;
|
|
29
35
|
status: z.ZodLiteral<"input_required">;
|
|
30
36
|
}, z.core.$strip>, z.ZodObject<{
|
|
31
|
-
metadata: z.ZodObject<{
|
|
37
|
+
metadata: z.ZodUnion<readonly [z.ZodObject<{
|
|
32
38
|
agentId: z.ZodString;
|
|
33
39
|
kind: z.ZodLiteral<"subagent">;
|
|
34
40
|
mode: z.ZodEnum<{
|
|
@@ -36,7 +42,10 @@ declare const taskViewJsonSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
36
42
|
remote: "remote";
|
|
37
43
|
}>;
|
|
38
44
|
name: z.ZodString;
|
|
39
|
-
}, z.core.$strip
|
|
45
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
46
|
+
kind: z.ZodString;
|
|
47
|
+
name: z.ZodString;
|
|
48
|
+
}, z.core.$strip>]>;
|
|
40
49
|
taskId: z.ZodString;
|
|
41
50
|
lastOutput: z.ZodObject<{
|
|
42
51
|
data: z.ZodType<JsonValue, unknown, z.core.$ZodTypeInternals<JsonValue, unknown>>;
|
|
@@ -44,7 +53,7 @@ declare const taskViewJsonSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
44
53
|
}, z.core.$strip>;
|
|
45
54
|
status: z.ZodLiteral<"completed">;
|
|
46
55
|
}, z.core.$strip>, z.ZodObject<{
|
|
47
|
-
metadata: z.ZodObject<{
|
|
56
|
+
metadata: z.ZodUnion<readonly [z.ZodObject<{
|
|
48
57
|
agentId: z.ZodString;
|
|
49
58
|
kind: z.ZodLiteral<"subagent">;
|
|
50
59
|
mode: z.ZodEnum<{
|
|
@@ -52,7 +61,10 @@ declare const taskViewJsonSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
52
61
|
remote: "remote";
|
|
53
62
|
}>;
|
|
54
63
|
name: z.ZodString;
|
|
55
|
-
}, z.core.$strip
|
|
64
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
65
|
+
kind: z.ZodString;
|
|
66
|
+
name: z.ZodString;
|
|
67
|
+
}, z.core.$strip>]>;
|
|
56
68
|
taskId: z.ZodString;
|
|
57
69
|
lastOutput: z.ZodObject<{
|
|
58
70
|
data: z.ZodType<JsonValue, unknown, z.core.$ZodTypeInternals<JsonValue, unknown>>;
|
|
@@ -60,7 +72,7 @@ declare const taskViewJsonSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
60
72
|
}, z.core.$strip>;
|
|
61
73
|
status: z.ZodLiteral<"failed">;
|
|
62
74
|
}, z.core.$strip>, z.ZodObject<{
|
|
63
|
-
metadata: z.ZodObject<{
|
|
75
|
+
metadata: z.ZodUnion<readonly [z.ZodObject<{
|
|
64
76
|
agentId: z.ZodString;
|
|
65
77
|
kind: z.ZodLiteral<"subagent">;
|
|
66
78
|
mode: z.ZodEnum<{
|
|
@@ -68,7 +80,10 @@ declare const taskViewJsonSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
68
80
|
remote: "remote";
|
|
69
81
|
}>;
|
|
70
82
|
name: z.ZodString;
|
|
71
|
-
}, z.core.$strip
|
|
83
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
84
|
+
kind: z.ZodString;
|
|
85
|
+
name: z.ZodString;
|
|
86
|
+
}, z.core.$strip>]>;
|
|
72
87
|
taskId: z.ZodString;
|
|
73
88
|
status: z.ZodLiteral<"cancelled">;
|
|
74
89
|
}, z.core.$strip>], "status">;
|
package/dist/src/tasks/json.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{z}from"#compiled/zod/index.js";import{jsonValueSchema}from"#shared/json-schemas.js";const taskMetadataJsonSchema=z.object({agentId:z.string(),kind:z.literal(`subagent`),mode:z.enum([`local`,`remote`]),name:z.string()}),taskOutputJsonSchema=z.object({data:jsonValueSchema,type:z.enum([`result`,`error`])}),taskViewJsonBaseShape={metadata:taskMetadataJsonSchema,taskId:z.string()},taskViewJsonSchema=z.discriminatedUnion(`status`,[z.object({...taskViewJsonBaseShape,status:z.literal(`working`)}),z.object({...taskViewJsonBaseShape,inputRequests:z.array(jsonValueSchema).readonly(),status:z.literal(`input_required`)}),z.object({...taskViewJsonBaseShape,lastOutput:taskOutputJsonSchema.extend({type:z.literal(`result`)}),status:z.literal(`completed`)}),z.object({...taskViewJsonBaseShape,lastOutput:taskOutputJsonSchema.extend({type:z.literal(`error`)}),status:z.literal(`failed`)}),z.object({...taskViewJsonBaseShape,status:z.literal(`cancelled`)})]);function taskViewToJson(e){return taskViewJsonSchema.parse(e)}function taskViewsToJson(e){return{tasks:e.map(e=>taskViewToJson(e))}}export{taskViewToJson,taskViewsToJson};
|
|
1
|
+
import{z}from"#compiled/zod/index.js";import{jsonValueSchema}from"#shared/json-schemas.js";import{readSubagentTaskMetadata}from"#tasks/types.js";const taskMetadataJsonSchema=z.union([z.object({agentId:z.string(),kind:z.literal(`subagent`),mode:z.enum([`local`,`remote`]),name:z.string()}),z.object({kind:z.string(),name:z.string()})]),taskOutputJsonSchema=z.object({data:jsonValueSchema,type:z.enum([`result`,`error`])}),taskViewJsonBaseShape={metadata:taskMetadataJsonSchema,taskId:z.string()},taskViewJsonSchema=z.discriminatedUnion(`status`,[z.object({...taskViewJsonBaseShape,status:z.literal(`working`)}),z.object({...taskViewJsonBaseShape,inputRequests:z.array(jsonValueSchema).readonly(),status:z.literal(`input_required`)}),z.object({...taskViewJsonBaseShape,lastOutput:taskOutputJsonSchema.extend({type:z.literal(`result`)}),status:z.literal(`completed`)}),z.object({...taskViewJsonBaseShape,lastOutput:taskOutputJsonSchema.extend({type:z.literal(`error`)}),status:z.literal(`failed`)}),z.object({...taskViewJsonBaseShape,status:z.literal(`cancelled`)})]);function taskViewToJson(e){let t=readSubagentTaskMetadata(e),n=t===void 0?e.metadata:{agentId:t.agentId,kind:t.kind,mode:t.mode,name:t.name};return taskViewJsonSchema.parse({...e,metadata:n})}function taskViewsToJson(e){return{tasks:e.map(e=>taskViewToJson(e))}}export{taskViewToJson,taskViewsToJson};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { HarnessSession, SessionStateMap } from "#harness/types.js";
|
|
2
|
-
import type {
|
|
2
|
+
import type { TaskExecutorBinding } from "#shared/tool-task.js";
|
|
3
|
+
import { type DurableTaskMetadata, type TaskView } from "#tasks/types.js";
|
|
3
4
|
/**
|
|
4
5
|
* Session-state key for the parent's live-task index.
|
|
5
6
|
*
|
|
@@ -27,8 +28,9 @@ export interface SessionTaskIndexEntry {
|
|
|
27
28
|
readonly taskInboxToken: string;
|
|
28
29
|
readonly createdByStepIndex?: number;
|
|
29
30
|
readonly createdByTurnId: string;
|
|
30
|
-
readonly
|
|
31
|
-
readonly
|
|
31
|
+
readonly executor?: TaskExecutorBinding;
|
|
32
|
+
readonly metadata: DurableTaskMetadata;
|
|
33
|
+
readonly operationId?: string;
|
|
32
34
|
}
|
|
33
35
|
/**
|
|
34
36
|
* Reads and validates the task index from session state.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{z}from"#compiled/zod/index.js";const SESSION_TASKS_STATE_KEY=`eve.tasks`,taskMetadataSchema=z.strictObject({agentId:z.string().min(1),kind:z.literal(`subagent`),mode:z.enum([`local`,`remote`]),name:z.string().min(1)}),taskViewBaseShape={executor:z.strictObject({childSessionId:z.string().min(1).optional(),childTurnId:z.string().min(1).optional(),lifecycle:z.enum([`parked`,`terminal`]).optional()}).optional(),metadata:taskMetadataSchema,taskId:z.string().min(1),usage:z.strictObject({cacheReadTokens:z.number().nonnegative(),cacheWriteTokens:z.number().nonnegative(),inputTokens:z.number().nonnegative(),outputTokens:z.number().nonnegative()}).optional()},taskViewSchema=z.discriminatedUnion(`status`,[z.strictObject({...taskViewBaseShape,lastOutput:z.strictObject({data:z.custom(),type:z.literal(`result`)}),status:z.literal(`completed`)}),z.strictObject({...taskViewBaseShape,lastOutput:z.strictObject({data:z.custom(),type:z.literal(`error`)}),status:z.literal(`failed`)}),z.strictObject({...taskViewBaseShape,status:z.literal(`cancelled`)})]),sessionTaskIndexEntrySchema=z.strictObject({taskInboxToken:z.string().min(1),createdByStepIndex:z.number().int().nonnegative().optional(),createdByTurnId:z.string().min(1),metadata:taskMetadataSchema,operationId:z.string().min(1),taskId:z.string().min(1),taskRunId:z.string().min(1),terminalView:taskViewSchema.optional()}),sessionTaskIndexSchema=z.strictObject({tasks:z.array(sessionTaskIndexEntrySchema)}).refine(e=>new Set(e.tasks.map(e=>e.taskId)).size===e.tasks.length,{message:`Task ids must be unique.`}).refine(e=>e.tasks.every(e=>e.terminalView===void 0||e.terminalView.taskId===e.taskId&&sameTaskMetadata(e.terminalView.metadata,e.metadata)),{message:`Cached terminal views must match their task index entry.`});function getSessionTaskIndex(e){let
|
|
1
|
+
import{z}from"#compiled/zod/index.js";import{sameTaskMetadata}from"#tasks/types.js";const SESSION_TASKS_STATE_KEY=`eve.tasks`,taskMetadataSchema=z.union([z.strictObject({agentId:z.string().min(1),kind:z.literal(`subagent`),mode:z.enum([`local`,`remote`]),name:z.string().min(1)}),z.strictObject({kind:z.string().min(1),name:z.string().min(1)})]),taskViewBaseShape={executor:z.strictObject({binding:z.strictObject({data:z.record(z.string(),z.custom()),kind:z.string().min(1)}).optional(),childSessionId:z.string().min(1).optional(),childTurnId:z.string().min(1).optional(),lifecycle:z.enum([`parked`,`terminal`]).optional()}).optional(),metadata:taskMetadataSchema,taskId:z.string().min(1),usage:z.strictObject({cacheReadTokens:z.number().nonnegative(),cacheWriteTokens:z.number().nonnegative(),inputTokens:z.number().nonnegative(),outputTokens:z.number().nonnegative()}).optional()},taskViewSchema=z.discriminatedUnion(`status`,[z.strictObject({...taskViewBaseShape,lastOutput:z.strictObject({data:z.custom(),type:z.literal(`result`)}),status:z.literal(`completed`)}),z.strictObject({...taskViewBaseShape,lastOutput:z.strictObject({data:z.custom(),type:z.literal(`error`)}),status:z.literal(`failed`)}),z.strictObject({...taskViewBaseShape,status:z.literal(`cancelled`)})]),sessionTaskIndexEntrySchema=z.strictObject({taskInboxToken:z.string().min(1),createdByStepIndex:z.number().int().nonnegative().optional(),createdByTurnId:z.string().min(1),executor:z.strictObject({data:z.record(z.string(),z.custom()),kind:z.string().min(1)}).optional(),metadata:taskMetadataSchema,operationId:z.string().min(1).optional(),taskId:z.string().min(1),taskRunId:z.string().min(1),terminalView:taskViewSchema.optional()}),sessionTaskIndexSchema=z.strictObject({tasks:z.array(sessionTaskIndexEntrySchema)}).refine(e=>new Set(e.tasks.map(e=>e.taskId)).size===e.tasks.length,{message:`Task ids must be unique.`}).refine(e=>e.tasks.every(e=>e.terminalView===void 0||e.terminalView.taskId===e.taskId&&sameTaskMetadata(e.terminalView.metadata,e.metadata)),{message:`Cached terminal views must match their task index entry.`});function getSessionTaskIndex(e){let t=e?.[SESSION_TASKS_STATE_KEY];if(t===void 0)return[];let n=sessionTaskIndexSchema.safeParse(t);if(!n.success)throw Error(`Corrupt task index under session state key "${SESSION_TASKS_STATE_KEY}": ${n.error.message}`);return n.data.tasks}function cacheTerminalTaskView(e,n){if(!isValidTerminalView(n))throw Error(`Cannot cache invalid terminal task "${n.taskId}".`);let r=getSessionTaskIndex(e),i=r.findIndex(e=>e.taskId===n.taskId);if(i<0)return e;if(!sameTaskMetadata(r[i].metadata,n.metadata))throw Error(`Task view metadata does not match index entry "${n.taskId}".`);let a=[...r];return a[i]={...a[i],terminalView:n},{...e,[SESSION_TASKS_STATE_KEY]:{tasks:a}}}function isValidTerminalView(e){if(e.inputRequests!==void 0)return!1;switch(e.status){case`completed`:return e.lastOutput?.type===`result`;case`failed`:return e.lastOutput?.type===`error`;case`cancelled`:return e.lastOutput===void 0;case`working`:return!1}}function findSessionTaskEntry(e,t){return getSessionTaskIndex(e).find(e=>e.taskId===t)}function recordSessionTask(e,t){let n=[...getSessionTaskIndex(e.state).filter(e=>e.taskId!==t.taskId),t];return{...e,state:{...e.state,[SESSION_TASKS_STATE_KEY]:{tasks:n}}}}export{SESSION_TASKS_STATE_KEY,cacheTerminalTaskView,findSessionTaskEntry,getSessionTaskIndex,recordSessionTask};
|
|
@@ -1,23 +1,58 @@
|
|
|
1
1
|
import type { TaskCommand, TaskView } from "#tasks/types.js";
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
3
|
+
* Action taken on one command applied to a task view.
|
|
4
4
|
*
|
|
5
|
-
* - `accepted`: the
|
|
5
|
+
* - `accepted`: the view changed; the new view must be appended.
|
|
6
6
|
* - `noop`: the command is recognized and benign (idempotent cancel,
|
|
7
7
|
* stale answer); nothing changed and nothing is appended.
|
|
8
8
|
* - `rejected`: the command is invalid for the current status; the
|
|
9
9
|
* reason is diagnostic only.
|
|
10
10
|
*/
|
|
11
11
|
type TaskTransitionResult = {
|
|
12
|
-
readonly
|
|
12
|
+
readonly action: "accepted";
|
|
13
13
|
readonly view: TaskView;
|
|
14
14
|
} | {
|
|
15
|
-
readonly
|
|
15
|
+
readonly action: "noop";
|
|
16
16
|
readonly view: TaskView;
|
|
17
17
|
} | {
|
|
18
|
-
readonly
|
|
18
|
+
readonly action: "rejected";
|
|
19
19
|
readonly view: TaskView;
|
|
20
20
|
readonly reason: string;
|
|
21
21
|
};
|
|
22
|
+
/**
|
|
23
|
+
* Pure transition function for the task lifecycle:
|
|
24
|
+
*
|
|
25
|
+
* ```text
|
|
26
|
+
* working <-> input_required
|
|
27
|
+
* | |
|
|
28
|
+
* +-----> completed
|
|
29
|
+
* +-----> failed
|
|
30
|
+
* +-----> cancelled
|
|
31
|
+
* ```
|
|
32
|
+
*
|
|
33
|
+
* Terminal states are final: a late child result can never revive a
|
|
34
|
+
* cancelled task, and repeated cancellation is idempotent. The durable
|
|
35
|
+
* task run is the only caller that persists accepted views, which is
|
|
36
|
+
* what serializes competing completion, cancellation, and input
|
|
37
|
+
* transitions.
|
|
38
|
+
*
|
|
39
|
+
* Orthogonal to the status, the view carries private executor state
|
|
40
|
+
* (`TaskExecutorState`) with its own lifecycle. These commands move
|
|
41
|
+
* executor fields, never the status above:
|
|
42
|
+
*
|
|
43
|
+
* ```text
|
|
44
|
+
* binding: unset --bind-------> bound (replay noop, conflict rejected)
|
|
45
|
+
* address: unset --start-turn-> session pinned (turn id updated per delivery)
|
|
46
|
+
* verdict: unset --complete/fail/cancel/settle-executor-> parked | terminal
|
|
47
|
+
* ```
|
|
48
|
+
*
|
|
49
|
+
* - `bind` writes the executor binding exactly once: replaying the
|
|
50
|
+
* same binding is a noop, a different one is rejected.
|
|
51
|
+
* - `start-turn` records the child session/turn ids used to address
|
|
52
|
+
* the executor, rejecting a child-session mismatch.
|
|
53
|
+
* - Terminal commands and a late `settle-executor` record the child's
|
|
54
|
+
* lifecycle verdict: `parked` means the child session survived and
|
|
55
|
+
* can take another delivery, `terminal` means it ended with the turn.
|
|
56
|
+
*/
|
|
22
57
|
export declare function applyTaskTransition(view: TaskView, command: TaskCommand): TaskTransitionResult;
|
|
23
58
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{isTerminalTaskStatus,readTaskInputRequestId}from"#tasks/types.js";function terminalView(e,t,n){let r={executor:t.lifecycle===void 0?e.executor:{...e.executor,lifecycle:t.lifecycle},metadata:e.metadata,taskId:e.taskId};switch(t.usage!==void 0&&(r.usage=t.usage),n.status){case`completed`:return{...r,lastOutput:n.lastOutput,status:`completed`};case`failed`:return{...r,lastOutput:n.lastOutput,status:`failed`};case`cancelled`:return{...r,status:`cancelled`}}}function applyTaskTransition(
|
|
1
|
+
import{jsonValuesEqual}from"#shared/json.js";import{isTerminalTaskStatus,readTaskInputRequestId}from"#tasks/types.js";function terminalView(e,t,n){let r={executor:t.lifecycle===void 0?e.executor:{...e.executor,lifecycle:t.lifecycle},metadata:e.metadata,taskId:e.taskId};switch(t.usage!==void 0&&(r.usage=t.usage),n.status){case`completed`:return{...r,lastOutput:n.lastOutput,status:`completed`};case`failed`:return{...r,lastOutput:n.lastOutput,status:`failed`};case`cancelled`:return{...r,status:`cancelled`}}}function applyTaskTransition(r,i){if(i.kind===`bind`){let t=r.executor?.binding;return t!==void 0&&t.kind===i.executor.kind&&jsonValuesEqual(t.data,i.executor.data)?{action:`noop`,view:r}:t===void 0?{action:`accepted`,view:{...r,executor:{...r.executor,binding:i.executor}}}:{action:`rejected`,reason:`Task "${r.taskId}" already has an executor binding.`,view:r}}if(isTerminalTaskStatus(r.status)){if(i.kind===`settle-executor`){let e={...r.executor,lifecycle:`terminal`};if(sameUsage(r.usage,i.usage)&&r.executor?.lifecycle===`terminal`)return{action:`noop`,view:r};let t={...r,executor:e};return{action:`accepted`,view:i.usage===void 0?t:{...t,usage:i.usage}}}return i.kind===`cancel`&&r.status===`cancelled`?{action:`noop`,view:r}:{action:`rejected`,reason:`Task "${r.taskId}" is already ${r.status}; "${i.kind}" cannot change a terminal task.`,view:r}}switch(i.kind){case`complete`:return{action:`accepted`,view:terminalView(r,i,{lastOutput:{data:i.data,type:`result`},status:`completed`})};case`fail`:case`reject-dispatch`:return{action:`accepted`,view:terminalView(r,i,{lastOutput:{data:i.data,type:`error`},status:`failed`})};case`cancel`:return{action:`accepted`,view:terminalView(r,i,{status:`cancelled`})};case`settle-executor`:return{action:`rejected`,reason:`Task "${r.taskId}" is not terminal; usage settles with its terminal command.`,view:r};case`require-authorization`:{let e={blockedOn:`authorization`,requestId:i.requestId};return r.status===`input_required`?r.inputRequests.some(e=>readTaskInputRequestId(e)===i.requestId)?{action:`noop`,view:r}:{action:`accepted`,view:{...r,inputRequests:[...r.inputRequests,e]}}:{action:`accepted`,view:{inputRequests:[e],executor:r.executor,metadata:r.metadata,status:`input_required`,taskId:r.taskId}}}case`require-input`:return isValidInputRequestBatch(i.inputRequests)?{action:`accepted`,view:{inputRequests:i.inputRequests,executor:r.executor,metadata:r.metadata,status:`input_required`,taskId:r.taskId}}:{action:`rejected`,reason:`Task "${r.taskId}" received an invalid input request batch.`,view:r};case`ready`:return{action:`accepted`,view:r};case`answered`:{if(r.status!==`input_required`)return{action:`noop`,view:r};let e=new Set(i.requestIds),t=r.inputRequests,a=t.filter(t=>{let r=readTaskInputRequestId(t);return r===void 0||!e.has(r)});return a.length===t.length?{action:`noop`,view:r}:a.length>0?{action:`accepted`,view:{inputRequests:a,executor:r.executor,metadata:r.metadata,status:`input_required`,taskId:r.taskId}}:{action:`accepted`,view:{executor:r.executor,metadata:r.metadata,status:`working`,taskId:r.taskId}}}case`start-turn`:return i.taskId===r.taskId?r.executor?.childSessionId!==void 0&&r.executor.childSessionId!==i.childSessionId?{action:`rejected`,reason:`Task child session "${i.childSessionId}" does not match "${r.executor.childSessionId}".`,view:r}:r.executor?.childSessionId===i.childSessionId&&r.executor.childTurnId===i.childTurnId?{action:`noop`,view:r}:{action:`accepted`,view:{...r,executor:{...r.executor,childSessionId:i.childSessionId,childTurnId:i.childTurnId}}}:{action:`rejected`,reason:`Task turn identity "${i.taskId}" does not match "${r.taskId}".`,view:r}}}function isValidInputRequestBatch(e){if(e.length===0)return!1;let t=e.map(readTaskInputRequestId);return t.every(e=>e!==void 0&&e.length>0)&&new Set(t).size===t.length}function sameUsage(e,t){return e===void 0||t===void 0?e===t:e?.cacheReadTokens===t.cacheReadTokens&&e.cacheWriteTokens===t.cacheWriteTokens&&e.inputTokens===t.inputTokens&&e.outputTokens===t.outputTokens}export{applyTaskTransition};
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { AgentAddress, AgentIdentity } from "#harness/handles/store.js";
|
|
2
|
+
import { type JsonValue } from "#shared/json.js";
|
|
3
|
+
import type { TaskExecutorBinding } from "#shared/tool-task.js";
|
|
2
4
|
import type { SubagentAuthorizationEvent } from "#channel/types.js";
|
|
3
5
|
/**
|
|
4
6
|
* Task lifecycle contract for `experimental.tasks`.
|
|
@@ -33,10 +35,45 @@ export interface TaskMetadata {
|
|
|
33
35
|
/** Authored subagent name the parent dispatched. */
|
|
34
36
|
readonly name: string;
|
|
35
37
|
}
|
|
38
|
+
export type SubagentTaskMetadata = TaskMetadata;
|
|
39
|
+
/** Executor-neutral metadata retained by a non-subagent durable task. */
|
|
40
|
+
export interface BackgroundTaskMetadata {
|
|
41
|
+
readonly kind: string;
|
|
42
|
+
readonly name: string;
|
|
43
|
+
}
|
|
44
|
+
export type DurableTaskMetadata = BackgroundTaskMetadata | TaskMetadata;
|
|
45
|
+
export declare function createSubagentTaskMetadata(metadata: Omit<SubagentTaskMetadata, "kind" | "name"> & {
|
|
46
|
+
readonly name: string;
|
|
47
|
+
}): SubagentTaskMetadata;
|
|
48
|
+
export declare function readSubagentTaskMetadata(task: {
|
|
49
|
+
readonly executor?: TaskExecutorBinding | TaskExecutorState;
|
|
50
|
+
readonly metadata: DurableTaskMetadata;
|
|
51
|
+
}): SubagentTaskMetadata | undefined;
|
|
52
|
+
/**
|
|
53
|
+
* Durable subagent executor binding payload: the child's stable identity and
|
|
54
|
+
* private delivery address, copied from the parent's agent handle store at
|
|
55
|
+
* delegation time. Every field derives deterministically from the
|
|
56
|
+
* originating call (operation-hashed id, dispatch-chosen continuation
|
|
57
|
+
* token), so a replayed delegation produces a deep-equal binding — the
|
|
58
|
+
* equality the task run's `bind` replay check compares.
|
|
59
|
+
*/
|
|
60
|
+
export interface SubagentExecutorData {
|
|
61
|
+
readonly address: AgentAddress;
|
|
62
|
+
readonly identity: AgentIdentity;
|
|
63
|
+
}
|
|
64
|
+
export declare function createSubagentExecutorBinding(executor: SubagentExecutorData): TaskExecutorBinding;
|
|
65
|
+
export declare function readSubagentExecutor(executor: TaskExecutorBinding | TaskExecutorState | undefined): SubagentExecutorData | undefined;
|
|
66
|
+
export declare function sameTaskMetadata(left: DurableTaskMetadata, right: DurableTaskMetadata): boolean;
|
|
36
67
|
/** Private executor state retained for cancellation and address reconciliation. */
|
|
37
68
|
export interface TaskExecutorState {
|
|
69
|
+
/** Write-once executor address recorded by the `bind` command. */
|
|
70
|
+
readonly binding?: TaskExecutorBinding;
|
|
38
71
|
readonly childSessionId?: string;
|
|
39
72
|
readonly childTurnId?: string;
|
|
73
|
+
/**
|
|
74
|
+
* Child-session verdict from the last settled turn: `parked` survived
|
|
75
|
+
* and can take another delivery, `terminal` ended with the turn.
|
|
76
|
+
*/
|
|
40
77
|
readonly lifecycle?: "parked" | "terminal";
|
|
41
78
|
}
|
|
42
79
|
/**
|
|
@@ -92,7 +129,7 @@ export declare function readTaskInputRequestId(request: TaskInputRequest): strin
|
|
|
92
129
|
/** Fields shared by every durable task view. */
|
|
93
130
|
interface TaskViewBase {
|
|
94
131
|
readonly taskId: string;
|
|
95
|
-
readonly metadata:
|
|
132
|
+
readonly metadata: DurableTaskMetadata;
|
|
96
133
|
/** Private executor state; deliberately excluded from model-visible JSON. */
|
|
97
134
|
readonly executor?: TaskExecutorState;
|
|
98
135
|
/**
|
|
@@ -140,6 +177,9 @@ export type TaskView = TaskViewBase & ({
|
|
|
140
177
|
});
|
|
141
178
|
/** Commands accepted by the durable task run's transition function. */
|
|
142
179
|
export type TaskCommand = {
|
|
180
|
+
readonly executor: TaskExecutorBinding;
|
|
181
|
+
readonly kind: "bind";
|
|
182
|
+
} | {
|
|
143
183
|
readonly kind: "complete";
|
|
144
184
|
readonly data: JsonValue;
|
|
145
185
|
readonly lifecycle?: "parked" | "terminal";
|
|
@@ -260,8 +300,10 @@ export interface TaskInboundTurnStarted {
|
|
|
260
300
|
/** Intermediate progress sent by a running child to its parent agent. */
|
|
261
301
|
export interface TaskInboundUpdate {
|
|
262
302
|
readonly callId: string;
|
|
263
|
-
|
|
264
|
-
readonly
|
|
303
|
+
/** Executor-neutral monotonic index within {@link updateEpoch}. */
|
|
304
|
+
readonly updateIndex: number;
|
|
305
|
+
/** Executor-neutral epoch id used with {@link updateIndex} for update dedupe. */
|
|
306
|
+
readonly updateEpoch: string;
|
|
265
307
|
readonly kind: "task-update";
|
|
266
308
|
readonly message: string;
|
|
267
309
|
}
|
package/dist/src/tasks/types.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
function readTaskUsage(e){if(typeof e!=`object`||!e||Array.isArray(e))return;let t=readUsageAxis(e,`cacheReadTokens`),n=readUsageAxis(e,`cacheWriteTokens`),r=readUsageAxis(e,`inputTokens`),i=readUsageAxis(e,`outputTokens`);if(!(t===void 0||n===void 0||r===void 0||i===void 0))return{cacheReadTokens:t,cacheWriteTokens:n,inputTokens:r,outputTokens:i}}function readUsageAxis(e,t){let n=Reflect.get(e,t);return typeof n==`number`&&Number.isFinite(n)&&n>=0?n:void 0}const TASK_AUTHORIZATION_REQUEST_ID_PREFIX=`task:authorization`;function taskAuthorizationRequestId(
|
|
1
|
+
import{isJsonObjectValue}from"#shared/json.js";function createSubagentTaskMetadata(e){return{...e,kind:`subagent`}}function readSubagentTaskMetadata(e){if(e.metadata.kind===`subagent`&&`agentId`in e.metadata)return e.metadata;let t=readSubagentExecutor(e.executor);if(t!==void 0)return{agentId:t.identity.id,kind:`subagent`,mode:t.address.kind===`agent/remote`?`remote`:`local`,name:t.identity.name}}function createSubagentExecutorBinding(e){let{address:t,identity:n}=e;return{data:{address:{...t},identity:{id:n.id,name:n.name,nodeId:n.nodeId}},kind:`subagent`}}function readSubagentExecutor(e){let t=e!==void 0&&`kind`in e?e:e?.binding;if(t?.kind!==`subagent`)return;let n=readAgentIdentity(t.data.identity),r=readAgentAddress(t.data.address);return n===void 0||r===void 0?void 0:{address:r,identity:n}}function readAgentIdentity(t){if(t===void 0||!isJsonObjectValue(t))return;let{id:n,name:r,nodeId:i}=t;return typeof n==`string`&&typeof r==`string`&&typeof i==`string`?{id:n,name:r,nodeId:i}:void 0}function readAgentAddress(t){if(t===void 0||!isJsonObjectValue(t))return;let{callbackBaseUrl:n,continuationToken:r,kind:i,sessionId:a,url:o}=t;if(typeof a==`string`){if(i===`agent/local`||i===`agent/self`)return typeof r==`string`?{continuationToken:r,kind:i,sessionId:a}:void 0;if(i===`agent/remote`)return typeof o==`string`&&typeof n==`string`?{callbackBaseUrl:n,kind:i,sessionId:a,url:o}:void 0}}function sameTaskMetadata(e,t){if(e.kind!==t.kind||e.name!==t.name)return!1;let n=`agentId`in e,r=`agentId`in t;return n===r&&(!n||!r||e.agentId===t.agentId&&e.mode===t.mode)}function readTaskUsage(e){if(typeof e!=`object`||!e||Array.isArray(e))return;let t=readUsageAxis(e,`cacheReadTokens`),n=readUsageAxis(e,`cacheWriteTokens`),r=readUsageAxis(e,`inputTokens`),i=readUsageAxis(e,`outputTokens`);if(!(t===void 0||n===void 0||r===void 0||i===void 0))return{cacheReadTokens:t,cacheWriteTokens:n,inputTokens:r,outputTokens:i}}function readUsageAxis(e,t){let n=Reflect.get(e,t);return typeof n==`number`&&Number.isFinite(n)&&n>=0?n:void 0}const TASK_AUTHORIZATION_REQUEST_ID_PREFIX=`task:authorization`;function taskAuthorizationRequestId(e){return e.type===`approval.candidate`||e.type===`approval.settled`?`${TASK_AUTHORIZATION_REQUEST_ID_PREFIX}:${e.data.requestId}`:`${TASK_AUTHORIZATION_REQUEST_ID_PREFIX}:${e.data.attemptId??e.data.name}`}function readTaskInputRequestId(e){if(typeof e!=`object`||!e||Array.isArray(e))return;let t=Reflect.get(e,`requestId`);return typeof t==`string`?t:void 0}const TASK_VIEW_STREAM_NAMESPACE=`eve.task`;function isTerminalTaskStatus(e){return e===`completed`||e===`failed`||e===`cancelled`}function isReadyTaskStatus(e){return e===`input_required`||isTerminalTaskStatus(e)}export{TASK_VIEW_STREAM_NAMESPACE,createSubagentExecutorBinding,createSubagentTaskMetadata,isReadyTaskStatus,isTerminalTaskStatus,readSubagentExecutor,readSubagentTaskMetadata,readTaskInputRequestId,readTaskUsage,sameTaskMetadata,taskAuthorizationRequestId};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{ROOT_CONTEXT,SpanStatusCode,trace}from"#compiled/@opentelemetry/api/index.js";import{actionIdempotencyKey,attemptIdempotencyKey}from"#harness/instrumentation/lifecycle.js";import{contentAttribute}from"#tracing/agent-otel-content.js";import{setAgentUsage}from"#tracing/agent-otel-usage.js";function createAgentActionInstrumentation(
|
|
1
|
+
import{normalizeChannelAudience}from"#shared/channel-audience.js";import{ROOT_CONTEXT,SpanStatusCode,trace}from"#compiled/@opentelemetry/api/index.js";import{actionIdempotencyKey,attemptIdempotencyKey}from"#harness/instrumentation/lifecycle.js";import{contentAttribute}from"#tracing/agent-otel-content.js";import{setAgentUsage}from"#tracing/agent-otel-usage.js";import{isSampledTrace}from"#tracing/sampled-trace.js";import{withChannelAudience}from"#tracing/channel-audience-context.js";function createAgentActionInstrumentation(t){let n=new Map,onStarted=async r=>{let i=await t.resolveTraceContext(r);if(i===void 0||!isSampledTrace(i))return;let s=await t.stateStore.getAction(r.idempotencyKey)??{attemptIndex:r.scope.attemptIndex,callId:r.callId,channelAudience:normalizeChannelAudience(r.scope.channelAudience),inputAttribute:t.recordInputs?contentAttribute(r.input,!1):void 0,kind:r.kind,name:r.name,parent:{spanId:t.idGenerator.deriveSpanId(attemptIdempotencyKey(r.scope)),traceFlags:i.traceFlags,traceId:i.traceId},rootSessionId:r.scope.rootSessionId??r.scope.sessionId,sessionId:r.scope.sessionId,spanId:t.idGenerator.deriveSpanId(`action:${r.idempotencyKey}`),startTimeMs:Date.now(),stepIndex:r.scope.stepIndex,turnId:r.scope.turnId};await t.stateStore.setAction(r.idempotencyKey,s);let c=n.get(r.scope.attemptId)??new Set;c.add(r.idempotencyKey),n.set(r.scope.attemptId,c)},onTerminal=async e=>{let n=await t.stateStore.getAction(e.idempotencyKey);if(n!==void 0)try{let r=startSpan(n);if(r.setAttribute(`agent.action.outcome`,e.outcome),e.type===`action.failed`)e.errorCode!==void 0&&(r.setAttribute(`agent.action.error.code`,e.errorCode),r.setAttribute(`error.type`,e.errorCode)),recordError(r,e.error);else if(e.output.type===`error`)recordError(r,e.output.error);else if(e.usage!==void 0&&setAgentUsage(r,e.usage),t.recordOutputs){let t=contentAttribute(e.output.output,!1);t!==void 0&&r.setAttribute(`gen_ai.tool.call.result`,t)}r.end(e.acceptedAtMs)}finally{await t.stateStore.deleteAction(e.idempotencyKey),forget(e.idempotencyKey)}},startSpan=e=>{let n=t.idGenerator.withSpanId(e.spanId,()=>t.tracer.startSpan(`agent.action`,{attributes:{"agent.action.call_id":e.callId,"agent.action.kind":e.kind,"agent.action.name":e.name,"agent.framework.name":`eve`,"agent.framework.version":t.frameworkVersion,"agent.root.session.id":e.rootSessionId,"agent.session.id":e.sessionId,"agent.step.attempt":e.attemptIndex,"agent.step.index":e.stepIndex,"agent.turn.id":e.turnId},startTime:e.startTimeMs},contextFromActionState(e)));return e.inputAttribute!==void 0&&n.setAttribute(`gen_ai.tool.call.arguments`,e.inputAttribute),n};return{async contextFor(e,n,r){let a=actionIdempotencyKey(e,n,r),o=await t.stateStore.getAction(a);if(o!==void 0)return actionContext(o);let s=await t.stateStore.findAction(e,r);return s===void 0?void 0:actionContext(s)},deleteForSession:e=>t.stateStore.deleteActions(e),deleteForTurn:(e,n)=>t.stateStore.deleteActions(e,n),async failForAttempt(e,r){let i=n.get(e.attemptId);if(i!==void 0){n.delete(e.attemptId);for(let e of i){let n=await t.stateStore.getAction(e);if(n===void 0)continue;let i=startSpan(n);recordError(i,r),i.end(),await t.stateStore.deleteAction(e)}}},events:{"action.completed":onTerminal,"action.failed":onTerminal,"action.started":onStarted}};function forget(e){for(let[t,r]of n)r.delete(e),r.size===0&&n.delete(t)}}function actionContext(e){let n={isRemote:!1,spanId:e.spanId,traceFlags:e.parent.traceFlags,traceId:e.parent.traceId};return{context:withChannelAudience(trace.setSpan(ROOT_CONTEXT,trace.wrapSpanContext(n)),e.channelAudience),spanContext:n}}function contextFromActionState(e){return withChannelAudience(trace.setSpan(ROOT_CONTEXT,trace.wrapSpanContext({...e.parent,isRemote:!1})),e.channelAudience)}function recordError(e,t){t instanceof Error?(e.recordException(t),e.setStatus({code:SpanStatusCode.ERROR,message:t.message})):e.setStatus({code:SpanStatusCode.ERROR})}export{createAgentActionInstrumentation};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{ROOT_CONTEXT,SpanStatusCode,trace}from"#compiled/@opentelemetry/api/index.js";import{contentAttribute}from"#tracing/agent-otel-content.js";function createAgentApprovalInstrumentation(
|
|
1
|
+
import{normalizeChannelAudience}from"#shared/channel-audience.js";import{ROOT_CONTEXT,SpanStatusCode,trace}from"#compiled/@opentelemetry/api/index.js";import{contentAttribute}from"#tracing/agent-otel-content.js";function createAgentApprovalInstrumentation(n){return{"input.requested":async(t,r)=>{if(t.kind!==`tool-approval`||readState(r.state.get())!==void 0)return;let a=await n.actionContextFor(t.scope.sessionId,t.scope.turnId,t.action.callId);if(a===void 0)return;let o={actionCallId:t.action.callId,actionName:t.action.name,attemptIndex:t.scope.attemptIndex,channelAudience:normalizeChannelAudience(t.scope.channelAudience),parent:{spanId:a.spanContext.spanId,traceFlags:a.spanContext.traceFlags,traceId:a.spanContext.traceId},requestId:t.requestId,rootSessionId:t.scope.rootSessionId??t.scope.sessionId,sessionId:t.scope.sessionId,startTimeMs:Date.now(),stepIndex:t.scope.stepIndex,turnId:t.scope.turnId},s=n.recordInputs?contentAttribute(t.request,!1):void 0;s!==void 0&&(o.requestAttribute=s),r.state.set(o)},"input.resolved":(e,a)=>{let o=readState(a.state.get());if(o===void 0)return;let s=n.idGenerator.withSpanId(n.idGenerator.deriveSpanId(`approval:${e.idempotencyKey}`),()=>n.tracer.startSpan(`agent.approval`,{attributes:{"agent.action.call_id":o.actionCallId,"agent.action.name":o.actionName,"agent.approval.kind":`tool-approval`,"agent.approval.outcome":e.outcome,"agent.approval.request_id":o.requestId,"agent.framework.name":`eve`,"agent.framework.version":n.frameworkVersion,"agent.root.session.id":o.rootSessionId,"agent.session.id":o.sessionId,"agent.step.attempt":o.attemptIndex,"agent.step.index":o.stepIndex,"agent.turn.id":o.turnId},startTime:o.startTimeMs},trace.setSpan(ROOT_CONTEXT,trace.wrapSpanContext({...o.parent,isRemote:!1}))));if(o.requestAttribute!==void 0&&s.setAttribute(`agent.approval.request`,o.requestAttribute),n.recordOutputs&&e.response!==void 0){let t=contentAttribute(e.response,!1);t!==void 0&&s.setAttribute(`agent.approval.response`,t)}e.outcome===`failed`&&recordError(s,e.error),s.end()}}}function readState(t){if(typeof t!=`object`||!t||Array.isArray(t))return;let n=t,r=n.parent;if(typeof r!=`object`||!r||Array.isArray(r))return;let i=r;if(typeof n.actionCallId!=`string`||typeof n.actionName!=`string`||typeof n.attemptIndex!=`number`||typeof i.spanId!=`string`||typeof i.traceFlags!=`number`||typeof i.traceId!=`string`||typeof n.requestId!=`string`||typeof n.rootSessionId!=`string`||typeof n.sessionId!=`string`||typeof n.startTimeMs!=`number`||typeof n.stepIndex!=`number`||typeof n.turnId!=`string`)return;let a=n.requestAttribute;if(!(a!==void 0&&typeof a!=`string`))return{actionCallId:n.actionCallId,actionName:n.actionName,attemptIndex:n.attemptIndex,channelAudience:normalizeChannelAudience(n.channelAudience),parent:{isRemote:!1,spanId:i.spanId,traceFlags:i.traceFlags,traceId:i.traceId},requestAttribute:a,requestId:n.requestId,rootSessionId:n.rootSessionId,sessionId:n.sessionId,startTimeMs:n.startTimeMs,stepIndex:n.stepIndex,turnId:n.turnId}}function recordError(e,t){t instanceof Error?(e.recordException(t),e.setStatus({code:SpanStatusCode.ERROR,message:t.message})):e.setStatus({code:SpanStatusCode.ERROR})}export{createAgentApprovalInstrumentation};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{ROOT_CONTEXT,SpanKind,SpanStatusCode,trace}from"#compiled/@opentelemetry/api/index.js";import{sessionIdempotencyKey}from"#harness/instrumentation/lifecycle.js";import{contentAttribute}from"#tracing/agent-otel-content.js";function createAgentChannelDeliveryInstrumentation(
|
|
1
|
+
import{normalizeChannelAudience}from"#shared/channel-audience.js";import{ROOT_CONTEXT,SpanKind,SpanStatusCode,trace}from"#compiled/@opentelemetry/api/index.js";import{sessionIdempotencyKey}from"#harness/instrumentation/lifecycle.js";import{contentAttribute}from"#tracing/agent-otel-content.js";import{isSampledTrace}from"#tracing/sampled-trace.js";function createAgentChannelDeliveryInstrumentation(t){let onStarted=async(n,r)=>{let i=await t.ensureSessionContext({agentName:n.agentName,channelAudience:n.delivery.channelAudience,channelKind:n.delivery.channelKind,idempotencyKey:sessionIdempotencyKey(n.sessionId),parentTraceContext:n.parentTraceContext,rootSessionId:n.rootSessionId,sessionId:n.sessionId,type:`session.started`});if(!isSampledTrace(i.context))return;let c=t.recordInputs?contentAttribute(n.input,!1):void 0,l={channelAudience:normalizeChannelAudience(n.delivery.channelAudience),parent:{isRemote:i.context.isRemote??!1,spanId:i.context.spanId,traceFlags:i.context.traceFlags,traceId:i.context.traceId},spanId:t.idGenerator.deriveSpanId(`channel-delivery:${n.idempotencyKey}`),startTimeMs:Date.now(),window:i.window};c!==void 0&&(l.inputAttribute=c),n.delivery.requestTraceContext!==void 0&&(l.requestTraceContext={spanId:n.delivery.requestTraceContext.spanId,traceFlags:n.delivery.requestTraceContext.traceFlags,traceId:n.delivery.requestTraceContext.traceId}),r.state.set(l)},onTerminal=async(e,r)=>{let i=readState(r.state.get());if(i===void 0)return;let a=e.turnId===void 0?void 0:await t.stateStore.getTurn(e.sessionId,e.turnId),o=await t.stateStore.getSession(e.sessionId),s=a===void 0?i.parent:{isRemote:a.parentIsRemote??!1,spanId:a.parentSpanId,traceFlags:a.context.traceFlags,traceId:a.context.traceId},c=a===void 0?i.startTimeMs:Math.max(i.startTimeMs,a.startTimeMs),l=i.requestTraceContext,u=t.idGenerator.withSpanId(i.spanId,()=>t.tracer.startSpan(`agent.channel.delivery`,{attributes:{"agent.channel.delivery.id":e.delivery.deliveryId,"agent.channel.delivery.outcome":e.outcome,"agent.channel.kind":e.delivery.channelKind,"agent.channel.name":e.delivery.channelName,"agent.channel.request.id":e.delivery.requestId,"agent.framework.name":`eve`,"agent.framework.version":t.frameworkVersion,"agent.name":e.agentName,"agent.root.session.id":e.rootSessionId,"agent.session.id":e.sessionId,"agent.session.window":o?.window??i.window,"agent.turn.id":e.turnId,"agent.turn.sequence":e.sequence},kind:SpanKind.CONSUMER,links:l===void 0?void 0:[{attributes:{"eve.link.type":`channel.request`},context:l}],startTime:c},contextFromSpanContext(s)));if(u.addEvent(`channel.delivery.started`,void 0,c),u.addEvent(e.type),i.inputAttribute!==void 0&&u.setAttribute(`agent.channel.delivery.input`,i.inputAttribute),e.outcome===`failed`){let t=e.errorCode??(e.error instanceof Error?e.error.name:`Error`);u.setAttribute(`error.type`,t),e.errorCode!==void 0&&u.setAttribute(`agent.channel.delivery.error.code`,e.errorCode),recordError(u,e.error)}u.end()};return{"channel.delivery.cancelled":onTerminal,"channel.delivery.completed":onTerminal,"channel.delivery.failed":onTerminal,"channel.delivery.started":onStarted}}function readState(t){if(!isRecord(t)||!isSpanContext(t.parent)||typeof t.spanId!=`string`||typeof t.startTimeMs!=`number`||typeof t.window!=`number`)return;let n=isSpanContext(t.requestTraceContext)?t.requestTraceContext:void 0;return{channelAudience:normalizeChannelAudience(t.channelAudience),inputAttribute:typeof t.inputAttribute==`string`?t.inputAttribute:void 0,parent:t.parent,requestTraceContext:n,spanId:t.spanId,startTimeMs:t.startTimeMs,window:t.window}}function isSpanContext(e){return isRecord(e)&&typeof e.spanId==`string`&&typeof e.traceFlags==`number`&&typeof e.traceId==`string`}function isRecord(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function contextFromSpanContext(e){return trace.setSpan(ROOT_CONTEXT,trace.wrapSpanContext(e))}function recordError(e,t){t instanceof Error?(e.recordException(t),e.setStatus({code:SpanStatusCode.ERROR,message:t.message})):e.setStatus({code:SpanStatusCode.ERROR})}export{createAgentChannelDeliveryInstrumentation};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type Tracer } from "#compiled/@opentelemetry/api/index.js";
|
|
2
2
|
import type { AgentTraceStateStore } from "#tracing/agent-trace-state.js";
|
|
3
3
|
import type { AgentSpanIdGenerator } from "#tracing/agent-span-id-generator.js";
|
|
4
|
+
import type { TraceCapturePolicy } from "#tracing/otel-declaration.js";
|
|
4
5
|
import type { InstrumentationContextRunner, InstrumentationProviderDefinition, InstrumentationSessionStartedEvent, InstrumentationTraceContext, InstrumentationTurnStartedEvent } from "#harness/instrumentation/lifecycle.js";
|
|
5
6
|
export interface AgentOtelInstrumentationInput {
|
|
6
7
|
/**
|
|
@@ -15,6 +16,7 @@ export interface AgentOtelInstrumentationInput {
|
|
|
15
16
|
readonly idGenerator: AgentSpanIdGenerator;
|
|
16
17
|
readonly stateStore: AgentTraceStateStore;
|
|
17
18
|
readonly tracer: Tracer;
|
|
19
|
+
readonly tracePolicy?: TraceCapturePolicy;
|
|
18
20
|
}
|
|
19
21
|
/** OTel event definition and its trusted framework context runner. */
|
|
20
22
|
export interface AgentOtelInstrumentation {
|