eve 0.79.0 → 0.79.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 +29 -0
- package/dist/src/chunks/{use-eve-agent-BSYe_Re7.js → use-eve-agent-Ch-Q-s12.js} +43 -13
- package/dist/src/chunks/{use-eve-agent-B8brxCk-.js → use-eve-agent-Vsl-S0yI.js} +43 -13
- package/dist/src/client/abort-signal.d.ts +2 -0
- package/dist/src/client/abort-signal.js +1 -0
- package/dist/src/client/conversation-client.d.ts +2 -0
- package/dist/src/client/conversation-client.js +1 -1
- package/dist/src/client/eve-agent-store-state.d.ts +9 -0
- package/dist/src/client/eve-agent-store.js +1 -1
- package/dist/src/client/ndjson.js +1 -1
- package/dist/src/client/open-stream.js +1 -1
- package/dist/src/client/session-turn-dispatch.js +1 -1
- package/dist/src/client/session-utils.js +1 -1
- package/dist/src/client/session.js +1 -1
- package/dist/src/compiled/.vendor-stamp.json +2 -2
- package/dist/src/compiled/@eve/tracing/adapters/serialization.d.ts +2 -2
- package/dist/src/compiled/@eve/tracing/core/types.d.ts +6 -1
- package/dist/src/compiled/@eve/tracing/index.js +1 -1
- package/dist/src/compiled/@eve/tracing/otel.js +1 -1
- package/dist/src/compiled/_chunks/workflow/{mcp-CrGp4EC8.js → mcp-C01bDEX-.js} +2 -2
- package/dist/src/compiler/extension-compatibility.d.ts +4 -4
- package/dist/src/compiler/extension-compatibility.js +1 -1
- package/dist/src/compiler/project-sources.js +1 -1
- package/dist/src/context/memory-tools.js +1 -1
- package/dist/src/evals/runner/reporters/assertion-scores.d.ts +6 -4
- package/dist/src/evals/runner/reporters/assertion-scores.js +1 -1
- package/dist/src/evals/runner/reporters/braintrust.js +1 -1
- package/dist/src/eve-channel/request.js +1 -1
- package/dist/src/execution/authorization-callback-match.d.ts +2 -2
- package/dist/src/execution/authorization-callback-match.js +1 -1
- package/dist/src/execution/durable-session-store.js +1 -1
- package/dist/src/execution/dynamic-workflow/tool.js +1 -1
- package/dist/src/execution/forward-session-input.js +1 -1
- package/dist/src/execution/proxied-deliver-step.js +1 -1
- package/dist/src/execution/publish-session-events.d.ts +13 -2
- package/dist/src/execution/publish-session-events.js +1 -1
- package/dist/src/execution/sandbox/bindings/vercel-create-sdk.js +1 -1
- package/dist/src/execution/sandbox/bindings/vercel-credentials.d.ts +2 -0
- package/dist/src/execution/sandbox/bindings/vercel-credentials.js +1 -1
- package/dist/src/execution/sandbox/bindings/vercel-lifecycle.js +1 -1
- package/dist/src/execution/sandbox/bindings/vercel-lookup.js +1 -1
- package/dist/src/execution/sandbox/bindings/vercel.d.ts +3 -6
- package/dist/src/execution/sandbox/bindings/vercel.js +1 -1
- package/dist/src/execution/session/checkpoint-migrations.js +1 -1
- package/dist/src/execution/session/handoff-steps.js +1 -1
- package/dist/src/execution/session/handoff.d.ts +1 -1
- package/dist/src/execution/session/handoff.js +1 -1
- package/dist/src/execution/session/input-queue.d.ts +13 -6
- package/dist/src/execution/session/input-queue.js +1 -1
- package/dist/src/execution/session/pending-turn-state.js +1 -1
- package/dist/src/execution/session/turn-step.js +1 -1
- package/dist/src/execution/session/turn.d.ts +4 -1
- package/dist/src/execution/session/turn.js +1 -1
- package/dist/src/execution/tasks/steps.d.ts +1 -1
- package/dist/src/execution/tasks/steps.js +1 -1
- package/dist/src/execution/tool-auth.js +1 -1
- package/dist/src/execution/tools/agent-router-workflow.js +1 -1
- package/dist/src/execution/tools/workflow/answer.d.ts +1 -1
- package/dist/src/execution/tools/workflow/withdraw-step.d.ts +2 -2
- package/dist/src/execution/tools/workflow/withdraw-step.js +1 -1
- package/dist/src/execution/workflow-callback-url.d.ts +10 -1
- package/dist/src/execution/workflow-callback-url.js +1 -1
- package/dist/src/harness/authorization.d.ts +3 -13
- package/dist/src/harness/authorization.js +1 -1
- package/dist/src/harness/compaction/step.d.ts +1 -0
- package/dist/src/harness/compaction/step.js +1 -1
- package/dist/src/harness/coordination.js +1 -1
- package/dist/src/harness/hitl/approvals.d.ts +1 -1
- package/dist/src/harness/hitl/approvals.js +1 -1
- package/dist/src/harness/hitl/approved-calls.d.ts +3 -0
- package/dist/src/harness/hitl/approved-calls.js +1 -1
- package/dist/src/harness/hitl/candidates.d.ts +13 -0
- package/dist/src/harness/hitl/candidates.js +1 -1
- package/dist/src/harness/hitl/coordinator.js +1 -1
- package/dist/src/harness/hitl/index.d.ts +2 -5
- package/dist/src/harness/hitl/index.js +1 -1
- package/dist/src/harness/hitl/intake.js +1 -1
- package/dist/src/harness/{proxy-input-requests.d.ts → hitl/relays.d.ts} +3 -39
- package/dist/src/harness/hitl/relays.js +1 -0
- package/dist/src/harness/hitl/requests.d.ts +64 -0
- package/dist/src/harness/hitl/requests.js +1 -0
- package/dist/src/harness/hitl/sign-ins.d.ts +9 -0
- package/dist/src/harness/hitl/sign-ins.js +1 -0
- package/dist/src/harness/inline-tool-authorization.js +1 -1
- package/dist/src/harness/model-call/call.js +1 -1
- package/dist/src/harness/model-call/model.d.ts +3 -1
- package/dist/src/harness/model-call/model.js +1 -1
- package/dist/src/harness/session-machine/commit.d.ts +14 -3
- package/dist/src/harness/session-machine/commit.js +1 -1
- package/dist/src/harness/session-machine/transitions.d.ts +16 -0
- package/dist/src/harness/session-machine/transitions.js +1 -1
- package/dist/src/instrumentation/runtime.d.ts +1 -0
- package/dist/src/instrumentation/runtime.js +1 -1
- package/dist/src/internal/application/stamped-package-version.js +1 -1
- package/dist/src/internal/authored-definition/source-identity.d.ts +6 -0
- package/dist/src/internal/authored-definition/source-identity.js +1 -1
- package/dist/src/internal/authored-module-map-loader.js +1 -1
- package/dist/src/internal/helpers/markdown.js +1 -1
- package/dist/src/internal/workflow/is-inactive-workflow-run-error.d.ts +2 -0
- package/dist/src/internal/workflow/is-inactive-workflow-run-error.js +1 -1
- package/dist/src/protocol/baggage.d.ts +1 -0
- package/dist/src/protocol/baggage.js +1 -1
- package/dist/src/public/definitions/connections/mcp.js +1 -1
- package/dist/src/public/definitions/connections/openapi.js +1 -1
- package/dist/src/public/sandbox/vercel.d.ts +2 -0
- package/dist/src/public/tools/index.d.ts +1 -1
- package/dist/src/public/tools/result.d.ts +10 -7
- package/dist/src/react/use-eve-agent.d.ts +6 -0
- package/dist/src/react/use-eve-agent.js +1 -1
- package/dist/src/runtime/authorization-context.d.ts +5 -0
- package/dist/src/runtime/authorization-context.js +1 -1
- package/dist/src/runtime/connections/mcp-tracing.js +1 -1
- package/dist/src/runtime/connections/openapi-operations.js +1 -1
- package/dist/src/runtime/connections/scoped-authorization.d.ts +6 -0
- package/dist/src/runtime/connections/scoped-authorization.js +1 -1
- package/dist/src/runtime/resolve-connection.js +1 -1
- package/dist/src/setup/scaffold/create/project.js +1 -1
- package/dist/src/setup/scaffold/create/web-template.d.ts +1 -1
- package/dist/src/setup/scaffold/create/web-template.js +18 -10
- package/dist/src/shared/git.js +1 -1
- package/dist/src/shared/instrumentation-content.d.ts +1 -1
- package/dist/src/shared/instrumentation-content.js +1 -1
- package/dist/src/shared/instrumentation-decision.d.ts +3 -0
- package/dist/src/shared/instrumentation-decision.js +1 -1
- package/dist/src/shared/skill-package.js +1 -1
- package/dist/src/shared/trace-policy.js +1 -1
- package/dist/src/subagents/adapter.js +1 -1
- package/dist/src/subagents/event-proxy-step.d.ts +1 -1
- package/dist/src/subagents/event-proxy-step.js +1 -1
- package/dist/src/subagents/hitl-proxy.d.ts +1 -1
- package/dist/src/subagents/hitl-proxy.js +1 -1
- package/dist/src/svelte/index.js +1 -1
- package/dist/src/svelte/use-eve-agent.d.ts +6 -0
- package/dist/src/svelte/use-eve-agent.js +1 -1
- package/dist/src/tools/definition.d.ts +38 -1
- package/dist/src/tools/provided/ask-question-workflow.js +1 -1
- package/dist/src/tools/provided/sleep-workflow.js +1 -1
- package/dist/src/tracing/eve/agent-otel-provider.js +1 -1
- package/dist/src/tracing/eve/gateway.d.ts +2 -1
- package/dist/src/tracing/eve/gateway.js +1 -1
- package/dist/src/tracing/eve/invoke-tool-span.js +1 -1
- package/dist/src/tracing/eve/otel-declaration.d.ts +9 -8
- package/dist/src/tracing/eve/policy.js +1 -1
- package/dist/src/vue/index.js +1 -1
- package/dist/src/vue/use-eve-agent.d.ts +6 -0
- package/dist/src/vue/use-eve-agent.js +1 -1
- package/docs/agent-config.md +48 -0
- package/docs/channels/eve.mdx +2 -0
- package/docs/connections/overview.mdx +9 -6
- package/docs/guides/frontend/overview.mdx +10 -1
- package/docs/guides/hooks.md +2 -2
- package/docs/guides/instrumentation/otel.mdx +3 -0
- package/docs/reference/cli.md +1 -1
- package/docs/reference/typescript-api.md +7 -6
- package/docs/sandbox/vercel.mdx +9 -0
- package/docs/skills.mdx +1 -1
- package/docs/tools/human-in-the-loop.md +21 -0
- package/package.json +1 -1
- package/dist/src/harness/proxy-input-requests.js +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
import{isObject}from"#shared/guards.js";import{isUserMessageKind}from"#harness/messages.js";import{resolveInstrumentationEnvironment}from"#internal/application/dev-environment.js";import{isSampledTrace}from"#shared/trace-policy.js";import{ROOT_CONTEXT,context,trace}from"#compiled/@opentelemetry/api/index.js";import{createAgentToolInstrumentation}from"#tracing/eve/agent-tool-instrumentation.js";import{withChannelAudience}from"#tracing/eve/channel-audience-context.js";import{createEveTracing}from"#tracing/eve/operation-input.js";import{createAgentApprovalInstrumentation}from"#tracing/eve/agent-approval-instrumentation.js";import{createAgentChannelDeliveryInstrumentation}from"#tracing/eve/agent-channel-delivery-instrumentation.js";import{eveActivationMetadata}from"#tracing/eve/metadata.js";import{createAgentMemoryInstrumentation}from"#tracing/eve/agent-memory-instrumentation.js";import{
|
|
1
|
+
import{isObject}from"#shared/guards.js";import{isUserMessageKind}from"#harness/messages.js";import{resolveInstrumentationEnvironment}from"#internal/application/dev-environment.js";import{isSampledTrace}from"#shared/trace-policy.js";import{ROOT_CONTEXT,context,trace}from"#compiled/@opentelemetry/api/index.js";import{gatewayCostAttributes,readGatewayCostData}from"#tracing/eve/gateway.js";import{createAgentToolInstrumentation}from"#tracing/eve/agent-tool-instrumentation.js";import{withChannelAudience}from"#tracing/eve/channel-audience-context.js";import{createEveTracing}from"#tracing/eve/operation-input.js";import{createAgentApprovalInstrumentation}from"#tracing/eve/agent-approval-instrumentation.js";import{createAgentChannelDeliveryInstrumentation}from"#tracing/eve/agent-channel-delivery-instrumentation.js";import{eveActivationMetadata}from"#tracing/eve/metadata.js";import{createAgentMemoryInstrumentation}from"#tracing/eve/agent-memory-instrumentation.js";import{createEveSessionTracing}from"#tracing/eve/session.js";import{createEveCapturePolicy}from"#tracing/eve/policy.js";function createAgentOtelInstrumentation(e){let t=e.environment??resolveInstrumentationEnvironment(),n=e.recordInputs??!1,r=e.recordOutputs??!1,i=createEveTracing(e),a=new Map,o=new Map,s=createEveSessionTracing({...e,environment:t,tracing:i}),{prepareSessionTrace:c,prepareTurnTrace:l}=s;async function attemptFor(e){let t=a.get(e.attemptId);if(t!==void 0)return t;let n=await s.turnFor(e.sessionId,e.turnId,withChannelAudience(ROOT_CONTEXT,e.channelAudience)),r={stepIndex:e.stepIndex,attempt:e.attemptIndex};return n?.findAttempt(r)??(n?.finished===!1?n.attempt(r):void 0)}let u=createAgentToolInstrumentation({tracing:i,attemptFor,stepFor:e=>a.get(e.attemptId),recordInputs:n,recordOutputs:r,stateStore:e.stateStore}),d=createAgentApprovalInstrumentation({tracing:i,actionStateFor:u.stateFor}),f=createAgentMemoryInstrumentation({...e,environment:t,tracing:i}),p=createEveCapturePolicy({stateStore:e.stateStore,environment:t,recordInputs:n,recordOutputs:r});function turnState(t){return e.stateStore.get(`turn`,JSON.stringify([t.sessionId,t.turnId]))}let onSessionStarted=async e=>{await c(e)},onTurnStarted=async e=>{await l(e)},onStepStarted=async t=>{let n=await turnState(t.scope);if(n===void 0||!isSampledTrace(n.context))return;let r=await e.stateStore.get(`session`,t.scope.sessionId),i=await s.turnFor(t.scope.sessionId,t.scope.turnId,withChannelAudience(ROOT_CONTEXT,t.scope.channelAudience));if(i===void 0||i.finished)return;let o=trace.getSpan(context.active())?.spanContext(),c=await i.attempt({stepIndex:t.scope.stepIndex,attempt:t.scope.attemptIndex,runtimeContext:t.runtimeContext,channel:eveActivationMetadata({session:r,turn:n,sessionId:t.scope.sessionId}).channel,links:o===void 0||o.traceId===n.context.traceId?void 0:[{relationship:`execution.delivery`,context:o}]});a.set(t.scope.attemptId,c)},onStepTerminal=async e=>{let t=e.type===`step.attempt.failed`?{error:e.error}:void 0;await drainOpenSpans(e),await u.drain(e.scope.attemptId,t);let n=a.get(e.scope.attemptId)??await attemptFor(e.scope);a.delete(e.scope.attemptId),t===void 0?await n?.complete():(await n?.fail(t.error),await u.forgetAttempt(e.scope))},onSessionTransition=async t=>{await s.sessionTransition(t),(t.type===`session.completed`||t.type===`session.failed`)&&(await u.deleteForSession(t.sessionId),await e.stateStore.delete(`session`,t.sessionId))},onModelCallStarted=async e=>{let t=a.get(e.scope.attemptId);if(t===void 0)return;let r=await t.modelCall({provider:e.model.provider,modelId:e.model.modelId,messages:n?e.input?.messages.map(e=>isObject(e)&&e.role===`user`?{...e,kind:isUserMessageKind(e.kind)?e.kind:void 0}:e):void 0,instructions:n?e.input?.instructions:void 0,tools:n?e.input?.tools:void 0,runtimeContext:e.runtimeContext},e.idempotencyKey),i=o.get(e.scope.attemptId);i===void 0&&o.set(e.scope.attemptId,i=new Map),i.set(e.idempotencyKey,r)},onModelCallTerminal=async e=>{let t=o.get(e.scope.attemptId),n=t?.get(e.idempotencyKey);t?.delete(e.idempotencyKey),n!==void 0&&(e.type===`model.call.failed`?await n.fail(e.error):await n.complete({outcome:`completed`,result:{...e,content:r?e.content:void 0}}))},m=createAgentChannelDeliveryInstrumentation({recordInputs:n,stateStore:e.stateStore}),onStepMetadata=e=>{let t=a.get(e.scope.attemptId);if(t===void 0)return;let n=readGatewayCostData(e.providerMetadata);n!==void 0&&t.attributes(gatewayCostAttributes(n))};return{hook:{events:{...m,...d,"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,...u.events,"turn.cancelled":s.turnTerminal,"turn.completed":s.turnTerminal,"turn.failed":s.turnTerminal,"turn.started":onTurnStarted},name:`eve.otel`,projectEvent:p.projectEvent,tracePolicy:()=>({emit:!0,recordInputs:n,recordOutputs:r})},prepareSessionTrace:c,prepareTurnTrace:l,async runInContext(t,n){if(t.type===`memory.operation`)return f.runInContext(t,n);let r={emit:!0,...await p.forOperation(t.scope)},inTurn=async()=>{let i=await s.turnFor(t.scope.sessionId,t.scope.turnId,withChannelAudience(ROOT_CONTEXT,t.scope.channelAudience));if(i!==void 0&&!i.finished)return i.run(n,r);let{sessionId:a,turnId:o}=t.scope;return e.telemetry.suppressed!==void 0&&await s.dropped(a,o)?e.telemetry.suppressed(n):n()};if(t.type===`tool.call`)return u.runInContext(t,n,r,inTurn);let i=o.get(t.scope.attemptId)?.get(t.idempotencyKey);return i!==void 0&&!i.finished?i.run(n,r):inTurn()}};async function drainOpenSpans(e){for(let t of o.get(e.scope.attemptId)?.values()??[])e.type===`step.attempt.failed`?await t.fail(e.error):await t.complete({outcome:`completed`,result:{finishReason:`unknown`,usage:{}}});o.delete(e.scope.attemptId)}}export{createAgentOtelInstrumentation};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
/** Converts Gateway response metadata to cost data. */
|
|
2
1
|
import type { Attributes } from "#compiled/@eve/tracing/index.js";
|
|
2
|
+
export declare function createGatewayTraceContextHeaders(): Record<string, string> | undefined;
|
|
3
|
+
/** Converts Gateway response metadata to cost data. */
|
|
3
4
|
export declare function gatewayCostAttributes(input: {
|
|
4
5
|
cost?: number;
|
|
5
6
|
gatewayCost?: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
function gatewayCostAttributes(e){return{"gen_ai.usage.cost":e.cost,"gen_ai.usage.gateway_cost":e.gatewayCost,"gen_ai.usage.input_cost":e.inputCost,"gen_ai.usage.output_cost":e.outputCost,"gen_ai.generation.id":e.generationId}}function readGatewayCostData(e){if(e===void 0)return;let t=e.gateway;if(typeof t!=`object`||!t||Array.isArray(t))return;let n=t;return{cost:readUsd(n.cost),gatewayCost:readUsd(n.gatewayCost),inputCost:readUsd(n.inputInferenceCost),outputCost:readUsd(n.outputInferenceCost),generationId:typeof n.generationId==`string`&&n.generationId.length>0?n.generationId:void 0}}function readUsd(e){if(typeof e!=`string`||e.trim()===``)return;let t=Number(e);return Number.isFinite(t)?t:void 0}export{gatewayCostAttributes,readGatewayCostData};
|
|
1
|
+
import{stripEveTraceBaggage}from"#protocol/baggage.js";import{context,createContextKey,propagation,trace}from"#compiled/@opentelemetry/api/index.js";const SUPPRESS_TRACING_KEY=createContextKey(`OpenTelemetry SDK Context Key SUPPRESS_TRACING`),traceContextSetter={set(e,t,n){e[t]=n}};function createGatewayTraceContextHeaders(){let e=context.active();if(e.getValue(SUPPRESS_TRACING_KEY)===!0||trace.getSpan(e)===void 0)return;let t={};return propagation.inject(e,t,traceContextSetter),stripEveTraceBaggage(t),Object.keys(t).length===0?void 0:t}function gatewayCostAttributes(e){return{"gen_ai.usage.cost":e.cost,"gen_ai.usage.gateway_cost":e.gatewayCost,"gen_ai.usage.input_cost":e.inputCost,"gen_ai.usage.output_cost":e.outputCost,"gen_ai.generation.id":e.generationId}}function readGatewayCostData(e){if(e===void 0)return;let t=e.gateway;if(typeof t!=`object`||!t||Array.isArray(t))return;let n=t;return{cost:readUsd(n.cost),gatewayCost:readUsd(n.gatewayCost),inputCost:readUsd(n.inputInferenceCost),outputCost:readUsd(n.outputInferenceCost),generationId:typeof n.generationId==`string`&&n.generationId.length>0?n.generationId:void 0}}function readUsd(e){if(typeof e!=`string`||e.trim()===``)return;let t=Number(e);return Number.isFinite(t)?t:void 0}export{createGatewayTraceContextHeaders,gatewayCostAttributes,readGatewayCostData};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createLogger,formatError}from"#internal/logging.js";import{applyLiveDeliveryAudienceCeiling}from"#shared/forwarded-trace-policy.js";import{DIRECT_TOOL_CALL_ATTRIBUTE,DIRECT_TOOL_CALL_VALUE}from"#tracing/local/inspection.js";import{resolveInstrumentationEnvironment}from"#internal/application/dev-environment.js";import{operationConversationId}from"#tracing/eve/conversation-context.js";import{resolveTracePolicy}from"#shared/trace-policy.js";import{context}from"#compiled/@opentelemetry/api/index.js";import{buildConversationContext}from"#channel/conversation-context.js";import{markAgentTraceContext}from"#tracing/eve/agent-trace-context.js";import{toolCallIdempotencyKey}from"#instrumentation/lifecycle.js";import{contentAttribute,mcpLifecycle,withErrorContent}from"#compiled/@eve/tracing/otel.js";import{otelTelemetry}from"#compiled/@eve/tracing/index.js";import{getInstrumentationRuntime}from"#instrumentation/runtime-global.js";import{MCP_SERIALIZER}from"#tracing/eve/mcp.js";import{withChannelAudience}from"#tracing/eve/channel-audience-context.js";import{eveOutputMapping}from"#tracing/eve/profile.js";const log=createLogger(`invoke-tool`),agentTelemetry=()=>otelTelemetry({tracerName:`eve.agent`,mapping:eveOutputMapping()});async function withInvokeToolSpan(e,t){let n=withErrorContent(context.active(),!1);return await context.with(n,()=>traced(e,n,t))}async function traced(e,t,n){let r=getInstrumentationRuntime();if(r===void 0)return await n(silentObserver);let i=agentTelemetry(),a=buildConversationContext({adapter:e.origin?.adapter??{kind:`channel`},auth:e.auth,channelName:e.origin?.channelName},resolveInstrumentationEnvironment()),o=toolCallEvents(r.hooks.forTrace?.({agentName:e.agentName,...a})??r.hooks,{attemptId:e.callId,attemptIndex:0,channelAudience:a.audience,functionId:e.agentName,rootSessionId:e.sessionId,sessionId:e.sessionId,stepIndex:0,traceSessionId:e.sessionId,turnId:e.callId},e),s=r.otelSettings;if(s===void 0)return await n(o.observer(void 0));let c=resolveTracePolicy(s.tracePolicy,{agentName:e.agentName,...a},e=>log.warn(`tracePolicy threw; dropping the tool call's trace`,{error:formatError(e)}));if(c.action===`drop`)return await i.suppressed(()=>n(o.observer(void 0)));let l=applyLiveDeliveryAudienceCeiling({
|
|
1
|
+
import{createLogger,formatError}from"#internal/logging.js";import{applyLiveDeliveryAudienceCeiling}from"#shared/forwarded-trace-policy.js";import{DIRECT_TOOL_CALL_ATTRIBUTE,DIRECT_TOOL_CALL_VALUE}from"#tracing/local/inspection.js";import{resolveInstrumentationEnvironment}from"#internal/application/dev-environment.js";import{operationConversationId}from"#tracing/eve/conversation-context.js";import{resolveTracePolicy}from"#shared/trace-policy.js";import{context}from"#compiled/@opentelemetry/api/index.js";import{buildConversationContext}from"#channel/conversation-context.js";import{markAgentTraceContext}from"#tracing/eve/agent-trace-context.js";import{toolCallIdempotencyKey}from"#instrumentation/lifecycle.js";import{contentAttribute,mcpLifecycle,withErrorContent}from"#compiled/@eve/tracing/otel.js";import{otelTelemetry}from"#compiled/@eve/tracing/index.js";import{getInstrumentationRuntime}from"#instrumentation/runtime-global.js";import{MCP_SERIALIZER}from"#tracing/eve/mcp.js";import{withChannelAudience}from"#tracing/eve/channel-audience-context.js";import{eveOutputMapping}from"#tracing/eve/profile.js";const log=createLogger(`invoke-tool`),agentTelemetry=()=>otelTelemetry({tracerName:`eve.agent`,mapping:eveOutputMapping()});async function withInvokeToolSpan(e,t){let n=withErrorContent(context.active(),!1);return await context.with(n,()=>traced(e,n,t))}async function traced(e,t,n){let r=getInstrumentationRuntime();if(r===void 0)return await n(silentObserver);let i=agentTelemetry(),a=buildConversationContext({adapter:e.origin?.adapter??{kind:`channel`},auth:e.auth,channelName:e.origin?.channelName},resolveInstrumentationEnvironment()),o=toolCallEvents(r.hooks.forTrace?.({agentName:e.agentName,...a})??r.hooks,{attemptId:e.callId,attemptIndex:0,channelAudience:a.audience,functionId:e.agentName,rootSessionId:e.sessionId,sessionId:e.sessionId,stepIndex:0,traceSessionId:e.sessionId,turnId:e.callId},e),s=r.otelSettings;if(s===void 0)return await n(o.observer(void 0));let c=resolveTracePolicy(s.tracePolicy,{agentName:e.agentName,...a},e=>log.warn(`tracePolicy threw; dropping the tool call's trace`,{error:formatError(e)}));if(c.action===`drop`)return await i.suppressed(()=>n(o.observer(void 0)));let l=applyLiveDeliveryAudienceCeiling({...c,recordInputs:s.recordInputs&&c.recordInputs,recordOutputs:s.recordOutputs&&c.recordOutputs},a.audience,void 0,a.environment),u=l.action===`record`&&l.recordInputs,d=l.action===`record`&&l.recordOutputs,f=`execute_tool ${e.toolName}`,p=withChannelAudience(t,a.audience),m={"agent.tool.is_framework":!1,"gen_ai.agent.name":e.agentName,"gen_ai.operation.name":`execute_tool`,"gen_ai.tool.call.id":e.callId,"gen_ai.tool.name":e.toolName,"gen_ai.tool.type":`function`,[DIRECT_TOOL_CALL_ATTRIBUTE]:DIRECT_TOOL_CALL_VALUE,"operation.name":`execute_tool`,"resource.name":f,"agent.run.id":e.sessionId,"agent.trace.schema.version":4,"gen_ai.conversation.id":operationConversationId({sessionId:e.sessionId})};process.env.VERCEL_ENV!==void 0&&(m[`vercel.session_id`]=e.sessionId),e.origin!==void 0&&(m[`eve.channel.kind`]=a.channel.kind,m[`eve.channel.name`]=e.origin.channelName);let h=i.startSpan({type:`tool`,operationId:e.callId,name:f,kind:`INTERNAL`,attributes:m},{context:p}),g={emit:!0,recordInputs:u,recordOutputs:d},_=markAgentTraceContext(withErrorContent(p,d)),v=mcpLifecycle({serializer:MCP_SERIALIZER,...g,write:e=>setDefined(h,e),error:(e,t)=>h.fail(d?e:void 0,t)}),y,b=o.observer({failedWith:e=>{y={error:e}},recordInputs:u,span:h});try{let e=await i.run({type:`tool`,reference:h.reference,capture:g,mcp:v},()=>n(b),_);if(h.setAttribute(`eve.tool.outcome`,e.status),e.status===`completed`&&d){let t=contentAttribute(e.output);t!==void 0&&h.setAttribute(`gen_ai.tool.call.result`,t)}return e.status===`invalid-input`?h.fail(void 0,e.status):e.status===`failed`&&h.fail(d?y?.error:void 0,y===void 0?e.status:void 0),e}catch(e){throw h.fail(d?e:void 0),e}finally{h.end(),await r.forceFlush().catch(e=>{log.warn(`flushing a tool call's trace failed`,{error:formatError(e)})})}}const silentObserver={executed:async()=>{},executing:async()=>{},failedWith:()=>{}};function toolCallEvents(e,t,n){let r=e.capturesInputs??e.capturesContent,i=e.capturesOutputs??e.capturesContent,a=toolCallIdempotencyKey(t,n.callId,0);return{observer(o){return{async executing(i){if(o?.recordInputs){let e=contentAttribute(i);e!==void 0&&o.span.setAttribute(`gen_ai.tool.call.arguments`,e)}await e.publish(Object.freeze({callId:n.callId,idempotencyKey:a,input:r?i:void 0,scope:t,toolName:n.toolName,type:`tool.call.started`}))},async executed(n){o?.span.setAttribute(`gen_ai.execute_tool.duration`,n.durationMs/1e3);let r=n.type===`result`?i?{output:n.output,type:`result`}:{type:`result`}:i?{error:n.error,type:`error`}:{type:`error`};await e.publish(Object.freeze({durationMs:n.durationMs,idempotencyKey:a,output:Object.freeze(r),scope:t,type:`tool.call.completed`,outcome:n.type===`result`?`completed`:`failed`}))},failedWith(e){o?.failedWith(e)}}}}}function setDefined(e,t){for(let[n,r]of Object.entries(t))r!==void 0&&e.setAttribute(n,r)}export{withInvokeToolSpan};
|
|
@@ -33,14 +33,15 @@ export interface OtelOptions {
|
|
|
33
33
|
/**
|
|
34
34
|
* Process-wide trace and content decision. Boolean returns preserve the
|
|
35
35
|
* existing audience-aware behavior; explicit decisions can disable emission
|
|
36
|
-
* or select input and output capture independently
|
|
37
|
-
* every audience, with content only for public
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
* parent's effective ceiling, so every
|
|
42
|
-
*
|
|
43
|
-
*
|
|
36
|
+
* or select input and output capture independently for any audience.
|
|
37
|
+
* Defaults to emitting every audience, with content only for public
|
|
38
|
+
* conversations or development. Explicit content decisions override defaults
|
|
39
|
+
* for the evaluated audience, but destination settings can only narrow them.
|
|
40
|
+
* For a trusted remote trace, eve evaluates this policy against the immutable
|
|
41
|
+
* origin audience and intersects it with the parent's effective ceiling, so every
|
|
42
|
+
* hop can only narrow capture. It never changes what lifecycle instrumentation
|
|
43
|
+
* receives. A thrown error rejects trace production without silencing
|
|
44
|
+
* lifecycle providers. The policy may be invoked more than once
|
|
44
45
|
* while a new session is being prepared, so it must be deterministic for
|
|
45
46
|
* consistent results.
|
|
46
47
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{normalizeChannelAudience}from"#shared/channel-audience.js";import{applyLiveDeliveryAudienceCeiling,resolveForwardedTraceSeed}from"#shared/forwarded-trace-policy.js";import{contextStorage}from"#context/container.js";import{SessionTraceSeedKey}from"#context/keys.js";import{isSampledTrace,resolveTracePolicyDecision}from"#shared/trace-policy.js";import{withoutInstrumentationContent}from"#instrumentation/content.js";import{readInstrumentationDecision}from"#shared/instrumentation-decision.js";import{instrumentationEventForTraceDecision}from"#instrumentation/content-policy.js";function createEveCapturePolicy(e){return{async projectEvent(t){let n=await e.stateStore.get(`session`,`scope`in t?t.scope.sessionId:t.sessionId),r=audienceForEvent(t,n?.channelAudience),i=`traceSeed`in t?t.traceSeed:void 0,a=contextStorage.getStore()?.get(SessionTraceSeedKey),o=resolveForwardedTraceSeed(a),s=resolveForwardedTraceSeed(i,o?.forwardedTracePolicy),decisionForTrace=t=>t===void 0?void 0:resolveTracePolicyDecision(isSampledTrace(t),{audience:r,environment:e.environment}),c=s?.decision??o?.decision??readInstrumentationDecision(n?.decision)??decisionForTrace(i)??decisionForTrace(a)??decisionForTrace(n?.context);if(c===void 0)return withoutInstrumentationContent(t);let l=s===void 0||!(`traceSeed`in t)||t.traceSeed===void 0?t:{...t,traceSeed:{...t.traceSeed,decision:s.decision,traceFlags:s.traceFlags}};return instrumentationEventForTraceDecision(l,applyLiveDeliveryAudienceCeiling(c.action===`drop`?c:{
|
|
1
|
+
import{normalizeChannelAudience}from"#shared/channel-audience.js";import{applyLiveDeliveryAudienceCeiling,resolveForwardedTraceSeed}from"#shared/forwarded-trace-policy.js";import{contextStorage}from"#context/container.js";import{SessionTraceSeedKey}from"#context/keys.js";import{isSampledTrace,resolveTracePolicyDecision}from"#shared/trace-policy.js";import{withoutInstrumentationContent}from"#instrumentation/content.js";import{readInstrumentationDecision}from"#shared/instrumentation-decision.js";import{instrumentationEventForTraceDecision}from"#instrumentation/content-policy.js";function createEveCapturePolicy(e){return{async projectEvent(t){let n=await e.stateStore.get(`session`,`scope`in t?t.scope.sessionId:t.sessionId),r=audienceForEvent(t,n?.channelAudience),i=`traceSeed`in t?t.traceSeed:void 0,a=contextStorage.getStore()?.get(SessionTraceSeedKey),o=resolveForwardedTraceSeed(a),s=resolveForwardedTraceSeed(i,o?.forwardedTracePolicy),decisionForTrace=t=>t===void 0?void 0:resolveTracePolicyDecision(isSampledTrace(t),{audience:r,environment:e.environment}),c=s?.decision??o?.decision??readInstrumentationDecision(n?.decision)??decisionForTrace(i)??decisionForTrace(a)??decisionForTrace(n?.context);if(c===void 0)return withoutInstrumentationContent(t);let l=s===void 0||!(`traceSeed`in t)||t.traceSeed===void 0?t:{...t,traceSeed:{...t.traceSeed,decision:s.decision,traceFlags:s.traceFlags}};return instrumentationEventForTraceDecision(l,applyLiveDeliveryAudienceCeiling(c.action===`drop`?c:{...c,recordInputs:e.recordInputs&&c.recordInputs,recordOutputs:e.recordOutputs&&c.recordOutputs},r,s?.forwardedTracePolicy??o?.forwardedTracePolicy,e.environment),{audience:r,environment:e.environment},{applyAudienceCeiling:!1})},async forOperation(t){let n=await e.stateStore.get(`session`,t.sessionId),r=resolveForwardedTraceSeed(contextStorage.getStore()?.get(SessionTraceSeedKey)),i=r?.decision??n?.decision,a=i===void 0?void 0:applyLiveDeliveryAudienceCeiling(i,normalizeChannelAudience(t.channelAudience),r?.forwardedTracePolicy,e.environment);return{recordInputs:e.recordInputs&&a?.action===`record`&&a.recordInputs,recordOutputs:e.recordOutputs&&a?.action===`record`&&a.recordOutputs}}}}function audienceForEvent(e,t){return`delivery`in e?normalizeChannelAudience(e.delivery.channelAudience):`scope`in e&&e.scope.channelAudience!==void 0?normalizeChannelAudience(e.scope.channelAudience):e.type===`session.started`?normalizeChannelAudience(e.channelAudience):normalizeChannelAudience(t)}export{createEveCapturePolicy};
|
package/dist/src/vue/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as conversationProjection, i as openConversationInputs, n as conversationReducer, o as callStatus, r as defaultMessageReducer, t as useEveAgent } from "../chunks/use-eve-agent-
|
|
1
|
+
import { a as conversationProjection, i as openConversationInputs, n as conversationReducer, o as callStatus, r as defaultMessageReducer, t as useEveAgent } from "../chunks/use-eve-agent-Vsl-S0yI.js";
|
|
2
2
|
|
|
3
3
|
//#region src/client/tool-call-state.ts
|
|
4
4
|
function toolCallState(conversation, callId, options = {}) {
|
|
@@ -104,6 +104,12 @@ export interface UseEveAgentOptions<TData> extends EveAgentStoreCallbacks<TData>
|
|
|
104
104
|
readonly optimistic?: boolean;
|
|
105
105
|
/** Follow each subagent call's session into `conversation.agents` while mounted. @default false */
|
|
106
106
|
readonly followSubagents?: boolean;
|
|
107
|
+
/**
|
|
108
|
+
* Keep the session stream open between turns to show events that arrive from schedules,
|
|
109
|
+
* channels, or other clients. Set to false to close it once the session is idle and reopen it
|
|
110
|
+
* on the next send, answer, or resume. @default true
|
|
111
|
+
*/
|
|
112
|
+
readonly followIdle?: boolean;
|
|
107
113
|
/** Prewarm an owned session on mount and after reset. @default false */
|
|
108
114
|
readonly prewarm?: boolean;
|
|
109
115
|
/**
|
package/docs/agent-config.md
CHANGED
|
@@ -75,6 +75,54 @@ prefix. Each subagent session gets its own key. An authored
|
|
|
75
75
|
in the `session-id` header, which the Codex backend uses for cache routing.
|
|
76
76
|
Gateway-routed calls do not receive the option.
|
|
77
77
|
|
|
78
|
+
### Use a local model
|
|
79
|
+
|
|
80
|
+
To test against a model running on your own machine, point the AI SDK
|
|
81
|
+
[OpenAI-compatible provider](https://ai-sdk.dev/providers/openai-compatible-providers)
|
|
82
|
+
at a local server. This works with any server that implements the OpenAI Chat
|
|
83
|
+
Completions API, such as Ollama, LM Studio, llama.cpp, or vLLM. With
|
|
84
|
+
[Ollama](https://docs.ollama.com/api/openai-compatibility):
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
pnpm add @ai-sdk/openai-compatible
|
|
88
|
+
ollama pull gpt-oss:20b
|
|
89
|
+
OLLAMA_CONTEXT_LENGTH=64000 ollama serve
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
```ts title="agent/agent.ts"
|
|
93
|
+
import { createOpenAICompatible } from "@ai-sdk/openai-compatible";
|
|
94
|
+
import { defineAgent } from "eve";
|
|
95
|
+
|
|
96
|
+
const ollama = createOpenAICompatible({
|
|
97
|
+
name: "ollama",
|
|
98
|
+
baseURL: "http://localhost:11434/v1",
|
|
99
|
+
includeUsage: true, // report token usage while streaming
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
export default defineAgent({
|
|
103
|
+
model: ollama("gpt-oss:20b"),
|
|
104
|
+
modelContextWindowTokens: 64_000,
|
|
105
|
+
});
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
- **Context window.** AI Gateway has no metadata for local models, so set
|
|
109
|
+
`modelContextWindowTokens` to the context length your server allocates, not
|
|
110
|
+
the model's maximum. eve uses it to decide when to compact. Ollama allocates
|
|
111
|
+
as little as 4K tokens by default; raise it to at least 64K for agents, as
|
|
112
|
+
above.
|
|
113
|
+
- **Tool calling.** eve agents call tools on most turns, so pick a model with
|
|
114
|
+
native tool-calling support. `gpt-oss:20b`, `qwen3`, and `gemma4` are good
|
|
115
|
+
starting points on Ollama.
|
|
116
|
+
- **Usage.** `includeUsage: true` lets token usage reach eve's
|
|
117
|
+
[session limits](#runtime-limits). Local models report no cost, so
|
|
118
|
+
`maxTokenCostUsdPerSession` does not apply.
|
|
119
|
+
- **Other servers.** Change `baseURL`, for example to
|
|
120
|
+
`http://localhost:1234/v1` for LM Studio. Pass `apiKey` for a remote
|
|
121
|
+
OpenAI-compatible server that requires one.
|
|
122
|
+
|
|
123
|
+
A deployment cannot reach a server on your machine, so use a Gateway or hosted
|
|
124
|
+
provider model when you deploy.
|
|
125
|
+
|
|
78
126
|
### Choose the model dynamically
|
|
79
127
|
|
|
80
128
|
To select a model from the incoming prompt with an AI SDK decision model, use
|
package/docs/channels/eve.mdx
CHANGED
|
@@ -203,6 +203,8 @@ Stream a session as newline-delimited JSON from `GET /eve/v1/session/:sessionId/
|
|
|
203
203
|
|
|
204
204
|
Following a stranded session's stream returns `409 session_stranded`, just like a send. The TypeScript client reports `ClientSessionStrandedError` without retrying. Pass `follow=false` to read the recorded history instead: the response ends at the durable tail, carries the `x-eve-stream-tail-index` header, and never inspects or changes the session, so it works before a reset. A reset attempts to append `session.failed` with code `session_stranded` and close the stream. Existing readers finish when they receive that terminal event.
|
|
205
205
|
|
|
206
|
+
After a session ends, the World keeps its stream only for its retention period. Reading a stream past that point returns `410 session_expired`. The history is gone, so the TypeScript client fails on the first response with a `ClientError` whose `code` is `"session_expired"`, without retrying.
|
|
207
|
+
|
|
206
208
|
### Cancel a turn
|
|
207
209
|
|
|
208
210
|
Post to `/eve/v1/session/:sessionId/cancel` to request cancellation of the active turn. You can include the observed `turnId` to keep a late request from cancelling a newer turn. Cancellation is asynchronous; confirm the turn boundary on the stream as `turn.cancelled` followed by `session.waiting`.
|
|
@@ -254,12 +254,13 @@ App-scoped Connect auth is non-interactive. eve asks Vercel Connect for an app t
|
|
|
254
254
|
|
|
255
255
|
### Troubleshooting Vercel Connect auth
|
|
256
256
|
|
|
257
|
-
| Symptom
|
|
258
|
-
|
|
|
259
|
-
| `reason: "principal_required"`
|
|
260
|
-
| `authorization.required` appears but no UI
|
|
261
|
-
| OAuth works locally but fails after deploy
|
|
262
|
-
| A scheduled or internal run needs user OAuth
|
|
257
|
+
| Symptom | What it means | Fix |
|
|
258
|
+
| ------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
259
|
+
| `reason: "principal_required"` | A user-scoped connection ran without an authenticated user on the active session. | Return `principalType: "user"` from the channel's route auth, or use `connect({ connector, principalType: "app" })` if the Connect credential should be shared. |
|
|
260
|
+
| `authorization.required` appears but no UI | eve parked the turn for OAuth, but the channel or frontend is not rendering the challenge. | Render the challenge from the stream event and continue the same session after the callback. |
|
|
261
|
+
| OAuth works locally but fails after deploy | The project may not be linked to the Connect client, or the deployed runtime may not have the expected Vercel OIDC/project scope. | Run Connect setup from the consuming project directory, link the project, deploy again, and verify the connector UID in `connect("...")`. |
|
|
262
|
+
| A scheduled or internal run needs user OAuth | Schedules and runtime callers do not automatically carry an end-user principal. | Dispatch through a user-authenticated channel when work is user-owned, or use app-scoped auth for agent-owned background work. |
|
|
263
|
+
| Sign-in ends on a Vercel login or protection page | The deployment is behind Deployment Protection, and sign-in callback URLs never carry the automation bypass secret. | Have the user sign in to Vercel with access to the project, or add a Deployment Protection Exception for the domain. |
|
|
263
264
|
|
|
264
265
|
## Self-hosted interactive OAuth
|
|
265
266
|
|
|
@@ -316,6 +317,8 @@ export default defineMcpClientConnection({
|
|
|
316
317
|
|
|
317
318
|
Drop `resume` when the provider keeps flow state server-side, so nothing has to cross the step boundary.
|
|
318
319
|
|
|
320
|
+
The callback URL never carries `VERCEL_AUTOMATION_BYPASS_SECRET`, because the user's browser and the provider both see it. On a deployment behind [Deployment Protection](https://vercel.com/docs/deployment-protection), the person signing in must pass protection on their own, for example through Vercel Authentication or a [Deployment Protection Exception](https://vercel.com/docs/deployment-protection/methods-to-bypass-deployment-protection/deployment-protection-exceptions).
|
|
321
|
+
|
|
319
322
|
`displayName` is presentation-only. The connection's resolved name still keys
|
|
320
323
|
the callback URL, while eve scopes token caching and authorization completion
|
|
321
324
|
to the opaque resolved instance identity. You can also set `displayName` on the
|
|
@@ -165,6 +165,15 @@ its cursor after a disconnect or the
|
|
|
165
165
|
server's renewable 60-second lease; lease renewal does not start a turn or clear UI state.
|
|
166
166
|
Unmounting or resetting closes the local stream without cancelling the old durable session.
|
|
167
167
|
|
|
168
|
+
An open stream reconnects for as long as the chat stays mounted, even when nothing happens. If
|
|
169
|
+
your UI only shows replies to its own messages, such as a help sidebar that stays mounted across
|
|
170
|
+
pages, pass `followIdle: false`. The binding then closes the stream once the session is idle: no
|
|
171
|
+
turn is running or parked, no task is working, and no sign-in is pending. A prewarmed session
|
|
172
|
+
opens no stream until its first message. The next `send()`, `respond()`, or `resume()` reopens
|
|
173
|
+
the stream from the session cursor, so events that arrived in between are applied then. Leave
|
|
174
|
+
`followIdle` on when other sources, such as schedules, channels, or another tab, can start turns
|
|
175
|
+
in the session while your UI is idle.
|
|
176
|
+
|
|
168
177
|
`reset()` reuses the hook instance and clears the conversation. When `prewarm` is true after
|
|
169
178
|
the reset, it prepares the next owned session; otherwise, the next send creates it. An explicitly
|
|
170
179
|
supplied `session` remains externally owned and is never replaced by prewarming or reset. Use
|
|
@@ -399,7 +408,7 @@ then save a final snapshot in `onFinish`.
|
|
|
399
408
|
|
|
400
409
|
`initialEvents` must be an ordered prefix of the same session's stream, but its endpoint does not have to line up exactly with where the stream resumes. When the event count matches `initialSession.streamIndex`, catch-up continues from that cursor. A partial or overlapping saved log falls back to index `0`. Every event carries a stable [`meta.id`](/docs/concepts/sessions-runs-and-streaming#the-event-envelope), and the store drops any event whose id it has already applied, so an overlapping replay renders once and `onEvent` only fires for events your UI has not seen.
|
|
401
410
|
|
|
402
|
-
For multiple chat threads, keep one saved event log and session cursor per thread. `agent`, `host`, `reducer`, `session`, `initialEvents`, `initialSession`, `auth`, `headers`, `optimistic`, and `resume` are read when the hook creates its store, so remount the chat component when switching threads, for example with `key={chat.id}`. React reads `prewarm` on every render.
|
|
411
|
+
For multiple chat threads, keep one saved event log and session cursor per thread. `agent`, `host`, `reducer`, `session`, `initialEvents`, `initialSession`, `auth`, `headers`, `optimistic`, `followIdle`, and `resume` are read when the hook creates its store, so remount the chat component when switching threads, for example with `key={chat.id}`. React reads `prewarm` on every render.
|
|
403
412
|
|
|
404
413
|
Pass `resume: true` with `initialSession` to rebuild the projection from the durable stream after mount. While `status` is `"resuming"`, render hydrated `data` but disable message and HITL submission; do not present cancellation or active-turn progress controls. If catch-up finds an in-flight turn, `status` changes to `"streaming"` before the binding follows it to a boundary. The stream reports its initial durable tail so catch-up can finish without closing the connection or waiting for an idle timeout. A settled tail changes directly to `"ready"`; a newer turn or pending authorization remains `"streaming"`. The connection stays open to receive later events. A terminal session failure changes to `"error"`.
|
|
405
414
|
|
package/docs/guides/hooks.md
CHANGED
|
@@ -97,7 +97,7 @@ when the parent's current model step ends if one is running.
|
|
|
97
97
|
|
|
98
98
|
### Narrowing tool results
|
|
99
99
|
|
|
100
|
-
`toolResultFrom` narrows an `action.result` event to a specific authored tool or MCP
|
|
100
|
+
`toolResultFrom` narrows an `action.result` event to a specific authored tool or connection (MCP or OpenAPI) and returns typed output. Import it from `eve/tools`:
|
|
101
101
|
|
|
102
102
|
```ts
|
|
103
103
|
import { defineHook } from "eve/hooks";
|
|
@@ -114,7 +114,7 @@ export default defineHook({
|
|
|
114
114
|
console.log(weather.output.temperature);
|
|
115
115
|
}
|
|
116
116
|
|
|
117
|
-
//
|
|
117
|
+
// Connection: output is unknown, toolName is qualified
|
|
118
118
|
const linearResult = toolResultFrom(event.data.result, linear);
|
|
119
119
|
if (linearResult) {
|
|
120
120
|
console.log(linearResult.connectionToolName, linearResult.output);
|
|
@@ -174,6 +174,9 @@ each turn. Remote requests carry the conversation ID in W3C Baggage.
|
|
|
174
174
|
`trustedForwarders` controls whether the receiver accepts parent session data
|
|
175
175
|
and the trace-content policy. See
|
|
176
176
|
[Remote agents](../guides/remote-agents#preserving-trace-content).
|
|
177
|
+
Gateway-routed model calls propagate the configured OpenTelemetry context at
|
|
178
|
+
each provider request. Eve-owned baggage is removed before forwarding. Gateway
|
|
179
|
+
controls whether its spans are sampled and which destinations receive them.
|
|
177
180
|
|
|
178
181
|
## Local traces
|
|
179
182
|
|
package/docs/reference/cli.md
CHANGED
|
@@ -403,7 +403,7 @@ Each root agent turn starts a new trace. With local caller trace context, that t
|
|
|
403
403
|
|
|
404
404
|
Every span carries a real duration. A turn's root `invoke_agent` span is written when the turn settles, so a running turn shows only its steps.
|
|
405
405
|
|
|
406
|
-
Model, `execute_tool`, and memory spans retain their content by default. Set `EVE_TRACES_CONTENT=off` to omit system prompts, prompt messages, and response text for models; call arguments and results for tools; and recalled memory records. Each captured value is capped at 32 KB.
|
|
406
|
+
Model, `execute_tool`, and memory spans retain their content by default. Set `EVE_TRACES_CONTENT=off` to omit system prompts, prompt messages, and response text for models; call arguments and results for tools; and recalled memory records. Each captured value is capped at 32 KB. When a model call's prompt messages exceed the cap, the oldest are dropped first and `agent.input.messages.omitted` records how many.
|
|
407
407
|
|
|
408
408
|
Step spans carry token counts under `agent.usage.*`, and cost when Vercel AI Gateway served the call. Model spans also expose `gen_ai.usage.*` token counters. The CLI sums step-level counters only, so model and delegated-call totals are not counted twice.
|
|
409
409
|
|
|
@@ -103,12 +103,13 @@ import template from "../../prompts/template.txt?raw";
|
|
|
103
103
|
|
|
104
104
|
`ctx` is passed to your tool `execute`, hook handlers, channel event handlers, and connection auth/header resolvers. It is live only while authored code is running, so reaching for it at module top level throws. See [Session context](../guides/session-context) for the full model.
|
|
105
105
|
|
|
106
|
-
| Member | Use
|
|
107
|
-
| --------------------------- |
|
|
108
|
-
| `ctx.session` | Current session, turn, auth, and optional parent lineage (read-only)
|
|
109
|
-
| `ctx.getSandbox()` | Live sandbox handle; `stop()` releases compute but preserves durable state
|
|
110
|
-
| `ctx.getToken(provider)` | Resolve a bearer token for an inline auth provider such as `connect("...")`
|
|
111
|
-
| `ctx.requireAuth(provider)` | Evict and re-authorize an inline provider, commonly after a downstream `401`
|
|
106
|
+
| Member | Use |
|
|
107
|
+
| --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
108
|
+
| `ctx.session` | Current session, turn, auth, and optional parent lineage (read-only) |
|
|
109
|
+
| `ctx.getSandbox()` | Live sandbox handle; `stop()` releases compute but preserves durable state |
|
|
110
|
+
| `ctx.getToken(provider)` | Resolve a bearer token for an inline auth provider such as `connect("...")` |
|
|
111
|
+
| `ctx.requireAuth(provider)` | Evict and re-authorize an inline provider, commonly after a downstream `401` |
|
|
112
|
+
| `ctx.approval` | Present only while a call runs after a person approved it: `responder` is who approved it and `responder.getToken(provider)` resolves their token. The call still runs as `ctx.session.auth.current`; see [Human-in-the-loop](/docs/human-in-the-loop) |
|
|
112
113
|
|
|
113
114
|
Tool definitions accept `availableInSubagents: false` to restrict the tool to top-level root sessions, and `deferred: true` to keep the tool out of the model's tool list so the model finds it with `eve__search` and calls it with `eve__tool`; see [Tools](../tools#keep-a-tool-out-of-the-tool-list). `defineTool` definitions accept `endsTurn: true`, or a function that receives the `execute` output, to end the turn without a reply after a successful call; see [Tools](../tools#end-the-turn-after-a-tool-call). Authored workflow bodies also receive `ctx.agents`, a replay-stable map of callable-agent metadata, and `ctx.agent(name)`, which returns an `AgentSession` whose `send(message, options?)` resolves to a response with `result()`. A `"use step"` helper that receives the context directly should type it as `WorkflowStepToolContext`, which excludes `agents`, `agent`, and `ask`. The root-copy `agent` entry has an empty description when the root omits `description`. See [Workflows as tools](../tools/workflows#delegate-work-ctxagent) for the workflow-only context.
|
|
114
115
|
|
package/docs/sandbox/vercel.mdx
CHANGED
|
@@ -95,6 +95,15 @@ await sandbox.setNetworkPolicy("deny-all");
|
|
|
95
95
|
return sandbox;
|
|
96
96
|
```
|
|
97
97
|
|
|
98
|
+
## Live sandbox name
|
|
99
|
+
|
|
100
|
+
Sessions returned by `environment.open()` and `ctx.getSandbox(environment)` expose a read-only `name` property. The name identifies the live Vercel Sandbox and stays stable across stop/resume for the session. Use it as `sandboxName` when creating Vercel git-credential-broker grants scoped to that sandbox:
|
|
101
|
+
|
|
102
|
+
```ts
|
|
103
|
+
const sandbox = await ctx.getSandbox(environment);
|
|
104
|
+
const sandboxName = sandbox.name;
|
|
105
|
+
```
|
|
106
|
+
|
|
98
107
|
## Live sandbox options
|
|
99
108
|
|
|
100
109
|
`open()` also accepts Vercel compute resources, timeout, and Drive mounts. Configure project credentials and custom fetch behavior on the environment, not in `open()`, because resume does not reconstruct start-only options.
|
package/docs/skills.mdx
CHANGED
|
@@ -44,7 +44,7 @@ A skill's name comes from its path and must use only ASCII letters, digits, unde
|
|
|
44
44
|
|
|
45
45
|
A flat markdown skill can skip the `description` frontmatter. When it does, eve advertises the first non-empty, non-code-fence line of the body with any leading `#`, `>`, `*`, or `-` marker stripped. If the body has no such line, eve falls back to the literal `Instructions for the <name> skill.`, which is a weak routing hint, so add a `description` when you want the model to route on intent.
|
|
46
46
|
|
|
47
|
-
A packaged skill is a directory with a `SKILL.md` plus sibling files like `references/`, `assets/`, and `scripts/`. The packaged `SKILL.md` must carry `description` frontmatter; it has no filename slug to fall back on.
|
|
47
|
+
A packaged skill is a directory with a `SKILL.md` plus sibling files like `references/`, `assets/`, and `scripts/`. The packaged `SKILL.md` must carry `description` frontmatter; it has no filename slug to fall back on. eve ignores frontmatter it does not use so skills authored for other Agent Skills clients remain importable.
|
|
48
48
|
|
|
49
49
|
```md title="agent/skills/research/SKILL.md"
|
|
50
50
|
---
|
|
@@ -256,6 +256,27 @@ When a subagent requests input, eve emits the same `input.requested` event on it
|
|
|
256
256
|
|
|
257
257
|
Approval is consent only. An approved tool call runs with the requesting user's identity, connections, and credentials, including its policy recheck. The approver's access is never lent to the call. Subsequent tool calls in the turn also stay with the original owner.
|
|
258
258
|
|
|
259
|
+
A `defineTool` tool can still act on the approver's behalf when it chooses to. While an approved `defineTool` call runs, `ctx.approval.responder` is the principal who approved it, and `ctx.approval.responder.getToken(provider)` resolves that person's token for an inline provider, as `ctx.getToken(provider)` does for the requester. `ctx.session.auth.current` stays the requester. `ctx.approval` is absent for calls that needed no approval, and workflow tools don't receive it. `ctx.approval.responder.getToken(provider)` never starts a sign-in: when the approver has no token, it throws a `ConnectionAuthorizationFailedError` with `reason: "approver_authorization_required"`.
|
|
260
|
+
|
|
261
|
+
```ts
|
|
262
|
+
export default defineTool({
|
|
263
|
+
description: "Grant the requester access to a repository.",
|
|
264
|
+
inputSchema: z.object({ repo: z.string() }),
|
|
265
|
+
approval: {
|
|
266
|
+
request: always(),
|
|
267
|
+
response: ({ response }) =>
|
|
268
|
+
itAdmins.includes(response.principal.principalId)
|
|
269
|
+
? { status: "allowed" }
|
|
270
|
+
: { status: "rejected" },
|
|
271
|
+
},
|
|
272
|
+
async execute({ repo }, ctx) {
|
|
273
|
+
const admin = await ctx.approval?.responder.getToken(github);
|
|
274
|
+
if (admin === undefined) throw new Error("An IT admin must approve this grant.");
|
|
275
|
+
return await grantAccess(repo, ctx.session.auth.current, admin.token);
|
|
276
|
+
},
|
|
277
|
+
});
|
|
278
|
+
```
|
|
279
|
+
|
|
259
280
|
For approval requests, a follow-up message that doesn't match an option steers the turn instead of answering it. eve cancels the turn's pending approval, so the call doesn't run and `input.resolved` reports `outcome: "ignored"`, and the model reads the message next. This happens even when the message is sent with `turnPolicy: "queue"`, because a turn held on a person can't end until they act. Calls the person already approved in the same batch still run. A message from someone other than the person the turn serves waits until the turn ends. Cancelling the turn withdraws its approval: the call doesn't run, `input.resolved` reports `outcome: "cancelled"`, and a later answer to it approves nothing.
|
|
260
281
|
|
|
261
282
|
### Several requests at once
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{isSessionInboxAddress}from"#execution/session-inbox/address.js";import{inputOptionSchema}from"#shared/input.js";const PROXY_INPUT_REQUESTS_KEY=`eve.runtime.proxyInputRequests`,PROXY_INPUT_REQUEST_KINDS={question:!0,"session-limit":!0,"tool-approval":!0};function resolvedByChild(e){return e===`tool-approval`}function resolvedForParent(e){let t=e.resolutions.filter(({kind:e})=>resolvedByChild(e));return t.length===0?void 0:{...e,resolutions:t}}function getProxyInputRequests(e){return new Map(Object.entries(readMap(e)))}function hasProxyInputRequests(e){for(let t of Object.keys(readMap(e)))return!0;return!1}function upsertProxyInputRequests(e){return{...e.session,state:upsertProxyInputRequestState({entries:e.entries,forChildContinuationToken:e.forChildContinuationToken,inputSource:e.inputSource,state:e.session.state})}}function upsertProxyInputRequestState(e){let t={};for(let[n,r]of Object.entries(readMap(e.state)))(r.childContinuationToken!==e.forChildContinuationToken||r.inputSource!==e.inputSource)&&(t[n]=r);for(let[n,r]of e.entries)t[n]=r;let n={...e.state};return Object.keys(t).length===0?delete n[PROXY_INPUT_REQUESTS_KEY]:n[PROXY_INPUT_REQUESTS_KEY]=t,Object.keys(n).length>0?n:void 0}function clearProxyInputRequestsWhere(e,t){return retireProxyInputRequests(e,Object.entries(readMap(e.state)).filter(([e,n])=>t(n,e)).map(([e])=>e))}function retireProxyInputRequests(e,t){let n={...readMap(e.state)},r=!1;for(let e of t)Object.hasOwn(n,e)&&(delete n[e],r=!0);return r?writeMap(e,n):e}function toProxyInputRequestEntries(e){let t={approvalRequestIds:e.event.requests.flatMap(e=>e.kind===`tool-approval`?[e.requestId]:[]),requestIds:e.event.requests.map(e=>e.requestId)},n={sequence:e.event.sequence,stepIndex:e.event.stepIndex,turnId:e.event.turnId};return e.event.requests.map(r=>{let i={batch:t,childContinuationToken:e.childContinuationToken,...e.inputSource!==void 0&&{inputSource:e.inputSource},...e.remote!==void 0&&{remote:e.remote},event:n,kind:r.kind,reply:{...r.allowFreeform!==void 0&&{allowFreeform:r.allowFreeform},...r.options!==void 0&&{options:[...r.options]}}};return e.childSessionInbox?.sessionId===e.childSessionId&&(i.childSessionInbox=e.childSessionInbox),[r.requestId,i]})}function readMap(e){let t=e?.[PROXY_INPUT_REQUESTS_KEY];if(typeof t!=`object`||!t||Array.isArray(t))return{};let n={};for(let[e,r]of Object.entries(t)){let t=parseProxyInputRequest(r,e);t!==void 0&&(n[e]=t)}return n}function writeMap(e,t){let n={...e.state};return Object.keys(t).length===0?(delete n[PROXY_INPUT_REQUESTS_KEY],{...e,state:Object.keys(n).length>0?n:void 0}):(n[PROXY_INPUT_REQUESTS_KEY]=t,{...e,state:n})}function parseProxyInputRequest(e,t){if(typeof e!=`object`||!e||Array.isArray(e)||!(`childContinuationToken`in e)||!(`kind`in e)||typeof e.childContinuationToken!=`string`||!isInputRequestKind(e.kind))return;let n=`remote`in e?parseRemoteAgentBinding(e.remote):void 0;if(`remote`in e&&n===void 0)return;let r=`inputSource`in e?e.inputSource:void 0;if(r!==void 0&&(typeof r!=`string`||r.length===0))return;let i=`event`in e?parseInputRequestEvent(e.event):void 0;if(i===void 0)return;let a=`batch`in e?parseProxyInputRequestBatch(e.batch):void 0,o=`workflowAsk`in e?parseWorkflowAskRoute(e.workflowAsk):void 0;if(`workflowAsk`in e&&o===void 0)return;let s=`runId`in e?e.runId:void 0;if(s!==void 0&&(typeof s!=`string`||s.length===0))return;let c=`reply`in e?parseProxyInputReply(e.reply):void 0;if(`reply`in e&&c===void 0)return;let l=`childSessionInbox`in e?e.childSessionInbox:void 0;if(l!==void 0&&!isSessionInboxAddress(l))return;let u={childContinuationToken:e.childContinuationToken,event:i,kind:e.kind};return typeof r==`string`&&(u.inputSource=r),n!==void 0&&(u.remote=n),o!==void 0&&(u.workflowAsk=o),typeof s==`string`&&(u.runId=s),l!==void 0&&(u.childSessionInbox=l),a!==void 0&&a.requestIds.includes(t)&&(u.batch=a),c!==void 0&&(u.reply=c),u}function parseInputRequestEvent(e){if(typeof e!=`object`||!e||Array.isArray(e))return;let t=Reflect.get(e,`sequence`),n=Reflect.get(e,`stepIndex`),r=Reflect.get(e,`turnId`);if(typeof t==`number`&&typeof n==`number`&&typeof r==`string`)return{sequence:t,stepIndex:n,turnId:r}}function parseWorkflowAskRoute(e){if(typeof e!=`object`||!e)return;let t=Reflect.get(e,`control`);if(typeof t==`string`&&t.length!==0)return{control:t}}function parseRemoteAgentBinding(e){if(typeof e!=`object`||!e||Array.isArray(e))return;let t=Reflect.get(e,`name`),n=Reflect.get(e,`url`),r=Reflect.get(e,`resolverId`),i=Reflect.get(e,`forwardPrincipal`),a=Reflect.get(e,`sessionId`);if(typeof t==`string`&&t&&typeof n==`string`&&n&&typeof a==`string`&&a&&(r===void 0||typeof r==`string`&&r)&&(i===void 0||typeof i==`boolean`))return{name:t,url:n,sessionId:a,...r!==void 0&&{resolverId:r},...i!==void 0&&{forwardPrincipal:i}}}function parseProxyInputReply(e){if(typeof e!=`object`||!e||Array.isArray(e))return;let t={},n=Reflect.get(e,`allowFreeform`);if(n!==void 0){if(typeof n!=`boolean`)return;t.allowFreeform=n}let r=Reflect.get(e,`options`);if(r!==void 0){let e=inputOptionSchema.array().safeParse(r);if(!e.success)return;t.options=e.data}return t}function parseProxyInputRequestBatch(e){if(typeof e!=`object`||!e||Array.isArray(e)||!(`approvalRequestIds`in e)||!(`requestIds`in e)||!isStringArray(e.approvalRequestIds)||!isStringArray(e.requestIds))return;let t=new Set(e.requestIds);if(!(t.size!==e.requestIds.length||e.approvalRequestIds.some(e=>!t.has(e))))return{approvalRequestIds:e.approvalRequestIds,requestIds:e.requestIds}}function isStringArray(e){return Array.isArray(e)&&e.every(e=>typeof e==`string`)}function isInputRequestKind(e){return typeof e==`string`&&Object.hasOwn(PROXY_INPUT_REQUEST_KINDS,e)}export{clearProxyInputRequestsWhere,getProxyInputRequests,hasProxyInputRequests,resolvedByChild,resolvedForParent,retireProxyInputRequests,toProxyInputRequestEntries,upsertProxyInputRequestState,upsertProxyInputRequests};
|