eve 0.43.0 → 0.44.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 +26 -0
- package/dist/src/channel/adapter.d.ts +2 -1
- package/dist/src/channel/instrumentation.js +1 -1
- package/dist/src/chunks/{use-eve-agent-C0SG1Ttk.js → use-eve-agent-BsLJiIbc.js} +224 -62
- package/dist/src/chunks/{use-eve-agent-D71oDil7.js → use-eve-agent-DpUEwS23.js} +222 -62
- package/dist/src/cli/commands/extension-init.js +1 -1
- package/dist/src/cli/commands/init.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/setup-commands.js +1 -1
- package/dist/src/cli/dev/tui/traces/trace-view.js +1 -1
- package/dist/src/client/eve-agent-store-helpers.d.ts +12 -0
- package/dist/src/client/eve-agent-store-helpers.js +2 -0
- package/dist/src/client/eve-agent-store.d.ts +8 -6
- package/dist/src/client/eve-agent-store.js +1 -2
- package/dist/src/client/ndjson.d.ts +3 -1
- package/dist/src/client/ndjson.js +3 -3
- package/dist/src/client/open-stream.d.ts +3 -0
- package/dist/src/client/open-stream.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 +2 -2
- package/dist/src/compiler/extension-compatibility.js +1 -1
- package/dist/src/context/build-dynamic-tools.js +1 -1
- package/dist/src/context/dynamic-tool-lifecycle.d.ts +5 -1
- package/dist/src/context/dynamic-tool-lifecycle.js +1 -1
- package/dist/src/context/keys.d.ts +4 -2
- package/dist/src/context/keys.js +1 -1
- package/dist/src/execution/cancel-descendant-turns-step.js +1 -1
- package/dist/src/execution/dispatch-turn-step.js +1 -1
- package/dist/src/execution/eve-workflow-attributes.d.ts +3 -0
- package/dist/src/execution/eve-workflow-attributes.js +1 -1
- package/dist/src/execution/pending-turn-state.d.ts +9 -0
- package/dist/src/execution/pending-turn-state.js +1 -0
- package/dist/src/execution/settle-cancelled-turn-step.js +1 -1
- package/dist/src/execution/tasks/parent/tool-execution.js +1 -1
- package/dist/src/execution/turn-workflow.js +1 -1
- package/dist/src/execution/workflow-steps.js +1 -1
- package/dist/src/execution/workflow-trace-context.js +1 -1
- package/dist/src/harness/channel-delivery-instrumentation.js +1 -1
- package/dist/src/harness/instrumentation/content-policy.d.ts +6 -0
- package/dist/src/harness/instrumentation/content-policy.js +1 -0
- package/dist/src/harness/instrumentation/lifecycle.d.ts +6 -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/instrumentation/runtime-context.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/runtime-actions.js +1 -1
- package/dist/src/harness/tool-loop.js +2 -2
- package/dist/src/internal/application/package.js +1 -1
- package/dist/src/internal/workflow-bundle/dynamic-remote-agent-transform.js +2 -2
- package/dist/src/internal/workflow-bundle/dynamic-tool-transform.d.ts +4 -4
- package/dist/src/internal/workflow-bundle/dynamic-tool-transform.js +3 -4
- package/dist/src/internal/workflow-bundle/stable-module-id.d.ts +6 -0
- package/dist/src/internal/workflow-bundle/stable-module-id.js +1 -0
- 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/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/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/react/use-eve-agent.d.ts +10 -1
- package/dist/src/react/use-eve-agent.js +1 -1
- package/dist/src/runtime/attributes/emit.d.ts +1 -1
- package/dist/src/runtime/attributes/normalize.d.ts +1 -1
- package/dist/src/runtime/attributes/normalize.js +1 -1
- package/dist/src/runtime/framework-tools/connection-search-dynamic.js +2 -2
- package/dist/src/runtime/framework-tools/subagent/local.js +1 -1
- package/dist/src/runtime/sessions/runtime-context-keys.js +1 -1
- package/dist/src/setup/integrations/linq/connect.js +1 -1
- package/dist/src/setup/primitives/pm/npm.js +1 -1
- package/dist/src/setup/primitives/pm/pnpm.js +5 -9
- package/dist/src/setup/primitives/pm/types.d.ts +0 -2
- package/dist/src/setup/scaffold/create/project.js +1 -1
- package/dist/src/setup/scaffold/create/web-template.d.ts +10 -4
- package/dist/src/setup/scaffold/create/web-template.js +669 -74
- 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 +43 -19
- package/dist/src/shared/durable-dynamic-tool-callbacks.js +1 -1
- package/dist/src/svelte/index.js +1 -1
- package/dist/src/svelte/use-eve-agent.d.ts +4 -0
- package/dist/src/svelte/use-eve-agent.js +1 -1
- package/dist/src/tasks/delivery-context.d.ts +9 -0
- package/dist/src/tasks/delivery-context.js +5 -2
- 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/dist/src/vue/index.js +1 -1
- package/dist/src/vue/use-eve-agent.d.ts +4 -0
- package/dist/src/vue/use-eve-agent.js +1 -1
- package/docs/channels/custom.mdx +2 -0
- package/docs/concepts/sessions-runs-and-streaming.md +1 -1
- package/docs/guides/dynamic-capabilities.md +10 -2
- package/docs/guides/frontend/nextjs.mdx +23 -0
- package/docs/guides/frontend/overview.mdx +24 -9
- package/docs/guides/frontend/use-eve-agent-svelte.mdx +9 -9
- package/docs/guides/frontend/use-eve-agent-vue.mdx +9 -9
- package/docs/guides/instrumentation.md +2 -0
- package/docs/tools/overview.mdx +5 -4
- package/docs/tutorial/ship-it.mdx +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export declare const CHANNEL_AUDIENCES: readonly ["public", "private", "unknown"];
|
|
2
|
+
/** Who can observe the conversation on its originating channel. */
|
|
3
|
+
export type ChannelAudience = (typeof CHANNEL_AUDIENCES)[number];
|
|
4
|
+
export interface ChannelAudienceMetadata {
|
|
5
|
+
readonly audience?: ChannelAudience;
|
|
6
|
+
}
|
|
7
|
+
export declare function normalizeChannelAudience(value: unknown): ChannelAudience;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const CHANNEL_AUDIENCES=[`public`,`private`,`unknown`];function normalizeChannelAudience(e){return typeof e==`string`&&CHANNEL_AUDIENCES.includes(e)?e:`unknown`}export{CHANNEL_AUDIENCES,normalizeChannelAudience};
|
|
@@ -5,6 +5,7 @@ import type { RouteDefinition } from "#channel/routes.js";
|
|
|
5
5
|
import type { Session, SessionHandle } from "#channel/session.js";
|
|
6
6
|
import type { DeliverPayload, SessionAuthContext, TurnPolicy } from "#channel/types.js";
|
|
7
7
|
import type { StepInput } from "#harness/types.js";
|
|
8
|
+
import type { ChannelAudienceMetadata } from "#shared/channel-audience.js";
|
|
8
9
|
/**
|
|
9
10
|
* Enriched return shape from a channel's {@link ChannelAdapter.fetchFile}
|
|
10
11
|
* function. Return a bare {@link Buffer} when only bytes are known, or
|
|
@@ -40,7 +41,7 @@ export interface GenericReceiveInput<TReceiveTarget = Record<string, unknown>> {
|
|
|
40
41
|
* `TReceiveTarget` (cross-channel target shape), `TMetadata` (instrumentation
|
|
41
42
|
* projection).
|
|
42
43
|
*/
|
|
43
|
-
export interface GenericChannelDefinition<TEvents, TState = undefined, TCtx = void, TReceiveTarget = Record<string, unknown>, TMetadata extends Record<string, unknown> = Record<string, unknown>> {
|
|
44
|
+
export interface GenericChannelDefinition<TEvents, TState = undefined, TCtx = void, TReceiveTarget = Record<string, unknown>, TMetadata extends Record<string, unknown> & ChannelAudienceMetadata = Record<string, unknown>> {
|
|
44
45
|
/** Policy used by message sends that do not provide an explicit override. */
|
|
45
46
|
readonly turnPolicy?: TurnPolicy;
|
|
46
47
|
deliver?(payload: DeliverPayload, ctx: TCtx): StepInput | void | Promise<StepInput | void>;
|
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
import type { Approval } from "#public/definitions/approval.js";
|
|
2
2
|
import type { JsonObject } from "#shared/json.js";
|
|
3
|
+
export type DurableDynamicCallbackPhase = "approvalRequest" | "approvalResponse" | "execute" | "toModelOutput";
|
|
4
|
+
export type DurableDynamicCallbackFn = (closure: JsonObject, ...args: never[]) => unknown;
|
|
5
|
+
/**
|
|
6
|
+
* Persisted binding for one callback phase. Identity is
|
|
7
|
+
* `(toolName, phase)` — carried by the surrounding metadata — so only the
|
|
8
|
+
* snapshotted closure values persist.
|
|
9
|
+
*/
|
|
3
10
|
export interface DurableDynamicCallbackReference {
|
|
4
|
-
readonly stepId: string;
|
|
5
11
|
readonly closure: JsonObject;
|
|
6
12
|
}
|
|
7
13
|
export interface DurableDynamicToolCallbacks {
|
|
@@ -10,25 +16,43 @@ export interface DurableDynamicToolCallbacks {
|
|
|
10
16
|
readonly approvalResponse?: DurableDynamicCallbackReference;
|
|
11
17
|
readonly toModelOutput?: DurableDynamicCallbackReference;
|
|
12
18
|
}
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
export declare function registerDurableDynamicCallback<TArgs extends unknown[], TResult>(stepId: string, callback: (closure: JsonObject, ...args: TArgs) => TResult): void;
|
|
17
|
-
/** Marks a live callback with the descriptor needed to reconstruct it after a cold start. */
|
|
18
|
-
export declare function stampDurableDynamicCallback<TCallback extends Callback>(callback: TCallback, reference: DurableDynamicCallbackReference): TCallback;
|
|
19
|
-
/** Creates a live callback backed by the same registered function used during durable replay. */
|
|
20
|
-
export declare function createDurableDynamicCallback<TArgs extends unknown[], TResult>(input: {
|
|
19
|
+
/** Live descriptor stamped on authored callbacks; `callback` never persists. */
|
|
20
|
+
export interface StampedDurableDynamicCallback {
|
|
21
|
+
readonly callback: DurableDynamicCallbackFn;
|
|
21
22
|
readonly closure: JsonObject;
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
}
|
|
24
|
+
export type LiveDurableDynamicToolCallbacks = Partial<{
|
|
25
|
+
execute: StampedDurableDynamicCallback;
|
|
26
|
+
approvalRequest: StampedDurableDynamicCallback;
|
|
27
|
+
approvalResponse: StampedDurableDynamicCallback;
|
|
28
|
+
toModelOutput: StampedDurableDynamicCallback;
|
|
29
|
+
}>;
|
|
30
|
+
export declare const DURABLE_DYNAMIC_TOOL_CALLBACKS: unique symbol;
|
|
31
|
+
/**
|
|
32
|
+
* Binds the current implementation of one tool callback phase. Re-resolution
|
|
33
|
+
* replaces the binding, so replay after a redeploy runs the latest code.
|
|
34
|
+
*/
|
|
35
|
+
export declare function registerDurableDynamicCallback(input: {
|
|
36
|
+
readonly callback: DurableDynamicCallbackFn;
|
|
37
|
+
readonly phase: DurableDynamicCallbackPhase;
|
|
38
|
+
readonly toolName: string;
|
|
39
|
+
}): void;
|
|
40
|
+
export declare function lookupDurableDynamicCallback(toolName: string, phase: DurableDynamicCallbackPhase): DurableDynamicCallbackFn | undefined;
|
|
41
|
+
/** Invokes a registered callback with its snapshotted closure and live arguments. */
|
|
42
|
+
export declare function callDurableDynamicCallback(callback: DurableDynamicCallbackFn, closure: JsonObject, ...args: unknown[]): unknown;
|
|
43
|
+
/** True when any persisted callback of these tools has no registered binding. */
|
|
44
|
+
export declare function hasUnregisteredDurableDynamicCallbacks(metadata: readonly {
|
|
45
|
+
callbacks: DurableDynamicToolCallbacks;
|
|
46
|
+
name: string;
|
|
47
|
+
}[]): boolean;
|
|
48
|
+
/** Marks a live callback with the descriptor needed to register it at resolve time. */
|
|
49
|
+
export declare function stampDurableDynamicCallback<TCallback extends (...args: never[]) => unknown>(callback: TCallback, descriptor: StampedDurableDynamicCallback): TCallback;
|
|
50
|
+
export declare function readDurableDynamicCallback(callback: unknown): StampedDurableDynamicCallback | undefined;
|
|
26
51
|
/** Copies phase-specific callback descriptors onto a branded tool definition. */
|
|
27
|
-
export declare function stampDurableDynamicToolCallbacks(definition: object, callbacks:
|
|
52
|
+
export declare function stampDurableDynamicToolCallbacks(definition: object, callbacks: LiveDurableDynamicToolCallbacks): void;
|
|
28
53
|
export declare function collectDurableDynamicToolCallbacks(input: {
|
|
29
54
|
readonly approval?: Approval<never>;
|
|
30
|
-
readonly execute:
|
|
31
|
-
readonly toModelOutput?:
|
|
32
|
-
}):
|
|
33
|
-
export declare function readDurableDynamicToolCallbacks(definition: object):
|
|
34
|
-
export {};
|
|
55
|
+
readonly execute: (...args: never[]) => unknown;
|
|
56
|
+
readonly toModelOutput?: (...args: never[]) => unknown;
|
|
57
|
+
}): LiveDurableDynamicToolCallbacks;
|
|
58
|
+
export declare function readDurableDynamicToolCallbacks(definition: object): LiveDurableDynamicToolCallbacks | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{resolveApprovalPolicy}from"#public/definitions/approval.js";const
|
|
1
|
+
import{resolveApprovalPolicy}from"#public/definitions/approval.js";const STAMPED_CALLBACK=Symbol.for(`eve:durable-dynamic-callback`),DURABLE_DYNAMIC_TOOL_CALLBACKS=Symbol.for(`eve:durable-dynamic-tool-callbacks`),REGISTRY=Symbol.for(`eve:dynamic-tool-callbacks`);function getRegistry(){let e=globalThis,t=e[REGISTRY];if(t!==void 0)return t;let n=new Map;return e[REGISTRY]=n,n}function registerDurableDynamicCallback(e){let t=getRegistry(),n=t.get(e.toolName);n===void 0&&(n=new Map,t.set(e.toolName,n)),n.set(e.phase,e.callback)}function lookupDurableDynamicCallback(e,t){return getRegistry().get(e)?.get(t)}function callDurableDynamicCallback(e,t,...n){return e(t,...n)}function hasUnregisteredDurableDynamicCallbacks(e){return e.some(e=>Object.keys(e.callbacks).some(t=>lookupDurableDynamicCallback(e.name,t)===void 0))}function stampDurableDynamicCallback(e,n){return Object.defineProperty(e,STAMPED_CALLBACK,{configurable:!0,value:n}),e}function readDurableDynamicCallback(e){if(typeof e==`function`)return Reflect.get(e,STAMPED_CALLBACK)}function stampDurableDynamicToolCallbacks(e,t){Object.defineProperty(e,DURABLE_DYNAMIC_TOOL_CALLBACKS,{configurable:!0,value:t})}function collectDurableDynamicToolCallbacks(t){let n=t.approval===void 0?void 0:readDurableDynamicCallback(resolveApprovalPolicy(t.approval)),r=t.approval===void 0||typeof t.approval==`function`?void 0:readDurableDynamicCallback(t.approval.response),i=readDurableDynamicCallback(t.execute),a=readDurableDynamicCallback(t.toModelOutput),o={};return i!==void 0&&(o.execute=i),n!==void 0&&(o.approvalRequest=n),r!==void 0&&(o.approvalResponse=r),a!==void 0&&(o.toModelOutput=a),o}function readDurableDynamicToolCallbacks(e){return e[DURABLE_DYNAMIC_TOOL_CALLBACKS]}export{DURABLE_DYNAMIC_TOOL_CALLBACKS,callDurableDynamicCallback,collectDurableDynamicToolCallbacks,hasUnregisteredDurableDynamicCallbacks,lookupDurableDynamicCallback,readDurableDynamicCallback,readDurableDynamicToolCallbacks,registerDurableDynamicCallback,stampDurableDynamicCallback,stampDurableDynamicToolCallbacks};
|
package/dist/src/svelte/index.js
CHANGED
|
@@ -34,6 +34,8 @@ export interface UseEveAgentReturn<TData> {
|
|
|
34
34
|
readonly error: Error | undefined;
|
|
35
35
|
/** Raw server events received during this session (authoritative stream). */
|
|
36
36
|
readonly events: readonly MessageStreamEvent[];
|
|
37
|
+
/** Replay the attached durable session and follow its in-flight turn, if any. */
|
|
38
|
+
readonly resume: () => Promise<void>;
|
|
37
39
|
/** Clear all state and start a new session. */
|
|
38
40
|
readonly reset: () => void;
|
|
39
41
|
/** Send a message with optional turn settings. */
|
|
@@ -97,6 +99,8 @@ export interface UseEveAgentOptions<TData> extends EveAgentStoreCallbacks<TData>
|
|
|
97
99
|
* which fixes `TData` to {@link EveMessageData}.
|
|
98
100
|
*/
|
|
99
101
|
readonly reducer?: EveAgentReducer<TData>;
|
|
102
|
+
/** Replay the attached durable session after mount. Requires `initialSession` or `session`. */
|
|
103
|
+
readonly resume?: boolean;
|
|
100
104
|
/**
|
|
101
105
|
* Pre-built client session to bind to. When omitted, the binding creates its
|
|
102
106
|
* own session from `auth`, `headers`, and `host`.
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { SessionStateMap } from "#harness/types.js";
|
|
2
2
|
export declare const TASK_DELIVERY_CONTEXT_LABEL = "[Task state]";
|
|
3
|
+
export declare const TASK_DELIVERY_INITIATING_INSTRUCTION = "Background task reporting: launch acknowledgement\nThe accompanying [Task state] system message is runtime-authored and lists background tasks accepted so far from the current turn. They continue independently after this turn.\n\nContinue carrying out the user's request, including starting any remaining background work. When no further tool calls are needed in this turn, send one brief user-facing acknowledgement that the background work has started. Do not wait for results or report results that are not available yet. End the turn after the acknowledgement.";
|
|
3
4
|
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
5
|
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
6
|
/** Returns model context and cohort phase for tasks started by the same parent turn as this delivery. */
|
|
@@ -10,3 +11,11 @@ export declare function resolveTaskDeliveryContext(input: {
|
|
|
10
11
|
readonly context: string;
|
|
11
12
|
readonly phase: "pending" | "settled";
|
|
12
13
|
} | undefined;
|
|
14
|
+
/** Returns model context for durable tasks launched by the active parent turn. */
|
|
15
|
+
export declare function resolveInitiatingTaskContext(input: {
|
|
16
|
+
readonly state: SessionStateMap | undefined;
|
|
17
|
+
readonly turnId: string;
|
|
18
|
+
}): {
|
|
19
|
+
readonly context: string;
|
|
20
|
+
readonly phase: "initiating";
|
|
21
|
+
} | undefined;
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
import{getSessionTaskIndex}from"#tasks/session-index.js";import{EMPTY_DELIVERY_SENTINEL}from"#shared/empty-delivery.js";const TASK_DELIVERY_CONTEXT_LABEL=`[Task state]`,
|
|
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_INITIATING_INSTRUCTION=`Background task reporting: launch acknowledgement
|
|
2
|
+
The accompanying ${TASK_DELIVERY_CONTEXT_LABEL} system message is runtime-authored and lists background tasks accepted so far from the current turn. They continue independently after this turn.
|
|
3
|
+
|
|
4
|
+
Continue carrying out the user's request, including starting any remaining background work. When no further tool calls are needed in this turn, send one brief user-facing acknowledgement that the background work has started. Do not wait for results or report results that are not available yet. End the turn after the acknowledgement.`,TASK_DELIVERY_PENDING_INSTRUCTION=`Background task control: incomplete cohort
|
|
2
5
|
This framework-authored instruction overrides any earlier instruction to report, summarize, acknowledge, or otherwise handle background results.
|
|
3
6
|
|
|
4
7
|
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.
|
|
@@ -14,4 +17,4 @@ Delivery:
|
|
|
14
17
|
|
|
15
18
|
Incorrect: "Two of three tasks have completed."
|
|
16
19
|
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}:`));
|
|
20
|
+
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}:`));return r===void 0?void 0:projectTaskCohort(n.filter(e=>e.createdByTurnId===r.createdByTurnId))}function resolveInitiatingTaskContext(t){let n=getSessionTaskIndex(t.state).filter(e=>e.createdByTurnId===t.turnId);if(n.some(e=>e.executor!==void 0&&e.terminalView===void 0))return{...projectTaskCohort(n),phase:`initiating`}}function projectTaskCohort(e){let t=e.every(e=>e.terminalView!==void 0),r=e.map(e=>({name:e.metadata.name,output:t?e.terminalView?.lastOutput:void 0,status:e.terminalView?.status??`pending`,taskId:e.taskId}));return{context:`${TASK_DELIVERY_CONTEXT_LABEL}\n${JSON.stringify({tasks:r})}`,phase:t?`settled`:`pending`}}export{TASK_DELIVERY_CONTEXT_LABEL,TASK_DELIVERY_INITIATING_INSTRUCTION,TASK_DELIVERY_PENDING_INSTRUCTION,TASK_DELIVERY_SETTLED_INSTRUCTION,resolveInitiatingTaskContext,resolveTaskDeliveryContext};
|
|
@@ -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 {
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{ROOT_CONTEXT,SpanStatusCode,context,trace}from"#compiled/@opentelemetry/api/index.js";import{attemptIdempotencyKey}from"#harness/instrumentation/lifecycle.js";import{contentAttribute,genAiInputMessagesAttribute,genAiOutputMessagesAttribute,genAiSystemInstructionsAttribute,messagesContentAttribute,systemPromptAttribute,textContentAttribute,toolResultsContentAttribute}from"#tracing/agent-otel-content.js";import{setAgentUsage}from"#tracing/agent-otel-usage.js";import{createAgentActionInstrumentation}from"#tracing/agent-action-instrumentation.js";import{createAgentApprovalInstrumentation}from"#tracing/agent-approval-instrumentation.js";import{createAgentChannelDeliveryInstrumentation}from"#tracing/agent-channel-delivery-instrumentation.js";import{createAgentToolInstrumentation}from"#tracing/agent-tool-instrumentation.js";import{createAgentOtelSessionContext}from"#tracing/agent-otel-session-context.js";function createAgentOtelInstrumentation(e){let t=e.recordInputs??!1,f=e.recordOutputs??!1,p=new WeakMap,m=new Map,h=new WeakMap,g=new WeakMap,_=createAgentActionInstrumentation({frameworkVersion:e.frameworkVersion,idGenerator:e.idGenerator,recordInputs:t,recordOutputs:f,resolveTraceContext:async t=>(await e.stateStore.getTurn(t.scope.sessionId,t.scope.turnId))?.context,stateStore:e.stateStore,tracer:e.tracer}),v=createAgentApprovalInstrumentation({actionContextFor:_.contextFor,frameworkVersion:e.frameworkVersion,idGenerator:e.idGenerator,recordInputs:t,recordOutputs:f,tracer:e.tracer}),y=createAgentToolInstrumentation({actionContextFor:_.contextFor,idGenerator:e.idGenerator,recordInputs:t,recordOutputs:f,resolveFallback:e=>{let t=m.get(e.scope.attemptId)??e.scope,n=h.get(t)?.step;return n===void 0?void 0:{context:n.context,spanContext:n.span.spanContext()}},tracer:e.tracer}),{ensureSessionContext:b,prepareSessionTrace:x,prepareTurnTrace:S}=createAgentOtelSessionContext(e),onSessionStarted=async e=>{await x(e)},onTurnStarted=async e=>{await S(e)},onStepStarted=async t=>{let a=await e.stateStore.getTurn(t.scope.sessionId,t.scope.turnId);if(a===void 0)return;let o=contextFromSpanContext(a.context),s=trace.getSpan(context.active())?.spanContext(),c=e.idGenerator.withSpanId(e.idGenerator.deriveSpanId(attemptIdempotencyKey(t.scope)),()=>e.tracer.startSpan(`agent.step`,{attributes:{"agent.session.id":t.scope.sessionId,"agent.framework.name":`eve`,"agent.framework.version":e.frameworkVersion,"agent.root.session.id":t.scope.rootSessionId??t.scope.sessionId,"agent.step.attempt":t.scope.attemptIndex,"agent.step.index":t.scope.stepIndex,"agent.turn.id":t.scope.turnId,"agent.name":t.scope.functionId,...runtimeContextAttributes(t.runtimeContext)},links:s===void 0||s.traceId===a.context.traceId?void 0:[{attributes:{"eve.link.type":`workflow.delivery`},context:s}]},o));c.addEvent(`step.started`);let l=trace.setSpan(o,c),u=t.operation.operationId,d=e.tracer.startSpan(u,{attributes:{"ai.operation.name":u,"ai.provider.name":t.operation.provider,"ai.request.model":t.operation.modelId,...runtimeContextAttributes(t.runtimeContext)}},l);h.set(t.scope,{operation:{context:trace.setSpan(l,d),name:u,span:d},step:{context:l,span:c}}),m.set(t.scope.attemptId,t.scope)},onStepTerminal=async e=>{let t=m.get(e.scope.attemptId)??e.scope;p.delete(t),drainOpenSpans({...e,scope:t}),y.drain(e.scope.attemptId,e.type===`step.attempt.failed`?{error:e.error}:void 0),e.type===`step.attempt.failed`&&await _.failForAttempt(t,e.error),m.delete(e.scope.attemptId);let n=h.get(t);n!==void 0&&(n.step.span.addEvent(e.type===`step.attempt.completed`?`step.completed`:`step.failed`),e.type===`step.attempt.failed`&&(recordError(n.operation.span,e.error),recordError(n.step.span,e.error)),n.operation.span.end(),n.step.span.end(),h.delete(t))},onTurnTerminal=async t=>{(t.type===`turn.cancelled`||t.type===`turn.failed`)&&await _.deleteForTurn(t.sessionId,t.turnId);let n=await e.stateStore.getTurn(t.sessionId,t.turnId);n!==void 0&&await e.stateStore.setTurn(t.sessionId,t.turnId,{...n,terminal:t.type===`turn.failed`?{error:t.error,type:t.type}:{type:t.type}})},onSessionTransition=async t=>{if(t.turnId!==void 0){let n=await e.stateStore.getTurn(t.sessionId,t.turnId);if(n!==void 0){let r=await e.stateStore.getSession(t.sessionId)
|
|
2
|
-
`));i!==void 0&&t.span.setAttribute(`ai.response.reasoning`,i);let o=textContentAttribute(n.filter(e=>e.type===`text`).map(e=>e.text).join(``));o!==void 0&&t.span.setAttribute(`ai.response.text`,o);let c=n.filter(e=>e.type===`tool-call`).map(e=>({callId:e.callId,input:e.input,toolName:e.toolName}));if(c.length>0){let e=contentAttribute(c,!1);e!==void 0&&t.span.setAttribute(`ai.response.tool_calls`,e)}let l=n.filter(e=>e.type===`tool-result`||e.type===`tool-error`).map(e=>e.type===`tool-result`?{callId:e.callId,input:e.input,output:e.output,toolName:e.toolName}:{callId:e.callId,error:errorText(e.error),input:e.input,toolName:e.toolName});if(l.length>0){let e=toolResultsContentAttribute(l);e!==void 0&&t.span.setAttribute(`ai.response.tool_results`,e)}}}t.span.end()}},C=createAgentChannelDeliveryInstrumentation({ensureSessionContext:b,frameworkVersion:e.frameworkVersion,idGenerator:e.idGenerator,recordInputs:t,stateStore:e.stateStore,tracer:e.tracer}),onStepMetadata=e=>{let t=h.get(e.scope);if(t===void 0)return;let n=readGatewayCost(e.providerMetadata);if(n!==void 0)for(let[e,r]of Object.entries(n))t.step.span.setAttribute(e,r)};return{hook:{capture:t||f?`content`:`metadata`,events:{...C,"action.completed":_.events[`action.completed`],"action.failed":_.events[`action.failed`],async"action.started"(e,t){await _.events[`action.started`](e,t),await y.actionStarted(e)},...v,"step.attempt.completed":onStepTerminal,"step.attempt.failed":onStepTerminal,"step.attempt.metadata":onStepMetadata,"step.attempt.started":onStepStarted,"model.call.completed":onModelCallTerminal,"model.call.failed":onModelCallTerminal,"model.call.started":onModelCallStarted,"session.completed":onSessionTransition,"session.failed":onSessionTransition,"session.started":onSessionStarted,"session.waiting":onSessionTransition,...y.events,"turn.cancelled":onTurnTerminal,"turn.completed":onTurnTerminal,"turn.failed":onTurnTerminal,"turn.started":onTurnStarted},name:`eve.otel`},prepareSessionTrace:x,prepareTurnTrace:S,runInContext(
|
|
1
|
+
import{ROOT_CONTEXT,SpanStatusCode,context,trace}from"#compiled/@opentelemetry/api/index.js";import{attemptIdempotencyKey}from"#harness/instrumentation/lifecycle.js";import{contentAttribute,genAiInputMessagesAttribute,genAiOutputMessagesAttribute,genAiSystemInstructionsAttribute,messagesContentAttribute,systemPromptAttribute,textContentAttribute,toolResultsContentAttribute}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";import{createAgentActionInstrumentation}from"#tracing/agent-action-instrumentation.js";import{createAgentApprovalInstrumentation}from"#tracing/agent-approval-instrumentation.js";import{createAgentChannelDeliveryInstrumentation}from"#tracing/agent-channel-delivery-instrumentation.js";import{createAgentToolInstrumentation}from"#tracing/agent-tool-instrumentation.js";import{createAgentOtelSessionContext}from"#tracing/agent-otel-session-context.js";import{suppressTracing}from"#tracing/suppress-tracing.js";function createAgentOtelInstrumentation(e){let t=e.recordInputs??!1,f=e.recordOutputs??!1,p=new WeakMap,m=new Map,h=new WeakMap,g=new WeakMap,_=createAgentActionInstrumentation({frameworkVersion:e.frameworkVersion,idGenerator:e.idGenerator,recordInputs:t,recordOutputs:f,resolveTraceContext:async t=>(await e.stateStore.getTurn(t.scope.sessionId,t.scope.turnId))?.context,stateStore:e.stateStore,tracer:e.tracer}),v=createAgentApprovalInstrumentation({actionContextFor:_.contextFor,frameworkVersion:e.frameworkVersion,idGenerator:e.idGenerator,recordInputs:t,recordOutputs:f,tracer:e.tracer}),y=createAgentToolInstrumentation({actionContextFor:_.contextFor,idGenerator:e.idGenerator,recordInputs:t,recordOutputs:f,resolveFallback:e=>{let t=m.get(e.scope.attemptId)??e.scope,n=h.get(t)?.step;return n===void 0?void 0:{context:n.context,spanContext:n.span.spanContext()}},tracer:e.tracer}),{ensureSessionContext:b,prepareSessionTrace:x,prepareTurnTrace:S}=createAgentOtelSessionContext(e),onSessionStarted=async e=>{await x(e)},onTurnStarted=async e=>{await S(e)},onStepStarted=async t=>{let a=await e.stateStore.getTurn(t.scope.sessionId,t.scope.turnId);if(a===void 0||!isSampledTrace(a.context))return;let o=withChannelAudience(contextFromSpanContext(a.context),t.scope.channelAudience),s=trace.getSpan(context.active())?.spanContext(),c=e.idGenerator.withSpanId(e.idGenerator.deriveSpanId(attemptIdempotencyKey(t.scope)),()=>e.tracer.startSpan(`agent.step`,{attributes:{"agent.session.id":t.scope.sessionId,"agent.framework.name":`eve`,"agent.framework.version":e.frameworkVersion,"agent.root.session.id":t.scope.rootSessionId??t.scope.sessionId,"agent.step.attempt":t.scope.attemptIndex,"agent.step.index":t.scope.stepIndex,"agent.turn.id":t.scope.turnId,"agent.name":t.scope.functionId,...runtimeContextAttributes(t.runtimeContext)},links:s===void 0||s.traceId===a.context.traceId?void 0:[{attributes:{"eve.link.type":`workflow.delivery`},context:s}]},o));c.addEvent(`step.started`);let l=trace.setSpan(o,c),u=t.operation.operationId,d=e.tracer.startSpan(u,{attributes:{"ai.operation.name":u,"ai.provider.name":t.operation.provider,"ai.request.model":t.operation.modelId,...runtimeContextAttributes(t.runtimeContext)}},l);h.set(t.scope,{operation:{context:trace.setSpan(l,d),name:u,span:d},step:{context:l,span:c}}),m.set(t.scope.attemptId,t.scope)},onStepTerminal=async e=>{let t=m.get(e.scope.attemptId)??e.scope;p.delete(t),drainOpenSpans({...e,scope:t}),y.drain(e.scope.attemptId,e.type===`step.attempt.failed`?{error:e.error}:void 0),e.type===`step.attempt.failed`&&await _.failForAttempt(t,e.error),m.delete(e.scope.attemptId);let n=h.get(t);n!==void 0&&(n.step.span.addEvent(e.type===`step.attempt.completed`?`step.completed`:`step.failed`),e.type===`step.attempt.failed`&&(recordError(n.operation.span,e.error),recordError(n.step.span,e.error)),n.operation.span.end(),n.step.span.end(),h.delete(t))},onTurnTerminal=async t=>{(t.type===`turn.cancelled`||t.type===`turn.failed`)&&await _.deleteForTurn(t.sessionId,t.turnId);let n=await e.stateStore.getTurn(t.sessionId,t.turnId);n!==void 0&&await e.stateStore.setTurn(t.sessionId,t.turnId,{...n,terminal:t.type===`turn.failed`?{error:t.error,type:t.type}:{type:t.type}})},onSessionTransition=async t=>{if(t.turnId!==void 0){let n=await e.stateStore.getTurn(t.sessionId,t.turnId);if(n!==void 0){let r=await e.stateStore.getSession(t.sessionId);if(isSampledTrace(n.context)){let i=e.idGenerator.withSpanId(n.context.spanId,()=>e.tracer.startSpan(`agent.turn`,{attributes:{"agent.framework.name":`eve`,"agent.framework.version":e.frameworkVersion,"agent.name":r?.agentName,...parentLineageAttributes(n.lineage),"agent.root.session.id":n.rootSessionId,"agent.session.id":t.sessionId,"agent.session.window":r?.window,"agent.turn.id":t.turnId,"agent.turn.sequence":n.sequence},startTime:n.startTimeMs},contextFromSpanContext({isRemote:n.parentIsRemote??!1,spanId:n.parentSpanId,traceFlags:n.context.traceFlags,traceId:n.context.traceId})));i.addEvent(`turn.started`,void 0,n.startTimeMs),n.terminal!==void 0&&(i.addEvent(n.terminal.type),n.terminal.type===`turn.failed`&&recordError(i,n.terminal.error)),i.end()}await e.stateStore.deleteTurn(t.sessionId,t.turnId)}}(t.type===`session.completed`||t.type===`session.failed`)&&(await _.deleteForSession(t.sessionId),await e.stateStore.deleteSession(t.sessionId))},onModelCallStarted=n=>{let i=h.get(n.scope);if(i===void 0)return;i.step.span.setAttribute(`agent.model.id`,n.model.modelId),i.step.span.setAttribute(`agent.model.provider`,n.model.provider);let a=e.tracer.startSpan(modelSpanName(n.model.modelId),{attributes:{"gen_ai.agent.name":n.scope.functionId,"gen_ai.operation.name":`chat`,"gen_ai.provider.name":n.model.provider,"gen_ai.request.model":n.model.modelId,...runtimeContextAttributes(n.runtimeContext)}},i.operation.context);if(t&&n.input!==void 0){let e=messagesContentAttribute(n.input.messages);e!==void 0&&a.setAttribute(`ai.prompt.messages`,e);let t=genAiInputMessagesAttribute(n.input.messages);t!==void 0&&a.setAttribute(`gen_ai.input.messages`,t);let r=systemPromptAttribute(n.input.instructions);r!==void 0&&a.setAttribute(`ai.prompt.system`,r);let i=genAiSystemInstructionsAttribute(n.input.instructions);i!==void 0&&a.setAttribute(`gen_ai.system_instructions`,i)}let s={context:trace.setSpan(i.operation.context,a),span:a};getExecutionContexts(n.scope).set(n.idempotencyKey,s.context),getSpanStates(g,n.scope).set(n.idempotencyKey,s)},onModelCallTerminal=e=>{p.get(e.scope)?.delete(e.idempotencyKey);let t=takeSpanState(g,e.scope,e.idempotencyKey);if(t!==void 0){if(e.type===`model.call.failed`)recordError(t.span,e.error);else{setAgentUsage(t.span,e.usage),t.span.setAttribute(`gen_ai.response.finish_reasons`,[e.finishReason]);let n=h.get(e.scope);if(n!==void 0&&setAgentUsage(n.step.span,e.usage),f){t.span.setAttribute(`ai.response.finish_reason`,e.finishReason);let n=e.content??[],r=genAiOutputMessagesAttribute(n,e.finishReason);r!==void 0&&t.span.setAttribute(`gen_ai.output.messages`,r);let i=textContentAttribute(n.filter(e=>e.type===`reasoning`).map(e=>e.text).filter(e=>e.trim().length>0).join(`
|
|
2
|
+
`));i!==void 0&&t.span.setAttribute(`ai.response.reasoning`,i);let o=textContentAttribute(n.filter(e=>e.type===`text`).map(e=>e.text).join(``));o!==void 0&&t.span.setAttribute(`ai.response.text`,o);let c=n.filter(e=>e.type===`tool-call`).map(e=>({callId:e.callId,input:e.input,toolName:e.toolName}));if(c.length>0){let e=contentAttribute(c,!1);e!==void 0&&t.span.setAttribute(`ai.response.tool_calls`,e)}let l=n.filter(e=>e.type===`tool-result`||e.type===`tool-error`).map(e=>e.type===`tool-result`?{callId:e.callId,input:e.input,output:e.output,toolName:e.toolName}:{callId:e.callId,error:errorText(e.error),input:e.input,toolName:e.toolName});if(l.length>0){let e=toolResultsContentAttribute(l);e!==void 0&&t.span.setAttribute(`ai.response.tool_results`,e)}}}t.span.end()}},C=createAgentChannelDeliveryInstrumentation({ensureSessionContext:b,frameworkVersion:e.frameworkVersion,idGenerator:e.idGenerator,recordInputs:t,stateStore:e.stateStore,tracer:e.tracer}),onStepMetadata=e=>{let t=h.get(e.scope);if(t===void 0)return;let n=readGatewayCost(e.providerMetadata);if(n!==void 0)for(let[e,r]of Object.entries(n))t.step.span.setAttribute(e,r)};return{hook:{capture:t||f?`content`:`metadata`,events:{...C,"action.completed":_.events[`action.completed`],"action.failed":_.events[`action.failed`],async"action.started"(e,t){await _.events[`action.started`](e,t),await y.actionStarted(e)},...v,"step.attempt.completed":onStepTerminal,"step.attempt.failed":onStepTerminal,"step.attempt.metadata":onStepMetadata,"step.attempt.started":onStepStarted,"model.call.completed":onModelCallTerminal,"model.call.failed":onModelCallTerminal,"model.call.started":onModelCallStarted,"session.completed":onSessionTransition,"session.failed":onSessionTransition,"session.started":onSessionStarted,"session.waiting":onSessionTransition,...y.events,"turn.cancelled":onTurnTerminal,"turn.completed":onTurnTerminal,"turn.failed":onTurnTerminal,"turn.started":onTurnStarted},name:`eve.otel`},prepareSessionTrace:x,prepareTurnTrace:S,async runInContext(t,r){let i=m.get(t.scope.attemptId)??t.scope,a=p.get(i),o=t.type===`model.call`?a?.get(t.idempotencyKey):y.contextFor(t.scope.attemptId,t.idempotencyKey);if(o===void 0){let n=await e.stateStore.getTurn(t.scope.sessionId,t.scope.turnId);n!==void 0&&(o=withChannelAudience(contextFromSpanContext(n.context),t.scope.channelAudience),isSampledTrace(n.context)||(o=suppressTracing(o)))}return o===void 0?r():context.with(o,r)}};function getExecutionContexts(e){let t=p.get(e);return t===void 0&&(t=new Map,p.set(e,t)),t}function drainOpenSpans(e){for(let t of g.get(e.scope)?.values()??[])e.type===`step.attempt.failed`&&recordError(t.span,e.error),t.span.end();g.delete(e.scope)}}function getSpanStates(e,t){let n=e.get(t);return n===void 0&&(n=new Map,e.set(t,n)),n}function takeSpanState(e,t,n){let r=e.get(t),i=r?.get(n);if(r!==void 0)return r.delete(n),r.size===0&&e.delete(t),i}function parentLineageAttributes(e){if(e===void 0)return{};let t={"agent.parent.call_id":e.callId,"agent.parent.session.id":e.sessionId,"agent.parent.turn.id":e.turnId};return e.subagentName!==void 0&&(t[`agent.subagent.name`]=e.subagentName),t}function contextFromSpanContext(t){return trace.setSpan(ROOT_CONTEXT,trace.wrapSpanContext(t))}function readGatewayCost(e){let t=e.gateway;if(!isRecord(t))return;let n={},r=readUsd(t.cost);r!==void 0&&(n[`gen_ai.usage.cost`]=r);let i=readUsd(t.gatewayCost);i!==void 0&&(n[`gen_ai.usage.gateway_cost`]=i);let a=readUsd(t.inputInferenceCost);a!==void 0&&(n[`gen_ai.usage.input_cost`]=a);let o=readUsd(t.outputInferenceCost);return o!==void 0&&(n[`gen_ai.usage.output_cost`]=o),typeof t.generationId==`string`&&t.generationId.length>0&&(n[`gen_ai.generation.id`]=t.generationId),Object.keys(n).length===0?void 0:n}function readUsd(e){if(typeof e!=`string`)return;let t=Number(e);return Number.isFinite(t)?t:void 0}function isRecord(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function modelSpanName(e){return`chat ${e}`}function runtimeContextAttributes(e){let t={};if(e===void 0)return t;for(let[n,r]of Object.entries(e))flattenContextAttribute(t,`ai.settings.context.${n}`,r);return t}function flattenContextAttribute(e,t,n){if(n!=null){if(typeof n==`string`||typeof n==`number`||typeof n==`boolean`){e[t]=n;return}if(Array.isArray(n)){let r=n.filter(e=>typeof e==`string`||typeof e==`number`||typeof e==`boolean`);if(r.length!==n.length||new Set(r.map(e=>typeof e)).size!==1)return;e[t]=r;return}if(typeof n==`object`)for(let[r,i]of Object.entries(n))flattenContextAttribute(e,`${t}.${r}`,i)}}function errorText(e){return e instanceof Error?e.message:e}function recordError(e,n){n instanceof Error?(e.recordException(n),e.setStatus({code:SpanStatusCode.ERROR,message:n.message})):e.setStatus({code:SpanStatusCode.ERROR})}export{createAgentOtelInstrumentation};
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import type { Tracer } from "#compiled/@opentelemetry/api/index.js";
|
|
2
2
|
import { type InstrumentationSessionStartedEvent, type InstrumentationTraceContext, type InstrumentationTurnStartedEvent } from "#harness/instrumentation/lifecycle.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 AgentSessionTraceState, type AgentTraceStateStore } from "#tracing/agent-trace-state.js";
|
|
5
6
|
interface AgentOtelSessionContextInput {
|
|
6
7
|
readonly frameworkVersion: string;
|
|
7
8
|
readonly idGenerator: AgentSpanIdGenerator;
|
|
8
9
|
readonly stateStore: AgentTraceStateStore;
|
|
9
10
|
readonly tracer: Tracer;
|
|
11
|
+
readonly tracePolicy?: TraceCapturePolicy;
|
|
10
12
|
}
|
|
11
13
|
interface AgentOtelSessionContext {
|
|
12
14
|
readonly ensureSessionContext: (event: InstrumentationSessionStartedEvent) => Promise<AgentSessionTraceState>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{sessionIdempotencyKey}from"#harness/instrumentation/lifecycle.js";import{SESSION_WINDOW_TURN_LIMIT}from"#tracing/agent-trace-state.js";function createAgentOtelSessionContext(
|
|
1
|
+
import{normalizeChannelAudience}from"#shared/channel-audience.js";import{sessionIdempotencyKey}from"#harness/instrumentation/lifecycle.js";import{SESSION_WINDOW_TURN_LIMIT}from"#tracing/agent-trace-state.js";function createAgentOtelSessionContext(r){let openSessionWindow=e=>{if(!shouldTrace(r.tracePolicy,e))return{isRemote:!1,spanId:r.idGenerator.deriveSpanId(`session:${e.sessionId}:${e.index}`),traceFlags:0,traceId:r.idGenerator.generateTraceId()};let t=r.tracer.startSpan(`agent.session`,{attributes:{"agent.framework.name":`eve`,"agent.framework.version":r.frameworkVersion,"agent.channel.audience":e.channelAudience,"agent.name":e.agentName,"agent.root.session.id":e.rootSessionId,"agent.session.id":e.sessionId,"agent.session.window":e.index,"agent.trace.schema.version":1,...e.previousTraceId===void 0?{}:{"agent.session.window.previous.trace.id":e.previousTraceId}},root:!0});return t.addEvent(e.index===0?`session.started`:`session.window.opened`),t.end(),t.spanContext()},ensureSessionContext=async t=>{let n=await r.stateStore.getSession(t.sessionId);return n===void 0&&(n={agentName:t.agentName,channelAudience:normalizeChannelAudience(t.channelAudience),channelKind:t.channelKind,context:t.parentTraceContext===void 0?openSessionWindow({agentName:t.agentName,channelAudience:normalizeChannelAudience(t.channelAudience),index:0,rootSessionId:t.rootSessionId,sessionId:t.sessionId}):adoptedSpanContext(t.parentTraceContext,shouldTrace(r.tracePolicy,{agentName:t.agentName,channelAudience:normalizeChannelAudience(t.channelAudience),rootSessionId:t.rootSessionId,sessionId:t.sessionId})),rootSessionId:t.rootSessionId,turnsInWindow:0,window:0},await r.stateStore.setSession(t.sessionId,n)),n},advanceSessionWindow=(t,r)=>{if(r.turnsInWindow<SESSION_WINDOW_TURN_LIMIT)return r;let i=r.window+1;return{...r,context:openSessionWindow({agentName:r.agentName,channelAudience:normalizeChannelAudience(r.channelAudience),index:i,previousTraceId:r.context.traceId,rootSessionId:r.rootSessionId,sessionId:t}),turnsInWindow:0,window:i}};return{ensureSessionContext,prepareSessionTrace:async e=>portableSpanContext((await ensureSessionContext(e)).context),prepareTurnTrace:async e=>{let n=await r.stateStore.getTurn(e.sessionId,e.turnId);if(n!==void 0)return{spanId:n.parentSpanId,traceFlags:n.context.traceFlags,traceId:n.context.traceId};let i=advanceSessionWindow(e.sessionId,await ensureSessionContext({agentName:void 0,channelAudience:`unknown`,channelKind:void 0,idempotencyKey:sessionIdempotencyKey(e.sessionId),parentTraceContext:e.parentTraceContext,rootSessionId:e.rootSessionId,sessionId:e.sessionId,type:`session.started`})),a={isRemote:!1,spanId:r.idGenerator.deriveSpanId(`turn:${e.idempotencyKey}`),traceFlags:i.context.traceFlags,traceId:i.context.traceId};return await r.stateStore.setSession(e.sessionId,{...i,turnsInWindow:i.turnsInWindow+1}),await r.stateStore.setTurn(e.sessionId,e.turnId,{context:a,lineage:e.parentLineage,parentIsRemote:i.context.isRemote,parentSpanId:i.context.spanId,rootSessionId:e.rootSessionId,sequence:e.sequence,startTimeMs:Date.now()}),portableSpanContext(i.context)}}}function shouldTrace(e,t){try{return e?.({agentName:t.agentName,audience:t.channelAudience,rootSessionId:t.rootSessionId,sessionId:t.sessionId})??t.channelAudience===`public`}catch{return!1}}function portableSpanContext(e){return{spanId:e.spanId,traceFlags:e.traceFlags,traceId:e.traceId}}function adoptedSpanContext(e,t=!0){return{isRemote:`isRemote`in e&&e.isRemote===!0,spanId:e.spanId,traceFlags:t?e.traceFlags:0,traceId:e.traceId}}export{createAgentOtelSessionContext};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{contextStorage,loadContext}from"#context/container.js";import{ContextKey}from"#context/key.js";const AgentTraceContextKey=new ContextKey(`eve.harness.agentTrace`,{codec:{deserialize:deserializeState,serialize:serializeState}});function preserveSerializedAgentTraceState(e,t){let n=t[AgentTraceContextKey.name];return n===void 0?e:{...e,[AgentTraceContextKey.name]:n}}function readSessionTraceContext(e,t){let n=e[AgentTraceContextKey.name];if(n!==void 0)return deserializeState(n).sessions[t]?.context}function readActionTraceContext(e,t,n,
|
|
1
|
+
import{normalizeChannelAudience}from"#shared/channel-audience.js";import{contextStorage,loadContext}from"#context/container.js";import{ContextKey}from"#context/key.js";const AgentTraceContextKey=new ContextKey(`eve.harness.agentTrace`,{codec:{deserialize:deserializeState,serialize:serializeState}});function preserveSerializedAgentTraceState(e,t){let n=t[AgentTraceContextKey.name];return n===void 0?e:{...e,[AgentTraceContextKey.name]:n}}function readSessionTraceContext(e,t){let n=e[AgentTraceContextKey.name];if(n!==void 0)return deserializeState(n).sessions[t]?.context}function readActionTraceContext(e,t,n,r){let a=e[AgentTraceContextKey.name];if(a===void 0)return;let o=Object.values(deserializeState(a).actions).find(e=>e.sessionId===t&&e.turnId===n&&e.callId===r);if(o!==void 0)return{isRemote:!1,spanId:o.spanId,traceFlags:o.parent.traceFlags,traceId:o.parent.traceId}}var ContextAgentTraceStateStore=class{deleteAction(e){updateState(t=>{let n={...t.actions};return delete n[e],{...t,actions:n}})}deleteActions(e,t){updateState(n=>{let r={...n.actions};for(let[n,i]of Object.entries(r))i.sessionId===e&&(t===void 0||i.turnId===t)&&delete r[n];return{...n,actions:r}})}deleteSession(e){updateState(t=>{let n={...t.sessions};return delete n[e],{...t,sessions:n}})}deleteTurn(e,t){updateState(n=>{let r={...n.turns};return delete r[turnKey(e,t)],{...n,turns:r}})}findAction(e,n){return Object.values(contextStorage.getStore()?.get(AgentTraceContextKey)?.actions??{}).find(t=>t.sessionId===e&&t.callId===n)}getAction(e){return contextStorage.getStore()?.get(AgentTraceContextKey)?.actions[e]}getSession(e){return contextStorage.getStore()?.get(AgentTraceContextKey)?.sessions[e]}getTurn(e,n){return contextStorage.getStore()?.get(AgentTraceContextKey)?.turns[turnKey(e,n)]}setAction(e,t){updateState(n=>({...n,actions:{...n.actions,[e]:t}}))}setSession(e,t){updateState(n=>({...n,sessions:{...n.sessions,[e]:t}}))}setTurn(e,t,n){updateState(r=>({...r,turns:{...r.turns,[turnKey(e,t)]:n}}))}};function updateState(e){loadContext().set(AgentTraceContextKey,t=>e(t??{actions:{},sessions:{},turns:{}}))}function turnKey(e,t){return`${e}\0${t}`}function serializeState(e){return{actions:e.actions,sessions:Object.fromEntries(Object.entries(e.sessions).map(([e,t])=>[e,{...t,context:serializeSpanContext(t.context)}])),turns:Object.fromEntries(Object.entries(e.turns).map(([e,t])=>[e,{...t,context:serializeSpanContext(t.context),terminal:t.terminal===void 0?void 0:t.terminal.type===`turn.failed`?{error:serializeError(t.terminal.error),type:t.terminal.type}:{type:t.terminal.type}}]))}}function deserializeState(t){return isRecord(t)?{actions:deserializeRecord(t.actions,deserializeAction),sessions:deserializeRecord(t.sessions,t=>{if(!(!isRecord(t)||!isSpanContext(t.context)))return{agentName:typeof t.agentName==`string`?t.agentName:void 0,channelAudience:normalizeChannelAudience(t.channelAudience),channelKind:typeof t.channelKind==`string`?t.channelKind:void 0,context:t.context,rootSessionId:typeof t.rootSessionId==`string`?t.rootSessionId:``,turnsInWindow:typeof t.turnsInWindow==`number`?t.turnsInWindow:0,window:typeof t.window==`number`?t.window:0}}),turns:deserializeRecord(t.turns,e=>{if(!(!isRecord(e)||!isSpanContext(e.context))&&!(typeof e.parentSpanId!=`string`||typeof e.startTimeMs!=`number`))return{context:e.context,lineage:deserializeLineage(e.lineage),parentIsRemote:typeof e.parentIsRemote==`boolean`?e.parentIsRemote:void 0,parentSpanId:e.parentSpanId,rootSessionId:typeof e.rootSessionId==`string`?e.rootSessionId:``,sequence:typeof e.sequence==`number`?e.sequence:0,startTimeMs:e.startTimeMs,terminal:deserializeTerminal(e.terminal)}})}:{actions:{},sessions:{},turns:{}}}function deserializeAction(t){if(!(!isRecord(t)||typeof t.attemptIndex!=`number`||typeof t.callId!=`string`||!isActionKind(t.kind)||typeof t.name!=`string`||!isSpanContext(t.parent)||typeof t.rootSessionId!=`string`||typeof t.sessionId!=`string`||typeof t.spanId!=`string`||typeof t.startTimeMs!=`number`||typeof t.stepIndex!=`number`||typeof t.turnId!=`string`))return{attemptIndex:t.attemptIndex,callId:t.callId,channelAudience:normalizeChannelAudience(t.channelAudience),inputAttribute:typeof t.inputAttribute==`string`?t.inputAttribute:void 0,kind:t.kind,name:t.name,parent:t.parent,rootSessionId:t.rootSessionId,sessionId:t.sessionId,spanId:t.spanId,startTimeMs:t.startTimeMs,stepIndex:t.stepIndex,turnId:t.turnId}}function isActionKind(e){return e===`load-skill`||e===`remote-agent-call`||e===`subagent-call`||e===`tool-call`}function deserializeRecord(e,t){if(!isRecord(e))return{};let n={};for(let[r,i]of Object.entries(e)){let e=t(i);e!==void 0&&(n[r]=e)}return n}function deserializeLineage(e){if(!(!isRecord(e)||typeof e.callId!=`string`||typeof e.sessionId!=`string`||typeof e.turnId!=`string`))return{callId:e.callId,sessionId:e.sessionId,subagentName:typeof e.subagentName==`string`?e.subagentName:void 0,turnId:e.turnId}}function deserializeTerminal(e){if(!isRecord(e)||typeof e.type!=`string`)return;let t=e.type;if(isTurnTerminalType(t))return t===`turn.failed`?{error:deserializeError(e.error),type:t}:{type:t}}function serializeSpanContext(e){return{isRemote:e.isRemote,spanId:e.spanId,traceFlags:e.traceFlags,traceId:e.traceId}}function isSpanContext(e){return isRecord(e)&&typeof e.spanId==`string`&&typeof e.traceFlags==`number`&&typeof e.traceId==`string`}function serializeError(e){return e instanceof Error?{message:e.message,name:e.name,stack:e.stack}:void 0}function deserializeError(e){if(!isRecord(e)||typeof e.message!=`string`)return;let t=Error(e.message);return typeof e.name==`string`&&(t.name=e.name),typeof e.stack==`string`&&(t.stack=e.stack),t}function isTurnTerminalType(e){return e===`turn.cancelled`||e===`turn.completed`||e===`turn.failed`}function isRecord(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}export{ContextAgentTraceStateStore,preserveSerializedAgentTraceState,readActionTraceContext,readSessionTraceContext};
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import type { SpanContext } from "#compiled/@opentelemetry/api/index.js";
|
|
2
2
|
import type { InstrumentationActionKind, InstrumentationParentLineage, InstrumentationTraceContext, InstrumentationTurnFailedEvent, InstrumentationTurnSettledEvent } from "#harness/instrumentation/lifecycle.js";
|
|
3
|
+
import type { ChannelAudience } from "#shared/channel-audience.js";
|
|
3
4
|
/** Sized so an ordinary session stays one trace and only an outsized one rolls. */
|
|
4
5
|
export declare const SESSION_WINDOW_TURN_LIMIT = 200;
|
|
5
6
|
export interface AgentSessionTraceState {
|
|
7
|
+
readonly channelAudience?: ChannelAudience;
|
|
6
8
|
readonly agentName?: string;
|
|
7
9
|
readonly channelKind?: string;
|
|
8
10
|
readonly context: SpanContext;
|
|
@@ -28,6 +30,7 @@ export interface AgentTurnTraceState {
|
|
|
28
30
|
export interface AgentActionTraceState {
|
|
29
31
|
readonly attemptIndex: number;
|
|
30
32
|
readonly callId: string;
|
|
33
|
+
readonly channelAudience?: ChannelAudience;
|
|
31
34
|
readonly inputAttribute?: string;
|
|
32
35
|
readonly kind: InstrumentationActionKind;
|
|
33
36
|
readonly name: string;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { type Context } from "#compiled/@opentelemetry/api/index.js";
|
|
2
|
+
import { type ChannelAudience } from "#shared/channel-audience.js";
|
|
3
|
+
export declare function channelAudienceFromContext(context: unknown): ChannelAudience;
|
|
4
|
+
export declare function withChannelAudience(context: Context, audience: unknown): Context;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{normalizeChannelAudience}from"#shared/channel-audience.js";import{createContextKey}from"#compiled/@opentelemetry/api/index.js";const CHANNEL_AUDIENCE_KEY=createContextKey(`eve.channel.audience`);function channelAudienceFromContext(e){if(typeof e!=`object`||!e)return`unknown`;let t=Reflect.get(e,`getValue`);return typeof t==`function`?normalizeChannelAudience(Reflect.apply(t,e,[CHANNEL_AUDIENCE_KEY])):`unknown`}function withChannelAudience(e,t){return e.setValue(CHANNEL_AUDIENCE_KEY,normalizeChannelAudience(t))}export{channelAudienceFromContext,withChannelAudience};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
const INPUT_CONTENT_ATTRIBUTES=new Set([`agent.channel.delivery.input`,`ai.documents`,`ai.prompt`,`ai.prompt.messages`,`ai.prompt.system`,`ai.prompt.toolChoice`,`ai.prompt.tools`,`ai.value`,`ai.values`,`gen_ai.input.messages`,`gen_ai.system_instructions`,`gen_ai.tool.call.arguments`,`gen_ai.tool.definitions`]),OUTPUT_CONTENT_ATTRIBUTES=new Set([`ai.embedding`,`ai.embeddings`,`ai.ranking`,`ai.response.files`,`ai.response.object`,`ai.response.reasoning`,`ai.response.text`,`ai.response.toolCalls`,`ai.response.tool_calls`,`ai.response.tool_results`,`ai.toolCall.args`,`ai.toolCall.result`,`gen_ai.output.messages`,`gen_ai.tool.call.result`]);function isDeclined(n,r){return!r.recordInputs&&INPUT_CONTENT_ATTRIBUTES.has(n)?!0:!r.recordOutputs&&OUTPUT_CONTENT_ATTRIBUTES.has(n)}function withoutDeclinedContent(e,t){let n=Object.keys(e);if(!n.some(e=>isDeclined(e,t)))return;let r={};for(let i of n)isDeclined(i,t)||(r[i]=e[i]);return r}export{withoutDeclinedContent};
|
|
1
|
+
const INPUT_CONTENT_ATTRIBUTES=new Set([`agent.channel.delivery.input`,`agent.approval.request`,`ai.documents`,`ai.prompt`,`ai.prompt.messages`,`ai.prompt.system`,`ai.prompt.toolChoice`,`ai.prompt.tools`,`ai.value`,`ai.values`,`gen_ai.input.messages`,`gen_ai.system_instructions`,`gen_ai.tool.call.arguments`,`gen_ai.tool.definitions`]),OUTPUT_CONTENT_ATTRIBUTES=new Set([`agent.approval.response`,`ai.embedding`,`ai.embeddings`,`ai.ranking`,`ai.response.files`,`ai.response.object`,`ai.response.reasoning`,`ai.response.text`,`ai.response.toolCalls`,`ai.response.tool_calls`,`ai.response.tool_results`,`ai.toolCall.args`,`ai.toolCall.result`,`gen_ai.output.messages`,`gen_ai.tool.call.result`]);function isDeclined(n,r){return!r.recordInputs&&INPUT_CONTENT_ATTRIBUTES.has(n)?!0:!r.recordOutputs&&OUTPUT_CONTENT_ATTRIBUTES.has(n)}function withoutDeclinedContent(e,t){let n=Object.keys(e);if(!n.some(e=>isDeclined(e,t)))return;let r={};for(let i of n)isDeclined(i,t)||(r[i]=e[i]);return r}export{withoutDeclinedContent};
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import type { SpanProcessor } from "#compiled/@vercel/otel/index.js";
|
|
2
|
-
import { type
|
|
2
|
+
import { type SpanExportPolicy } from "#tracing/span-export-policy.js";
|
|
3
3
|
/**
|
|
4
4
|
* Puts one destination's content policy in front of it.
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
6
|
+
* Accepted traces carry content before they reach destination policies. This
|
|
7
|
+
* cannot strip an attribute in place: the span object is shared with every
|
|
8
|
+
* processor in the pipeline, and editing it would strip the attribute
|
|
9
|
+
* everywhere. So it gives the destination a facade whose attributes omit what
|
|
10
|
+
* its policy redacted.
|
|
11
11
|
*
|
|
12
12
|
* One facade follows the original from start through end. This preserves the
|
|
13
13
|
* object identity stateful processors key on without ever exposing the original
|
|
@@ -16,4 +16,4 @@ import { type ResolvedContentOptions } from "#tracing/content-attributes.js";
|
|
|
16
16
|
*
|
|
17
17
|
* @internal
|
|
18
18
|
*/
|
|
19
|
-
export declare function contentFilteringProcessor(downstream: SpanProcessor,
|
|
19
|
+
export declare function contentFilteringProcessor(downstream: SpanProcessor, exportPolicy?: SpanExportPolicy): SpanProcessor;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{hasSessionRelease}from"#tracing/local-traces.js";import{withoutDeclinedContent}from"#tracing/content-attributes.js";function contentFilteringProcessor(t
|
|
1
|
+
import{normalizeChannelAudience}from"#shared/channel-audience.js";import{hasSessionRelease}from"#tracing/local-traces.js";import{channelAudienceFromContext}from"#tracing/channel-audience-context.js";import{withoutDeclinedContent}from"#tracing/content-attributes.js";import{contentRedactionForSpan,spanExportPolicyStages}from"#tracing/span-export-policy.js";function contentFilteringProcessor(e,t){if(t===void 0)return e;let n=e;for(let e of spanExportPolicyStages(t).toReversed())n=policyFilteringProcessor(n,e);return n}function policyFilteringProcessor(e,r){let i=new WeakMap,a=new WeakSet,o={forceFlush:()=>e.forceFlush(),onEnd:t=>{if(typeof t!=`object`||!t)return;let n=facadeFor(t,r,i);if(a.has(t)||!n.exported){a.delete(t),i.delete(t);return}n.refresh();try{e.onEnd(n.value)}finally{i.delete(t)}},onStart:(t,o)=>{if(typeof t!=`object`||!t)return;let s=facadeFor(t,r,i,channelAudienceFromContext(o));if(!s.exported){a.add(t);return}e.onStart(s.value,o)},shutdown:()=>e.shutdown()};return hasSessionRelease(e)?{...o,releaseSession:t=>e.releaseSession(t)}:o}function facadeFor(e,t,n,r){let i=n.get(e);if(i!==void 0)return i;let a=spanExportContext(e,r),o=contentForSpan(a,t),s={},c=[],l={},u=Object.create(Reflect.getPrototypeOf(e)),d=new Map,refresh=()=>{refreshAttributes(s,e,o,a,t),refreshEvents(c,e,o),refreshStatus(l,e,o)},f,readOriginal=t=>{let n=Reflect.get(e,t,e);if(typeof n!=`function`||t===`constructor`)return n;let r=d.get(t);if(r!==void 0)return r;let created=(...t)=>{let r=Reflect.apply(n,e,t);return refresh(),r===e?f:r};return d.set(t,created),created};Object.defineProperty(u,"attributes",{configurable:!0,enumerable:!0,value:s}),Object.defineProperty(u,"events",{configurable:!0,enumerable:!0,value:c}),Object.defineProperty(u,"status",{configurable:!0,enumerable:!0,value:l});for(let t of Reflect.ownKeys(e)){if(t===`attributes`||t===`events`||t===`status`)continue;let n=Reflect.getOwnPropertyDescriptor(e,t);Object.defineProperty(u,t,{configurable:!0,enumerable:n?.enumerable??!1,get:()=>readOriginal(t)})}f=new Proxy(u,{get:(e,t,n)=>Object.hasOwn(e,t)?Reflect.get(e,t,n):readOriginal(t)});let p={context:a,exported:shouldExport(a,t),refresh,value:f};return p.refresh(),n.set(e,p),p}function contentForSpan(e,t){let n=contentRedactionForSpan(t,e);return{recordInputs:!n.redactInputs,recordOutputs:!n.redactOutputs}}function refreshAttributes(e,t,n,i,a){for(let t of Object.keys(e))delete e[t];let o=t.attributes;if(typeof o!=`object`||!o)return;let s=withoutDeclinedContent(o,n)??o;for(let[t,n]of Object.entries(s)){let r=attributeDecision(a,{key:t,span:i,value:n});r.action===`keep`?e[t]=n:r.action===`replace`&&(e[t]=r.value)}}function spanExportContext(t,n=`unknown`){let r=t.attributes,i=typeof r==`object`&&r?r:{},a=[i[`agent.channel.audience`],i[`ai.settings.context.eve.channel.audience`]].filter(e=>e!==void 0).map(normalizeChannelAudience),o=a.length>0&&a.every(e=>e===a[0])?a[0]:a.length>0?`unknown`:n,s=t.spanContext?.(),c=typeof s==`object`&&s?s:{},l=t.name;return{attributes:i,audience:o,name:typeof l==`string`?l:``,spanId:typeof c.spanId==`string`?c.spanId:``,traceId:typeof c.traceId==`string`?c.traceId:``}}function shouldExport(e,t){if(t===void 0)return!0;try{return t.span?.(e)!==!1}catch{return!1}}function attributeDecision(e,t){if(e?.attribute===void 0)return{action:`keep`};try{return e.attribute(t)}catch{return{action:`drop`}}}function refreshEvents(e,t,n){e.length=0;let r=t.events;if(Array.isArray(r)){if(n.recordOutputs){e.push(...r);return}for(let t of r){if(typeof t!=`object`||!t)continue;let n=t;n.name!==`exception`&&e.push({...n,attributes:void 0})}}}function refreshStatus(e,t,n){for(let t of Object.keys(e))delete e[t];let r=t.status;if(typeof r!=`object`||!r)return;let i=r;i.code!==void 0&&(e.code=i.code),n.recordOutputs&&i.message!==void 0&&(e.message=i.message)}export{contentFilteringProcessor};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createLogger,formatError}from"#internal/logging.js";import{ContextAgentTraceStateStore}from"#tracing/agent-trace-context-store.js";import{registerInstrumentationRuntime}from"#harness/instrumentation/runtime.js";import{trace}from"#compiled/@opentelemetry/api/index.js";import{createInstrumentationHooks}from"#harness/instrumentation/lifecycle.js";import{hasSessionRelease}from"#tracing/local-traces.js";import{createAgentOtelInstrumentation}from"#tracing/agent-otel-provider.js";import{registerOtelPipeline}from"#tracing/otel-registration.js";const log=createLogger(`tracing.install-instrumentation-runtime`);function installInstrumentationRuntime(e){let t=[],a=[],o,s,c,runInContext=(e,t)=>t();if(e.collected.declared){o=registerOtelPipeline({pipeline:e.collected.pipeline,serviceName:e.serviceName});let r=createAgentOtelInstrumentation({frameworkVersion:e.frameworkVersion,idGenerator:o.idGenerator,recordInputs:e.collected.settings.recordInputs,recordOutputs:e.collected.settings.recordOutputs,stateStore:new ContextAgentTraceStateStore,tracer:trace.getTracer(`eve.agent`,e.frameworkVersion)});t.push({...r.hook,stateNamespace:`internal:otel`}),s=r.prepareSessionTrace,c=r.prepareTurnTrace,runInContext=r.runInContext;let i=e.collected.pipeline.spanProcessors.filter(isSpanProcessor).filter(hasSessionRelease);i.length>0&&a.push(sessionReleaseProvider(i))}let l=[...t,...e.providers,...a],u;return registerInstrumentationRuntime({forceFlush:()=>settleAll([...o===void 0?[]:[o.forceFlush],...l.map(e=>()=>e.flush?.())]),hooks:createInstrumentationHooks({parallel:e.providers,serialAfter:a,serialBefore:t}),otelSettings:e.collected.declared?e.collected.settings:void 0,prepareSessionTrace:s,prepareTurnTrace:c,runtimeContextResolvers:e.runtimeContextResolvers,runInContext,shutdown:()=>(u??=settleAll([...o===void 0?[]:[o.shutdown],...l.map(e=>()=>e.shutdown?.())]),u)})}function isSpanProcessor(e){return e!==`auto`}function sessionReleaseProvider(e){let release=async t=>{await Promise.all(e.map(e=>e.releaseSession(t.sessionId)))};return{events:{"session.completed":release,"session.failed":release},name:`eve.session-release`,stateNamespace:`internal:session-release`}}async function settleAll(e){let n=await Promise.allSettled(e.map(async e=>e()));for(let e of n)e.status===`rejected`&&log.warn(`instrumentation drain failed`,{error:formatError(e.reason)})}export{installInstrumentationRuntime};
|
|
1
|
+
import{createLogger,formatError}from"#internal/logging.js";import{ContextAgentTraceStateStore}from"#tracing/agent-trace-context-store.js";import{registerInstrumentationRuntime}from"#harness/instrumentation/runtime.js";import{trace}from"#compiled/@opentelemetry/api/index.js";import{createInstrumentationHooks}from"#harness/instrumentation/lifecycle.js";import{hasSessionRelease}from"#tracing/local-traces.js";import{createAgentOtelInstrumentation}from"#tracing/agent-otel-provider.js";import{registerOtelPipeline}from"#tracing/otel-registration.js";const log=createLogger(`tracing.install-instrumentation-runtime`);function installInstrumentationRuntime(e){let t=[],a=[],o,s,c,runInContext=(e,t)=>t();if(e.collected.declared){o=registerOtelPipeline({pipeline:e.collected.pipeline,serviceName:e.serviceName});let r=createAgentOtelInstrumentation({frameworkVersion:e.frameworkVersion,idGenerator:o.idGenerator,recordInputs:e.collected.settings.recordInputs,recordOutputs:e.collected.settings.recordOutputs,stateStore:new ContextAgentTraceStateStore,tracer:trace.getTracer(`eve.agent`,e.frameworkVersion),tracePolicy:e.collected.settings.tracePolicy});t.push({...r.hook,stateNamespace:`internal:otel`}),s=r.prepareSessionTrace,c=r.prepareTurnTrace,runInContext=r.runInContext;let i=e.collected.pipeline.spanProcessors.filter(isSpanProcessor).filter(hasSessionRelease);i.length>0&&a.push(sessionReleaseProvider(i))}let l=[...t,...e.providers,...a],u;return registerInstrumentationRuntime({forceFlush:()=>settleAll([...o===void 0?[]:[o.forceFlush],...l.map(e=>()=>e.flush?.())]),hooks:createInstrumentationHooks({parallel:e.providers,serialAfter:a,serialBefore:t}),otelSettings:e.collected.declared?e.collected.settings:void 0,prepareSessionTrace:s,prepareTurnTrace:c,runtimeContextResolvers:e.runtimeContextResolvers,runInContext,shutdown:()=>(u??=settleAll([...o===void 0?[]:[o.shutdown],...l.map(e=>()=>e.shutdown?.())]),u)})}function isSpanProcessor(e){return e!==`auto`}function sessionReleaseProvider(e){let release=async t=>{await Promise.all(e.map(e=>e.releaseSession(t.sessionId)))};return{events:{"session.completed":release,"session.failed":release},name:`eve.session-release`,stateNamespace:`internal:session-release`}}async function settleAll(e){let n=await Promise.allSettled(e.map(async e=>e()));for(let e of n)e.status===`rejected`&&log.warn(`instrumentation drain failed`,{error:formatError(e.reason)})}export{installInstrumentationRuntime};
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import { type InstrumentationRuntime } from "#harness/instrumentation/runtime.js";
|
|
2
|
+
import { type TraceCapturePolicy } from "#tracing/otel-declaration.js";
|
|
3
|
+
/** Zero-config local tracing keeps unclassified HTTP/TUI sessions observable. @internal */
|
|
4
|
+
export declare const localTracePolicy: TraceCapturePolicy;
|
|
2
5
|
/** Installs the zero-config local OTel runtime once in an `eve dev` worker. */
|
|
3
6
|
export declare function installLocalInstrumentationRuntime(input: {
|
|
4
7
|
readonly appRoot: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{getInstrumentationRuntime}from"#harness/instrumentation/runtime.js";import{installInstrumentationRuntime}from"#tracing/install-instrumentation-runtime.js";import{collectOtelPipeline,otel
|
|
1
|
+
import{getInstrumentationRuntime}from"#harness/instrumentation/runtime.js";import{installInstrumentationRuntime}from"#tracing/install-instrumentation-runtime.js";import{collectOtelPipeline,managedOtelIntegration,otel}from"#tracing/otel-declaration.js";import{createLocalTracesProcessor,resolveLocalTracesContent}from"#tracing/local-traces.js";const localTracePolicy=({audience:e})=>e===`public`||e===`unknown`;function installLocalInstrumentationRuntime(t){let n=getInstrumentationRuntime();if(n!==void 0)return n;let r=createLocalTracesProcessor({appRoot:t.appRoot});return installInstrumentationRuntime({collected:collectOtelPipeline([otel({tracePolicy:localTracePolicy}),managedOtelIntegration({...resolveLocalTracesContent(),spanProcessors:[r]})]),frameworkVersion:t.frameworkVersion,providers:[],serviceName:t.serviceName})}export{installLocalInstrumentationRuntime,localTracePolicy};
|
|
@@ -37,16 +37,7 @@ export declare function hasSessionRelease(processor: SpanProcessor): processor i
|
|
|
37
37
|
export declare function createLocalTracesProcessor(input?: {
|
|
38
38
|
readonly appRoot?: string;
|
|
39
39
|
}): LocalTracesProcessor;
|
|
40
|
-
/**
|
|
41
|
-
* The local spool's content policy: its options, intersected with
|
|
42
|
-
* `EVE_TRACES_CONTENT`.
|
|
43
|
-
*
|
|
44
|
-
* The variable applies to this destination only. `on` opts the zero-config
|
|
45
|
-
* spool into content, while `off` overrides authored local options without
|
|
46
|
-
* changing what a hosted backend beside it receives.
|
|
47
|
-
*
|
|
48
|
-
* @internal
|
|
49
|
-
*/
|
|
40
|
+
/** Maps legacy local content configuration onto destination redaction. @internal */
|
|
50
41
|
export declare function resolveLocalTracesContent(options?: {
|
|
51
42
|
readonly recordInputs?: boolean;
|
|
52
43
|
readonly recordOutputs?: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{LocalTraceSpanProcessor}from"#tracing/local-trace-span-processor.js";import{AgentTraceSpanProcessor}from"#tracing/agent-trace-span-processor.js";import{requestLocalTraceStorePrune,resolveLocalTraceRetentionSettings}from"#tracing/local-trace-retention.js";function hasSessionRelease(e){return typeof e.releaseSession==`function`}function createLocalTracesProcessor(
|
|
1
|
+
import{LocalTraceSpanProcessor}from"#tracing/local-trace-span-processor.js";import{AgentTraceSpanProcessor}from"#tracing/agent-trace-span-processor.js";import{requestLocalTraceStorePrune,resolveLocalTraceRetentionSettings}from"#tracing/local-trace-retention.js";function hasSessionRelease(e){return typeof e.releaseSession==`function`}function createLocalTracesProcessor(n={}){let r=n.appRoot??process.env.EVE_DEV_WORKER_APP_ROOT;if(r===void 0)return inertLocalTracesProcessor();let i=resolveLocalTraceRetentionSettings(),a=new AgentTraceSpanProcessor(i.enabled?[new LocalTraceSpanProcessor(r)]:[]),requestPrune=()=>{i.enabled&&requestLocalTraceStorePrune({activeTraceIds:a.activeTraceIds(),appRoot:r,maxAgeMs:i.maxAgeMs,maxTotalBytes:i.maxTotalBytes,retainCount:i.retainCount})};return requestPrune(),{forceFlush:()=>a.forceFlush(),onEnd:e=>a.onEnd(e),onStart:(e,t)=>a.onStart(e,t),async releaseSession(e){return await a.forceFlush(),a.releaseSession(e)?(requestPrune(),!0):!1},shutdown:()=>a.shutdown()}}function resolveLocalTracesContent(e={}){return process.env.EVE_TRACES_CONTENT===`off`?{recordInputs:!1,recordOutputs:!1}:{recordInputs:e.recordInputs!==!1,recordOutputs:e.recordOutputs!==!1}}function inertLocalTracesProcessor(){return{forceFlush:async()=>void 0,onEnd:()=>void 0,onStart:()=>void 0,releaseSession:async()=>!1,shutdown:async()=>void 0}}export{createLocalTracesProcessor,hasSessionRelease,resolveLocalTracesContent};
|