eve 0.53.0 → 0.54.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 +25 -0
- package/dist/src/channel/types.d.ts +2 -0
- package/dist/src/cli/commands/trace-detail.js +1 -1
- package/dist/src/cli/commands/trace.d.ts +2 -2
- package/dist/src/cli/commands/trace.js +3 -3
- package/dist/src/cli/dev/tui/runner.js +1 -1
- package/dist/src/cli/dev/tui/traces/trace-conversation.d.ts +5 -5
- package/dist/src/cli/dev/tui/traces/trace-conversation.js +1 -1
- package/dist/src/cli/dev/tui/traces/trace-view.js +1 -1
- package/dist/src/cli/dev/tui/traces/trace-viewer-session.js +1 -1
- package/dist/src/compiled/.vendor-stamp.json +1 -1
- package/dist/src/compiled/@opentelemetry/api/index.d.ts +1 -0
- package/dist/src/compiler/extension-compatibility.d.ts +6 -6
- package/dist/src/compiler/extension-compatibility.js +1 -1
- package/dist/src/compiler/manifest.d.ts +1 -1
- package/dist/src/compiler/manifest.js +1 -1
- package/dist/src/compiler/normalize-agent-config.js +1 -1
- package/dist/src/context/dynamic-instruction-lifecycle.d.ts +2 -1
- package/dist/src/context/dynamic-instruction-lifecycle.js +1 -1
- package/dist/src/context/keys.d.ts +3 -1
- package/dist/src/context/keys.js +1 -1
- package/dist/src/eve-channel/index.js +1 -1
- package/dist/src/execution/cancelled-model-call-batch.js +1 -1
- package/dist/src/execution/cancelled-turn-message.js +1 -1
- package/dist/src/execution/compaction.d.ts +2 -2
- package/dist/src/execution/coordination-dispatch-shared.d.ts +0 -1
- package/dist/src/execution/coordination-dispatch-shared.js +1 -1
- package/dist/src/execution/dispatch-turn-step.js +1 -1
- package/dist/src/execution/durable-session-migrations/turn-workflow.d.ts +7 -0
- package/dist/src/execution/durable-session-store.d.ts +2 -2
- package/dist/src/execution/eve-workflow-attributes.d.ts +3 -3
- package/dist/src/execution/next-driver-action.d.ts +2 -0
- package/dist/src/execution/route-child-delivery.js +1 -1
- package/dist/src/execution/runtime-context.js +1 -1
- package/dist/src/execution/sandbox/bindings/vercel-lifecycle.d.ts +5 -0
- package/dist/src/execution/sandbox/bindings/vercel-lifecycle.js +1 -1
- package/dist/src/execution/sandbox/bindings/vercel.js +1 -1
- package/dist/src/execution/session.js +2 -2
- package/dist/src/execution/tasks/parent/hitl-proxy-steps.d.ts +5 -1
- package/dist/src/execution/tasks/parent/hitl-proxy-steps.js +1 -1
- package/dist/src/execution/tasks/parent/tool-execution.js +1 -1
- package/dist/src/execution/tools/sleep-workflow.js +1 -1
- package/dist/src/execution/tools/subagent/invoke-step.d.ts +4 -0
- package/dist/src/execution/tools/subagent/invoke-step.js +1 -1
- package/dist/src/execution/tools/subagent/start.d.ts +2 -2
- package/dist/src/execution/tools/subagent/start.js +1 -1
- package/dist/src/execution/tools/subagent/task-agent-requests.js +1 -1
- package/dist/src/execution/tools/todo.d.ts +2 -2
- package/dist/src/execution/tools/todo.js +2 -2
- package/dist/src/execution/turn-dispatch.d.ts +2 -0
- package/dist/src/execution/turn-dispatch.js +1 -1
- package/dist/src/execution/turn-workflow.js +1 -1
- package/dist/src/execution/workflow-entry-crash.d.ts +39 -0
- package/dist/src/execution/workflow-entry-crash.js +1 -0
- package/dist/src/execution/workflow-entry.d.ts +2 -0
- package/dist/src/execution/workflow-entry.js +1 -1
- package/dist/src/execution/workflow-runtime.js +1 -1
- package/dist/src/execution/workflow-steps.js +1 -1
- package/dist/src/harness/compaction.js +1 -1
- package/dist/src/harness/current-messages.d.ts +7 -6
- package/dist/src/harness/current-messages.js +1 -1
- package/dist/src/harness/messages.d.ts +36 -0
- package/dist/src/harness/messages.js +1 -1
- package/dist/src/harness/provider-tool-history.d.ts +5 -5
- package/dist/src/harness/provider-tool-history.js +1 -1
- package/dist/src/harness/session-limit-enforcement.d.ts +2 -15
- package/dist/src/harness/tool-loop.js +2 -2
- package/dist/src/harness/types.d.ts +6 -4
- package/dist/src/instrumentation/ai-sdk-hook-bridge.js +1 -1
- package/dist/src/instrumentation/background-task-runtime.d.ts +18 -0
- package/dist/src/instrumentation/background-task-runtime.js +1 -0
- package/dist/src/instrumentation/channel-delivery.js +1 -1
- package/dist/src/instrumentation/lifecycle.d.ts +13 -0
- package/dist/src/instrumentation/lifecycle.js +1 -1
- package/dist/src/instrumentation/native-events.d.ts +7 -0
- package/dist/src/instrumentation/native-events.js +1 -1
- package/dist/src/instrumentation/parent-lineage.d.ts +2 -2
- package/dist/src/instrumentation/parent-lineage.js +1 -1
- package/dist/src/instrumentation/prepare-trace-context.d.ts +3 -11
- package/dist/src/instrumentation/prepare-trace-context.js +1 -1
- package/dist/src/instrumentation/principal-summary.d.ts +11 -0
- package/dist/src/instrumentation/principal-summary.js +1 -0
- package/dist/src/instrumentation/providers.js +1 -1
- package/dist/src/instrumentation/runtime.d.ts +8 -7
- package/dist/src/instrumentation/runtime.js +1 -1
- package/dist/src/instrumentation/session-context.d.ts +22 -0
- package/dist/src/instrumentation/session-context.js +1 -0
- package/dist/src/instrumentation/state.d.ts +7 -2
- package/dist/src/instrumentation/state.js +1 -1
- package/dist/src/internal/application/package.js +1 -1
- package/dist/src/internal/authored-definition/core.js +1 -1
- package/dist/src/internal/logging.js +1 -1
- package/dist/src/internal/nitro/routes/channel-dispatch.js +1 -1
- package/dist/src/internal/nitro/routes/channel-request-instrumentation.d.ts +4 -5
- package/dist/src/internal/nitro/routes/channel-request-instrumentation.js +1 -1
- package/dist/src/internal/vercel/build-agent-workspace.js +1 -1
- package/dist/src/internal/vercel-agent-summary.d.ts +24 -0
- package/dist/src/internal/vercel-agent-summary.js +1 -1
- package/dist/src/protocol/baggage.d.ts +15 -2
- package/dist/src/protocol/baggage.js +1 -1
- package/dist/src/public/channels/slack/api.d.ts +2 -0
- package/dist/src/public/channels/slack/api.js +1 -1
- package/dist/src/public/channels/slack/defaults.d.ts +6 -0
- package/dist/src/public/channels/slack/defaults.js +3 -3
- package/dist/src/public/channels/slack/limits.d.ts +6 -0
- package/dist/src/public/channels/slack/limits.js +1 -1
- package/dist/src/public/channels/slack/slackChannel.js +1 -1
- package/dist/src/public/definitions/agent.d.ts +1 -1
- package/dist/src/public/index.d.ts +1 -1
- package/dist/src/public/instrumentation/index.d.ts +5 -4
- package/dist/src/public/instrumentation/otel.d.ts +1 -1
- package/dist/src/runtime/agent/bootstrap.d.ts +2 -2
- package/dist/src/runtime/agent/bootstrap.js +1 -1
- package/dist/src/runtime/agent/resolve-model.js +1 -1
- package/dist/src/runtime/resolve-agent.js +1 -1
- package/dist/src/runtime/subagents/dynamic-agent-config.js +1 -1
- package/dist/src/self-modification/agent.js +1 -1
- package/dist/src/self-modification/extension/instructions.js +21 -20
- package/dist/src/self-modification/extension/tools/edit_file.js +1 -1
- package/dist/src/self-modification/extension/tools/search_registry.d.ts +1 -1
- package/dist/src/self-modification/extension/tools/search_registry.js +1 -1
- package/dist/src/setup/integrations/self-modification/setup.js +1 -1
- package/dist/src/setup/scaffold/create/project.js +1 -1
- package/dist/src/shared/agent-definition.d.ts +35 -0
- package/dist/src/shared/agent-definition.js +1 -1
- package/dist/src/shared/memory-state.js +1 -1
- package/dist/src/shared/serialized-observability-state.d.ts +12 -0
- package/dist/src/shared/serialized-observability-state.js +1 -0
- package/dist/src/subagents/invocation.d.ts +9 -0
- package/dist/src/subagents/remote-dispatch.d.ts +3 -3
- package/dist/src/subagents/remote-dispatch.js +1 -1
- package/dist/src/subagents/start-local.d.ts +2 -6
- package/dist/src/subagents/start-local.js +1 -1
- package/dist/src/subagents/start-remote.d.ts +2 -8
- package/dist/src/subagents/start-remote.js +1 -1
- package/dist/src/subagents/tool.d.ts +3 -13
- package/dist/src/subagents/tool.js +1 -1
- package/dist/src/tasks/delivery-context.d.ts +10 -1
- package/dist/src/tasks/delivery-context.js +2 -2
- package/dist/src/tracing/agent-action-instrumentation.d.ts +3 -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.d.ts +1 -6
- package/dist/src/tracing/agent-channel-delivery-instrumentation.js +1 -1
- package/dist/src/tracing/agent-invocation-coordinator.d.ts +28 -0
- package/dist/src/tracing/agent-invocation-coordinator.js +1 -0
- package/dist/src/tracing/agent-invocation-terminal.d.ts +18 -0
- package/dist/src/tracing/agent-invocation-terminal.js +1 -0
- package/dist/src/tracing/agent-otel-attributes.d.ts +4 -0
- package/dist/src/tracing/agent-otel-attributes.js +1 -0
- package/dist/src/tracing/agent-otel-content.js +1 -1
- package/dist/src/tracing/agent-otel-provider.d.ts +4 -6
- package/dist/src/tracing/agent-otel-provider.js +2 -2
- package/dist/src/tracing/agent-otel-runtime-context.d.ts +9 -0
- package/dist/src/tracing/agent-otel-runtime-context.js +1 -1
- package/dist/src/tracing/agent-otel-session-context.d.ts +4 -3
- package/dist/src/tracing/agent-otel-session-context.js +1 -1
- package/dist/src/tracing/agent-otel-usage.d.ts +4 -10
- package/dist/src/tracing/agent-otel-usage.js +1 -1
- package/dist/src/tracing/agent-span-contract.d.ts +25 -0
- package/dist/src/tracing/agent-span-contract.js +1 -0
- package/dist/src/tracing/agent-span-error.d.ts +3 -0
- package/dist/src/tracing/agent-span-error.js +1 -0
- package/dist/src/tracing/agent-span-id-generator.d.ts +3 -0
- package/dist/src/tracing/agent-span-id-generator.js +1 -1
- package/dist/src/tracing/agent-tool-instrumentation.js +1 -1
- package/dist/src/tracing/agent-trace-context-codec.d.ts +12 -0
- package/dist/src/tracing/agent-trace-context-codec.js +1 -0
- package/dist/src/tracing/agent-trace-context-store.d.ts +35 -8
- package/dist/src/tracing/agent-trace-context-store.js +1 -1
- package/dist/src/tracing/agent-trace-span-processor.d.ts +5 -7
- package/dist/src/tracing/agent-trace-span-processor.js +1 -1
- package/dist/src/tracing/agent-trace-state.d.ts +41 -3
- package/dist/src/tracing/agent-trace-state.js +1 -1
- package/dist/src/tracing/bounded-error.d.ts +1 -0
- package/dist/src/tracing/bounded-error.js +1 -0
- package/dist/src/tracing/content-span-processor.js +1 -1
- package/dist/src/tracing/conversation-context.d.ts +4 -0
- package/dist/src/tracing/conversation-context.js +1 -0
- package/dist/src/tracing/error-content-context.d.ts +3 -0
- package/dist/src/tracing/error-content-context.js +1 -0
- package/dist/src/tracing/install-instrumentation-runtime.js +1 -1
- package/dist/src/tracing/local-trace-reader.d.ts +6 -6
- package/dist/src/tracing/local-trace-reader.js +1 -1
- package/dist/src/tracing/local-traces.d.ts +6 -8
- package/dist/src/tracing/local-traces.js +1 -1
- package/dist/src/tracing/otel-declaration.d.ts +6 -4
- package/dist/src/tracing/otel-registration.d.ts +2 -1
- package/dist/src/tracing/otel-registration.js +1 -1
- package/dist/src/tracing/telemetry-budget.d.ts +4 -0
- package/dist/src/tracing/telemetry-budget.js +1 -0
- package/docs/agent-config.md +42 -8
- package/docs/channels/slack.mdx +5 -8
- package/docs/guides/instrumentation-providers.md +6 -1
- package/docs/guides/instrumentation.md +144 -14
- package/docs/guides/remote-agents.md +11 -0
- package/docs/reference/cli.md +8 -6
- package/docs/reference/typescript-api.md +1 -1
- package/docs/sandbox.mdx +1 -1
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { SpanContext } from "#compiled/@opentelemetry/api/index.js";
|
|
2
|
-
import type { InstrumentationActionKind, InstrumentationTraceContext, InstrumentationTurnFailedEvent, InstrumentationTurnSettledEvent } from "#instrumentation/lifecycle.js";
|
|
2
|
+
import type { InstrumentationActionKind, InstrumentationActionOutcome, InstrumentationParentLineage, InstrumentationPrincipalSummary, InstrumentationTraceContext, InstrumentationTurnFailedEvent, InstrumentationTurnSettledEvent, InstrumentationUsage } from "#instrumentation/lifecycle.js";
|
|
3
3
|
import type { ChannelAudience } from "#shared/channel-audience.js";
|
|
4
4
|
import type { InstrumentationDecision } from "#shared/instrumentation-decision.js";
|
|
5
5
|
export interface AgentSessionTraceState {
|
|
@@ -8,16 +8,20 @@ export interface AgentSessionTraceState {
|
|
|
8
8
|
readonly channelKind?: string;
|
|
9
9
|
readonly context: SpanContext;
|
|
10
10
|
readonly decision?: InstrumentationDecision;
|
|
11
|
+
readonly parentLineage?: InstrumentationParentLineage;
|
|
11
12
|
readonly rootSessionId: string;
|
|
12
13
|
}
|
|
13
14
|
export interface AgentTurnTraceState {
|
|
15
|
+
readonly caller?: SpanContext;
|
|
16
|
+
readonly channelDelivery?: AgentTurnChannelDeliveryTraceState;
|
|
14
17
|
readonly context: SpanContext;
|
|
18
|
+
readonly currentPrincipal?: InstrumentationPrincipalSummary;
|
|
19
|
+
readonly initiatorPrincipal?: InstrumentationPrincipalSummary;
|
|
20
|
+
readonly parentLineage?: InstrumentationParentLineage;
|
|
15
21
|
readonly modelUsage?: {
|
|
16
22
|
readonly inputTokens?: number;
|
|
17
23
|
readonly outputTokens?: number;
|
|
18
24
|
};
|
|
19
|
-
readonly parentIsRemote?: boolean;
|
|
20
|
-
readonly parentSpanId: string;
|
|
21
25
|
readonly rootSessionId: string;
|
|
22
26
|
readonly sequence: number;
|
|
23
27
|
readonly startTimeMs: number;
|
|
@@ -29,6 +33,14 @@ export interface AgentTurnTraceState {
|
|
|
29
33
|
readonly type: InstrumentationTurnSettledEvent["type"];
|
|
30
34
|
};
|
|
31
35
|
}
|
|
36
|
+
export interface AgentTurnChannelDeliveryTraceState {
|
|
37
|
+
readonly channelKind: string;
|
|
38
|
+
readonly channelName: string;
|
|
39
|
+
readonly deliveryId: string;
|
|
40
|
+
readonly inputAttribute?: string;
|
|
41
|
+
readonly requestId?: string;
|
|
42
|
+
readonly requestTraceContext?: SpanContext;
|
|
43
|
+
}
|
|
32
44
|
export interface AgentActionTraceState {
|
|
33
45
|
readonly attemptIndex: number;
|
|
34
46
|
readonly callId: string;
|
|
@@ -44,17 +56,36 @@ export interface AgentActionTraceState {
|
|
|
44
56
|
readonly stepIndex: number;
|
|
45
57
|
readonly turnId: string;
|
|
46
58
|
}
|
|
59
|
+
export interface AgentInvocationTraceState extends Omit<AgentActionTraceState, "inputAttribute" | "kind"> {
|
|
60
|
+
readonly kind: "remote-agent-call" | "subagent-call";
|
|
61
|
+
readonly parentActionCallId: string;
|
|
62
|
+
readonly recordOutputs?: boolean;
|
|
63
|
+
readonly terminal?: AgentActionTraceTerminalState;
|
|
64
|
+
}
|
|
65
|
+
export interface AgentActionTraceTerminalState {
|
|
66
|
+
readonly acceptedAtMs?: number;
|
|
67
|
+
readonly error?: unknown;
|
|
68
|
+
readonly outcome: InstrumentationActionOutcome;
|
|
69
|
+
readonly usage?: InstrumentationUsage;
|
|
70
|
+
}
|
|
47
71
|
/** Provider-owned serializable storage for durable agent trace state. */
|
|
48
72
|
export interface AgentTraceStateStore {
|
|
49
73
|
deleteAction(idempotencyKey: string): void | PromiseLike<void>;
|
|
74
|
+
deleteActionAnchors(sessionId: string): void | PromiseLike<void>;
|
|
50
75
|
deleteActions(sessionId: string, turnId?: string): void | PromiseLike<void>;
|
|
76
|
+
deleteInvocation(idempotencyKey: string): void | PromiseLike<void>;
|
|
77
|
+
deleteInvocations(sessionId: string, turnId?: string): void | PromiseLike<void>;
|
|
51
78
|
deleteSession(sessionId: string): void | PromiseLike<void>;
|
|
52
79
|
deleteTurn(sessionId: string, turnId: string): void | PromiseLike<void>;
|
|
53
80
|
findAction(sessionId: string, callId: string): AgentActionTraceState | undefined | PromiseLike<AgentActionTraceState | undefined>;
|
|
81
|
+
findActionAnchor(sessionId: string, turnId: string, callId: string): AgentActionTraceState | undefined | PromiseLike<AgentActionTraceState | undefined>;
|
|
82
|
+
findInvocations(sessionId?: string, turnId?: string, parentActionCallId?: string): readonly AgentInvocationTraceState[] | PromiseLike<readonly AgentInvocationTraceState[]>;
|
|
54
83
|
getAction(idempotencyKey: string): AgentActionTraceState | undefined | PromiseLike<AgentActionTraceState | undefined>;
|
|
55
84
|
getSession(sessionId: string): AgentSessionTraceState | undefined | PromiseLike<AgentSessionTraceState | undefined>;
|
|
56
85
|
getTurn(sessionId: string, turnId: string): AgentTurnTraceState | undefined | PromiseLike<AgentTurnTraceState | undefined>;
|
|
57
86
|
setAction(idempotencyKey: string, state: AgentActionTraceState): void | PromiseLike<void>;
|
|
87
|
+
setActionAnchor(idempotencyKey: string, state: AgentActionTraceState): void | PromiseLike<void>;
|
|
88
|
+
setInvocation(idempotencyKey: string, state: AgentInvocationTraceState): void | PromiseLike<void>;
|
|
58
89
|
setSession(sessionId: string, state: AgentSessionTraceState): void | PromiseLike<void>;
|
|
59
90
|
setTurn(sessionId: string, turnId: string, state: AgentTurnTraceState): void | PromiseLike<void>;
|
|
60
91
|
/** Atomically updates an existing turn and does nothing after that turn is deleted. */
|
|
@@ -64,14 +95,21 @@ export interface AgentTraceStateStore {
|
|
|
64
95
|
export declare class InMemoryAgentTraceStateStore implements AgentTraceStateStore {
|
|
65
96
|
#private;
|
|
66
97
|
deleteAction(idempotencyKey: string): void;
|
|
98
|
+
deleteActionAnchors(sessionId: string): void;
|
|
67
99
|
deleteActions(sessionId: string, turnId?: string): void;
|
|
100
|
+
deleteInvocation(idempotencyKey: string): void;
|
|
101
|
+
deleteInvocations(sessionId: string, turnId?: string): void;
|
|
68
102
|
deleteSession(sessionId: string): void;
|
|
69
103
|
deleteTurn(sessionId: string, turnId: string): void;
|
|
70
104
|
findAction(sessionId: string, callId: string): AgentActionTraceState | undefined;
|
|
105
|
+
findActionAnchor(sessionId: string, turnId: string, callId: string): AgentActionTraceState | undefined;
|
|
106
|
+
findInvocations(sessionId?: string, turnId?: string, parentActionCallId?: string): readonly AgentInvocationTraceState[];
|
|
71
107
|
getAction(idempotencyKey: string): AgentActionTraceState | undefined;
|
|
72
108
|
getSession(sessionId: string): AgentSessionTraceState | undefined;
|
|
73
109
|
getTurn(sessionId: string, turnId: string): AgentTurnTraceState | undefined;
|
|
74
110
|
setAction(idempotencyKey: string, state: AgentActionTraceState): void;
|
|
111
|
+
setActionAnchor(idempotencyKey: string, state: AgentActionTraceState): void;
|
|
112
|
+
setInvocation(idempotencyKey: string, state: AgentInvocationTraceState): void;
|
|
75
113
|
setSession(sessionId: string, state: AgentSessionTraceState): void;
|
|
76
114
|
setTurn(sessionId: string, turnId: string, state: AgentTurnTraceState): void;
|
|
77
115
|
updateTurn(sessionId: string, turnId: string, update: (state: AgentTurnTraceState) => AgentTurnTraceState): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var InMemoryAgentTraceStateStore=class{#e=new Map;#t=new Map;#n=new Map;deleteAction(e){this.#
|
|
1
|
+
var InMemoryAgentTraceStateStore=class{#e=new Map;#t=new Map;#n=new Map;#r=new Map;#i=new Map;deleteAction(e){this.#t.delete(e)}deleteActionAnchors(e){for(let[t,n]of this.#e)n.sessionId===e&&this.#e.delete(t)}deleteActions(e,t){for(let[n,r]of this.#t)r.sessionId===e&&(t===void 0||r.turnId===t)&&this.#t.delete(n)}deleteInvocation(e){this.#n.delete(e)}deleteInvocations(e,t){for(let[n,r]of this.#n)r.sessionId===e&&(t===void 0||r.turnId===t)&&this.#n.delete(n)}deleteSession(e){this.#r.delete(e)}deleteTurn(e,t){this.#i.delete(turnKey(e,t))}findAction(e,t){return[...this.#t.values()].find(n=>n.sessionId===e&&n.callId===t)}findActionAnchor(e,t,n){return[...this.#e.values()].find(r=>r.sessionId===e&&r.turnId===t&&r.callId===n)}findInvocations(e,t,n){return[...this.#n.values()].filter(r=>(e===void 0||r.sessionId===e)&&(t===void 0||r.turnId===t)&&(n===void 0||r.parentActionCallId===n))}getAction(e){return this.#t.get(e)}getSession(e){return this.#r.get(e)}getTurn(e,t){return this.#i.get(turnKey(e,t))}setAction(e,t){this.#t.set(e,t)}setActionAnchor(e,t){this.#e.set(e,t)}setInvocation(e,t){this.#n.set(e,t)}setSession(e,t){this.#r.set(e,t)}setTurn(e,t,n){this.#i.set(turnKey(e,t),n)}updateTurn(e,t,n){let r=turnKey(e,t),i=this.#i.get(r);i!==void 0&&this.#i.set(r,n(i))}};function turnKey(e,t){return`${e}:${t}`}export{InMemoryAgentTraceStateStore,turnKey};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function boundedTraceError(value: Error): Error;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{truncateTelemetryText}from"#tracing/telemetry-budget.js";function boundedTraceError(e){let t=Error(truncateTelemetryText(e.message,4096));return t.name=truncateTelemetryText(e.name,128),t.stack=e.stack===void 0?void 0:truncateTelemetryText(e.stack,8192),t}export{boundedTraceError};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{normalizeChannelAudience}from"#shared/channel-audience.js";import{
|
|
1
|
+
import{normalizeChannelAudience}from"#shared/channel-audience.js";import{hasConversationRelease}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,t){let n=new WeakMap,r=new WeakSet,i={forceFlush:()=>e.forceFlush(),onEnd:i=>{if(typeof i!=`object`||!i)return;let a=facadeFor(i,t,n);if(r.has(i)||!a.exported){r.delete(i),n.delete(i);return}a.refresh();try{e.onEnd(a.value)}finally{n.delete(i)}},onStart:(i,a)=>{if(typeof i!=`object`||!i)return;let o=facadeFor(i,t,n,channelAudienceFromContext(a));if(!o.exported){r.add(i);return}e.onStart(o.value,a)},shutdown:()=>e.shutdown()};return hasConversationRelease(e)?{...i,releaseConversation:t=>e.releaseConversation(t)}:i}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,r,i){for(let t of Object.keys(e))delete e[t];let a=t.attributes;if(typeof a!=`object`||!a)return;let o=withoutDeclinedContent(a,n)??a;for(let[t,n]of Object.entries(o)){let a=attributeDecision(i,{key:t,span:r,value:n});a.action===`keep`?e[t]=n:a.action===`replace`&&(e[t]=a.value)}}function spanExportContext(e,t=`unknown`){let n=e.attributes,r=typeof n==`object`&&n?n:{},i=[r[`agent.channel.audience`],r[`ai.settings.context.eve.channel.audience`]].filter(e=>e!==void 0).map(normalizeChannelAudience),a=i.length>0&&i.every(e=>e===i[0])?i[0]:i.length>0?`unknown`:t,o=e.spanContext?.(),s=typeof o==`object`&&o?o:{},c=e.name;return{attributes:r,audience:a,name:typeof c==`string`?c:``,spanId:typeof s.spanId==`string`?s.spanId:``,traceId:typeof s.traceId==`string`?s.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};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export declare function readConversationId(value: unknown): string | undefined;
|
|
2
|
+
export declare function resolveConversationId(fallback: string): string;
|
|
3
|
+
export declare function readConversationBaggage(value: string | null): string | undefined;
|
|
4
|
+
export declare function writeConversationBaggage(value: string | undefined, conversationId: string | undefined): string | undefined;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{contextStorage}from"#context/container.js";import{ConversationIdKey}from"#context/keys.js";import{readBaggageMember,replaceBaggageMember}from"#protocol/baggage.js";const BAGGAGE_KEY=`eve.conversation.id`,MAX_ID_BYTES=1024,encoder=new TextEncoder;function readConversationId(e){if(!(typeof e!=`string`||e.length===0||e.length>MAX_ID_BYTES||/[\u0000-\u001f\u007f-\u009f\u2028\u2029]/u.test(e)||encoder.encode(e).byteLength>MAX_ID_BYTES))try{return e}catch{return}}function resolveConversationId(e){return readConversationId(contextStorage.getStore()?.get(ConversationIdKey))??e}function readConversationBaggage(e){let t=readBaggageMember(e,BAGGAGE_KEY);return typeof t==`string`?void 0:readConversationId(t.value)}function writeConversationBaggage(e,t){let n=readConversationId(t);return n===void 0?e:replaceBaggageMember(e,BAGGAGE_KEY,encodeURIComponent(n))}export{readConversationBaggage,readConversationId,resolveConversationId,writeConversationBaggage};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{context,createContextKey}from"#compiled/@opentelemetry/api/index.js";const ERROR_CONTENT_KEY=createContextKey(`eve.trace.error-content`);function withErrorContent(e,t){return e.setValue(ERROR_CONTENT_KEY,t)}function capturesErrorContent(){return context.active().getValue(ERROR_CONTENT_KEY)!==!1}export{capturesErrorContent,withErrorContent};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createLogger,formatError}from"#internal/logging.js";import{ContextAgentTraceStateStore}from"#tracing/agent-trace-context-store.js";import{registerInstrumentationRuntime}from"#instrumentation/runtime.js";import{trace}from"#compiled/@opentelemetry/api/index.js";import{createInstrumentationHooks}from"#instrumentation/lifecycle.js";import{
|
|
1
|
+
import{createLogger,formatError}from"#internal/logging.js";import{contextStorage}from"#context/container.js";import{ConversationIdKey}from"#context/keys.js";import{readConversationId}from"#tracing/conversation-context.js";import{ContextAgentTraceStateStore}from"#tracing/agent-trace-context-store.js";import{registerInstrumentationRuntime}from"#instrumentation/runtime.js";import{trace}from"#compiled/@opentelemetry/api/index.js";import{createInstrumentationHooks}from"#instrumentation/lifecycle.js";import{AgentSpanIdGenerator}from"#tracing/agent-span-id-generator.js";import{hasConversationRelease}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=[],n=[],r,flushSettledInvocations,i,a,runInContext=(e,t)=>t();if(e.collected.declared){r=registerOtelPipeline({pipeline:e.collected.pipeline,serviceName:e.serviceName});let o=createAgentOtelInstrumentation({frameworkVersion:e.frameworkVersion,idGenerator:r.idGenerator,recordInputs:e.collected.settings.recordInputs,recordOutputs:e.collected.settings.recordOutputs,samplesTrace:r.samplesTrace,stateStore:new ContextAgentTraceStateStore,tracer:trace.getTracer(`eve.agent`,e.frameworkVersion),tracePolicy:e.collected.settings.tracePolicy});t.push({...o.hook,stateNamespace:`internal:otel`}),flushSettledInvocations=async()=>{await o.hook.flush?.()},i=o.prepareSessionTrace,a=o.prepareTurnTrace,runInContext=o.runInContext;let s=e.collected.pipeline.spanProcessors.filter(isSpanProcessor).filter(hasConversationRelease);s.length>0&&n.push(sessionReleaseProvider(s))}let o=[...t,...e.providers,...n],s;return registerInstrumentationRuntime({flushSettledInvocations,forceFlush:async()=>{await settleAll(o.map(e=>()=>e.flush?.())),await settleAll(r===void 0?[]:[r.forceFlush])},hooks:createInstrumentationHooks({parallel:e.providers,serialAfter:n,serialBefore:t}),idGenerator:r?.idGenerator??new AgentSpanIdGenerator,instrumentationProviders:e.instrumentationProviders,otelSettings:e.collected.declared?e.collected.settings:void 0,ownsAgentSpans:r!==void 0,prepareSessionTrace:i,prepareTurnTrace:a,runtimeContextResolvers:e.runtimeContextResolvers,runInContext,samplesTrace:r?.samplesTrace,shutdown:()=>(s??=(async()=>{await settleAll(o.map(e=>()=>e.shutdown?.())),await settleAll(r===void 0?[]:[r.shutdown])})(),s)})}function isSpanProcessor(e){return e!==`auto`}function sessionReleaseProvider(e){let release=async t=>{let n=readConversationId(contextStorage.getStore()?.get(ConversationIdKey))??t.sessionId;n===t.sessionId&&await Promise.all(e.map(e=>e.releaseConversation(n)))};return{events:{"session.completed":release,"session.failed":release},name:`eve.conversation-release`,stateNamespace:`internal:conversation-release`}}async function settleAll(e){let t=await Promise.allSettled(e.map(async e=>e()));for(let e of t)e.status===`rejected`&&log.warn(`instrumentation drain failed`,{error:formatError(e.reason)})}export{installInstrumentationRuntime};
|
|
@@ -31,15 +31,15 @@ export interface LocalTraceSpan {
|
|
|
31
31
|
export interface LocalTrace {
|
|
32
32
|
readonly agentName?: string;
|
|
33
33
|
readonly endTimeNs: bigint;
|
|
34
|
-
/**
|
|
35
|
-
readonly
|
|
34
|
+
/** Conversation that owns the trace, which is the one the list shows. */
|
|
35
|
+
readonly conversationId?: string;
|
|
36
36
|
/**
|
|
37
|
-
* Every
|
|
37
|
+
* Every conversation identifier recorded in the trace.
|
|
38
38
|
*
|
|
39
|
-
* A
|
|
40
|
-
*
|
|
39
|
+
* A logical conversation can contain separate root traces for the parent
|
|
40
|
+
* and child activations. Any matching conversation ID resolves to them.
|
|
41
41
|
*/
|
|
42
|
-
readonly
|
|
42
|
+
readonly conversationIds: readonly string[];
|
|
43
43
|
readonly spans: readonly LocalTraceSpan[];
|
|
44
44
|
readonly startTimeNs: bigint;
|
|
45
45
|
readonly traceId: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{readFile,readdir,stat}from"node:fs/promises";import{join}from"node:path";import{resolveLocalTraceSchemaDirectory,resolveLocalTraceSegmentsDirectory}from"#tracing/local-trace-span-processor.js";const TRACE_ID_PATTERN=/^[0-9a-f]{32}$/u,SPAN_FILE_PATTERN=/^[0-9a-f]{16}\.otlp\.json$/u;async function listLocalTraceIds(e){let t;try{t=await readdir(resolveLocalTraceSchemaDirectory(e),{withFileTypes:!0})}catch(e){if(isMissing(e))return[];throw e}return t.filter(e=>e.isDirectory()&&TRACE_ID_PATTERN.test(e.name)).map(e=>e.name)}async function readLocalTraceActivityMs(e,t){try{return(await stat(resolveLocalTraceSegmentsDirectory(e,t))).mtimeMs}catch(e){if(isMissing(e))return;throw e}}async function listLocalTraceSegments(e,t){let n;try{n=await readdir(resolveLocalTraceSegmentsDirectory(e,t),{withFileTypes:!0})}catch(e){if(isMissing(e))return;throw e}return n.filter(e=>e.isFile()&&SPAN_FILE_PATTERN.test(e.name)).map(e=>e.name).sort((e,t)=>e.localeCompare(t))}async function readLocalTraceSegment(e,t,n){let r=join(resolveLocalTraceSegmentsDirectory(e,t),n),i;try{if((await stat(r)).size>8388608)return[];i=await readFile(r,`utf8`)}catch{return[]}return parseLocalTraceSegment(i,t)}async function listLocalTraces(e){let t=[];for(let n of await listLocalTraceIds(e)){let r=await readLocalTrace(e,n).catch(()=>void 0);r!==void 0&&t.push(r)}return t.sort((e,t)=>e.startTimeNs===t.startTimeNs?e.traceId.localeCompare(t.traceId):e.startTimeNs>t.startTimeNs?-1:1)}async function readLocalTrace(e,t){let n=await listLocalTraceSegments(e,t);if(n===void 0)return;let r=new Map;for(let i of n)for(let n of await readLocalTraceSegment(e,t,i))r.has(n.spanId)||r.set(n.spanId,n);if(r.size!==0)return assembleLocalTrace(t,[...r.values()])}function compareLocalTraceSpans(e,t){return e.startTimeNs===t.startTimeNs?e.endTimeNs===t.endTimeNs?e.name.localeCompare(t.name)||e.spanId.localeCompare(t.spanId):e.endTimeNs<t.endTimeNs?-1:1:e.startTimeNs<t.startTimeNs?-1:1}function assembleLocalTrace(e,t){let n=[...t].sort(compareLocalTraceSpans),r=n.map(e=>e.attributes),i=distinctAttributes(r,`
|
|
1
|
+
import{readFile,readdir,stat}from"node:fs/promises";import{join}from"node:path";import{isAgentActivationSpan}from"#tracing/agent-span-contract.js";import{resolveLocalTraceSchemaDirectory,resolveLocalTraceSegmentsDirectory}from"#tracing/local-trace-span-processor.js";const TRACE_ID_PATTERN=/^[0-9a-f]{32}$/u,SPAN_FILE_PATTERN=/^[0-9a-f]{16}\.otlp\.json$/u;async function listLocalTraceIds(e){let t;try{t=await readdir(resolveLocalTraceSchemaDirectory(e),{withFileTypes:!0})}catch(e){if(isMissing(e))return[];throw e}return t.filter(e=>e.isDirectory()&&TRACE_ID_PATTERN.test(e.name)).map(e=>e.name)}async function readLocalTraceActivityMs(e,t){try{return(await stat(resolveLocalTraceSegmentsDirectory(e,t))).mtimeMs}catch(e){if(isMissing(e))return;throw e}}async function listLocalTraceSegments(e,t){let n;try{n=await readdir(resolveLocalTraceSegmentsDirectory(e,t),{withFileTypes:!0})}catch(e){if(isMissing(e))return;throw e}return n.filter(e=>e.isFile()&&SPAN_FILE_PATTERN.test(e.name)).map(e=>e.name).sort((e,t)=>e.localeCompare(t))}async function readLocalTraceSegment(e,t,n){let r=join(resolveLocalTraceSegmentsDirectory(e,t),n),i;try{if((await stat(r)).size>8388608)return[];i=await readFile(r,`utf8`)}catch{return[]}return parseLocalTraceSegment(i,t)}async function listLocalTraces(e){let t=[];for(let n of await listLocalTraceIds(e)){let r=await readLocalTrace(e,n).catch(()=>void 0);r!==void 0&&t.push(r)}return t.sort((e,t)=>e.startTimeNs===t.startTimeNs?e.traceId.localeCompare(t.traceId):e.startTimeNs>t.startTimeNs?-1:1)}async function readLocalTrace(e,t){let n=await listLocalTraceSegments(e,t);if(n===void 0)return;let r=new Map;for(let i of n)for(let n of await readLocalTraceSegment(e,t,i))r.has(n.spanId)||r.set(n.spanId,n);if(r.size!==0)return assembleLocalTrace(t,[...r.values()])}function compareLocalTraceSpans(e,t){return e.startTimeNs===t.startTimeNs?e.endTimeNs===t.endTimeNs?e.name.localeCompare(t.name)||e.spanId.localeCompare(t.spanId):e.endTimeNs<t.endTimeNs?-1:1:e.startTimeNs<t.startTimeNs?-1:1}function assembleLocalTrace(e,t){let n=[...t].sort(compareLocalTraceSpans),r=n.map(e=>e.attributes),i=distinctAttributes(r,`gen_ai.conversation.id`);return{agentName:firstAttribute(r,`agent.name`),endTimeNs:n.reduce((e,t)=>t.endTimeNs>e?t.endTimeNs:e,0n),conversationId:i[0],conversationIds:i,spans:n,startTimeNs:n.reduce((e,t)=>t.startTimeNs<e?t.startTimeNs:e,n[0].startTimeNs),traceId:e}}function describeLocalTraceSpan(e){let t=[],n=stringSpanAttribute(e,`agent.turn.id`),r=valueSpanAttribute(e,`agent.step.index`),i=valueSpanAttribute(e,`agent.step.attempt`),a=stringSpanAttribute(e,`agent.action.kind`),o=stringSpanAttribute(e,`agent.action.name`),s=stringSpanAttribute(e,`agent.model.id`)??stringSpanAttribute(e,`gen_ai.request.model`);return isAgentTurnSpan(e)&&n!==void 0&&t.push(n),e.name===`agent.step`&&r!==void 0&&t.push(`step ${String(r)}${i===void 0?``:`, attempt ${String(i)}`}`),e.name===`agent.action`&&o!==void 0&&t.push(`${a??`action`}: ${o}`),s!==void 0&&e.name.includes(`do`)&&t.push(`model ${s}`),t}function isAgentTurnSpan(e){return isAgentActivationSpan(e)}function parseLocalTraceSegment(e,t){try{let n=JSON.parse(e);if(!isRecord(n)||!Array.isArray(n.resourceSpans))return[];let r=[];for(let e of n.resourceSpans)if(isRecord(e)&&Array.isArray(e.scopeSpans))for(let n of e.scopeSpans){if(!isRecord(n)||!Array.isArray(n.spans))continue;let e=isRecord(n.scope)&&typeof n.scope.name==`string`?n.scope.name:void 0;for(let i of n.spans){let n=parseLocalTraceSpan(i,t,e);n!==void 0&&r.push(n)}}return r}catch{return[]}}function parseLocalTraceSpan(e,t,n){if(!isRecord(e)||e.traceId!==t||typeof e.spanId!=`string`||!/^[0-9a-f]{16}$/u.test(e.spanId)||typeof e.name!=`string`)return;let r=parseNanos(e.startTimeUnixNano),i=parseNanos(e.endTimeUnixNano);if(!(r===void 0||i===void 0||i<r))return{attributes:parseAttributes(e.attributes),endTimeNs:i,events:parseEvents(e.events),kind:typeof e.kind==`number`?e.kind:void 0,name:e.name,parentSpanId:typeof e.parentSpanId==`string`&&/^[0-9a-f]{16}$/u.test(e.parentSpanId)?e.parentSpanId:void 0,scope:n,spanId:e.spanId,startTimeNs:r,statusCode:parseStatusCode(e.status),statusMessage:parseStatusMessage(e.status),traceId:t}}function parseEvents(e){if(!Array.isArray(e))return[];let t=[];for(let n of e){if(!isRecord(n)||typeof n.name!=`string`)continue;let e=parseNanos(n.timeUnixNano);e!==void 0&&t.push({attributes:parseAttributes(n.attributes),name:n.name,timeNs:e})}return t.sort((e,t)=>e.timeNs===t.timeNs?e.name.localeCompare(t.name):e.timeNs<t.timeNs?-1:1)}function parseAttributes(e){if(!Array.isArray(e))return{};let t={};for(let n of e){if(!isRecord(n)||typeof n.key!=`string`||!isRecord(n.value))continue;let e=parseAnyValue(n.value);e!==void 0&&(t[n.key]=e)}return t}function parseAnyValue(e){for(let t of[`stringValue`,`boolValue`,`intValue`,`doubleValue`])if(t in e)return e[t];if(isRecord(e.arrayValue)&&Array.isArray(e.arrayValue.values))return e.arrayValue.values.filter(isRecord).map(e=>parseAnyValue(e))}function parseNanos(e){if(typeof e==`string`||typeof e==`number`)try{let t=BigInt(e);return t>=0n&&t<=18446744073709551615n?t:void 0}catch{return}}function parseStatusCode(e){return isRecord(e)?typeof e.code==`number`?e.code:e.code===`STATUS_CODE_ERROR`?2:0:0}function parseStatusMessage(e){if(isRecord(e)&&typeof e.message==`string`)return e.message.length===0?void 0:e.message}function firstAttribute(e,t){for(let n of e){let e=n[t];if(typeof e==`string`&&e.length>0)return e}}function distinctAttributes(e,t){let n=new Set;for(let r of e){let e=r[t];typeof e==`string`&&e.length>0&&n.add(e)}return[...n]}function stringSpanAttribute(e,t){let n=e.attributes[t];return typeof n==`string`?n:void 0}function valueSpanAttribute(e,t){let n=e.attributes[t];return typeof n==`string`||typeof n==`number`?n:void 0}function isMissing(e){return e.code===`ENOENT`}function isRecord(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}export{assembleLocalTrace,compareLocalTraceSpans,describeLocalTraceSpan,isAgentTurnSpan,listLocalTraceIds,listLocalTraceSegments,listLocalTraces,parseLocalTraceSegment,readLocalTraceActivityMs,readLocalTraceSegment};
|
|
@@ -8,29 +8,27 @@ import type { SpanProcessor } from "#compiled/@vercel/otel/index.js";
|
|
|
8
8
|
*/
|
|
9
9
|
export interface LocalTracesProcessor extends SpanProcessor {
|
|
10
10
|
/**
|
|
11
|
-
* Settles pending writes and
|
|
12
|
-
* the store. A subagent child owns no traces, so releasing one is a no-op
|
|
13
|
-
* and leaves the shared trace pinned until its root finishes.
|
|
11
|
+
* Settles pending writes and releases this conversation's active traces.
|
|
14
12
|
*/
|
|
15
|
-
|
|
13
|
+
releaseConversation(conversationId: string): Promise<boolean>;
|
|
16
14
|
}
|
|
17
15
|
/**
|
|
18
|
-
* Reports whether a processor tracks which
|
|
19
|
-
* tell it when that
|
|
16
|
+
* Reports whether a processor tracks which conversation owns which trace, so
|
|
17
|
+
* eve can tell it when that conversation is done.
|
|
20
18
|
*
|
|
21
19
|
* Anything standing between eve and the spool has to answer for the spool, so
|
|
22
20
|
* this is the check a wrapper uses to decide whether it must forward the call.
|
|
23
21
|
*
|
|
24
22
|
* @internal
|
|
25
23
|
*/
|
|
26
|
-
export declare function
|
|
24
|
+
export declare function hasConversationRelease(processor: SpanProcessor): processor is LocalTracesProcessor;
|
|
27
25
|
/**
|
|
28
26
|
* Writes the OTLP/JSON spool under `.eve/traces/v1`.
|
|
29
27
|
*
|
|
30
28
|
* `EVE_TRACES=off` removes the writer but keeps the processor: eve still has
|
|
31
29
|
* to observe spans to track which session owns which trace.
|
|
32
30
|
*
|
|
33
|
-
* Internal because of `
|
|
31
|
+
* Internal because of `releaseConversation`, which eve's runtime drives off session
|
|
34
32
|
* lifecycle. The authored surface is `localTraces()`, which wraps this in an
|
|
35
33
|
* `OtelIntegration`.
|
|
36
34
|
*/
|
|
@@ -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
|
|
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 hasConversationRelease(e){return typeof e.releaseConversation==`function`}function createLocalTracesProcessor(e={}){let t=e.appRoot??process.env.EVE_DEV_WORKER_APP_ROOT;if(t===void 0)return inertLocalTracesProcessor();let n=resolveLocalTraceRetentionSettings(),r=new AgentTraceSpanProcessor(n.enabled?[new LocalTraceSpanProcessor(t)]:[]),requestPrune=()=>{n.enabled&&requestLocalTraceStorePrune({activeTraceIds:r.activeTraceIds(),appRoot:t,maxAgeMs:n.maxAgeMs,maxTotalBytes:n.maxTotalBytes,retainCount:n.retainCount})};requestPrune();let forceFlush=async()=>{await r.forceFlush(),r.releaseCompletedTraces()&&requestPrune()};return{forceFlush,onEnd:e=>r.onEnd(e),onStart:(e,t)=>r.onStart(e,t),async releaseConversation(e){return await forceFlush(),r.releaseConversation(e)?(requestPrune(),!0):!1},shutdown:()=>r.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,releaseConversation:async()=>!1,shutdown:async()=>void 0}}export{createLocalTracesProcessor,hasConversationRelease,resolveLocalTracesContent};
|
|
@@ -28,9 +28,11 @@ export interface OtelOptions {
|
|
|
28
28
|
*/
|
|
29
29
|
readonly functionId?: string;
|
|
30
30
|
/**
|
|
31
|
-
* Whether to emit
|
|
32
|
-
* request
|
|
33
|
-
*
|
|
31
|
+
* Whether to emit an eve-owned HTTP `SERVER` span around each channel
|
|
32
|
+
* request. For a one-to-one delivery, the activation remains a separate
|
|
33
|
+
* trace root and links to this span; when disabled, it links to any
|
|
34
|
+
* already-active upstream request or function span instead. Defaults to
|
|
35
|
+
* `false`.
|
|
34
36
|
*/
|
|
35
37
|
readonly traceChannelRequests?: boolean;
|
|
36
38
|
/**
|
|
@@ -150,7 +152,7 @@ export declare function otel(options?: OtelOptions): OtelDeclaration;
|
|
|
150
152
|
export declare function otelIntegration(options?: OtelIntegrationOptions): OtelIntegration;
|
|
151
153
|
/** @internal Local and Agent Runs destination declaration. */
|
|
152
154
|
export declare function managedOtelIntegration(options?: OtelIntegrationOptions & ManagedTraceOptions): OtelIntegration;
|
|
153
|
-
/** Vercel Agent Runs through the
|
|
155
|
+
/** Vercel Agent Runs through the hosted request-context transport. @internal */
|
|
154
156
|
export declare function agentRunsIntegration(options?: ManagedTraceOptions): OtelIntegration;
|
|
155
157
|
export declare function resolveContentOptions(options: ContentOptions): ResolvedContentOptions;
|
|
156
158
|
export declare function isOtelDeclaration(value: unknown): value is OtelDeclaration;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { AgentSpanIdGenerator } from "#tracing/agent-span-id-generator.js";
|
|
2
2
|
import type { OtelPipeline } from "#tracing/otel-declaration.js";
|
|
3
|
+
import { type AgentSamplingOperation } from "#tracing/agent-span-contract.js";
|
|
3
4
|
/**
|
|
4
5
|
* Builds the process's one OpenTelemetry tracer provider from a merged
|
|
5
6
|
* declaration, then proves it took the global slot.
|
|
@@ -18,6 +19,6 @@ export interface RegisteredOtelPipeline {
|
|
|
18
19
|
readonly forceFlush: () => Promise<void>;
|
|
19
20
|
readonly idGenerator: AgentSpanIdGenerator;
|
|
20
21
|
/** Whether the installed sampler would record a trace with this id. */
|
|
21
|
-
readonly samplesTrace: (traceId: string) => boolean;
|
|
22
|
+
readonly samplesTrace: (traceId: string, operation?: AgentSamplingOperation) => boolean;
|
|
22
23
|
readonly shutdown: () => Promise<void>;
|
|
23
24
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createRequire}from"node:module";import{context,metrics,propagation,trace}from"#compiled/@opentelemetry/api/index.js";import{AgentSpanIdGenerator}from"#tracing/agent-span-id-generator.js";import{registerOTel}from"#compiled/@vercel/otel/index.js";const REGISTRATION_SPAN_NAME=`eve.otel.registration`,REPLAY_DEDUPLICATION_LIMIT=1e5,require=createRequire(import.meta.url);var RegistrationMarkerPropagator=class{#e=!1;extract(e){return e}fields(){return[]}inject(){this.#e=!0}isInstalled(){return this.#e=!1,propagation.inject(context.active(),{},{set:()=>{}}),this.#e}},PrivateSpanFilteringProcessor=class{endedSpans
|
|
1
|
+
import{createRequire}from"node:module";import{agentInvocationSpanName}from"#tracing/agent-span-contract.js";import{SpanKind,context,metrics,propagation,trace}from"#compiled/@opentelemetry/api/index.js";import{AgentSpanIdGenerator}from"#tracing/agent-span-id-generator.js";import{registerOTel}from"#compiled/@vercel/otel/index.js";const REGISTRATION_SPAN_NAME=`eve.otel.registration`,REPLAY_DEDUPLICATION_LIMIT=1e5,REPLAY_DEDUPLICATION_KEY=Symbol.for(`eve.otel.replay-deduplication`),require=createRequire(import.meta.url),replayDeduplicationGlobal=globalThis;var RegistrationMarkerPropagator=class{#e=!1;extract(e){return e}fields(){return[]}inject(){this.#e=!0}isInstalled(){return this.#e=!1,propagation.inject(context.active(),{},{set:()=>{}}),this.#e}},PrivateSpanFilteringProcessor=class{endedSpans;forwardedSpans=new Set;pendingByParent=new Map;pendingSpanCount=0;processors;startedSpans=new Set;constructor(e,t){this.processors=e,this.endedSpans=t}async forceFlush(){this.drainPendingSpans(),await Promise.all(this.processors.map(e=>e.forceFlush()))}onEnd(e){if(isRegistrationSpan(e))return;let t=spanIdentity(e);if(t!==void 0){if(this.endedSpans.has(t))return;if(this.endedSpans.size>=REPLAY_DEDUPLICATION_LIMIT){let e=this.endedSpans.values().next().value;e!==void 0&&this.endedSpans.delete(e)}this.endedSpans.add(t)}let n=parentIdentity(e);if(n!==void 0&&this.startedSpans.has(n)&&!this.forwardedSpans.has(n)){let t=this.pendingByParent.get(n)??[];t.push(e),this.pendingByParent.set(n,t),this.pendingSpanCount+=1,this.pendingSpanCount>1e4&&this.releaseOldestPendingParent();return}this.forward(e,t)}onStart(e,t){if(isRegistrationSpan(e))return;let n=spanIdentity(e);n!==void 0&&addBounded(this.startedSpans,n);for(let n of this.processors)n.onStart(e,t)}async shutdown(){this.drainPendingSpans(),await Promise.all(this.processors.map(e=>e.shutdown()))}drainPendingSpans(){for(;this.pendingByParent.size>0;)this.releaseOldestPendingParent()}releaseOldestPendingParent(){let e=this.pendingByParent.keys().next().value;e!==void 0&&this.releaseChildren(e)}releaseChildren(e){let t=this.pendingByParent.get(e);if(t!==void 0){this.pendingByParent.delete(e),this.pendingSpanCount-=t.length;for(let e of t)this.forward(e,spanIdentity(e))}}forward(e,t){for(let t of this.processors)t.onEnd(e);t!==void 0&&(addBounded(this.forwardedSpans,t),this.releaseChildren(t))}};function registerOtelPipeline(e){let{pipeline:t}=e,n=captureOptionalPeerTracerProxy(),r=new AgentSpanIdGenerator,i=new RegistrationMarkerPropagator,a=privateSpanProcessors(t.spanProcessors),o={attributes:t.resource,autoDetectResources:!1,idGenerator:r,instrumentations:t.instrumentations??[],metricReaders:t.metricReaders,propagators:[...t.propagators??[`auto`],i],serviceName:e.serviceName,spanProcessors:a};registerOTel(t.sampler===void 0?o:{...o,traceSampler:t.sampler});let s=globalTracerUses(r),c=i.isInstalled();if((!s||!c)&&rollbackRegistration({ownsPropagator:c,ownsTracer:s}),!s)throw Error("eve could not register OpenTelemetry because another runtime already owns the global tracer provider. Remove the other `registerOTel` call, or move its exporters into eve's `otelIntegration({ spanProcessors: [...] })`.");if(!c)throw Error("eve could not register OpenTelemetry because another runtime already owns the global propagator. Remove the other global propagator registration and declare propagators through eve's `otel()` instead.");let l=runtimeTracerProvider();if(typeof l.forceFlush!=`function`||typeof l.shutdown!=`function`)throw rollbackRegistration({ownsPropagator:c,ownsTracer:s}),Error(`The registered OpenTelemetry tracer provider has no lifecycle methods.`);n?.setDelegate(l);let u=runtimeMeterProvider();return{forceFlush:async()=>{await Promise.all([l.forceFlush(),u.forceFlush?.()])},idGenerator:r,samplesTrace:(e,t)=>samplerAdmitsTrace(r,e,t),shutdown:async()=>{disableInstrumentations(t.instrumentations),await Promise.all([l.shutdown(),u.shutdown?.()])}}}function privateSpanProcessors(e){let t=e.filter(isSpanProcessor);if(t.length===0)return[...e];let n=new PrivateSpanFilteringProcessor(t,replayDeduplicationRegistry()),r=[],i=!1;for(let t of e){if(!isSpanProcessor(t)){r.push(t);continue}i||(i=!0,r.push(n))}return r}function replayDeduplicationRegistry(){let e=replayDeduplicationGlobal[REPLAY_DEDUPLICATION_KEY];if(e!==void 0)return e;let t=new Set;return replayDeduplicationGlobal[REPLAY_DEDUPLICATION_KEY]=t,t}function samplerAdmitsTrace(e,t,n={name:agentInvocationSpanName(void 0)}){return(e.withTraceId(t,()=>trace.getTracer(`eve.registration`).startSpan(n.name,{attributes:n.attributes,kind:SpanKind.INTERNAL,root:!0})).spanContext().traceFlags&1)==1}function captureOptionalPeerTracerProxy(){try{let e=require("@opentelemetry/api"),t=e.trace.getTracerProvider();return t instanceof e.ProxyTracerProvider?t:void 0}catch{return}}function rollbackRegistration(e){if(e.ownsPropagator&&propagation.disable(),!e.ownsTracer)return;let t=runtimeTracerProvider();if(typeof t.shutdown==`function`)try{t.shutdown().catch(()=>{})}catch{}trace.disable()}function runtimeTracerProvider(){let e=trace.getTracerProvider();return e.getDelegate?.()??e}function runtimeMeterProvider(){let e=metrics.getMeterProvider();return{forceFlush:typeof e?.forceFlush==`function`?()=>e.forceFlush():void 0,shutdown:typeof e?.shutdown==`function`?()=>e.shutdown():void 0}}function disableInstrumentations(e){for(let t of e??[]){let e=t?.disable;if(typeof e==`function`)try{e.call(t)}catch{}}}function globalTracerUses(e){let t=e.allocateSpanId();return e.withSpanId(t,()=>trace.getTracer(`eve.registration`).startSpan(REGISTRATION_SPAN_NAME)).spanContext().spanId===t}function isRegistrationSpan(e){return typeof e==`object`&&!!e&&(`name`in e&&e.name===REGISTRATION_SPAN_NAME||`instrumentationScope`in e&&e.instrumentationScope?.name===`eve.registration`)}function spanIdentity(e){if(typeof e!=`object`||!e||!(`spanContext`in e)||typeof e.spanContext!=`function`)return;let t=e.spanContext();return typeof t.traceId==`string`&&typeof t.spanId==`string`?`${t.traceId}:${t.spanId}`:void 0}function parentIdentity(e){if(typeof e!=`object`||!e||!(`parentSpanContext`in e))return;let t=e.parentSpanContext;return typeof t?.traceId==`string`&&typeof t.spanId==`string`?`${t.traceId}:${t.spanId}`:void 0}function addBounded(e,t){if(e.size>=REPLAY_DEDUPLICATION_LIMIT){let t=e.values().next().value;t!==void 0&&e.delete(t)}e.add(t)}function isSpanProcessor(e){return e!==`auto`}export{registerOtelPipeline};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export declare const TELEMETRY_PRINCIPAL_ID_BYTES = 1024;
|
|
2
|
+
export declare function boundedPrincipalId(value: unknown): string | undefined;
|
|
3
|
+
export declare function telemetryByteLength(text: string): number;
|
|
4
|
+
export declare function truncateTelemetryText(text: string, maxBytes: number): string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const TELEMETRY_PRINCIPAL_ID_BYTES=1024;function boundedPrincipalId(e){return typeof e==`string`&&e.length>0&&e.length<=1024&&telemetryByteLength(e)<=1024?e:void 0}const encoder=new TextEncoder,decoder=new TextDecoder;function telemetryByteLength(e){return encoder.encode(e).length}function truncateTelemetryText(e,t){let n=e.slice(0,t+1),r=encoder.encode(n);if(n.length===e.length&&r.length<=t)return e;let i=`... [truncated]`.slice(0,t),a=Math.max(0,t-i.length);for(;a>0&&(r[a]&192)==128;)--a;return decoder.decode(r.subarray(0,a))+i}export{TELEMETRY_PRINCIPAL_ID_BYTES,boundedPrincipalId,telemetryByteLength,truncateTelemetryText};
|
package/docs/agent-config.md
CHANGED
|
@@ -283,18 +283,52 @@ disappear in any release. See [Execution model and
|
|
|
283
283
|
durability](./concepts/execution-model-and-durability#resuming-after-a-crash)
|
|
284
284
|
for the retry behavior.
|
|
285
285
|
|
|
286
|
+
## Run data retention
|
|
287
|
+
|
|
288
|
+
The runtime keeps each run's data after the run finishes: model and tool
|
|
289
|
+
payloads, streamed output, and the event log eve replays from. How long it keeps
|
|
290
|
+
them is the World's decision, and on Vercel that follows your team's plan. Set
|
|
291
|
+
`experimental.workflow.retention` to `0` to have it deleted as soon as the run
|
|
292
|
+
finishes instead:
|
|
293
|
+
|
|
294
|
+
```ts title="agent/agent.ts"
|
|
295
|
+
import { defineAgent } from "eve";
|
|
296
|
+
|
|
297
|
+
export default defineAgent({
|
|
298
|
+
model: "anthropic/claude-opus-4.8",
|
|
299
|
+
experimental: {
|
|
300
|
+
workflow: {
|
|
301
|
+
retention: 0,
|
|
302
|
+
},
|
|
303
|
+
},
|
|
304
|
+
});
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
This will be applied to the session run and every turn run the session
|
|
308
|
+
dispatches, as well as the run that collects session activity. Runs eve
|
|
309
|
+
starts for other purposes keep the world's default: session timeouts,
|
|
310
|
+
background tasks, and [workflow tools](./tools/workflows).
|
|
311
|
+
|
|
312
|
+
The value applies per agent. A [subagent](./subagents) that runs its own session
|
|
313
|
+
uses its own value, unlike `experimental.workflow.world`, which is root-only.
|
|
314
|
+
|
|
315
|
+
Custom Worlds used with eve might not support this feature, in which case
|
|
316
|
+
it falls back to the World's default retention period.
|
|
317
|
+
|
|
318
|
+
> ⚠️ **At `0`, a finished session's output is usually gone before you can read it.** Since data is deleted immediately before it can be read back, results and transcripts become unreadable and a client polling for a finished session's output can see it disappear.
|
|
319
|
+
|
|
286
320
|
## Other defineAgent fields
|
|
287
321
|
|
|
288
322
|
`defineAgent` takes a few more fields, all optional. For the exported types, see the [TypeScript API Reference](./reference/typescript-api).
|
|
289
323
|
|
|
290
|
-
| Field | Type | Default | Description
|
|
291
|
-
| -------------- | --------------------------------------- | ---------------- |
|
|
292
|
-
| `reasoning` | `AgentReasoningDefinition` | provider default | Provider-agnostic reasoning effort forwarded to the agent's turn model calls.
|
|
293
|
-
| `modelOptions` | `AgentModelOptionsDefinition` | none | Provider option overrides forwarded to the model call.
|
|
294
|
-
| `limits` | `AgentLimitsDefinition` | field-specific | Framework-owned runtime limits. Sessions complete after 30 days by default; usage-limit defaults and inheritance are described above. Set a limit to `false` to disable it.
|
|
295
|
-
| `experimental` | `AgentExperimentalDefinition` | unset | Unstable opt-ins. `workflow.world` selects the Workflow world package on the root agent; `workflow.modelCallsPerStep` batches sequential model calls into a wider replay unit.
|
|
296
|
-
| `outputSchema` | Standard Schema or a JSON Schema object | none | Structured return type for function-like invocations such as a subagent turn, schedule, or remote job. Ordinary interactive turns ignore it unless the client supplies a per-message schema.
|
|
297
|
-
| `build` | `{ externalDependencies?: string[] }` | none | Hosted-build packaging controls. `externalDependencies` keeps listed packages external while eve compiles authored modules such as tools and channels, and traces those packages into the hosted output.
|
|
324
|
+
| Field | Type | Default | Description |
|
|
325
|
+
| -------------- | --------------------------------------- | ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
326
|
+
| `reasoning` | `AgentReasoningDefinition` | provider default | Provider-agnostic reasoning effort forwarded to the agent's turn model calls. |
|
|
327
|
+
| `modelOptions` | `AgentModelOptionsDefinition` | none | Provider option overrides forwarded to the model call. |
|
|
328
|
+
| `limits` | `AgentLimitsDefinition` | field-specific | Framework-owned runtime limits. Sessions complete after 30 days by default; usage-limit defaults and inheritance are described above. Set a limit to `false` to disable it. |
|
|
329
|
+
| `experimental` | `AgentExperimentalDefinition` | unset | Unstable opt-ins. `workflow.world` selects the Workflow world package on the root agent; `workflow.modelCallsPerStep` batches sequential model calls into a wider replay unit; `workflow.retention` controls how long the durable runtime keeps run data. |
|
|
330
|
+
| `outputSchema` | Standard Schema or a JSON Schema object | none | Structured return type for function-like invocations such as a subagent turn, schedule, or remote job. Ordinary interactive turns ignore it unless the client supplies a per-message schema. |
|
|
331
|
+
| `build` | `{ externalDependencies?: string[] }` | none | Hosted-build packaging controls. `externalDependencies` keeps listed packages external while eve compiles authored modules such as tools and channels, and traces those packages into the hosted output. |
|
|
298
332
|
|
|
299
333
|
`externalDependencies` is a packaging control only. It keeps selected packages as runtime dependencies in the hosted output; it does not authorize, configure, or review any third-party service those packages may call.
|
|
300
334
|
|
package/docs/channels/slack.mdx
CHANGED
|
@@ -53,7 +53,7 @@ Use this fallback when the agent does not run on Vercel or Vercel Connect is una
|
|
|
53
53
|
|
|
54
54
|
This option does not create or install the Slack app. Configure it in [Slack app settings](https://api.slack.com/apps):
|
|
55
55
|
|
|
56
|
-
1. Add the `app_mentions:read` and `chat:write` bot scopes. Add `im:history` for DMs, `files:read` for inbound attachments, and `files:write`
|
|
56
|
+
1. Add the `app_mentions:read` and `chat:write` bot scopes. Add `im:history` for DMs, `files:read` for inbound attachments, and `files:write` for explicit uploads and automatic long-response snippets.
|
|
57
57
|
2. Install or reinstall the app, copy its Bot User OAuth Token to `SLACK_BOT_TOKEN`, and copy the signing secret from **Basic Information** to `SLACK_SIGNING_SECRET`.
|
|
58
58
|
3. Set both values in `.env.local` for local development or in the target runtime's environment, then start or deploy the agent at a public URL.
|
|
59
59
|
4. Under **Event Subscriptions**, set the Request URL to `https://your-agent.example/eve/v1/slack`. Subscribe to `app_mention`, plus `message.im` for DMs.
|
|
@@ -133,6 +133,7 @@ Check the delivery path in order so you can identify where a Slack event stops:
|
|
|
133
133
|
| Setup says it could not remove an existing trigger destination | Check the connector's destinations in the Connect dashboard. `vercel connect detach` removes project token access, not trigger destinations. | Edit or remove the stale destination in the dashboard, then register `/eve/v1/slack` with `vercel connect attach`. |
|
|
134
134
|
| Mentions never reach the deployment | Confirm that the connector trigger destination uses the intended project and branch, enables triggers, and points to `/eve/v1/slack`. | Edit or remove stale destinations in the Connect dashboard, then register the intended destination with `vercel connect attach`. |
|
|
135
135
|
| Mentions work but DMs or thread replies do not | Check the Slack app's Event Subscriptions and OAuth scopes. DMs require `message.im` and `im:history`; channel replies require the matching message event and history scope. | Add the missing events or scopes, then reinstall the Slack app if Slack requires it. |
|
|
136
|
+
| A long response cannot be uploaded as a snippet | Check whether the installed Slack app has the `files:write` bot scope. | Add `files:write`, then reinstall the Slack app so the new scope takes effect. |
|
|
136
137
|
| A preview request receives an authentication page or protection error | Check whether the branch domain is exempt or the direct Slack request URL includes `x-vercel-protection-bypass`. Slack cannot complete an interactive Vercel Authentication challenge. | Add a Deployment Protection Exception for the branch domain, or add the automation bypass query parameter to a Slack app that uses environment-variable credentials. |
|
|
137
138
|
| The webhook reaches the deployment but the agent does not reply | Open the project's Vercel runtime logs, then inspect the session in **Agent Runs** when your team has access. | Use the first missing or failed stage to narrow the issue to channel dispatch, the agent run, or outbound Slack delivery. |
|
|
138
139
|
|
|
@@ -414,11 +415,13 @@ when you need the bearer token itself.
|
|
|
414
415
|
|
|
415
416
|
The default handlers reply in-thread and show activity. Typing indicators post automatically: `Thinking…` on inbound, `Working…` on `turn.started`, a truncated reasoning snippet on `reasoning.appended`, and an action label on `actions.requested` — the tool name plus its most telling argument (`grep useEveAgent`, `read_file agent/agent.ts`), the subagent or remote-agent name for dispatched calls, and `+N more` when the model requests several actions at once. The model's own pre-tool narration, when present, takes precedence over the derived label. Reasoning snippets build progressively: extensions of at least four characters appear immediately, while smaller streamed deltas use the five-second refresh interval to avoid one Slack request per token. Override `events["reasoning.appended"]` if you prefer generic wording. Override an inbound handler or the `events` handlers to customize.
|
|
416
417
|
|
|
418
|
+
The built-in `message.completed` handler renders responses up to 12,000 characters inline. Longer responses are uploaded unchanged as a Markdown snippet named `eve-response.md` with a short in-thread note, which requires the `files:write` bot scope. Upload failures are logged by the channel dispatcher; they do not trigger a model retry. An authored `events["message.completed"]` handler replaces this behavior and owns its own delivery limits.
|
|
419
|
+
|
|
417
420
|
Outbound text preserves bare `@` tokens as literal text. To mention a user, embed Slack's `<@USER_ID>` syntax directly or use `channel.thread.mentionUser(userId)`.
|
|
418
421
|
|
|
419
422
|
When a session starts without a `threadTs` (say, from a schedule's `to(slack, target).send(...)`), eve gives it a unique temporary continuation token. The first agent post anchors the session to the Slack message timestamp, and later posts and mentions resume that same session. Pass `initialMessage` with a `Card` to land a structured anchor first instead. `threadTs` and `initialMessage` are mutually exclusive.
|
|
420
423
|
|
|
421
|
-
The example below overrides `onAppMention` to gate on an authored message
|
|
424
|
+
The example below overrides `onAppMention` to gate on an authored message. The built-in completion handler still posts the reply and uploads long responses as snippets. Event handlers receive `(eventData, channel, ctx)`, with Slack platform handles on `channel.thread` and `channel.slack`:
|
|
422
425
|
|
|
423
426
|
```ts
|
|
424
427
|
import { defaultSlackAuth, slackChannel } from "eve/channels/slack";
|
|
@@ -428,12 +431,6 @@ export default slackChannel({
|
|
|
428
431
|
credentials: connectSlackCredentials("slack/my-agent"),
|
|
429
432
|
onAppMention: (ctx, message) =>
|
|
430
433
|
message.author ? { auth: defaultSlackAuth(message, ctx) } : null,
|
|
431
|
-
events: {
|
|
432
|
-
"message.completed"(eventData, channel, ctx) {
|
|
433
|
-
if (eventData.finishReason === "tool-calls") return;
|
|
434
|
-
if (eventData.message) channel.thread.post(eventData.message);
|
|
435
|
-
},
|
|
436
|
-
},
|
|
437
434
|
});
|
|
438
435
|
```
|
|
439
436
|
|
|
@@ -153,6 +153,8 @@ export default otelIntegration({
|
|
|
153
153
|
});
|
|
154
154
|
```
|
|
155
155
|
|
|
156
|
+
Custom destinations receive the schema v4 agent trace contract. Follow [Query exported traces](./instrumentation#query-exported-traces) to find activations and join sessions across traces.
|
|
157
|
+
|
|
156
158
|
Add `agent/instrumentation/otel.ts` when you need process-wide settings or want to control which content eve writes to OpenTelemetry spans:
|
|
157
159
|
|
|
158
160
|
```ts title="agent/instrumentation/otel.ts"
|
|
@@ -217,7 +219,7 @@ Policies run in declaration order. A later policy sees the filtered span produce
|
|
|
217
219
|
The provider layout adds two environment-specific defaults:
|
|
218
220
|
|
|
219
221
|
- `local` records local traces during `eve dev`.
|
|
220
|
-
- `agent-runs` exports to Vercel Agent Runs in production.
|
|
222
|
+
- `agent-runs` exports to Vercel Agent Runs in preview and production deployments.
|
|
221
223
|
|
|
222
224
|
Omitting these files preserves the defaults. Reconfigure a slot by exporting `localTraces()` or `agentRuns()` from the matching file. Disable one explicitly:
|
|
223
225
|
|
|
@@ -235,6 +237,9 @@ An ordinary tool emits both `action.*` and `tool.call.*` events. Use `action.*`
|
|
|
235
237
|
|
|
236
238
|
Handlers for different providers run concurrently and are failure-isolated. Do not depend on provider execution order. Use `flush` to drain buffered records and `shutdown` to release resources.
|
|
237
239
|
|
|
240
|
+
The [agent trace contract](./instrumentation#agent-trace-contract) defines span
|
|
241
|
+
names, identities, and usage counters shared by the exporters and local viewers.
|
|
242
|
+
|
|
238
243
|
## What to read next
|
|
239
244
|
|
|
240
245
|
- [Observability](./instrumentation): the default `instrumentation.ts` API and trace hierarchy
|