eve 0.23.0 → 0.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +13 -0
- package/dist/src/channel/types.d.ts +1 -1
- package/dist/src/cli/run.d.ts +2 -2
- package/dist/src/cli/run.js +1 -1
- package/dist/src/compiler/manifest.d.ts +12 -6
- package/dist/src/compiler/manifest.js +1 -1
- package/dist/src/compiler/normalize-agent-config.js +1 -1
- package/dist/src/compiler/normalize-extension.js +1 -1
- package/dist/src/compiler/normalize-manifest.js +2 -2
- package/dist/src/compiler/normalize-tool.d.ts +2 -1
- package/dist/src/compiler/normalize-tool.js +1 -1
- package/dist/src/context/build-base-tool-context.d.ts +5 -1
- package/dist/src/context/build-base-tool-context.js +1 -1
- package/dist/src/context/build-dynamic-tools.js +1 -1
- package/dist/src/context/dynamic-tool-lifecycle.js +1 -1
- package/dist/src/execution/create-session-step.js +1 -1
- package/dist/src/execution/node-step.d.ts +2 -3
- package/dist/src/execution/node-step.js +1 -1
- package/dist/src/execution/run-session-limits.d.ts +0 -9
- package/dist/src/execution/run-session-limits.js +1 -1
- package/dist/src/execution/subagent-tool.js +1 -1
- package/dist/src/execution/tool-auth.js +1 -1
- package/dist/src/harness/types.d.ts +5 -7
- package/dist/src/harness/workflow-subagent-limit.d.ts +2 -2
- package/dist/src/internal/application/compiled-artifacts.d.ts +7 -1
- package/dist/src/internal/application/compiled-artifacts.js +2 -2
- package/dist/src/internal/application/package.js +1 -1
- package/dist/src/internal/authored-definition/core.js +1 -1
- package/dist/src/internal/authored-definition/schema-backed.d.ts +3 -2
- package/dist/src/internal/authored-definition/schema-backed.js +1 -1
- package/dist/src/internal/authored-module.d.ts +4 -0
- package/dist/src/internal/authored-module.js +1 -1
- package/dist/src/internal/nitro/host/build-application.d.ts +2 -1
- package/dist/src/internal/nitro/host/build-application.js +1 -1
- package/dist/src/internal/nitro/host/configure-nitro-routes.js +1 -1
- package/dist/src/internal/nitro/host/create-application-nitro.js +1 -1
- package/dist/src/internal/nitro/host/dispatch-schedule-in-dev.d.ts +6 -1
- package/dist/src/internal/nitro/host/dispatch-schedule-in-dev.js +1 -1
- package/dist/src/internal/nitro/host/prepare-application-host.js +1 -1
- package/dist/src/internal/nitro/host/types.d.ts +4 -0
- package/dist/src/internal/nitro/host/vercel-build-prewarm.d.ts +2 -9
- package/dist/src/internal/nitro/host/vercel-build-prewarm.js +1 -1
- package/dist/src/internal/nitro/routes/agent-info/build-agent-info-response-from-manifest.js +1 -1
- package/dist/src/internal/nitro/routes/agent-info/build-agent-info-response.js +1 -1
- package/dist/src/internal/nitro/routes/dev-schedule-dispatch.d.ts +2 -3
- package/dist/src/internal/nitro/routes/dev-schedule-dispatch.js +1 -1
- package/dist/src/public/channels/teams/api.d.ts +8 -0
- package/dist/src/public/channels/teams/api.js +2 -2
- package/dist/src/public/channels/teams/defaults.d.ts +2 -2
- package/dist/src/public/channels/teams/defaults.js +1 -1
- package/dist/src/public/channels/teams/hitl.d.ts +4 -0
- package/dist/src/public/channels/teams/hitl.js +1 -1
- package/dist/src/public/channels/teams/index.d.ts +1 -1
- package/dist/src/public/channels/teams/teamsChannel.d.ts +6 -0
- package/dist/src/public/channels/teams/teamsChannel.js +1 -1
- package/dist/src/public/definitions/tool.d.ts +40 -24
- package/dist/src/public/definitions/tool.js +1 -1
- package/dist/src/public/tools/index.d.ts +1 -1
- package/dist/src/public/tools/index.js +1 -1
- package/dist/src/runtime/resolve-agent.js +1 -1
- package/dist/src/runtime/types.d.ts +6 -6
- package/dist/src/setup/scaffold/create/project.js +1 -1
- package/dist/src/shared/agent-definition.d.ts +0 -16
- package/dist/src/shared/dynamic-tool-definition.d.ts +2 -0
- package/docs/agent-config.md +8 -8
- package/docs/channels/teams.mdx +5 -1
- package/docs/concepts/default-harness.md +5 -3
- package/docs/guides/deployment.md +3 -3
- package/docs/guides/dynamic-workflows.md +9 -10
- package/docs/reference/cli.md +1 -1
- package/docs/reference/typescript-api.md +27 -27
- package/docs/subagents.mdx +1 -1
- package/docs/tools/overview.mdx +1 -0
- package/package.json +1 -1
|
@@ -79,6 +79,10 @@ export type TeamsInboundResult = {
|
|
|
79
79
|
} | null;
|
|
80
80
|
/** Sync or async {@link TeamsInboundResult}. */
|
|
81
81
|
export type TeamsInboundResultOrPromise = TeamsInboundResult | Promise<TeamsInboundResult>;
|
|
82
|
+
/** Result of a Teams HITL submission authorization hook. Return `null` to reject. */
|
|
83
|
+
export type TeamsInputResponseResult = {
|
|
84
|
+
readonly auth: SessionAuthContext | null;
|
|
85
|
+
} | null;
|
|
82
86
|
/** Result of a non-HITL Teams invoke hook. A `Response` returns verbatim, a plain object is JSON-encoded as the body, and `null`/`undefined` yields a 200 OK. */
|
|
83
87
|
export type TeamsInvokeResult = Record<string, unknown> | Response | null | undefined;
|
|
84
88
|
/** Sync or async {@link TeamsInvokeResult}. */
|
|
@@ -117,6 +121,8 @@ export interface TeamsChannelConfig {
|
|
|
117
121
|
readonly route?: string;
|
|
118
122
|
/** Inbound message hook. Defaults to user-scoped auth and mention-gated dispatch outside personal chats. */
|
|
119
123
|
onMessage?(ctx: TeamsContext, message: TeamsMessageActivity): TeamsInboundResultOrPromise;
|
|
124
|
+
/** Authorizes HITL card submissions. Defaults to the submitting Teams user. */
|
|
125
|
+
onInputResponse?(ctx: TeamsContext, activity: TeamsInvokeActivity | TeamsMessageActivity): TeamsInputResponseResult | Promise<TeamsInputResponseResult>;
|
|
120
126
|
/** Handler for non-HITL Teams invoke activities. Return a body, a Response, or `null`/`undefined` for a 200 OK. */
|
|
121
127
|
onInvoke?(ctx: TeamsContext, activity: TeamsInvokeActivity): TeamsInvokeResultOrPromise;
|
|
122
128
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createLogger,logError}from"#internal/logging.js";import{parseJsonObject}from"#shared/json.js";import{POST,defineChannel}from"#public/definitions/channel.js";import{callTeamsConnectorApi,normalizeTeamsPostInput,replyToTeamsActivity,sendTeamsActivity,teamsContinuationToken,triggerTeamsTypingIndicator,updateTeamsActivity}from"#public/channels/teams/api.js";import{deriveTeamsInputResponses,isTeamsInputResponseActivity,teamsInvokeResponse}from"#public/channels/teams/hitl.js";import{formatTeamsContextBlock,parseTeamsActivity,teamsThreadRootActivityId}from"#public/channels/teams/inbound.js";import{buildTeamsTurnMessage,collectTeamsFileParts,createTeamsFetchFile,normalizeTeamsFilesPolicy}from"#public/channels/teams/attachments.js";import{defaultEvents,defaultOnMessage,teamsMentionUser}from"#public/channels/teams/defaults.js";import{verifyTeamsRequest}from"#public/channels/teams/verify.js";const log=createLogger(`teams.channel`);function teamsChannel(e={}){let t=normalizeTeamsFilesPolicy(e.files),a=e.onMessage??defaultOnMessage,o={...defaultEvents,...e.events};return defineChannel({kindHint:`teams`,state:initialTeamsState(),fetchFile:createTeamsFetchFile(t),metadata:e=>({channelId:e.channelId,conversationType:e.conversationType,teamId:e.teamId}),context(t,n){return rebuildTeamsContext(t,n,e)},routes:[POST(e.route??`/eve/v1/teams`,async(r,{send:i,waitUntil:
|
|
1
|
+
import{createLogger,logError}from"#internal/logging.js";import{parseJsonObject}from"#shared/json.js";import{POST,defineChannel}from"#public/definitions/channel.js";import{callTeamsConnectorApi,normalizeTeamsContinuationAddress,normalizeTeamsPostInput,replyToTeamsActivity,sendTeamsActivity,teamsContinuationToken,triggerTeamsTypingIndicator,updateTeamsActivity}from"#public/channels/teams/api.js";import{deriveTeamsInputResponses,isTeamsInputResponseActivity,readTeamsInputReplyToActivityId,teamsInvokeResponse}from"#public/channels/teams/hitl.js";import{formatTeamsContextBlock,parseTeamsActivity,teamsThreadRootActivityId}from"#public/channels/teams/inbound.js";import{buildTeamsTurnMessage,collectTeamsFileParts,createTeamsFetchFile,normalizeTeamsFilesPolicy}from"#public/channels/teams/attachments.js";import{defaultEvents,defaultOnMessage,defaultTeamsAuth,teamsMentionUser}from"#public/channels/teams/defaults.js";import{verifyTeamsRequest}from"#public/channels/teams/verify.js";const log=createLogger(`teams.channel`);function teamsChannel(e={}){let t=normalizeTeamsFilesPolicy(e.files),a=e.onMessage??defaultOnMessage,o=e.onInputResponse??(e.onMessage===void 0?defaultOnInputResponse:rejectInput),s={...defaultEvents,...e.events};return defineChannel({kindHint:`teams`,state:initialTeamsState(),fetchFile:createTeamsFetchFile(t),metadata:e=>({channelId:e.channelId,conversationType:e.conversationType,teamId:e.teamId}),context(t,n){return rebuildTeamsContext(t,n,e)},routes:[POST(e.route??`/eve/v1/teams`,async(r,{send:i,waitUntil:s})=>{let c=await verifyInbound(r,e.credentials);if(c===null)return new Response(`unauthorized`,{status:401});let l;try{l=parseJsonObject(JSON.parse(c))}catch(e){return log.warn(`inbound Teams body is not valid JSON`,{error:e}),teamsOk()}let u=parseTeamsActivity(l);return u===null?teamsOk():u.type===`message`?(s(isTeamsInputResponseActivity(u)?dispatchInputResponses({activity:u,config:e,onInputResponse:o,send:i}):dispatchMessage({activity:u,config:e,filesPolicy:t,onMessage:a,send:i})),teamsOk()):u.type===`invoke`?handleInvoke({activity:u,config:e,onInputResponse:o,send:i,waitUntil:s}):teamsOk()})],async receive(t,{send:n}){let r=t.target,i=readString(r.serviceUrl),a=readString(r.conversationId);if(!i||!a)throw Error(`teamsChannel().receive requires target.serviceUrl and target.conversationId.`);let o=readString(r.conversationType)??null,s=readString(r.replyToActivityId)??null,c=r.initialMessage;if(c!==void 0&&s!==null)throw Error("teamsChannel().receive: `replyToActivityId` and `initialMessage` are mutually exclusive.");let l={...initialTeamsState(),channelId:readString(r.channelId)??null,conversationId:a,conversationType:o,replyToActivityId:s,serviceUrl:i,teamId:readString(r.teamId)??null,tenantId:readString(r.tenantId)??null};if(c!==void 0){let t=await buildTeamsBinding({config:e,state:l}).thread.post(c);o!==`personal`&&t.id&&(s=t.id,l.replyToActivityId=t.id)}return n(t.message,{auth:t.auth,continuationToken:teamsContinuationToken({conversationId:a,replyToActivityId:s,tenantId:l.tenantId}),state:l})},events:s})}function rebuildTeamsContext(e,t,n){return{...buildTeamsBinding({config:n,session:t,state:e}),adaptiveCardVersion:n.adaptiveCardVersion??`1.5`,state:e}}function buildTeamsBinding(e){let n=buildTeamsHandle(e);return{teams:n,thread:{mentionUser:teamsMentionUser,post(e){return n.sendActivity(e)},async startTyping(){try{await n.startTyping()}catch(e){logError(log,`Teams typing indicator failed — swallowed`,e)}},update(e,t){return n.updateActivity(e,t)}}}}function buildTeamsHandle(e){let t=e.state,n=e.config.api,r=e.config.credentials;function requireAddress(){let e=t.conversationId??``,n=t.serviceUrl??``;if(!e||!n)throw Error(`teamsChannel: missing serviceUrl or conversationId for outbound message.`);return{conversationId:e,serviceUrl:n}}function anchor(n){if(!n.id||t.replyToActivityId||t.conversationType===`personal`)return;t.replyToActivityId=n.id;let r=t.conversationId;r&&e.session?.setContinuationToken(teamsContinuationToken({conversationId:r,replyToActivityId:n.id,tenantId:t.tenantId}))}async function send(e){let i=requireAddress(),a=buildOutboundActivity(t,e),o=t.replyToActivityId===null?await sendTeamsActivity({...n,body:a,credentials:r,conversationId:i.conversationId,serviceUrl:i.serviceUrl}):await replyToTeamsActivity({...n,body:a,credentials:r,activityId:t.replyToActivityId,conversationId:i.conversationId,serviceUrl:i.serviceUrl});return anchor(o),o}return{channelId:t.channelId??void 0,conversationId:t.conversationId??``,conversationType:t.conversationType??void 0,replyToActivityId:t.replyToActivityId??void 0,serviceUrl:t.serviceUrl??``,teamId:t.teamId??void 0,tenantId:t.tenantId??void 0,request(e,t,i){let o=requireAddress();return callTeamsConnectorApi({...n,body:t,credentials:r,method:i?.method,path:e,serviceUrl:o.serviceUrl})},sendActivity:send,replyToActivity(e){let i=requireAddress(),a=t.replyToActivityId??``;if(!a)throw Error(`teamsChannel: missing reply activity id.`);return replyToTeamsActivity({...n,body:buildOutboundActivity(t,e),credentials:r,activityId:a,conversationId:i.conversationId,serviceUrl:i.serviceUrl})},updateActivity(e,i){let a=requireAddress();return updateTeamsActivity({...n,body:buildOutboundActivity(t,i),credentials:r,activityId:e,conversationId:a.conversationId,serviceUrl:a.serviceUrl})},async startTyping(){let e=requireAddress();await triggerTeamsTypingIndicator({...n,credentials:r,conversationId:e.conversationId,serviceUrl:e.serviceUrl})}}}async function verifyInbound(e,t){try{return await verifyTeamsRequest(e,{appId:t?.webhookVerifier?void 0:t?.appId,webhookVerifier:t?.webhookVerifier})}catch(e){return log.warn(`teams inbound verification failed`,{error:e}),null}}async function dispatchMessage(e){let t=stateFromActivity(e.activity),n=buildTeamsBinding({config:e.config,state:t}),r;try{r=await e.onMessage(n,e.activity)}catch(e){log.error(`Teams message handler failed`,{error:e});return}if(r==null)return;let i=collectTeamsFileParts(e.activity.attachments,e.filesPolicy),a=buildTeamsTurnMessage(e.activity.text,i),o={activityId:e.activity.id,channelId:e.activity.teamsChannelId,conversationId:e.activity.conversation.id,conversationType:e.activity.conversationType,scope:e.activity.scope,teamId:e.activity.teamId,tenantId:e.activity.tenantId,userId:e.activity.from.id,userName:e.activity.from.name},s=r.context??[];try{await e.send({message:a,context:[formatTeamsContextBlock(o),...s]},{auth:r.auth,continuationToken:stateToken(t),state:t})}catch(e){log.error(`Teams message delivery failed`,{error:e})}}async function handleInvoke(e){if(isTeamsInputResponseActivity(e.activity))return e.waitUntil(dispatchInputResponses({activity:e.activity,config:e.config,onInputResponse:e.onInputResponse,send:e.send})),Response.json(teamsInvokeResponse());if(e.config.onInvoke===void 0)return teamsOk();let t=buildTeamsBinding({config:e.config,state:stateFromActivity(e.activity)}),n=await e.config.onInvoke(t,e.activity);return n instanceof Response?n:n&&typeof n==`object`?Response.json(n):teamsOk()}async function dispatchInputResponses(e){let t=deriveTeamsInputResponses(e.activity);if(t.length===0)return;let n=stateFromActivity(e.activity),r=buildTeamsBinding({config:e.config,state:n}),i;try{i=await e.onInputResponse(r,e.activity)}catch(e){log.error(`Teams input response authorization failed`,{error:e});return}if(i!==null)try{await e.send({inputResponses:t},{auth:i.auth,continuationToken:resolveInputContinuationToken(e.activity,n),state:n})}catch(e){log.error(`Teams input response delivery failed`,{error:e})}}function stateFromActivity(e){let t=normalizeTeamsContinuationAddress({conversationId:e.conversation.id,replyToActivityId:teamsThreadRootActivityId(e)});return{bot:e.recipient,channelId:e.teamsChannelId??null,conversationId:e.conversation.id,conversationType:e.conversationType??e.scope,pendingAuthActivityId:null,replyToActivityId:t.replyToActivityId,serviceUrl:e.serviceUrl,teamId:e.teamId??null,tenantId:e.tenantId??null,triggeringUser:e.from}}function resolveInputContinuationToken(e,t){let n=readTeamsInputReplyToActivityId(e);return n===null?stateToken(t):teamsContinuationToken({conversationId:e.conversation.id,replyToActivityId:n,tenantId:e.tenantId})}function defaultOnInputResponse(e,t){return{auth:defaultTeamsAuth(t)}}function rejectInput(){return null}function initialTeamsState(){return{bot:null,channelId:null,conversationId:null,conversationType:null,pendingAuthActivityId:null,replyToActivityId:null,serviceUrl:null,teamId:null,tenantId:null,triggeringUser:null}}function stateToken(e){let t=e.conversationId??``;if(!t)throw Error(`teamsChannel: missing conversation id.`);return teamsContinuationToken({conversationId:t,replyToActivityId:e.replyToActivityId,tenantId:e.tenantId})}function buildOutboundActivity(e,t){if(typeof t!=`string`&&`type`in t&&t.type===`typing`)return t;let n=normalizeTeamsPostInput(t),r=mergeChannelData(e,n.channelData);return{...n,channelData:r,conversation:e.conversationId?{id:e.conversationId}:void 0,from:e.bot??void 0,replyToId:e.replyToActivityId??void 0,type:`message`}}function mergeChannelData(e,t){let r={...t};return e.tenantId&&(r.tenant={id:e.tenantId}),e.teamId&&(r.team={id:e.teamId}),e.channelId&&(r.channel={id:e.channelId}),Object.keys(r).length>0?parseJsonObject(r):void 0}function teamsOk(){return new Response(`ok`,{status:200})}function readString(e){return typeof e==`string`&&e.length>0?e:void 0}export{teamsChannel};
|
|
@@ -61,6 +61,12 @@ export type ToolContext = SessionContext & {
|
|
|
61
61
|
* stream events and its {@link ApprovalContext}.
|
|
62
62
|
*/
|
|
63
63
|
readonly callId: string;
|
|
64
|
+
/**
|
|
65
|
+
* Final runtime name of the current tool, including any namespace
|
|
66
|
+
* qualification. This is the same `toolName` carried by stream events and
|
|
67
|
+
* the tool's {@link ApprovalContext}.
|
|
68
|
+
*/
|
|
69
|
+
readonly toolName: string;
|
|
64
70
|
/**
|
|
65
71
|
* Resolves the bearer token for an inline provider. This accepts the same
|
|
66
72
|
* auth shapes as a connection's `auth` field, including `connect("...")`
|
|
@@ -223,39 +229,49 @@ export declare function disableTool(): DisabledToolSentinel;
|
|
|
223
229
|
*/
|
|
224
230
|
export declare function isDisabledToolSentinel(value: unknown): value is DisabledToolSentinel;
|
|
225
231
|
/**
|
|
226
|
-
*
|
|
227
|
-
*
|
|
232
|
+
* Discriminator written into definitions returned by
|
|
233
|
+
* {@link experimental_workflow}.
|
|
228
234
|
*/
|
|
229
|
-
declare const
|
|
235
|
+
declare const EXPERIMENTAL_WORKFLOW_TOOL_KIND = "eve:enable-workflow-tool";
|
|
230
236
|
/**
|
|
231
|
-
*
|
|
232
|
-
* (conventionally `agent/tools/workflow.ts`) to enable the framework `Workflow`
|
|
233
|
-
* orchestration tool. The tool is off unless this marker is present,
|
|
234
|
-
* mirroring the {@link disableTool} opt-out in reverse.
|
|
237
|
+
* Configuration accepted by {@link experimental_workflow}.
|
|
235
238
|
*/
|
|
236
|
-
export interface
|
|
237
|
-
|
|
239
|
+
export interface ExperimentalWorkflowToolInput {
|
|
240
|
+
/**
|
|
241
|
+
* Maximum number of subagent or remote-agent calls one `Workflow` program
|
|
242
|
+
* may dispatch, counted across sequential and parallel calls alike.
|
|
243
|
+
*
|
|
244
|
+
* Calls beyond the limit fail with a `WORKFLOW_SUBAGENT_LIMIT_REACHED`
|
|
245
|
+
* result instead of starting a child session.
|
|
246
|
+
*
|
|
247
|
+
* @default 100
|
|
248
|
+
*/
|
|
249
|
+
readonly maxSubagents?: number;
|
|
238
250
|
}
|
|
239
251
|
/**
|
|
240
|
-
*
|
|
241
|
-
*
|
|
242
|
-
|
|
243
|
-
|
|
252
|
+
* Framework `Workflow` tool definition returned by
|
|
253
|
+
* {@link experimental_workflow}.
|
|
254
|
+
*/
|
|
255
|
+
export interface ExperimentalWorkflowToolDefinition extends ExperimentalWorkflowToolInput {
|
|
256
|
+
readonly kind: typeof EXPERIMENTAL_WORKFLOW_TOOL_KIND;
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Enables and configures the experimental framework `Workflow` tool, an
|
|
260
|
+
* isolated JavaScript sandbox whose only callable operations are this agent's
|
|
261
|
+
* subagents and remote agents. Export the result from
|
|
262
|
+
* `agent/tools/workflow.ts`:
|
|
244
263
|
*
|
|
245
264
|
* ```ts
|
|
246
|
-
*
|
|
247
|
-
* ```
|
|
265
|
+
* import { experimental_workflow } from "eve/tools";
|
|
248
266
|
*
|
|
249
|
-
*
|
|
250
|
-
*
|
|
251
|
-
* `limits.maxSubagents` subagent calls (default 100).
|
|
267
|
+
* export default experimental_workflow({ maxSubagents: 25 });
|
|
268
|
+
* ```
|
|
252
269
|
*
|
|
253
|
-
*
|
|
254
|
-
* called `Workflow`.
|
|
270
|
+
* Only the root session sees the tool. The resulting model-facing tool is
|
|
271
|
+
* still called `Workflow`.
|
|
255
272
|
*/
|
|
256
|
-
export declare
|
|
273
|
+
export declare function experimental_workflow(input?: ExperimentalWorkflowToolInput): ExperimentalWorkflowToolDefinition;
|
|
257
274
|
/**
|
|
258
|
-
* Type guard
|
|
259
|
-
* opt-in sentinel.
|
|
275
|
+
* Type guard for a definition returned by {@link experimental_workflow}.
|
|
260
276
|
*/
|
|
261
|
-
export declare function
|
|
277
|
+
export declare function isExperimentalWorkflowToolDefinition(value: unknown): value is ExperimentalWorkflowToolDefinition;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{DYNAMIC_SENTINEL_KIND,TOOL_BRAND}from"#shared/dynamic-tool-definition.js";import{stampDefinitionKey}from"#public/tool-result-narrowing.js";function defineTool(e){if(e.auth!==void 0)throw Error(`defineTool: The "auth" field is no longer supported. Pass auth providers inline to ctx.getToken(provider) or ctx.requireAuth(provider).`);return Object.assign(e,{[TOOL_BRAND]:!0}),stampDefinitionKey(e,`tool:${e.description}`),e}function defineDynamic(t){let n={kind:DYNAMIC_SENTINEL_KIND,events:t.events,...Object.hasOwn(t,`fallback`)?{fallback:t.fallback}:{}};return stampDefinitionKey(n,`dynamic:${Object.keys(t.events).join(`,`)}`),n}const DISABLED_TOOL_SENTINEL_KIND=`eve:disabled-tool`;function disableTool(){return{kind:DISABLED_TOOL_SENTINEL_KIND}}function isDisabledToolSentinel(e){return typeof e==`object`&&!!e&&e.kind===DISABLED_TOOL_SENTINEL_KIND}const
|
|
1
|
+
import{DYNAMIC_SENTINEL_KIND,TOOL_BRAND}from"#shared/dynamic-tool-definition.js";import{stampDefinitionKey}from"#public/tool-result-narrowing.js";function defineTool(e){if(e.auth!==void 0)throw Error(`defineTool: The "auth" field is no longer supported. Pass auth providers inline to ctx.getToken(provider) or ctx.requireAuth(provider).`);return Object.assign(e,{[TOOL_BRAND]:!0}),stampDefinitionKey(e,`tool:${e.description}`),e}function defineDynamic(t){let n={kind:DYNAMIC_SENTINEL_KIND,events:t.events,...Object.hasOwn(t,`fallback`)?{fallback:t.fallback}:{}};return stampDefinitionKey(n,`dynamic:${Object.keys(t.events).join(`,`)}`),n}const DISABLED_TOOL_SENTINEL_KIND=`eve:disabled-tool`;function disableTool(){return{kind:DISABLED_TOOL_SENTINEL_KIND}}function isDisabledToolSentinel(e){return typeof e==`object`&&!!e&&e.kind===DISABLED_TOOL_SENTINEL_KIND}const EXPERIMENTAL_WORKFLOW_TOOL_KIND=`eve:enable-workflow-tool`;function experimental_workflow(e={}){let t={kind:EXPERIMENTAL_WORKFLOW_TOOL_KIND};return e.maxSubagents!==void 0&&(t.maxSubagents=e.maxSubagents),t}function isExperimentalWorkflowToolDefinition(e){return typeof e==`object`&&!!e&&e.kind===EXPERIMENTAL_WORKFLOW_TOOL_KIND}export{defineDynamic,defineTool,disableTool,experimental_workflow,isDisabledToolSentinel,isExperimentalWorkflowToolDefinition};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Tool authoring helpers for `agent/tools/*.ts` files.
|
|
3
3
|
*/
|
|
4
|
-
export { type DisabledToolSentinel, type
|
|
4
|
+
export { type DisabledToolSentinel, type ExperimentalWorkflowToolDefinition, type ExperimentalWorkflowToolInput, defineDynamic, defineTool, disableTool, experimental_workflow, isDisabledToolSentinel, isExperimentalWorkflowToolDefinition, type ToolAuthOptions, type ToolAuthProvider, type ToolDefinition, type ToolContext, type ToolModelOutput, } from "#public/definitions/tool.js";
|
|
5
5
|
export type { Approval, ApprovalContext, ApprovalStatus } from "#public/definitions/approval.js";
|
|
6
6
|
export type { DynamicToolEntry, DynamicEvents, DynamicToolEvents, DynamicResolveContext, DynamicSentinel, DynamicToolSet, DynamicToolResult, } from "#shared/dynamic-tool-definition.js";
|
|
7
7
|
export { type SessionContext } from "#public/definitions/callback-context.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{defineDynamic,defineTool,disableTool,experimental_workflow,isDisabledToolSentinel,isExperimentalWorkflowToolDefinition}from"#public/definitions/tool.js";import{toolResultFrom}from"#public/tool-result-narrowing.js";import{defineBashTool}from"#public/tools/define-bash-tool.js";import{defineGlobTool}from"#public/tools/define-glob-tool.js";import{defineGrepTool}from"#public/tools/define-grep-tool.js";import{defineReadFileTool}from"#public/tools/define-read-file-tool.js";import{defineWriteFileTool}from"#public/tools/define-write-file-tool.js";export{defineBashTool,defineDynamic,defineGlobTool,defineGrepTool,defineReadFileTool,defineTool,defineWriteFileTool,disableTool,experimental_workflow,isDisabledToolSentinel,isExperimentalWorkflowToolDefinition,toolResultFrom};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{ResolveAgentError,createResolvedModuleSourceRef}from"#runtime/resolve-helpers.js";import{resolveChannelDefinition}from"#runtime/resolve-channel.js";import{resolveConnectionDefinition}from"#runtime/resolve-connection.js";import{resolveHookDefinition}from"#runtime/resolve-hook.js";import{resolveSandboxDefinition}from"#runtime/resolve-sandbox.js";import{resolveDynamicInstructionsDefinition}from"#runtime/resolve-dynamic-instructions.js";import{resolveDynamicSkillDefinition}from"#runtime/resolve-dynamic-skill.js";import{resolveDynamicToolDefinition}from"#runtime/resolve-dynamic-tool.js";import{resolveToolDefinition}from"#runtime/resolve-tool.js";async function resolveAgent(e){let t=e.manifest.skills.map(e=>({...e,metadata:e.metadata===void 0?void 0:{...e.metadata}})),r=[],i=[];for(let t of e.manifest.channels){if(t.kind===`disabled`){i.push(t.name);continue}r.push(await resolveChannelDefinition(t,e.moduleMap,e.nodeId))}let a=await Promise.all(e.manifest.tools.map(t=>resolveToolDefinition(t,e.moduleMap,e.nodeId))),o=await Promise.all((e.manifest.dynamicInstructions??[]).map(t=>resolveDynamicInstructionsDefinition(t,e.moduleMap,e.nodeId))),s=await Promise.all((e.manifest.dynamicSkills??[]).map(t=>resolveDynamicSkillDefinition(t,e.moduleMap,e.nodeId))),c=await Promise.all(e.manifest.dynamicTools.map(t=>resolveDynamicToolDefinition(t,e.moduleMap,e.nodeId))),l=await Promise.all(e.manifest.hooks.map(t=>resolveHookDefinition(t,e.moduleMap,e.nodeId))),u=await Promise.all(e.manifest.connections.map(t=>resolveConnectionDefinition(t,e.moduleMap,e.nodeId))),d=e.manifest.sandbox===null?null:await resolveSandboxDefinition(e.manifest.sandbox,e.moduleMap,e.nodeId),f=createResolvedInstructionsDefinition(e.manifest.instructions),p=e.manifest.workspaceResourceRoot,m={channels:r,config:createResolvedAgentConfig(e.manifest),connections:u,disabledFrameworkChannels:i,disabledFrameworkTools:[...e.manifest.disabledFrameworkTools],
|
|
1
|
+
import{ResolveAgentError,createResolvedModuleSourceRef}from"#runtime/resolve-helpers.js";import{resolveChannelDefinition}from"#runtime/resolve-channel.js";import{resolveConnectionDefinition}from"#runtime/resolve-connection.js";import{resolveHookDefinition}from"#runtime/resolve-hook.js";import{resolveSandboxDefinition}from"#runtime/resolve-sandbox.js";import{resolveDynamicInstructionsDefinition}from"#runtime/resolve-dynamic-instructions.js";import{resolveDynamicSkillDefinition}from"#runtime/resolve-dynamic-skill.js";import{resolveDynamicToolDefinition}from"#runtime/resolve-dynamic-tool.js";import{resolveToolDefinition}from"#runtime/resolve-tool.js";async function resolveAgent(e){let t=e.manifest.skills.map(e=>({...e,metadata:e.metadata===void 0?void 0:{...e.metadata}})),r=[],i=[];for(let t of e.manifest.channels){if(t.kind===`disabled`){i.push(t.name);continue}r.push(await resolveChannelDefinition(t,e.moduleMap,e.nodeId))}let a=await Promise.all(e.manifest.tools.map(t=>resolveToolDefinition(t,e.moduleMap,e.nodeId))),o=await Promise.all((e.manifest.dynamicInstructions??[]).map(t=>resolveDynamicInstructionsDefinition(t,e.moduleMap,e.nodeId))),s=await Promise.all((e.manifest.dynamicSkills??[]).map(t=>resolveDynamicSkillDefinition(t,e.moduleMap,e.nodeId))),c=await Promise.all(e.manifest.dynamicTools.map(t=>resolveDynamicToolDefinition(t,e.moduleMap,e.nodeId))),l=await Promise.all(e.manifest.hooks.map(t=>resolveHookDefinition(t,e.moduleMap,e.nodeId))),u=await Promise.all(e.manifest.connections.map(t=>resolveConnectionDefinition(t,e.moduleMap,e.nodeId))),d=e.manifest.sandbox===null?null:await resolveSandboxDefinition(e.manifest.sandbox,e.moduleMap,e.nodeId),f=createResolvedInstructionsDefinition(e.manifest.instructions),p=e.manifest.workspaceResourceRoot,m={channels:r,config:createResolvedAgentConfig(e.manifest),connections:u,disabledFrameworkChannels:i,disabledFrameworkTools:[...e.manifest.disabledFrameworkTools],workflowTool:e.manifest.workflowTool===void 0?void 0:{maxSubagents:e.manifest.workflowTool.maxSubagents},dynamicInstructionsResolvers:o,dynamicSkillResolvers:s,dynamicToolResolvers:c,hooks:l,metadata:{agentRoot:e.manifest.agentRoot,appRoot:e.manifest.appRoot,diagnosticsSummary:e.manifest.diagnosticsSummary},sandbox:d,workspaceResourceRoot:p,skills:t,tools:a,workspaceSpec:{rootEntries:[...p.rootEntries]}};return f===void 0?m:{...m,instructions:f}}function createResolvedInstructionsDefinition(e){if(e!==void 0)return{name:e.name,logicalPath:e.logicalPath,markdown:e.markdown,sourceId:e.sourceId,sourceKind:e.sourceKind}}function createResolvedAgentConfig(e){let n={model:e.config.model.source===void 0?{id:e.config.model.id,contextWindowTokens:e.config.model.contextWindowTokens,providerOptions:e.config.model.providerOptions}:{contextWindowTokens:e.config.model.contextWindowTokens,id:e.config.model.id,providerOptions:e.config.model.providerOptions,source:{exportName:e.config.model.source.exportName,sourceKind:`module`,logicalPath:e.config.model.source.logicalPath,sourceId:e.config.model.source.sourceId}},name:e.config.name};if(e.config.compaction!==void 0){let t={};e.config.compaction.model!==void 0&&(t.model=e.config.compaction.model.source===void 0?{contextWindowTokens:e.config.compaction.model.contextWindowTokens,id:e.config.compaction.model.id,providerOptions:e.config.compaction.model.providerOptions}:{contextWindowTokens:e.config.compaction.model.contextWindowTokens,id:e.config.compaction.model.id,providerOptions:e.config.compaction.model.providerOptions,source:{exportName:e.config.compaction.model.source.exportName,sourceKind:`module`,logicalPath:e.config.compaction.model.source.logicalPath,sourceId:e.config.compaction.model.source.sourceId}}),e.config.compaction.thresholdPercent!==void 0&&(t.thresholdPercent=e.config.compaction.thresholdPercent),n.compaction=t}return e.config.dynamicModel!==void 0&&(n.dynamicModel={...createResolvedModuleSourceRef(e.config.dynamicModel),eventNames:[...e.config.dynamicModel.eventNames]}),e.config.experimental!==void 0&&(n.experimental={workflow:e.config.experimental.workflow===void 0?void 0:{world:e.config.experimental.workflow.world}}),e.config.outputSchema!==void 0&&(n.outputSchema=e.config.outputSchema),e.config.reasoning!==void 0&&(n.reasoning=e.config.reasoning),e.config.source!==void 0&&(n.source=createResolvedModuleSourceRef(e.config.source)),e.config.limits!==void 0&&(n.limits={maxInputTokensPerSession:e.config.limits.maxInputTokensPerSession,maxOutputTokensPerSession:e.config.limits.maxOutputTokensPerSession}),n}export{ResolveAgentError,resolveAgent};
|
|
@@ -331,13 +331,13 @@ export interface ResolvedAgent {
|
|
|
331
331
|
*/
|
|
332
332
|
readonly disabledFrameworkTools: readonly string[];
|
|
333
333
|
/**
|
|
334
|
-
*
|
|
335
|
-
*
|
|
336
|
-
* `
|
|
337
|
-
* whose only callable operations are this agent's subagents and remote
|
|
338
|
-
* agents.
|
|
334
|
+
* Configuration for the experimental framework `Workflow` orchestration
|
|
335
|
+
* tool. Present when an authored tool module exports
|
|
336
|
+
* `experimental_workflow(...)`.
|
|
339
337
|
*/
|
|
340
|
-
readonly
|
|
338
|
+
readonly workflowTool?: {
|
|
339
|
+
readonly maxSubagents?: number;
|
|
340
|
+
};
|
|
341
341
|
readonly dynamicInstructionsResolvers: readonly ResolvedDynamicInstructionsResolver[];
|
|
342
342
|
readonly dynamicSkillResolvers: readonly ResolvedDynamicSkillResolver[];
|
|
343
343
|
readonly dynamicToolResolvers: readonly ResolvedDynamicToolResolver[];
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{pinnedNodeEngineMajor}from"../../node-engine.js";import{pathExists,writeTextFile}from"../files.js";import{resolveVersionToken}from"../version-tokens.js";import{applyPackageManagerWorkspaceConfiguration,isPackageManagerWorkspaceMember,patchWorkspaceRootPackageJson}from"../workspace-root.js";import{SUPPORTED_AUTHORED_MODULE_FILE_EXTENSIONS}from"../update/module-files.js";import{WEB_APP_TEMPLATE_FILES}from"./web-template.js";import{basename,join,resolve}from"node:path";import{mkdir,readdir,stat}from"node:fs/promises";const CURRENT_DIRECTORY_PROJECT_NAME=`.`,ALLOWED_CREATE_IN_PLACE_ENTRIES=new Set([`.DS_Store`,`.git`,`.gitkeep`,`.hg`]),DEFAULT_AI_PACKAGE_VERSION=`^7.0.0`,DEFAULT_CONNECT_PACKAGE_VERSION=`0.2.2`,DEFAULT_ZOD_PACKAGE_VERSION=`4.4.3`,DEFAULT_EVE_PACKAGE_CONTRACT={version:`0.
|
|
1
|
+
import{pinnedNodeEngineMajor}from"../../node-engine.js";import{pathExists,writeTextFile}from"../files.js";import{resolveVersionToken}from"../version-tokens.js";import{applyPackageManagerWorkspaceConfiguration,isPackageManagerWorkspaceMember,patchWorkspaceRootPackageJson}from"../workspace-root.js";import{SUPPORTED_AUTHORED_MODULE_FILE_EXTENSIONS}from"../update/module-files.js";import{WEB_APP_TEMPLATE_FILES}from"./web-template.js";import{basename,join,resolve}from"node:path";import{mkdir,readdir,stat}from"node:fs/promises";const CURRENT_DIRECTORY_PROJECT_NAME=`.`,ALLOWED_CREATE_IN_PLACE_ENTRIES=new Set([`.DS_Store`,`.git`,`.gitkeep`,`.hg`]),DEFAULT_AI_PACKAGE_VERSION=`^7.0.0`,DEFAULT_CONNECT_PACKAGE_VERSION=`0.2.2`,DEFAULT_ZOD_PACKAGE_VERSION=`4.4.3`,DEFAULT_EVE_PACKAGE_CONTRACT={version:`0.24.0`,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__",
|
|
@@ -119,22 +119,6 @@ export interface PublicAgentCompactionDefinition {
|
|
|
119
119
|
* Configures framework-owned runtime limits for this agent's runs.
|
|
120
120
|
*/
|
|
121
121
|
export interface AgentLimitsDefinition {
|
|
122
|
-
/**
|
|
123
|
-
* Maximum number of subagent calls one `Workflow` tool invocation may
|
|
124
|
-
* dispatch.
|
|
125
|
-
*
|
|
126
|
-
* Applies to the opt-in `Workflow` orchestration tool: a single
|
|
127
|
-
* model-authored workflow program may spawn at most this many subagent or
|
|
128
|
-
* remote-agent calls, counted across the whole program (sequential and
|
|
129
|
-
* parallel calls alike). Calls beyond the limit fail with an error result
|
|
130
|
-
* instead of starting a child session.
|
|
131
|
-
*
|
|
132
|
-
* Delegated subagent sessions resolve this against the cap inherited from
|
|
133
|
-
* the delegating parent; the tighter value wins.
|
|
134
|
-
*
|
|
135
|
-
* @default 100
|
|
136
|
-
*/
|
|
137
|
-
readonly maxSubagents?: number;
|
|
138
122
|
/**
|
|
139
123
|
* Maximum provider-reported input tokens accumulated by one durable session.
|
|
140
124
|
*
|
|
@@ -7,6 +7,8 @@ import type { HandleMessageStreamEvent } from "#protocol/message.js";
|
|
|
7
7
|
type ToolContext = SessionContext & {
|
|
8
8
|
/** Aborts when the active turn is cancelled. */
|
|
9
9
|
readonly abortSignal: AbortSignal;
|
|
10
|
+
/** Final runtime name of the current tool. */
|
|
11
|
+
readonly toolName: string;
|
|
10
12
|
};
|
|
11
13
|
/**
|
|
12
14
|
* Stream event types allowed for dynamic tool resolvers. Dispatch
|
package/docs/agent-config.md
CHANGED
|
@@ -203,14 +203,14 @@ installed package must stay external in hosted output, list it in
|
|
|
203
203
|
|
|
204
204
|
`defineAgent` takes a few more fields, all optional. For the exported types, see the [TypeScript API](./reference/typescript-api).
|
|
205
205
|
|
|
206
|
-
| Field | Type | Default | Description
|
|
207
|
-
| -------------- | --------------------------------------- | ---------------- |
|
|
208
|
-
| `reasoning` | `AgentReasoningDefinition` | provider default | Provider-agnostic reasoning effort forwarded to the agent's turn model calls.
|
|
209
|
-
| `modelOptions` | `AgentModelOptionsDefinition` | none | Provider option overrides forwarded to the model call.
|
|
210
|
-
| `limits` | `AgentLimitsDefinition` | field-specific | Framework-owned runtime limits. `maxInputTokensPerSession` defaults to `40_000_000` for root sessions, and delegated subagent sessions inherit the parent's remaining quota; `maxOutputTokensPerSession` is unset unless configured; `false` uncaps a session token limit.
|
|
211
|
-
| `experimental` | `{ workflow?: { world?: string } }` | unset | Opt-in settings that can change or disappear in any release. Treat them as unstable. `workflow.world` selects the Workflow world package backing session state, queues, hooks, and streams on the root agent.
|
|
212
|
-
| `outputSchema` | Standard Schema or a JSON Schema object | none | Structured return type for task-mode runs (a subagent, schedule, or remote job). Interactive conversation turns ignore it unless the client supplies a per-message schema.
|
|
213
|
-
| `build` | `{ externalDependencies?: string[] }` | none | Hosted-build packaging controls. `externalDependencies` keeps listed packages external while eve compiles authored modules such as tools and channels, and traces those packages into the hosted output.
|
|
206
|
+
| Field | Type | Default | Description |
|
|
207
|
+
| -------------- | --------------------------------------- | ---------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
208
|
+
| `reasoning` | `AgentReasoningDefinition` | provider default | Provider-agnostic reasoning effort forwarded to the agent's turn model calls. |
|
|
209
|
+
| `modelOptions` | `AgentModelOptionsDefinition` | none | Provider option overrides forwarded to the model call. |
|
|
210
|
+
| `limits` | `AgentLimitsDefinition` | field-specific | Framework-owned runtime limits. `maxInputTokensPerSession` defaults to `40_000_000` for root sessions, and delegated subagent sessions inherit the parent's remaining quota; `maxOutputTokensPerSession` is unset unless configured; `false` uncaps a session token limit. |
|
|
211
|
+
| `experimental` | `{ workflow?: { world?: string } }` | unset | Opt-in settings that can change or disappear in any release. Treat them as unstable. `workflow.world` selects the Workflow world package backing session state, queues, hooks, and streams on the root agent. |
|
|
212
|
+
| `outputSchema` | Standard Schema or a JSON Schema object | none | Structured return type for task-mode runs (a subagent, schedule, or remote job). Interactive conversation turns ignore it unless the client supplies a per-message schema. |
|
|
213
|
+
| `build` | `{ externalDependencies?: string[] }` | none | Hosted-build packaging controls. `externalDependencies` keeps listed packages external while eve compiles authored modules such as tools and channels, and traces those packages into the hosted output. |
|
|
214
214
|
|
|
215
215
|
`externalDependencies` is a packaging control only. It keeps selected packages as runtime dependencies in the hosted output; it does not authorize, configure, or review any third-party service those packages may call.
|
|
216
216
|
|
package/docs/channels/teams.mdx
CHANGED
|
@@ -45,7 +45,11 @@ Replies post as Markdown (`textFormat: "markdown"`), with oversized text split a
|
|
|
45
45
|
|
|
46
46
|
### Human-in-the-loop (HITL)
|
|
47
47
|
|
|
48
|
-
A human-in-the-loop (HITL) `input.requested` event renders as an Adaptive Card. Buttons and options map to `Action.Submit`, selects to `Input.ChoiceSet`, and freeform to `Input.Text`.
|
|
48
|
+
A human-in-the-loop (HITL) `input.requested` event renders as an Adaptive Card. Approval cards show the tool input in the card and fallback text. Buttons and options map to `Action.Submit`, selects to `Input.ChoiceSet`, and freeform to `Input.Text`. Teams may return a submission as a message or invoke; eve handles both before the normal message mention gate and resumes the thread recorded in the card.
|
|
49
|
+
|
|
50
|
+
By default, submissions use the Teams identity of the user who clicked the card. If you customize `onMessage` for an allowlist, configure the same policy in `onInputResponse`; eve otherwise rejects HITL submissions rather than bypassing the message gate.
|
|
51
|
+
|
|
52
|
+
For invokes that aren't HITL, handle them in `onInvoke(ctx, activity)`.
|
|
49
53
|
|
|
50
54
|
### Proactive sessions
|
|
51
55
|
|
|
@@ -91,13 +91,15 @@ Three moves shape the harness. The right one depends on whether the model should
|
|
|
91
91
|
|
|
92
92
|
## The opt-in `Workflow` tool
|
|
93
93
|
|
|
94
|
-
An experimental `Workflow` tool ships but stays off by default. To turn it on,
|
|
94
|
+
An experimental `Workflow` tool ships but stays off by default. To turn it on, export its definition from `agent/tools/workflow.ts`:
|
|
95
95
|
|
|
96
96
|
```ts
|
|
97
|
-
|
|
97
|
+
import { experimental_workflow } from "eve/tools";
|
|
98
|
+
|
|
99
|
+
export default experimental_workflow({ maxSubagents: 100 });
|
|
98
100
|
```
|
|
99
101
|
|
|
100
|
-
With it on, the model can orchestrate the agent's own subagents from model-authored JavaScript, all as one durable step. The tool is root-only — delegated subagent sessions never see it — and one program may dispatch at most `
|
|
102
|
+
With it on, the model can orchestrate the agent's own subagents from model-authored JavaScript, all as one durable step. The tool is root-only — delegated subagent sessions never see it — and one program may dispatch at most the configured `maxSubagents` calls (default 100). See [Dynamic workflows](../guides/dynamic-workflows).
|
|
101
103
|
|
|
102
104
|
## What to read next
|
|
103
105
|
|
|
@@ -99,9 +99,9 @@ For a self-deployed process, leave `defaultBackend()` in place or choose an expl
|
|
|
99
99
|
|
|
100
100
|
## 5. Build-time sandbox prewarm
|
|
101
101
|
|
|
102
|
-
During
|
|
102
|
+
During Vercel-targeted builds, eve prewarms reusable Vercel sandbox templates so the first session doesn't pay the cold-start cost. This includes hosted builds and local `vercel build` runs:
|
|
103
103
|
|
|
104
|
-
- Prewarm runs
|
|
104
|
+
- Prewarm runs for hosted Vercel builds and linked local `vercel build` runs.
|
|
105
105
|
- A sandbox with no `bootstrap()` and no workspace seed files gets skipped.
|
|
106
106
|
- Seed-only templates are keyed by skills and workspace file contents, so unchanged seeds reuse a template across deploys.
|
|
107
107
|
- Templates with a `bootstrap()` are keyed by the optional resolved `revalidationKey()` plus the authored sandbox source and seed contents, so matching inputs reuse a template across deploys.
|
|
@@ -109,7 +109,7 @@ During hosted builds, eve prewarms reusable Vercel sandbox templates so the firs
|
|
|
109
109
|
- Prewarming only covers template construction. `onSession()` still runs at runtime, once per session.
|
|
110
110
|
- **If build-time prewarm fails, the build fails.**
|
|
111
111
|
|
|
112
|
-
|
|
112
|
+
Local builds must be linked to a Vercel project with credentials that can provision Vercel Sandbox templates. If authentication or template provisioning fails, eve fails the build rather than emitting output that would fail after deployment.
|
|
113
113
|
|
|
114
114
|
## 6. Auth
|
|
115
115
|
|
|
@@ -9,10 +9,12 @@ A single turn can already call several subagents, and parallel tool calls dispat
|
|
|
9
9
|
|
|
10
10
|
## Enable the Workflow tool
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
Export the experimental Workflow definition from `agent/tools/workflow.ts`. The helper name carries the "experimental" warning, but the tool the model actually sees is named `Workflow`.
|
|
13
13
|
|
|
14
14
|
```ts title="agent/tools/workflow.ts"
|
|
15
|
-
|
|
15
|
+
import { experimental_workflow } from "eve/tools";
|
|
16
|
+
|
|
17
|
+
export default experimental_workflow();
|
|
16
18
|
```
|
|
17
19
|
|
|
18
20
|
Without that file, the `Workflow` tool stays off. It earns its keep only when the agent has subagents (or the built-in `agent`) worth coordinating:
|
|
@@ -55,15 +57,12 @@ A workflow reaches only this agent's own agents: the built-in `agent` (a copy of
|
|
|
55
57
|
|
|
56
58
|
Workflow orchestration is capped in two independent ways.
|
|
57
59
|
|
|
58
|
-
**Per-program call budget.** One Workflow program may dispatch at most `
|
|
60
|
+
**Per-program call budget.** One Workflow program may dispatch at most `maxSubagents` subagent calls in total, counted across the whole program — sequential and parallel calls alike. Configure it on `experimental_workflow`; the default is 100. Calls beyond the budget do not start a child session; they resolve inside the program with a `WORKFLOW_SUBAGENT_LIMIT_REACHED` error result, and the budget is stated in the tool's description so the model sizes its fan-out to fit.
|
|
59
61
|
|
|
60
|
-
```ts title="agent/
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
maxSubagents: 4,
|
|
65
|
-
},
|
|
66
|
-
});
|
|
62
|
+
```ts title="agent/tools/workflow.ts"
|
|
63
|
+
import { experimental_workflow } from "eve/tools";
|
|
64
|
+
|
|
65
|
+
export default experimental_workflow({ maxSubagents: 4 });
|
|
67
66
|
```
|
|
68
67
|
|
|
69
68
|
**Root-only orchestration.** Only the root session receives `Workflow`. Children started by a workflow receive neither `Workflow` nor the built-in `agent`, so Workflow programs cannot recurse. A declared child can still call subagents defined in its own directory (see [Subagents](../subagents)).
|
package/docs/reference/cli.md
CHANGED
|
@@ -93,7 +93,7 @@ Run this first when something behaves unexpectedly. It confirms a file was disco
|
|
|
93
93
|
eve build
|
|
94
94
|
```
|
|
95
95
|
|
|
96
|
-
|
|
96
|
+
Compiles to `.eve/` and builds the host output, then prints the built output path.
|
|
97
97
|
|
|
98
98
|
Useful artifacts written under `.eve/` (preserved even on partial failure):
|
|
99
99
|
|
|
@@ -52,7 +52,7 @@ export default defineTool({
|
|
|
52
52
|
| `mockModel` | `eve/evals` | Deterministic fixture agent models | [Evals](../evals/overview) |
|
|
53
53
|
| `useEveAgent` | `eve/react`, `eve/vue`, `eve/svelte` | frontend | [Frontend](../guides/frontend/overview) |
|
|
54
54
|
|
|
55
|
-
A few non-`define*` helpers round out the set: `disableTool` and `
|
|
55
|
+
A few non-`define*` helpers round out the set: `disableTool` and `experimental_workflow` from `eve/tools` (see [Default harness](../concepts/default-harness)), the route verbs `GET`/`POST`/`PUT`/`PATCH`/`DELETE`/`WS` from `eve/channels`, the approval policies `always`/`once`/`never` from `eve/tools/approval`, and the channel auth helpers `localDev`/`vercelOidc`/`placeholderAuth` from `eve/channels/auth`. To wrap a built-in tool, import its default value from `eve/tools/defaults` (`bash`, `readFile`, `writeFile`, `glob`, `grep`, `webFetch`, `webSearch`, `todo`, `loadSkill`). `AgentReasoningDefinition` is exported from `eve` for the top-level `defineAgent({ reasoning })` setting. `AgentLimitsDefinition` is exported for `defineAgent({ limits })`. `AgentWorkflowDefinition` and `AgentWorkflowWorldDefinition` are exported from `eve` for the `defineAgent({ experimental: { workflow } })` config shape. `ExperimentalWorkflowToolInput` is exported from `eve/tools` for the `experimental_workflow(...)` config shape.
|
|
56
56
|
|
|
57
57
|
## Runtime context (`ctx`)
|
|
58
58
|
|
|
@@ -68,32 +68,32 @@ A few non-`define*` helpers round out the set: `disableTool` and `ExperimentalWo
|
|
|
68
68
|
|
|
69
69
|
## Imports at a glance
|
|
70
70
|
|
|
71
|
-
| Import | Holds
|
|
72
|
-
| ----------------------------------------------------------- |
|
|
73
|
-
| `eve` | `defineAgent`, `defineRemoteAgent`, agent config types
|
|
74
|
-
| `eve/tools` | `defineTool`, `defineDynamic`, `disableTool`, `
|
|
75
|
-
| `eve/tools/defaults` | the built-in tools as plain values
|
|
76
|
-
| `eve/tools/approval` | `always`, `once`, `never`
|
|
77
|
-
| `eve/connections` | `defineMcpClientConnection`, `defineOpenAPIConnection`
|
|
78
|
-
| `eve/channels` | `defineChannel`, route verbs
|
|
79
|
-
| `eve/channels/eve` | `eveChannel`
|
|
80
|
-
| `eve/channels/auth` | `localDev`, `vercelOidc`, `placeholderAuth`
|
|
81
|
-
| `eve/channels/{slack,discord,teams,telegram,twilio,github}` | platform channel factories
|
|
82
|
-
| `eve/hooks` | `defineHook`
|
|
83
|
-
| `eve/schedules` | `defineSchedule`
|
|
84
|
-
| `eve/skills` | `defineSkill`, `defineDynamic`
|
|
85
|
-
| `eve/instructions` | `defineInstructions`, `defineDynamic`
|
|
86
|
-
| `eve/context` | `defineState`, session and state types
|
|
87
|
-
| `eve/sandbox` | `defineSandbox`, backends
|
|
88
|
-
| `eve/instrumentation` | `defineInstrumentation`, `isChannel`
|
|
89
|
-
| `eve/models/openai` | `experimental_chatgpt`
|
|
90
|
-
| `eve/evals` | `defineEval`, `defineEvalConfig`, `mockModel`, eval types
|
|
91
|
-
| `eve/evals/expect` | `includes`, `equals`, `matches`, `similarity`
|
|
92
|
-
| `eve/evals/reporters` | `Braintrust`, `JUnit`, `EvalReporter`
|
|
93
|
-
| `eve/evals/loaders` | `loadJson`, `loadYaml`
|
|
94
|
-
| `eve/react`, `eve/vue`, `eve/svelte` | `useEveAgent`
|
|
95
|
-
| `eve/next`, `eve/nuxt`, `eve/sveltekit` | framework bundler plugins
|
|
96
|
-
| [`eve/client`](../guides/client/overview) | `Client`, `ClientSession`
|
|
71
|
+
| Import | Holds |
|
|
72
|
+
| ----------------------------------------------------------- | --------------------------------------------------------------------- |
|
|
73
|
+
| `eve` | `defineAgent`, `defineRemoteAgent`, agent config types |
|
|
74
|
+
| `eve/tools` | `defineTool`, `defineDynamic`, `disableTool`, `experimental_workflow` |
|
|
75
|
+
| `eve/tools/defaults` | the built-in tools as plain values |
|
|
76
|
+
| `eve/tools/approval` | `always`, `once`, `never` |
|
|
77
|
+
| `eve/connections` | `defineMcpClientConnection`, `defineOpenAPIConnection` |
|
|
78
|
+
| `eve/channels` | `defineChannel`, route verbs |
|
|
79
|
+
| `eve/channels/eve` | `eveChannel` |
|
|
80
|
+
| `eve/channels/auth` | `localDev`, `vercelOidc`, `placeholderAuth` |
|
|
81
|
+
| `eve/channels/{slack,discord,teams,telegram,twilio,github}` | platform channel factories |
|
|
82
|
+
| `eve/hooks` | `defineHook` |
|
|
83
|
+
| `eve/schedules` | `defineSchedule` |
|
|
84
|
+
| `eve/skills` | `defineSkill`, `defineDynamic` |
|
|
85
|
+
| `eve/instructions` | `defineInstructions`, `defineDynamic` |
|
|
86
|
+
| `eve/context` | `defineState`, session and state types |
|
|
87
|
+
| `eve/sandbox` | `defineSandbox`, backends |
|
|
88
|
+
| `eve/instrumentation` | `defineInstrumentation`, `isChannel` |
|
|
89
|
+
| `eve/models/openai` | `experimental_chatgpt` |
|
|
90
|
+
| `eve/evals` | `defineEval`, `defineEvalConfig`, `mockModel`, eval types |
|
|
91
|
+
| `eve/evals/expect` | `includes`, `equals`, `matches`, `similarity` |
|
|
92
|
+
| `eve/evals/reporters` | `Braintrust`, `JUnit`, `EvalReporter` |
|
|
93
|
+
| `eve/evals/loaders` | `loadJson`, `loadYaml` |
|
|
94
|
+
| `eve/react`, `eve/vue`, `eve/svelte` | `useEveAgent` |
|
|
95
|
+
| `eve/next`, `eve/nuxt`, `eve/sveltekit` | framework bundler plugins |
|
|
96
|
+
| [`eve/client`](../guides/client/overview) | `Client`, `ClientSession` |
|
|
97
97
|
|
|
98
98
|
Exported types ship from the same entrypoint as the helper they describe (for example `ToolDefinition` and `ToolContext` from `eve/tools`). For the exhaustive list, read `packages/eve/src/public/index.ts`.
|
|
99
99
|
|
package/docs/subagents.mdx
CHANGED
|
@@ -81,7 +81,7 @@ eve lowers every subagent visible to the current agent (the root built-in copy,
|
|
|
81
81
|
|
|
82
82
|
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.
|
|
83
83
|
|
|
84
|
-
`Workflow` is also root-only. Child sessions can still call their own declared or remote subagents, but they receive neither `Workflow` nor the built-in `agent`. `
|
|
84
|
+
`Workflow` is also root-only. Child sessions can still call their own declared or remote subagents, but they receive neither `Workflow` nor the built-in `agent`. The Workflow tool's `maxSubagents` option caps the number of calls made by one program (default 100); see [Dynamic workflows](./guides/dynamic-workflows).
|
|
85
85
|
|
|
86
86
|
A declared subagent's tool name is the bare path-derived name, with no prefix. `agent/subagents/researcher/` registers as the tool `researcher`. Unlike connection tools (`<connection>__<tool>`), it carries no namespace, so the model, approvals, logs, and evals all reference it by that name. Its input schema is:
|
|
87
87
|
|
package/docs/tools/overview.mdx
CHANGED
|
@@ -38,6 +38,7 @@ When a tool returns structured data, add an optional `outputSchema`. With Zod or
|
|
|
38
38
|
|
|
39
39
|
- `ctx.session`: session metadata, turn, auth, parent lineage.
|
|
40
40
|
- `ctx.callId`: the id of the current tool call, carried by the call's [stream events](/docs/concepts/sessions-runs-and-streaming) and approval context.
|
|
41
|
+
- `ctx.toolName`: the final runtime name the model called, including any namespace qualification.
|
|
41
42
|
- `ctx.abortSignal`: aborts when the active turn is cancelled. Pass it to cancellation-aware work; sandbox sessions from `ctx.getSandbox()` are already bound to it.
|
|
42
43
|
- `ctx.getSandbox()`: the live [sandbox](/docs/sandbox) handle.
|
|
43
44
|
- `ctx.getSkill(id)`: read a packaged [skill](/docs/skills)'s metadata and files.
|