eve 0.30.6 → 0.30.7
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 +9 -0
- package/dist/src/cli/commands/trace-detail.d.ts +53 -0
- package/dist/src/cli/commands/trace-detail.js +1 -0
- package/dist/src/cli/commands/trace.d.ts +4 -1
- package/dist/src/cli/commands/trace.js +4 -4
- package/dist/src/cli/dev/tui/terminal-renderer.js +2 -2
- package/dist/src/cli/dev/tui/traces/trace-content.d.ts +3 -3
- package/dist/src/cli/dev/tui/traces/trace-content.js +1 -1
- package/dist/src/cli/dev/tui/traces/trace-view.js +1 -1
- package/dist/src/cli/run.js +1 -1
- package/dist/src/compiler/extension-compatibility.d.ts +10 -10
- package/dist/src/compiler/extension-compatibility.js +1 -1
- package/dist/src/context/dynamic-subagent-lifecycle.d.ts +2 -0
- package/dist/src/context/dynamic-subagent-lifecycle.js +1 -1
- package/dist/src/execution/agent-continuation-bundle.d.ts +13 -0
- package/dist/src/execution/agent-continuation-bundle.js +1 -0
- package/dist/src/execution/agent-handle-dispatch.d.ts +32 -4
- package/dist/src/execution/agent-handle-dispatch.js +1 -1
- package/dist/src/execution/cancel-descendant-turns-step.js +1 -1
- package/dist/src/execution/delegated-parent-notification.d.ts +30 -4
- package/dist/src/execution/delegated-parent-notification.js +1 -1
- package/dist/src/execution/delegated-parent-result.js +1 -1
- package/dist/src/execution/dispatch-action-failures.d.ts +8 -0
- package/dist/src/execution/dispatch-action-failures.js +1 -0
- package/dist/src/execution/dispatch-runtime-actions-step.d.ts +8 -7
- package/dist/src/execution/dispatch-runtime-actions-step.js +1 -1
- package/dist/src/execution/dispatch-start-operation.d.ts +15 -0
- package/dist/src/execution/dispatch-start-operation.js +1 -0
- package/dist/src/execution/forward-turn-cancellation-step.js +1 -1
- package/dist/src/execution/next-driver-action.d.ts +12 -0
- package/dist/src/execution/node-step.d.ts +1 -1
- package/dist/src/execution/node-step.js +1 -1
- package/dist/src/execution/parked-delivery-wait.d.ts +35 -0
- package/dist/src/execution/parked-delivery-wait.js +1 -0
- package/dist/src/execution/remote-agent-dispatch.d.ts +42 -0
- package/dist/src/execution/remote-agent-dispatch.js +1 -1
- package/dist/src/execution/sandbox/prewarm.js +1 -1
- package/dist/src/execution/session-timeout-steps.js +1 -1
- package/dist/src/execution/settle-cancelled-turn-step.js +1 -1
- package/dist/src/execution/subagent-invocation.d.ts +3 -0
- package/dist/src/execution/subagent-invocation.js +1 -1
- package/dist/src/execution/subagent-tool.d.ts +7 -0
- package/dist/src/execution/subagent-tool.js +1 -1
- package/dist/src/execution/terminate-child-sessions-step.d.ts +15 -0
- package/dist/src/execution/terminate-child-sessions-step.js +1 -0
- package/dist/src/execution/turn-control-protocol.js +1 -1
- package/dist/src/execution/turn-execution-cursor.d.ts +3 -0
- package/dist/src/execution/turn-workflow.js +1 -1
- package/dist/src/execution/workflow-entry.js +1 -1
- package/dist/src/execution/workflow-runtime.js +1 -1
- package/dist/src/execution/workflow-steps.d.ts +8 -1
- package/dist/src/execution/workflow-steps.js +1 -1
- package/dist/src/harness/agent-handle-errors.d.ts +0 -2
- package/dist/src/harness/agent-handle-errors.js +1 -1
- package/dist/src/harness/handles/transitions.d.ts +16 -1
- package/dist/src/harness/handles/transitions.js +1 -1
- package/dist/src/harness/messages.d.ts +4 -2
- package/dist/src/harness/messages.js +1 -1
- package/dist/src/harness/runtime-actions.js +1 -1
- package/dist/src/harness/tool-loop.js +2 -2
- package/dist/src/harness/turn-tag-state.d.ts +16 -0
- package/dist/src/harness/turn-tag-state.js +1 -1
- package/dist/src/harness/types.d.ts +7 -2
- package/dist/src/internal/application/package.js +1 -1
- package/dist/src/packages/eve-catalog/src/index.js +1 -1
- package/dist/src/public/channels/eve.js +1 -1
- package/dist/src/runtime/actions/types.d.ts +11 -2
- package/dist/src/runtime/actions/types.js +1 -1
- package/dist/src/runtime/agent/bootstrap.js +1 -1
- package/dist/src/runtime/framework-tools/agent.d.ts +16 -0
- package/dist/src/runtime/framework-tools/agent.js +1 -1
- package/dist/src/runtime/prompt/compose.d.ts +7 -0
- package/dist/src/runtime/prompt/compose.js +1 -1
- package/dist/src/runtime/resolve-agent-graph.js +1 -1
- package/dist/src/runtime/session-callback-route.js +1 -1
- package/dist/src/runtime/sessions/compiled-agent-cache.js +1 -1
- package/dist/src/runtime/subagents/registry.d.ts +20 -1
- package/dist/src/runtime/subagents/registry.js +1 -1
- package/dist/src/setup/integrations/github/connect.d.ts +28 -0
- package/dist/src/setup/integrations/github/connect.js +1 -0
- package/dist/src/setup/integrations/github/setup.d.ts +15 -0
- package/dist/src/setup/integrations/github/setup.js +15 -0
- package/dist/src/setup/integrations/registry.js +1 -1
- package/dist/src/setup/scaffold/create/project.js +1 -1
- package/dist/src/tracing/local-trace-reader.d.ts +10 -0
- package/dist/src/tracing/local-trace-reader.js +1 -1
- package/docs/channels/github.mdx +11 -16
- package/docs/concepts/security-model.md +1 -0
- package/docs/guides/state.md +1 -0
- package/docs/reference/cli.md +4 -0
- package/docs/schedules.mdx +1 -0
- package/docs/subagents.mdx +28 -1
- package/docs/tools/human-in-the-loop.md +1 -0
- package/package.json +1 -1
|
@@ -7,15 +7,25 @@
|
|
|
7
7
|
* span. Parsing is defensive end to end — malformed or oversized segments
|
|
8
8
|
* are skipped so a partial write never breaks a view.
|
|
9
9
|
*/
|
|
10
|
+
export interface LocalTraceSpanEvent {
|
|
11
|
+
readonly attributes: Readonly<Record<string, unknown>>;
|
|
12
|
+
readonly name: string;
|
|
13
|
+
readonly timeNs: bigint;
|
|
14
|
+
}
|
|
10
15
|
export interface LocalTraceSpan {
|
|
11
16
|
readonly attributes: Readonly<Record<string, unknown>>;
|
|
12
17
|
readonly endTimeNs: bigint;
|
|
18
|
+
readonly events: readonly LocalTraceSpanEvent[];
|
|
19
|
+
/** OTLP span kind (1 internal … 5 consumer); undefined when absent. */
|
|
20
|
+
readonly kind?: number;
|
|
13
21
|
readonly name: string;
|
|
14
22
|
readonly parentSpanId?: string;
|
|
15
23
|
readonly scope?: string;
|
|
16
24
|
readonly spanId: string;
|
|
17
25
|
readonly startTimeNs: bigint;
|
|
18
26
|
readonly statusCode: number;
|
|
27
|
+
/** Message carried by an ERROR status, when the span recorded one. */
|
|
28
|
+
readonly statusMessage?: string;
|
|
19
29
|
readonly traceId: string;
|
|
20
30
|
}
|
|
21
31
|
export interface LocalTrace {
|
|
@@ -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 n;try{n=await readdir(resolveLocalTraceSchemaDirectory(e),{withFileTypes:!0})}catch(e){if(isMissing(e))return[];throw e}return n.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,n){let r;try{r=await readdir(resolveLocalTraceSegmentsDirectory(e,n),{withFileTypes:!0})}catch(e){if(isMissing(e))return;throw e}return r.filter(e=>e.isFile()&&SPAN_FILE_PATTERN.test(e.name)).map(e=>e.name).sort((e,t)=>e.localeCompare(t))}async function readLocalTraceSegment(t,i,o){let s=join(resolveLocalTraceSegmentsDirectory(t,i),o),c;try{if((await stat(s)).size>8388608)return[];c=await readFile(s,`utf8`)}catch{return[]}return parseLocalTraceSegment(c,i)}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,`agent.session.id`);return{agentName:firstAttribute(r,`agent.name`),endTimeNs:n.reduce((e,t)=>t.endTimeNs>e?t.endTimeNs:e,0n),sessionId:i[0],sessionIds:i,spans:n,startTimeNs:n.reduce((e,t)=>t.startTimeNs<e?t.startTimeNs:e,n[0].startTimeNs),traceId:e,window:firstNumberAttribute(r,`agent.session.window`)}}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 e.name===`agent.turn`&&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 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,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),traceId:t}}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 firstAttribute(e,t){for(let n of e){let e=n[t];if(typeof e==`string`&&e.length>0)return e}}function firstNumberAttribute(e,t){for(let n of e){let e=n[t];if(typeof e==`number`)return e;if(typeof e==`bigint`)return Number(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,listLocalTraceIds,listLocalTraceSegments,listLocalTraces,parseLocalTraceSegment,readLocalTraceActivityMs,readLocalTraceSegment};
|
|
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 n;try{n=await readdir(resolveLocalTraceSchemaDirectory(e),{withFileTypes:!0})}catch(e){if(isMissing(e))return[];throw e}return n.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,n){let r;try{r=await readdir(resolveLocalTraceSegmentsDirectory(e,n),{withFileTypes:!0})}catch(e){if(isMissing(e))return;throw e}return r.filter(e=>e.isFile()&&SPAN_FILE_PATTERN.test(e.name)).map(e=>e.name).sort((e,t)=>e.localeCompare(t))}async function readLocalTraceSegment(t,i,o){let s=join(resolveLocalTraceSegmentsDirectory(t,i),o),c;try{if((await stat(s)).size>8388608)return[];c=await readFile(s,`utf8`)}catch{return[]}return parseLocalTraceSegment(c,i)}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,`agent.session.id`);return{agentName:firstAttribute(r,`agent.name`),endTimeNs:n.reduce((e,t)=>t.endTimeNs>e?t.endTimeNs:e,0n),sessionId:i[0],sessionIds:i,spans:n,startTimeNs:n.reduce((e,t)=>t.startTimeNs<e?t.startTimeNs:e,n[0].startTimeNs),traceId:e,window:firstNumberAttribute(r,`agent.session.window`)}}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 e.name===`agent.turn`&&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 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 firstNumberAttribute(e,t){for(let n of e){let e=n[t];if(typeof e==`number`)return e;if(typeof e==`bigint`)return Number(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,listLocalTraceIds,listLocalTraceSegments,listLocalTraces,parseLocalTraceSegment,readLocalTraceActivityMs,readLocalTraceSegment};
|
package/docs/channels/github.mdx
CHANGED
|
@@ -1,29 +1,24 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: "GitHub"
|
|
3
|
-
description: "Reach your agent from GitHub App webhooks, with
|
|
3
|
+
description: "Reach your agent from GitHub App webhooks, with comment invocation, PR diff context, sandbox checkout, and Vercel Connect credentials."
|
|
4
4
|
type: integration
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
The GitHub channel lets the agent work directly on a repository.
|
|
7
|
+
The GitHub channel lets the agent work directly on a repository. Add its invocation token, such as `@my-agent`, to a new issue, PR, or review comment and the agent answers in that thread, with the PR diff already in context and the repo checked out into the sandbox. The token is an eve convention: GitHub may not autocomplete it or render it as a linked mention. The channel takes GitHub App webhooks at `/eve/v1/github`, checks the signature, derives auth from whoever triggered the event, and replies on the native surface. Credentials can run through [Vercel Connect](../guides/auth-and-route-protection), which manages the GitHub App, the installation token, and inbound webhook verification, so there's no app private key or webhook secret for you to hold. See [Channels](./overview) for the contract this builds on.
|
|
8
8
|
|
|
9
|
-
##
|
|
9
|
+
## Guided Connect setup
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
Run the registry setup from the agent directory:
|
|
12
12
|
|
|
13
13
|
```bash
|
|
14
|
-
|
|
15
|
-
vercel connect create github --triggers
|
|
16
|
-
vercel connect detach <uid> --yes
|
|
17
|
-
vercel connect attach <uid> --triggers --trigger-path /eve/v1/github --yes
|
|
14
|
+
eve add channel/github
|
|
18
15
|
```
|
|
19
16
|
|
|
20
|
-
The
|
|
17
|
+
The flow checks that the Vercel CLI is authenticated, creates or links a Vercel project when needed, provisions an app-scoped GitHub Connect client, and replaces its default trigger with `/eve/v1/github`. It then installs `@vercel/connect` and writes `agent/channels/github.ts` with the connector UID.
|
|
21
18
|
|
|
22
|
-
|
|
19
|
+
Vercel Connect creates the GitHub App, receives and verifies its webhooks, and forwards them to the deployed agent. After deploying, open the GitHub App in the Connect dashboard and install it in the organization or account where you want to use it. Add the generated invocation token (for example, `@my-agent`) to a new issue, pull request, or review comment to start a conversation. GitHub may not autocomplete the token or render it as a linked mention.
|
|
23
20
|
|
|
24
|
-
|
|
25
|
-
npm install @vercel/connect
|
|
26
|
-
```
|
|
21
|
+
The generated channel uses Connect-managed credentials:
|
|
27
22
|
|
|
28
23
|
```ts title="agent/channels/github.ts"
|
|
29
24
|
import { connectGitHubCredentials } from "@vercel/connect/eve";
|
|
@@ -65,7 +60,7 @@ GITHUB_APP_SLUG=... # supplies botName when it is not set in config
|
|
|
65
60
|
|
|
66
61
|
`appId`/`privateKey`/`webhookSecret` also take a lazy resolver function if you'd rather fetch them on demand.
|
|
67
62
|
|
|
68
|
-
Point the GitHub App webhook URL at `https://<deployment>/eve/v1/github`. For
|
|
63
|
+
Point the GitHub App webhook URL at `https://<deployment>/eve/v1/github`. For comment-invoked turns, subscribe to `issue_comment` and `pull_request_review_comment`; add `issues`, `pull_request`, `check_suite`, `check_run`, or `workflow_run` if you wire up their opt-in hooks. After installing the App for the repository, a new comment that includes `@botName` starts a turn. This is a text invocation token, not a GitHub-native mention: GitHub may display the App as `botName[bot]`, but it may not autocomplete or link `@botName`.
|
|
69
64
|
|
|
70
65
|
## How the channel handles messages
|
|
71
66
|
|
|
@@ -78,7 +73,7 @@ import { defaultGitHubAuth, githubChannel } from "eve/channels/github";
|
|
|
78
73
|
|
|
79
74
|
export default githubChannel({
|
|
80
75
|
botName: "my-agent",
|
|
81
|
-
// Replaces the
|
|
76
|
+
// Replaces the default invocation-token gate. ctx.conversation.kind is "issue", "pull_request", or "review_thread".
|
|
82
77
|
onComment: (ctx, comment) => ({ auth: defaultGitHubAuth(ctx) }),
|
|
83
78
|
// Opt in; no default dispatch on these events.
|
|
84
79
|
onIssue: (ctx, issue) => (issue.action === "opened" ? { auth: defaultGitHubAuth(ctx) } : null),
|
|
@@ -108,7 +103,7 @@ GitHub comments have no interactive button or card affordance. A human-in-the-lo
|
|
|
108
103
|
|
|
109
104
|
### Proactive sessions
|
|
110
105
|
|
|
111
|
-
Start a session without an inbound
|
|
106
|
+
Start a session without an inbound comment invocation through `receive(github, { message, target, auth })` from a schedule `run` handler, or `args.receive(github, ...)` from another channel. The target requires `owner`, `repo`, and exactly one of `issueNumber` or `pullRequestNumber`.
|
|
112
107
|
|
|
113
108
|
### Attachments
|
|
114
109
|
|
|
@@ -103,3 +103,4 @@ Before exposing an agent to real traffic:
|
|
|
103
103
|
- [Sandbox](../sandbox): backends, network policy, and brokering config
|
|
104
104
|
- [Execution model and durability](./execution-model-and-durability): how durable sessions run
|
|
105
105
|
- [Connections](../connections): static-token and OAuth connections
|
|
106
|
+
- [Responsible use](../responsible-use): deployer responsibilities and safeguards to review before production
|
package/docs/guides/state.md
CHANGED
|
@@ -76,3 +76,4 @@ Every [subagent](../subagents) starts with its own fresh state, whether it's a b
|
|
|
76
76
|
- Read state inside dynamic resolvers → [Dynamic capabilities](./dynamic-capabilities)
|
|
77
77
|
- How step durability works → [Execution model & durability](../concepts/execution-model-and-durability)
|
|
78
78
|
- The `ctx` accessors available alongside state → [TypeScript API](../reference/typescript-api)
|
|
79
|
+
- Tenant-scoped long-term memory in your own store → [Multi-tenant memory](../patterns/multi-tenant-memory)
|
package/docs/reference/cli.md
CHANGED
|
@@ -254,10 +254,14 @@ eve traces ls # list traces, most recent first
|
|
|
254
254
|
eve traces ls --json # emit machine-readable trace summaries
|
|
255
255
|
eve traces # show the most recent span tree
|
|
256
256
|
eve traces <trace> # show one span tree
|
|
257
|
+
eve traces --verbose # expand every span with all attributes and events
|
|
258
|
+
eve traces --json # dump the full trace as JSON
|
|
257
259
|
```
|
|
258
260
|
|
|
259
261
|
Reads the immutable OTLP/JSON segments under `.eve/traces/v1`, so `eve dev` need not be running. Accepts a full trace id, an `agent.session.id`, or an unambiguous prefix of either. Malformed segments are skipped without hiding valid spans from the same trace.
|
|
260
262
|
|
|
263
|
+
Span rows carry inline metrics when the span recorded them — `↑input`/`↓output` token counts, gateway cost, and the tool name for `ai.toolCall` spans — and the header aggregates models, token totals, cost, and error count across the trace's step spans. `--verbose` expands each span under its tree row: status (with the error message on failures), timing, ids, every attribute (prompts, responses, and tool payloads as transcripts or pretty-printed JSON), and every span event with its offset from span start. `--json` prints the same records as JSON, one object per selected trace.
|
|
264
|
+
|
|
261
265
|
A subagent keeps its own session id but records into the trace its parent had open at dispatch, so delegated work appears under the session that caused it, tagged with `agent.root.session.id`. Either session id resolves to that trace. A remote agent traces under its own deployment and is not recorded here.
|
|
262
266
|
|
|
263
267
|
A session long enough to outgrow one trace — far longer than anything you will drive locally — continues into a new one. Each is a session window, numbered from zero on `agent.session.window`; passing a session id shows every window it produced, oldest first, and a trace id shows just that window.
|
package/docs/schedules.mdx
CHANGED
|
@@ -116,3 +116,4 @@ The gotcha is custom hosting. If you adapt the generated output to a process man
|
|
|
116
116
|
|
|
117
117
|
- [Channels](./channels/overview): deliver schedule output to users.
|
|
118
118
|
- [Sessions, runs & streaming](./concepts/sessions-runs-and-streaming): inspect a schedule run.
|
|
119
|
+
- [Dynamic scheduling](./patterns/dynamic-scheduling): manage schedule rows in your own store behind one dispatcher schedule.
|
package/docs/subagents.mdx
CHANGED
|
@@ -12,10 +12,13 @@ The root session receives `agent` by default. The model calls it to delegate a t
|
|
|
12
12
|
```ts
|
|
13
13
|
{
|
|
14
14
|
message: string; // everything the child needs; it does not see the parent's history
|
|
15
|
+
agentId?: string; // only with experimental.subagentPersistentSessions: continue an existing child
|
|
15
16
|
outputSchema?: object; // when set, the child runs in task mode and returns structured output
|
|
16
17
|
}
|
|
17
18
|
```
|
|
18
19
|
|
|
20
|
+
The `agentId` field exists only when the agent opts into [agent messaging](#agent-messaging); without the opt-in the schema is `{ message, outputSchema? }`.
|
|
21
|
+
|
|
19
22
|
The copy uses the root's instructions, connections, auth, and sandbox. It receives the same tools except for the root-only `agent` and `Workflow`, and starts with fresh conversation history and fresh state. Its file writes are immediately visible to the root. To run independent tasks in parallel, emit multiple `agent` calls in one response; eve runs the batch concurrently and returns every result before the root continues. Give parallel children non-overlapping write scopes.
|
|
20
23
|
|
|
21
24
|
`agent` is intentionally root-only. Copies created by it cannot call `agent`, and declared subagents never receive the built-in tool. If a stale or forced recursive call reaches execution, eve rejects it instead of starting another child session.
|
|
@@ -144,7 +147,7 @@ The root built-in `agent` tool is the exception. Its children share the root's s
|
|
|
144
147
|
|
|
145
148
|
## What the parent sees
|
|
146
149
|
|
|
147
|
-
eve lowers every subagent visible to the current agent (the root built-in copy, declared, or [remote](./guides/remote-agents)) into a model-visible tool with the same `{ message, outputSchema? }` shape. The parent packs `message` with everything the child needs, since the child never sees the parent's history. Set `outputSchema` to run the child in task mode, returning structured output as the tool result.
|
|
150
|
+
eve lowers every subagent visible to the current agent (the root built-in copy, declared, or [remote](./guides/remote-agents)) into a model-visible tool with the same `{ message, outputSchema? }` shape — plus `agentId` when the agent opts into [agent messaging](#agent-messaging). The parent packs `message` with everything the child needs, since the child never sees the parent's history. Set `outputSchema` to run the child in task mode, returning structured output as the tool result; this works the same with or without agent messaging.
|
|
148
151
|
|
|
149
152
|
Declared subagents can call nested subagents defined under their own directories. eve does not apply a separate depth limit; nesting ends where the authored directory tree ends. The built-in `agent` follows the stricter root-only rule above, so `limits.maxSubagentDepth` no longer exists.
|
|
150
153
|
|
|
@@ -155,6 +158,7 @@ A declared subagent's tool name is the bare path-derived name, with no prefix. `
|
|
|
155
158
|
```ts
|
|
156
159
|
{
|
|
157
160
|
message: string; // all context the child needs; it never sees the parent's history
|
|
161
|
+
agentId?: string; // only with experimental.subagentPersistentSessions: continue an existing child
|
|
158
162
|
outputSchema?: object; // when set, the child runs in task mode and returns structured output
|
|
159
163
|
}
|
|
160
164
|
```
|
|
@@ -169,6 +173,29 @@ Cancelling a parent turn also requests cancellation of every active child it sta
|
|
|
169
173
|
|
|
170
174
|
Subagent model calls automatically retry classified transient provider failures, including overload errors delivered after a stream starts. eve makes at most three fresh model-call attempts, repeating only the current uncommitted call so completed earlier steps, tool results, and sandbox work remain available to the child. Other recoverable task errors fall back to Workflow's durable step retry from the last committed session snapshot. Exhausting the transient model-call attempts or the dedicated empty-response reissue returns one failed task result instead of stacking both retry budgets; terminal errors fail immediately.
|
|
171
175
|
|
|
176
|
+
## Agent messaging
|
|
177
|
+
|
|
178
|
+
Agent messaging is experimental and off by default. Opt in per agent in `agent.ts`:
|
|
179
|
+
|
|
180
|
+
```ts title="agent/agent.ts"
|
|
181
|
+
import { defineAgent } from "eve";
|
|
182
|
+
|
|
183
|
+
export default defineAgent({
|
|
184
|
+
experimental: {
|
|
185
|
+
subagentPersistentSessions: true,
|
|
186
|
+
},
|
|
187
|
+
model: "anthropic/claude-sonnet-4.5",
|
|
188
|
+
});
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
Without the opt-in, delegated children run as one-shot tasks: they answer once and terminate, and the subagent tool schema carries no `agentId` field.
|
|
192
|
+
|
|
193
|
+
With it enabled, a child parks after answering instead of terminating, keeping its session and conversation history alive. A failed child turn can also leave the child parked — its latest status shows the error and the parent may message it again. Pass a parked child's `agentId` to the same subagent tool with a new `message` to continue that session. Omitting `agentId` (or passing an empty string or `null`) always starts a new child, and an `agentId` that matches no known agent falls back to starting a new child rather than failing. Passing a known `agentId` through a different subagent tool fails with `AGENT_MISMATCH`, and messaging a child that is still starting or working on its previous request fails with `AGENT_BUSY` — wait for its result before continuing it.
|
|
194
|
+
|
|
195
|
+
On every model call, eve injects a system message containing an `<agents>` block listing the currently parked (resumable) children — each entry carries the `agentId`, name, and latest status. It is a per-call injection, not part of the conversation history: it always reflects the current state, never accumulates stale copies, and children that are starting or running do not appear until they park again.
|
|
196
|
+
|
|
197
|
+
The parent holds agent handles only for its session lifetime. When the parent session ends, eve terminates its local children. Remote children are not terminated on parent shutdown — that is a known gap: a parked remote child stays alive on its own deployment until that deployment's own lifecycle ends it. For [remote agents](./guides/remote-agents), both deployments must run the same eve version to use agent messaging.
|
|
198
|
+
|
|
172
199
|
## When to split
|
|
173
200
|
|
|
174
201
|
Split out a subagent when the task needs a different prompt or specialist role, a narrower tool surface, or its own runtime context. Don't reach for one when a [skill](./skills) would do. If the agent can keep its identity and needs only an optional procedure, a skill is the lighter choice.
|
|
@@ -125,3 +125,4 @@ From your own frontend, read the pending request off the latest message and answ
|
|
|
125
125
|
- [Default harness](/docs/concepts/default-harness): the built-in tools, including `ask_question`
|
|
126
126
|
- [Sessions, runs & streaming](/docs/concepts/sessions-runs-and-streaming): the event and resume contract behind the pause
|
|
127
127
|
- [Building a frontend](/docs/guides/frontend/overview): render and answer requests from your own UI
|
|
128
|
+
- [Multi-tenant approvals](/docs/patterns/multi-tenant-approvals): resolve per-tenant approval policy for authored and connection tools
|