eve 0.30.6 → 0.30.8
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 +16 -0
- package/dist/src/chunks/{use-eve-agent-BXMIf5fR.js → use-eve-agent-Bx-ONuyb.js} +22 -0
- package/dist/src/chunks/{use-eve-agent-k-XHfrJT.js → use-eve-agent-DDoDDmJ2.js} +22 -0
- package/dist/src/cli/commands/registry-metadata.d.ts +15 -0
- package/dist/src/cli/commands/registry-metadata.js +1 -0
- package/dist/src/cli/commands/registry-package.d.ts +46 -0
- package/dist/src/cli/commands/registry-package.js +1 -0
- package/dist/src/cli/commands/registry.d.ts +1 -1
- package/dist/src/cli/commands/registry.js +4 -4
- 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/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/client/index.d.ts +1 -1
- package/dist/src/client/message-reducer-types.d.ts +3 -0
- package/dist/src/client/message-reducer.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/tool-auth.d.ts +1 -1
- package/dist/src/execution/tool-auth.js +1 -1
- 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/emission-state.d.ts +25 -0
- package/dist/src/harness/emission-state.js +1 -0
- package/dist/src/harness/emission.d.ts +4 -36
- package/dist/src/harness/emission.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/ordered-stream-emitter.d.ts +3 -2
- package/dist/src/harness/ordered-stream-emitter.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/tools.d.ts +1 -1
- package/dist/src/harness/tools.js +1 -1
- 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/protocol/message.d.ts +23 -3
- package/dist/src/protocol/message.js +2 -2
- package/dist/src/public/channels/discord/discordChannel.d.ts +1 -0
- package/dist/src/public/channels/eve.js +1 -1
- package/dist/src/public/channels/github/githubChannel.d.ts +1 -0
- package/dist/src/public/channels/linear/linearChannel.d.ts +1 -0
- package/dist/src/public/channels/slack/slackChannel.d.ts +1 -0
- package/dist/src/public/channels/teams/teamsChannel.d.ts +1 -0
- package/dist/src/public/channels/telegram/telegramChannel.d.ts +1 -0
- package/dist/src/public/channels/twilio/twilioChannel.d.ts +1 -0
- package/dist/src/public/definitions/channel.d.ts +1 -0
- package/dist/src/public/definitions/channel.js +1 -1
- package/dist/src/public/definitions/hook.d.ts +1 -0
- package/dist/src/public/definitions/tool.d.ts +5 -5
- 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/linear/setup.js +1 -1
- package/dist/src/setup/integrations/registry.js +1 -1
- package/dist/src/setup/scaffold/create/project.js +1 -1
- package/dist/src/shared/async-iterable.d.ts +2 -0
- package/dist/src/shared/async-iterable.js +1 -0
- package/dist/src/shared/tool-definition.d.ts +1 -1
- package/dist/src/svelte/index.js +1 -1
- package/dist/src/svelte/use-eve-agent.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/dist/src/vue/index.js +1 -1
- package/dist/src/vue/use-eve-agent.js +1 -1
- package/docs/channels/github.mdx +11 -16
- package/docs/channels/linear.mdx +4 -2
- package/docs/concepts/security-model.md +1 -0
- package/docs/concepts/sessions-runs-and-streaming.md +3 -0
- package/docs/guides/client/streaming.mdx +1 -0
- package/docs/guides/hooks.md +1 -1
- package/docs/guides/state.md +1 -0
- package/docs/install-integrations.mdx +4 -2
- package/docs/reference/cli.md +8 -1
- package/docs/schedules.mdx +1 -0
- package/docs/subagents.mdx +28 -1
- package/docs/tools/human-in-the-loop.md +1 -0
- package/docs/tools/overview.mdx +26 -2
- package/package.json +1 -1
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { type ChannelSetupLog } from "#setup/cli/index.js";
|
|
2
|
+
import type { VercelProjectReference } from "#setup/project-resolution.js";
|
|
3
|
+
import { runVercel, runVercelCaptureStdout } from "#setup/primitives/run-vercel.js";
|
|
4
|
+
export declare const GITHUB_TRIGGER_PATH = "/eve/v1/github";
|
|
5
|
+
/** Identity of the GitHub connector provisioned for an agent channel. */
|
|
6
|
+
export interface GitHubConnectorRef {
|
|
7
|
+
/** GitHub's actual @mention handle, without the `[bot]` suffix. */
|
|
8
|
+
appSlug: string;
|
|
9
|
+
id: string;
|
|
10
|
+
uid: string;
|
|
11
|
+
}
|
|
12
|
+
/** Effects used to provision a GitHub Connect connector. */
|
|
13
|
+
export interface ProvisionGitHubConnectorDeps {
|
|
14
|
+
runVercel: typeof runVercel;
|
|
15
|
+
runVercelCaptureStdout: typeof runVercelCaptureStdout;
|
|
16
|
+
}
|
|
17
|
+
/** Parses `vercel connect create -F json` output for an app-scoped GitHub connector. */
|
|
18
|
+
export declare function parseCreatedGitHubConnector(stdout: string): Omit<GitHubConnectorRef, "appSlug"> | undefined;
|
|
19
|
+
/** Creates a GitHub connector and routes its verified webhooks to eve. */
|
|
20
|
+
export declare function provisionGitHubConnector(input: {
|
|
21
|
+
events: readonly string[];
|
|
22
|
+
log: ChannelSetupLog;
|
|
23
|
+
project: VercelProjectReference;
|
|
24
|
+
projectRoot: string;
|
|
25
|
+
slug: string;
|
|
26
|
+
signal?: AbortSignal;
|
|
27
|
+
deps?: ProvisionGitHubConnectorDeps;
|
|
28
|
+
}): Promise<GitHubConnectorRef>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{array,literal,object,string}from"../../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/classic/schemas.js";import"../../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/index.js";import{runVercel,runVercelCaptureStdout}from"#setup/primitives/run-vercel.js";import{createPromptCommandOutput,withPhase}from"#setup/cli/index.js";import{replaceConnectTrigger}from"#setup/connect-provisioning.js";const GITHUB_TRIGGER_PATH=`/eve/v1/github`,GitHubConnectorRefSchema=object({id:string().min(1),uid:string().min(1),supportedSubjectTypes:array(string()).refine(e=>e.includes(`app`))}),GitHubConnectorDetailsSchema=object({data:object({appSlug:string().min(1)}),id:string().min(1),type:literal(`github`),uid:string().min(1)});function parseCreatedGitHubConnector(e){try{let t=GitHubConnectorRefSchema.safeParse(JSON.parse(e));return t.success?{id:t.data.id,uid:t.data.uid}:void 0}catch{return}}function parseGitHubConnectorDetails(e,t){try{let n=GitHubConnectorDetailsSchema.safeParse(JSON.parse(e));return!n.success||n.data.id!==t.id||n.data.uid!==t.uid?void 0:{...t,appSlug:n.data.data.appSlug}}catch{return}}async function provisionGitHubConnector(e){let t=e.deps??{runVercel,runVercelCaptureStdout},n=createPromptCommandOutput(e.log),r=await withPhase(e.log,`Creating GitHub connector...`,()=>t.runVercelCaptureStdout([`connect`,`create`,`github`,`--name`,e.slug,`--triggers`,...e.events.flatMap(e=>[`--trigger-event`,e]),`-F`,`json`,`--scope`,e.project.orgId],{cwd:e.projectRoot,nonInteractive:!0,onOutput:n,signal:e.signal}));if(e.signal?.throwIfAborted(),!r.ok){let e=[r.stderr,r.stdout].find(e=>e!==void 0&&e.trim().length>0);throw Error(e?`GitHub connector creation failed:\n${e}`:`GitHub connector creation failed.`)}let i=parseCreatedGitHubConnector(r.stdout);if(i===void 0)throw Error(`Vercel returned an invalid GitHub connector.`);let a=await withPhase(e.log,`Reading GitHub App details...`,()=>t.runVercelCaptureStdout([`api`,`/v1/connect/connectors/${encodeURIComponent(i.id)}`,`--scope`,e.project.orgId,`--raw`],{cwd:e.projectRoot,nonInteractive:!0,onOutput:n,signal:e.signal}));if(e.signal?.throwIfAborted(),!a.ok)throw Error(`Could not read the created GitHub connector.`);let o=parseGitHubConnectorDetails(a.stdout,i);if(o===void 0)throw Error(`Vercel returned invalid details for the GitHub connector.`);let s=await withPhase(e.log,`Connecting GitHub webhooks...`,()=>replaceConnectTrigger({connectorUid:o.uid,projectRoot:e.projectRoot,projectId:e.project.projectId,orgId:e.project.orgId,environment:`production`,triggerPath:GITHUB_TRIGGER_PATH,onOutput:n,signal:e.signal,deps:t}));if(e.signal?.throwIfAborted(),s.state!==`attached`)throw Error(`GitHub connector was created, but its trigger could not be attached. Run \`vercel connect attach ${o.uid} --project ${e.project.projectId} --environment production --triggers --trigger-path ${GITHUB_TRIGGER_PATH} --yes --scope ${e.project.orgId}\`.`);return o}export{GITHUB_TRIGGER_PATH,parseCreatedGitHubConnector,provisionGitHubConnector};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { ensureVercelProject } from "#setup/flows/ensure-vercel-project.js";
|
|
2
|
+
import { deriveSlackConnectorSlug } from "#setup/scaffold/index.js";
|
|
3
|
+
import { writeTextFile } from "#setup/scaffold/files.js";
|
|
4
|
+
import type { IntegrationSetupContext, IntegrationSetupResult, SetupIntegration } from "../types.js";
|
|
5
|
+
import { provisionGitHubConnector } from "./connect.js";
|
|
6
|
+
export interface GitHubSetupDeps {
|
|
7
|
+
deriveConnectorSlug: typeof deriveSlackConnectorSlug;
|
|
8
|
+
ensureVercelProject: typeof ensureVercelProject;
|
|
9
|
+
provisionConnector: typeof provisionGitHubConnector;
|
|
10
|
+
writeTextFile: typeof writeTextFile;
|
|
11
|
+
}
|
|
12
|
+
/** Runs guided GitHub App connector and channel setup. */
|
|
13
|
+
export declare function setupGitHub(context: IntegrationSetupContext, deps?: GitHubSetupDeps): Promise<IntegrationSetupResult>;
|
|
14
|
+
/** GitHub App setup registration. */
|
|
15
|
+
export declare const GITHUB_SETUP: SetupIntegration;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import{provisionGitHubConnector}from"./connect.js";import{join}from"node:path";import{deriveSlackConnectorSlug}from"#setup/scaffold/index.js";import{WizardCancelledError}from"#setup/step.js";import{ensureVercelProject}from"#setup/flows/ensure-vercel-project.js";import{writeTextFile}from"#setup/scaffold/files.js";const defaultDeps={deriveConnectorSlug:deriveSlackConnectorSlug,ensureVercelProject,provisionConnector:provisionGitHubConnector,writeTextFile},githubEventsQuestion={key:`github-events`,message:`What should this GitHub App respond to?`,options:[{id:`issue_comment`,label:`New issue and PR comments`,value:`issue_comment`,hint:"Reply when a new timeline comment includes `@<bot-name>`."},{id:`pull_request_review_comment`,label:`New inline PR review comments`,value:`pull_request_review_comment`,hint:"Reply when a new inline review comment includes `@<bot-name>`."},{id:`issues`,label:`New issues`,value:`issues`,hint:`Add comments to new issues.`},{id:`pull_request`,label:`New PRs`,value:`pull_request`,hint:`Add comments to new pull requests.`}],recommended:[`issue_comment`,`pull_request_review_comment`],requireSelection:!0};function connectTemplate(e,t,n){let r=[n.includes(`issues`)?` onIssue(ctx, issue) {
|
|
2
|
+
if (issue.action !== "opened") return null;
|
|
3
|
+
return { auth: defaultGitHubAuth(ctx) };
|
|
4
|
+
},`:void 0,n.includes(`pull_request`)?` onPullRequest(ctx, pullRequest) {
|
|
5
|
+
if (pullRequest.action !== "opened") return null;
|
|
6
|
+
return { auth: defaultGitHubAuth(ctx) };
|
|
7
|
+
},`:void 0].filter(e=>e!==void 0),i=r.length>0?`, defaultGitHubAuth`:``,a=r.length>0?`\n${r.join(`
|
|
8
|
+
`)}`:``;return`import { connectGitHubCredentials } from "@vercel/connect/eve";
|
|
9
|
+
import { githubChannel${i} } from "eve/channels/github";
|
|
10
|
+
|
|
11
|
+
export default githubChannel({
|
|
12
|
+
botName: ${JSON.stringify(t)},
|
|
13
|
+
credentials: connectGitHubCredentials(${JSON.stringify(e)}),${a}
|
|
14
|
+
});
|
|
15
|
+
`}async function setupGitHub(e,n=defaultDeps){if(e.environment.vercel.kind===`unavailable`)throw Error("GitHub setup requires an authenticated Vercel CLI. Run `vercel login`, then retry.");try{e.ui.prompter.log.info(`GitHub App`),e.ui.prompter.log.info(`Vercel Connect creates a GitHub App and routes verified webhooks to your deployed agent.`);let r=await e.ui.asker.askMany(githubEventsQuestion),i=await n.ensureVercelProject({appRoot:e.appRoot,prompter:e.ui.prompter,signal:e.signal}),a=await n.provisionConnector({log:e.ui.prompter.log,events:r,project:i,projectRoot:e.appRoot,slug:await n.deriveConnectorSlug(e.appRoot),signal:e.signal});return await n.writeTextFile(join(e.appRoot,`agent/channels/github.ts`),connectTemplate(a.uid,a.appSlug,r),{force:e.force}),e.ui.nextSteps([`Deploy the agent, then open the GitHub App in Vercel Connect and install it in the organization or account where you want to use it.`,`Add @${a.appSlug} to a new issue, pull request, or review comment to invoke the agent. GitHub may not autocomplete or render the token as a linked mention.`]),{kind:`done`,facts:[{label:`Vercel Connect`,value:`https://vercel.com/d?to=/%5Bteam%5D/~/connect&title=Open+Vercel+Connect`,kind:`url`}]}}catch(e){if(e instanceof WizardCancelledError)return{kind:`cancelled`};throw e}}const GITHUB_SETUP={kind:`github`,label:`GitHub`,hint:`Respond to issues, pull requests, and comments`,setup:setupGitHub};export{GITHUB_SETUP,setupGitHub};
|
|
@@ -4,4 +4,4 @@ import { linearChannel } from "eve/channels/linear";
|
|
|
4
4
|
export default linearChannel({
|
|
5
5
|
credentials: connectLinearCredentials(${JSON.stringify(e)}),
|
|
6
6
|
});
|
|
7
|
-
`}async function chooseConnector(e,t,n){let r=linearSafeConnectorSlug(await t.deriveConnectorSlug(e.appRoot)),i=linearSafeConnectorSlug(await e.ui.asker.ask(text({key:`linear.connector-name`,message:`Name your Linear agent`,recommended:r,validate:e=>e.trim().length===0?`A Linear agent name is required.`:null}))),a=await t.findConnector({project:n,projectRoot:e.appRoot,slug:i,signal:e.signal});if(a!==void 0){let r=await e.ui.asker.ask(select({key:`linear.existing-connector`,message:`A Linear connector named "${i}" already exists. What would you like to do?`,options:[{id:`reuse`,label:`Reuse existing connector`,value:`reuse`},{id:`new`,label:`Create a new connector`,value:`new`},{id:`exit`,label:`Exit setup`,value:`exit`}],recommended:`reuse`}));if(r===`exit`)return;if(r===`reuse`)return await t.attachConnector({connector:a,log:e.ui.prompter.log,project:n,projectRoot:e.appRoot,signal:e.signal}),a}let o=a===void 0?i:linearSafeConnectorSlug(await e.ui.asker.ask(text({key:`linear.new-connector-name`,message:`Name the new Linear agent`,recommended:`${i}-2`,validate:e=>e.trim().length===0?`A Linear agent name is required.`:null})));return t.provisionConnector({log:e.ui.prompter.log,project:n,projectRoot:e.appRoot,slug:o,signal:e.signal})}async function setupLinear(e,t=defaultDeps){if(e.environment.vercel.kind===`unavailable`)throw Error("Linear setup requires an authenticated Vercel CLI. Run `vercel login`, then retry.");try{let n=await chooseConnector(e,t,await t.ensureVercelProject({appRoot:e.appRoot,prompter:e.ui.prompter,signal:e.signal}));return n===void 0?{kind:`cancelled`}:(await t.writeTextFile(join(e.appRoot,`agent/channels/linear.ts`),connectTemplate(n.uid),{force:e.force}),
|
|
7
|
+
`}async function chooseConnector(e,t,n){let r=linearSafeConnectorSlug(await t.deriveConnectorSlug(e.appRoot)),i=linearSafeConnectorSlug(await e.ui.asker.ask(text({key:`linear.connector-name`,message:`Name your Linear agent`,recommended:r,validate:e=>e.trim().length===0?`A Linear agent name is required.`:null}))),a=await t.findConnector({project:n,projectRoot:e.appRoot,slug:i,signal:e.signal});if(a!==void 0){let r=await e.ui.asker.ask(select({key:`linear.existing-connector`,message:`A Linear connector named "${i}" already exists. What would you like to do?`,options:[{id:`reuse`,label:`Reuse existing connector`,value:`reuse`},{id:`new`,label:`Create a new connector`,value:`new`},{id:`exit`,label:`Exit setup`,value:`exit`}],recommended:`reuse`}));if(r===`exit`)return;if(r===`reuse`)return await t.attachConnector({connector:a,log:e.ui.prompter.log,project:n,projectRoot:e.appRoot,signal:e.signal}),a}let o=a===void 0?i:linearSafeConnectorSlug(await e.ui.asker.ask(text({key:`linear.new-connector-name`,message:`Name the new Linear agent`,recommended:`${i}-2`,validate:e=>e.trim().length===0?`A Linear agent name is required.`:null})));return t.provisionConnector({log:e.ui.prompter.log,project:n,projectRoot:e.appRoot,slug:o,signal:e.signal})}async function setupLinear(e,t=defaultDeps){if(e.environment.vercel.kind===`unavailable`)throw Error("Linear setup requires an authenticated Vercel CLI. Run `vercel login`, then retry.");try{let n=await chooseConnector(e,t,await t.ensureVercelProject({appRoot:e.appRoot,prompter:e.ui.prompter,signal:e.signal}));return n===void 0?{kind:`cancelled`}:(await t.writeTextFile(join(e.appRoot,`agent/channels/linear.ts`),connectTemplate(n.uid),{force:e.force}),{kind:`done`,facts:[{label:`Vercel Connect`,value:`https://vercel.com/d?to=/%5Bteam%5D/~/connect&title=Open+Vercel+Connect`,kind:`url`},{label:`Next step`,value:`Deploy the agent, then open the Linear app in Vercel Connect and install it in the workspace where you want to delegate issues and comments.`},{label:`In Linear`,value:`Delegate an issue or mention the agent in an Agent Session to start a conversation.`}]})}catch(e){if(e instanceof WizardCancelledError)return{kind:`cancelled`};throw e}}const LINEAR_SETUP={kind:`linear`,label:`Linear Agent`,hint:`Delegate Linear issues and comments`,setup:setupLinear};export{LINEAR_SETUP,linearSafeConnectorSlug,setupLinear};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{DISCORD_SETUP}from"./discord/setup.js";import{LINEAR_SETUP}from"./linear/setup.js";import{PHOTON_SETUP}from"./photon/setup.js";import{SLACK_SETUP}from"./slack/setup.js";import{WEB_SETUP}from"./web/setup.js";import{createIntegrationSetupUi}from"./shared/ui.js";const SETUP_INTEGRATIONS=[WEB_SETUP,SLACK_SETUP,DISCORD_SETUP,LINEAR_SETUP,PHOTON_SETUP];function setupIntegration(e){let t=SETUP_INTEGRATIONS.find(t=>t.kind===e);if(t===void 0)throw Error(`Integration setup "${e}" is not available in this version of eve. Upgrade eve and try again.`);return t}export{SETUP_INTEGRATIONS,createIntegrationSetupUi,setupIntegration};
|
|
1
|
+
import{DISCORD_SETUP}from"./discord/setup.js";import{GITHUB_SETUP}from"./github/setup.js";import{LINEAR_SETUP}from"./linear/setup.js";import{PHOTON_SETUP}from"./photon/setup.js";import{SLACK_SETUP}from"./slack/setup.js";import{WEB_SETUP}from"./web/setup.js";import{createIntegrationSetupUi}from"./shared/ui.js";const SETUP_INTEGRATIONS=[WEB_SETUP,SLACK_SETUP,DISCORD_SETUP,GITHUB_SETUP,LINEAR_SETUP,PHOTON_SETUP];function setupIntegration(e){let t=SETUP_INTEGRATIONS.find(t=>t.kind===e);if(t===void 0)throw Error(`Integration setup "${e}" is not available in this version of eve. Upgrade eve and try again.`);return t}export{SETUP_INTEGRATIONS,createIntegrationSetupUi,setupIntegration};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{pinnedNodeEngineMajor}from"../../node-engine.js";import{SUPPORTED_AUTHORED_MODULE_FILE_EXTENSIONS}from"../update/module-files.js";import{pathExists,writeTextFile}from"../files.js";import{blockingCreateInPlaceEntries}from"../create-in-place.js";import{resolveVersionToken}from"../version-tokens.js";import{applyPackageManagerWorkspaceConfiguration,isPackageManagerWorkspaceMember,patchWorkspaceRootPackageJson}from"../workspace-root.js";import{WEB_APP_TEMPLATE_FILES}from"./web-template.js";import{mkdir,readdir,stat}from"node:fs/promises";import{basename,join,resolve}from"node:path";const CURRENT_DIRECTORY_PROJECT_NAME=`.`,DEFAULT_AI_PACKAGE_VERSION=`^7.0.38`,DEFAULT_CONNECT_PACKAGE_VERSION=`0.4.3`,DEFAULT_ZOD_PACKAGE_VERSION=`4.4.3`,DEFAULT_EVE_PACKAGE_CONTRACT={version:`0.30.
|
|
1
|
+
import{pinnedNodeEngineMajor}from"../../node-engine.js";import{SUPPORTED_AUTHORED_MODULE_FILE_EXTENSIONS}from"../update/module-files.js";import{pathExists,writeTextFile}from"../files.js";import{blockingCreateInPlaceEntries}from"../create-in-place.js";import{resolveVersionToken}from"../version-tokens.js";import{applyPackageManagerWorkspaceConfiguration,isPackageManagerWorkspaceMember,patchWorkspaceRootPackageJson}from"../workspace-root.js";import{WEB_APP_TEMPLATE_FILES}from"./web-template.js";import{mkdir,readdir,stat}from"node:fs/promises";import{basename,join,resolve}from"node:path";const CURRENT_DIRECTORY_PROJECT_NAME=`.`,DEFAULT_AI_PACKAGE_VERSION=`^7.0.38`,DEFAULT_CONNECT_PACKAGE_VERSION=`0.4.3`,DEFAULT_ZOD_PACKAGE_VERSION=`4.4.3`,DEFAULT_EVE_PACKAGE_CONTRACT={version:`0.30.8`,nodeEngine:`>=24`};function resolveEvePackageContract(e=DEFAULT_EVE_PACKAGE_CONTRACT){return{version:resolveVersionToken(`evePackage.version`,e.version),nodeEngine:resolveVersionToken(`evePackage.nodeEngine`,e.nodeEngine)}}function modelProviderSlug(e){let t=(e.split(`/`)[0]??``).replaceAll(/[^A-Za-z0-9._-]/gu,``);return t.length>0?t:`anthropic`}function byokProviderEnvVar(e){let t=modelProviderSlug(e).toUpperCase().replaceAll(/[^A-Z0-9]/gu,`_`);return`${/^[0-9]/.test(t)?`_`:``}${t}_API_KEY`}function agentTemplateFiles(e){return{"agent/agent.ts":BASE_AGENT_TEMPLATE.replaceAll(`__EVE_INIT_MODEL__`,e),"agent/channels/eve.ts":WEB_APP_TEMPLATE_FILES[`agent/channels/eve.ts`],"agent/instructions.md":AGENT_INSTRUCTIONS_TEMPLATE}}function renderTemplate(e,t){return e.replaceAll(`__EVE_INIT_APP_NAME__`,t.appName).replaceAll(`__EVE_INIT_MODEL__`,t.model).replaceAll(`__EVE_INIT_BYOK_PROVIDER__`,modelProviderSlug(t.model)).replaceAll(`__EVE_INIT_BYOK_ENV_VAR__`,byokProviderEnvVar(t.model)).replaceAll(`__EVE_INIT_PACKAGE_VERSION__`,formatEveDependencySpecifier(t.eveVersion)).replaceAll(`__EVE_INIT_AI_SDK_VERSION__`,t.aiPackageVersion).replaceAll(`__EVE_INIT_CONNECT_VERSION__`,t.connectPackageVersion).replaceAll(`__EVE_INIT_ZOD_VERSION__`,t.zodPackageVersion).replaceAll(`__EVE_INIT_TYPESCRIPT_VERSION__`,t.typescriptPackageVersion).replaceAll(`__EVE_INIT_TYPES_NODE_VERSION__`,t.nodeTypesVersion).replaceAll(`__EVE_INIT_NODE_ENGINE__`,t.nodeEngine)}function formatEveDependencySpecifier(e){return/^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z-.]+)?$/.test(e)?`^${e}`:e}const BASE_AGENT_TEMPLATE=`import { defineAgent } from "eve";
|
|
2
2
|
|
|
3
3
|
export default defineAgent({
|
|
4
4
|
model: "__EVE_INIT_MODEL__",
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function isAsyncIterable(e){return typeof e==`object`&&!!e&&Symbol.asyncIterator in e&&typeof e[Symbol.asyncIterator]==`function`}export{isAsyncIterable};
|
|
@@ -6,7 +6,7 @@ import type { JsonObject } from "#shared/json.js";
|
|
|
6
6
|
* function. These are the same options the SDK passes to every tool call.
|
|
7
7
|
*/
|
|
8
8
|
export type ToolExecuteOptions = Omit<ToolExecutionOptions<unknown>, "context">;
|
|
9
|
-
export type ToolExecuteFn<TInput = unknown, TOutput = unknown> = (input: TInput, options: ToolExecuteOptions) => Promise<TOutput> | TOutput
|
|
9
|
+
export type ToolExecuteFn<TInput = unknown, TOutput = unknown> = (input: TInput, options: ToolExecuteOptions) => Promise<TOutput> | TOutput | AsyncIterable<TOutput>;
|
|
10
10
|
interface ToolDefinitionBase {
|
|
11
11
|
readonly description: string;
|
|
12
12
|
}
|
package/dist/src/svelte/index.js
CHANGED
|
@@ -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/dist/src/vue/index.js
CHANGED
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
|
|
package/docs/channels/linear.mdx
CHANGED
|
@@ -11,10 +11,12 @@ The Linear channel uses Linear's Agent Session surface rather than ordinary comm
|
|
|
11
11
|
Run the registry setup from the agent directory:
|
|
12
12
|
|
|
13
13
|
```bash
|
|
14
|
-
eve add
|
|
14
|
+
eve add linear
|
|
15
15
|
```
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
Select **Linear Channel** in the component checklist. **Linear MCP** is also selected by default if you want the agent to search and update Linear through MCP. Run `eve add channel/linear-agent` instead to install only the channel directly.
|
|
18
|
+
|
|
19
|
+
The flow checks that the Vercel CLI is authenticated, creates or links a Vercel project when needed, reuses a compatible existing connector when available or provisions an app-scoped Linear Connect client, and replaces its default trigger with `/eve/v1/linear`. It then installs `@vercel/connect` and writes `agent/channels/linear.ts` with the connector UID.
|
|
18
20
|
|
|
19
21
|
Vercel Connect creates the Linear app with the `app:assignable` and `app:mentionable` scopes required for Agent Sessions, receives and verifies `AgentSessionEvent` webhooks, and forwards them to the deployed agent. After deploying, open the Linear app in the Connect dashboard and install it in the workspace where you want to delegate work. Then delegate an issue or mention the agent in a Linear Agent Session.
|
|
20
22
|
|
|
@@ -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
|
|
@@ -47,6 +47,7 @@ The stream is newline-delimited JSON (NDJSON), one event per line:
|
|
|
47
47
|
| `message.received` | An inbound user message was accepted; carries flattened text plus structured text/file parts. |
|
|
48
48
|
| `step.started` | A model step began. |
|
|
49
49
|
| `actions.requested` | The model requested one or more actions, including tool calls; calls stream before execution. |
|
|
50
|
+
| `action.partial` | A locally executed tool generator yielded a preliminary output snapshot. |
|
|
50
51
|
| `action.result` | A tool call returned. |
|
|
51
52
|
| `input.requested` | The run paused for human input ([HITL](/docs/human-in-the-loop) approval or `ask_question`); carries `requests`. |
|
|
52
53
|
| `subagent.called` | A subagent was delegated; carries `childSessionId` to attach to. |
|
|
@@ -71,6 +72,8 @@ The stream is newline-delimited JSON (NDJSON), one event per line:
|
|
|
71
72
|
|
|
72
73
|
`reasoning.appended` and `message.appended` stream incremental output as it arrives. When the durable stream writer is busy, eve may coalesce adjacent deltas of the same type; the text remains in source order, and any other event forms an ordering barrier. Each append carries both the new delta and the cumulative text for the current block. The finalized block shows up on `message.completed` and `reasoning.completed`, which is the compatibility path for clients that don't render incremental streaming.
|
|
73
74
|
|
|
75
|
+
`action.partial` carries one complete preliminary output snapshot from an authored async-generator tool. A later partial for the same `callId` replaces it, and `action.result` is the final snapshot. When the durable writer is busy, eve may keep only the newest adjacent partial for a call. Treat partials as last-write-wins: a durable step can retry and replay overlapping event runs. Provider-executed tool progress and MCP progress notifications are not projected as `action.partial` events.
|
|
76
|
+
|
|
74
77
|
Note: consider the privacy, confidentiality, and user-experience implications for displaying, storing, or transmitting reasoning events in your application.
|
|
75
78
|
|
|
76
79
|
`message.completed` can fire more than once in a turn: the agent often emits interim assistant text before a tool call. To tell tool-call narration from a terminal reply, check `message.completed.data.finishReason`. `step.completed.data.finishReason` mirrors the step outcome, and usage lives on `step.completed`.
|
|
@@ -99,6 +99,7 @@ The most common UI events are:
|
|
|
99
99
|
| `reasoning.appended` | Render reasoning deltas when the model provides them. |
|
|
100
100
|
| `message.appended` | Render assistant text deltas. |
|
|
101
101
|
| `actions.requested` | Show tool calls as the model requests them, before execution. |
|
|
102
|
+
| `action.partial` | Update a generator tool's provisional output snapshot. |
|
|
102
103
|
| `action.result` | Show tool call results. |
|
|
103
104
|
| `input.requested` | Pause the UI for approval or a question answer. |
|
|
104
105
|
| `result.completed` | Read structured output from an [output schema](./output-schema). |
|
package/docs/guides/hooks.md
CHANGED
|
@@ -26,7 +26,7 @@ The slug is the path-relative basename. `agent/hooks/audit.ts` becomes `"audit"`
|
|
|
26
26
|
|
|
27
27
|
`defineHook`, `HookDefinition`, and `HookContext` live on `eve/hooks`.
|
|
28
28
|
|
|
29
|
-
A hook file declares stream-event subscribers under the `events` map, keyed by event type, with `*` matching every event. Subscribe to any event in the runtime stream vocabulary documented in [Sessions, runs and streaming](../concepts/sessions-runs-and-streaming), including the lifecycle events `session.started`, `turn.completed`, `message.completed`, and `action.result`. Handlers are observe-only. They cannot inject model context. To contribute runtime model messages, use `defineDynamic` and `defineInstructions` in `agent/instructions/`.
|
|
29
|
+
A hook file declares stream-event subscribers under the `events` map, keyed by event type, with `*` matching every event. Subscribe to any event in the runtime stream vocabulary documented in [Sessions, runs and streaming](../concepts/sessions-runs-and-streaming), including the lifecycle events `session.started`, `turn.completed`, `message.completed`, `action.partial`, and `action.result`. Handlers are observe-only. They cannot inject model context. To contribute runtime model messages, use `defineDynamic` and `defineInstructions` in `agent/instructions/`.
|
|
30
30
|
|
|
31
31
|
## Hook structure and context
|
|
32
32
|
|
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)
|
|
@@ -12,13 +12,15 @@ Run `eve add` from an eve agent project. This installs the integration's depende
|
|
|
12
12
|
|
|
13
13
|
```bash
|
|
14
14
|
eve add extension/agent-browser
|
|
15
|
-
eve add
|
|
15
|
+
eve add linear
|
|
16
16
|
eve add instrumentation/braintrust
|
|
17
17
|
```
|
|
18
18
|
|
|
19
19
|
Extensions may create a mount under `agent/extensions/`. Connections write their initial definition under `agent/connections/` and install `@vercel/connect` when required. Instrumentation providers write `agent/instrumentation.ts`; because an agent has one instrumentation file, compose multiple exporters there by hand. Configure generated files and required environment variables before running your agent.
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
Some integrations package several independently installable components. For example, `eve add linear` lets you choose the Linear Channel, Linear MCP, or both; both are selected by default. The specific `eve add channel/linear-agent` and `eve add connection/linear` commands remain available.
|
|
22
|
+
|
|
23
|
+
When an official item declares an interactive setup flow or flows, eve asks whether to run them after installation and runs multiple flows in declaration order. Run the printed `eve add <item> --skip-install` command to resume a skipped or cancelled setup later; it reruns the selected components' declared flows from the beginning.
|
|
22
24
|
|
|
23
25
|
## Find an integration
|
|
24
26
|
|
package/docs/reference/cli.md
CHANGED
|
@@ -87,6 +87,7 @@ Commands for installing and discovering [shadcn registry](https://ui.shadcn.com/
|
|
|
87
87
|
|
|
88
88
|
```bash
|
|
89
89
|
eve add extension/agent-browser
|
|
90
|
+
eve add linear
|
|
90
91
|
eve add channel/slack --skip-install
|
|
91
92
|
eve add https://example.com/r/my-extension.json --overwrite
|
|
92
93
|
eve registry add @acme=https://example.com/r/{name}.json
|
|
@@ -97,7 +98,9 @@ eve registry view @acme/my-extension
|
|
|
97
98
|
eve add @acme/my-extension
|
|
98
99
|
```
|
|
99
100
|
|
|
100
|
-
`eve add` asks before running setup declared by an official item and
|
|
101
|
+
`eve add` asks before running setup declared by an official item and runs multiple declared flows in declaration order. Product-level packages can offer independently installable components: `eve add linear` lets you select the Linear Channel, Linear MCP, or both, with both selected by default. `--yes` installs a package's default components.
|
|
102
|
+
|
|
103
|
+
When setup is skipped or cancelled, eve prints the matching `eve add <item> --skip-install` command. `--skip-install` reruns the selected components' declared flows from the beginning without reinstalling them.
|
|
101
104
|
|
|
102
105
|
`eve registry add` records configured sources in `package.json#registries`. `eve registry list` aggregates the official catalog and all configured sources by default. `eve registry search` also includes [skills.sh](https://skills.sh), available without configuration at `@skills`, and groups results by source with each source's available result count. Search returns up to 10 matches per source by default; pass `--limit <count>` to request between 1 and 100. Either command can browse one supplied URL or namespace. Official and other universal items with explicit file targets do not require shadcn project configuration.
|
|
103
106
|
|
|
@@ -254,10 +257,14 @@ eve traces ls # list traces, most recent first
|
|
|
254
257
|
eve traces ls --json # emit machine-readable trace summaries
|
|
255
258
|
eve traces # show the most recent span tree
|
|
256
259
|
eve traces <trace> # show one span tree
|
|
260
|
+
eve traces --verbose # expand every span with all attributes and events
|
|
261
|
+
eve traces --json # dump the full trace as JSON
|
|
257
262
|
```
|
|
258
263
|
|
|
259
264
|
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
265
|
|
|
266
|
+
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.
|
|
267
|
+
|
|
261
268
|
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
269
|
|
|
263
270
|
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
|
package/docs/tools/overview.mdx
CHANGED
|
@@ -28,10 +28,34 @@ A tool definition needs:
|
|
|
28
28
|
- a filename slug under `agent/tools/`, the model-facing name.
|
|
29
29
|
- a `description`: what the tool does, written for the model.
|
|
30
30
|
- an `inputSchema`: a Zod schema (or any Standard Schema, or a plain JSON Schema object). Required. For no input, pass `z.object({})`. Zod and Standard Schema infer the `input` type in `execute`. Plain JSON Schema types it as `Record<string, unknown>`.
|
|
31
|
-
- an `execute(input, ctx)`: the implementation. May be sync or async.
|
|
31
|
+
- an `execute(input, ctx)`: the implementation. May be sync, async, or an async generator.
|
|
32
32
|
|
|
33
33
|
When a tool returns structured data, add an optional `outputSchema`. With Zod or Standard Schema it also types the `execute` return.
|
|
34
34
|
|
|
35
|
+
### Stream preliminary tool results
|
|
36
|
+
|
|
37
|
+
An async generator lets a long-running tool stream complete output snapshots
|
|
38
|
+
before it finishes. Each `yield` replaces the previous snapshot; the final
|
|
39
|
+
yield is the normal tool result the model receives:
|
|
40
|
+
|
|
41
|
+
```ts title="agent/tools/build_report.ts"
|
|
42
|
+
export default defineTool({
|
|
43
|
+
description: "Build a project report.",
|
|
44
|
+
inputSchema: z.object({ project: z.string() }),
|
|
45
|
+
async *execute({ project }) {
|
|
46
|
+
yield { phase: "collecting", report: null };
|
|
47
|
+
const report = await buildReport(project);
|
|
48
|
+
yield { phase: "complete", report };
|
|
49
|
+
},
|
|
50
|
+
});
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
eve publishes every earlier yield as an `action.partial` stream event. The
|
|
54
|
+
snapshot is visible to channels, hooks, and clients but never enters model
|
|
55
|
+
history or `toModelOutput`; only the final yield does. Treat snapshots as
|
|
56
|
+
last-write-wins by tool call id, not append-only progress. The durable runtime
|
|
57
|
+
can retry a step and replay overlapping snapshots.
|
|
58
|
+
|
|
35
59
|
### The `ctx` parameter
|
|
36
60
|
|
|
37
61
|
`execute` gets a `ctx` carrying the runtime accessors:
|
|
@@ -78,7 +102,7 @@ toModelOutput(output) {
|
|
|
78
102
|
},
|
|
79
103
|
```
|
|
80
104
|
|
|
81
|
-
`toModelOutput` receives the
|
|
105
|
+
`toModelOutput` receives the final, typed `execute` return and only affects the model. Channel event handlers and hooks still get the full output on `action.result`, so a channel can render rich platform output (Slack Block Kit, say) the model never sees. Return `{ type: "text", value }` for a summary, or `{ type: "json", value }` for a smaller object.
|
|
82
106
|
|
|
83
107
|
Tool outputs must be JSON-serializable. Return plain objects, arrays, strings, numbers, booleans, or `null`; convert values like `Date`, `Map`, `Set`, `NaN`, and cyclic objects before returning them from `execute` or from a `{ type: "json" }` `toModelOutput`.
|
|
84
108
|
|