eve 0.71.0 → 0.71.2
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 +24 -0
- package/dist/src/channel/agent-description.d.ts +33 -0
- package/dist/src/channel/agent-description.js +1 -0
- package/dist/src/channel/resolved-prompt.d.ts +12 -0
- package/dist/src/channel/resolved-prompt.js +1 -0
- package/dist/src/channel/routes.d.ts +7 -0
- package/dist/src/channel/tool-eligibility.d.ts +39 -0
- package/dist/src/channel/tool-eligibility.js +1 -0
- package/dist/src/cli/dev/tui/transcript.js +1 -1
- package/dist/src/compiled/.vendor-stamp.json +1 -1
- package/dist/src/compiled/@ai-sdk/mcp/index.js +1 -1
- package/dist/src/compiled/@modelcontextprotocol/server/index.d.ts +18 -0
- package/dist/src/compiler/extension-compatibility.d.ts +2 -2
- package/dist/src/compiler/extension-compatibility.js +1 -1
- package/dist/src/context/serialize.js +1 -1
- package/dist/src/eve-channel/request.js +1 -1
- package/dist/src/execution/cancelled-model-call-batch.js +1 -1
- package/dist/src/execution/dynamic-workflow/tool.js +1 -1
- package/dist/src/execution/proxied-deliver-step.js +1 -1
- package/dist/src/execution/publish-session-events.d.ts +5 -4
- package/dist/src/execution/publish-session-events.js +1 -1
- package/dist/src/execution/sandbox/bindings/docker-templates.d.ts +1 -1
- package/dist/src/execution/sandbox/bindings/docker-templates.js +1 -1
- package/dist/src/execution/sandbox/bindings/docker.js +1 -1
- package/dist/src/execution/sandbox/ensure.js +1 -1
- package/dist/src/execution/sandbox/prewarm.js +1 -1
- package/dist/src/execution/sandbox/read-file.js +3 -3
- package/dist/src/execution/session/handoff-steps.js +1 -1
- package/dist/src/execution/tools/agent-router-workflow.js +1 -1
- package/dist/src/internal/application/package.js +1 -1
- package/dist/src/internal/attachments/media-metadata.d.ts +2 -0
- package/dist/src/internal/attachments/media-metadata.js +1 -1
- package/dist/src/internal/authored-definition/source-identity.d.ts +17 -8
- package/dist/src/internal/authored-definition/source-identity.js +1 -1
- package/dist/src/internal/authored-module-map-loader.js +1 -1
- package/dist/src/internal/mcp/streamable-http-server.js +1 -1
- package/dist/src/internal/nitro/routes/channel-dispatch.d.ts +1 -1
- package/dist/src/internal/nitro/routes/channel-dispatch.js +1 -1
- package/dist/src/internal/workflow/cancel-expired-development-run.js +1 -1
- package/dist/src/internal/workflow/development-world-client.js +1 -1
- package/dist/src/public/channels/chat-sdk/chatSdkChannel.d.ts +9 -0
- package/dist/src/public/channels/chat-sdk/chatSdkChannel.js +1 -1
- package/dist/src/public/channels/chat-sdk/input-actions.d.ts +4 -2
- package/dist/src/public/channels/chat-sdk/input-actions.js +1 -1
- package/dist/src/public/channels/discord/defaults.js +1 -1
- package/dist/src/public/channels/discord/discordChannel.d.ts +10 -0
- package/dist/src/public/channels/discord/discordChannel.js +1 -1
- package/dist/src/public/channels/discord/hitl.js +1 -1
- package/dist/src/public/channels/index.d.ts +1 -1
- package/dist/src/public/channels/slack/connections.d.ts +11 -11
- package/dist/src/public/channels/slack/connections.js +1 -1
- package/dist/src/public/channels/slack/defaults.js +1 -1
- package/dist/src/public/channels/teams/defaults.js +2 -2
- package/dist/src/public/channels/teams/teamsChannel.d.ts +8 -3
- package/dist/src/public/channels/teams/teamsChannel.js +1 -1
- package/dist/src/public/channels/telegram/defaults.d.ts +5 -2
- package/dist/src/public/channels/telegram/defaults.js +1 -1
- package/dist/src/public/channels/telegram/hitl.d.ts +23 -1
- package/dist/src/public/channels/telegram/hitl.js +2 -2
- package/dist/src/public/channels/telegram/telegramChannel.d.ts +1 -0
- package/dist/src/public/channels/telegram/telegramChannel.js +1 -1
- package/dist/src/public/channels/twilio/defaults.d.ts +1 -1
- package/dist/src/public/channels/twilio/defaults.js +4 -2
- package/dist/src/public/definitions/channel.d.ts +1 -0
- package/dist/src/public/tools/result.js +1 -1
- package/dist/src/runtime/resolve-connection.js +1 -1
- package/dist/src/runtime/resolve-dynamic-tool.js +1 -1
- package/dist/src/runtime/resolve-tool.js +1 -1
- package/dist/src/runtime/sessions/compiled-agent-cache.js +1 -1
- package/dist/src/setup/scaffold/create/project.js +1 -1
- package/dist/src/subagents/hitl-proxy.d.ts +2 -0
- package/dist/src/subagents/hitl-proxy.js +1 -1
- package/dist/src/tools/provided/ask-question-workflow.js +1 -1
- package/dist/src/tools/provided/read-file.js +1 -1
- package/dist/src/tools/provided/sleep-workflow.js +1 -1
- package/docs/channels/custom.mdx +1 -0
- package/docs/concepts/built-in-tools.md +1 -1
- package/docs/concepts/sessions-runs-and-streaming.md +1 -1
- package/docs/extensions.md +1 -1
- package/docs/guides/hooks.md +2 -0
- package/package.json +1 -1
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{createLogger,extractErrorId,formatErrorHint}from"#internal/logging.js";import{formatTelegramAuthorizationDisplayName,renderTelegramAuthorizationCompleted,renderTelegramAuthorizationPrompt,renderTelegramAuthorizationStatus}from"#public/channels/telegram/authorization.js";import{registerTelegramFreeformPrompt,renderTelegramInputRequest}from"#public/channels/telegram/hitl.js";const log=createLogger(`telegram.defaults`);function defaultTelegramAuth(e){let t=e.from;if(!t)return null;let n={chat_id:e.chat.id,chat_type:e.chat.type,message_id:e.messageId,user_id:t.id};e.chat.title!==void 0&&(n.chat_title=e.chat.title),e.messageThreadId!==void 0&&(n.message_thread_id=String(e.messageThreadId)),t.username!==void 0&&(n.username=t.username);let r=e.chat.type===`group`||e.chat.type===`supergroup`,i=r?`telegram:${e.chat.id}:${t.id}`:`telegram:${t.id}`;return{attributes:n,authenticator:`telegram-webhook`,issuer:r?`telegram:${e.chat.id}`:`telegram`,principalId:i,principalType:t.isBot?`service`:`user`}}async function defaultOnMessage(e,t){return shouldDispatchTelegramMessage(t,e.telegram.botUsername)?(await e.telegram.startTyping(),{auth:defaultTelegramAuth(t)}):null}function isTelegramBotMentioned(e,t){if(t===void 0)return!1;let n=e.text||e.caption;if(isTargetedBotCommand(n,t))return!0;let r=t.replace(/[.*+?^${}()|[\]\\]/gu,`\\$&`);return RegExp(`(?:^|[^A-Za-z0-9_])@${r}(?=$|[^A-Za-z0-9_])`,`iu`).test(n)}const defaultEvents={async"turn.started"(e,t,n){await t.telegram.startTyping()},async"authorization.required"(e,t,n){if(e.candidateId!==void 0)return;let r=formatTelegramAuthorizationDisplayName(e.name,e.authorization?.displayName),i=t.telegram.chatType===`private`,a=t.state.pendingAuthMessageIds??{};if(i){try{let n=await t.telegram.post(renderTelegramAuthorizationPrompt(e));n.id&&(t.state.pendingAuthMessageIds={...a,[e.name]:n.id})}catch(t){log.error(`Telegram authorization prompt delivery failed`,{error:t,name:e.name})}return}if(a[e.name]===void 0)try{let n=await t.telegram.post(renderTelegramAuthorizationStatus({displayName:r,requesterUserId:t.state.triggeringUserId}));n.id&&(t.state.pendingAuthMessageIds={...a,[e.name]:n.id})}catch(t){log.error(`Telegram authorization status delivery failed`,{error:t,name:e.name})}},async"authorization.completed"(e,t,n){if(e.outcome===`authorized`&&e.candidateId===void 0&&await t.telegram.startTyping(),e.candidateId!==void 0)return;let r=t.state.pendingAuthMessageIds??{},i=r[e.name];if(i===void 0)return;let a=formatTelegramAuthorizationDisplayName(e.name,e.authorization?.displayName);try{await t.telegram.editMessageText({messageId:i,replyMarkup:{inline_keyboard:[]},text:renderTelegramAuthorizationCompleted({displayName:a,outcome:e.outcome,reason:e.reason})})}catch(t){log.error(`Telegram authorization status edit failed`,{error:t,name:e.name})}let o={...r};delete o[e.name],t.state.pendingAuthMessageIds=o},async"actions.requested"(e,t,n){await t.telegram.startTyping()},async"input.requested"(e,t,n){for(let n of e.requests){let e=renderTelegramInputRequest(n,t.state),r=await t.telegram.post({reply_markup:e.replyMarkup,text:e.text});e.freeformRequestId
|
|
1
|
+
import{createLogger,extractErrorId,formatErrorHint}from"#internal/logging.js";import{formatTelegramAuthorizationDisplayName,renderTelegramAuthorizationCompleted,renderTelegramAuthorizationPrompt,renderTelegramAuthorizationStatus}from"#public/channels/telegram/authorization.js";import{registerTelegramFreeformPrompt,registerTelegramHitlPrompt,renderTelegramInputRequest,takeTelegramResolvedPrompt}from"#public/channels/telegram/hitl.js";const log=createLogger(`telegram.defaults`);function defaultTelegramAuth(e){let t=e.from;if(!t)return null;let n={chat_id:e.chat.id,chat_type:e.chat.type,message_id:e.messageId,user_id:t.id};e.chat.title!==void 0&&(n.chat_title=e.chat.title),e.messageThreadId!==void 0&&(n.message_thread_id=String(e.messageThreadId)),t.username!==void 0&&(n.username=t.username);let r=e.chat.type===`group`||e.chat.type===`supergroup`,i=r?`telegram:${e.chat.id}:${t.id}`:`telegram:${t.id}`;return{attributes:n,authenticator:`telegram-webhook`,issuer:r?`telegram:${e.chat.id}`:`telegram`,principalId:i,principalType:t.isBot?`service`:`user`}}async function defaultOnMessage(e,t){return shouldDispatchTelegramMessage(t,e.telegram.botUsername)?(await e.telegram.startTyping(),{auth:defaultTelegramAuth(t)}):null}function isTelegramBotMentioned(e,t){if(t===void 0)return!1;let n=e.text||e.caption;if(isTargetedBotCommand(n,t))return!0;let r=t.replace(/[.*+?^${}()|[\]\\]/gu,`\\$&`);return RegExp(`(?:^|[^A-Za-z0-9_])@${r}(?=$|[^A-Za-z0-9_])`,`iu`).test(n)}const defaultEvents={async"turn.started"(e,t,n){await t.telegram.startTyping()},async"authorization.required"(e,t,n){if(e.candidateId!==void 0)return;let r=formatTelegramAuthorizationDisplayName(e.name,e.authorization?.displayName),i=t.telegram.chatType===`private`,a=t.state.pendingAuthMessageIds??{};if(i){try{let n=await t.telegram.post(renderTelegramAuthorizationPrompt(e));n.id&&(t.state.pendingAuthMessageIds={...a,[e.name]:n.id})}catch(t){log.error(`Telegram authorization prompt delivery failed`,{error:t,name:e.name})}return}if(a[e.name]===void 0)try{let n=await t.telegram.post(renderTelegramAuthorizationStatus({displayName:r,requesterUserId:t.state.triggeringUserId}));n.id&&(t.state.pendingAuthMessageIds={...a,[e.name]:n.id})}catch(t){log.error(`Telegram authorization status delivery failed`,{error:t,name:e.name})}},async"authorization.completed"(e,t,n){if(e.outcome===`authorized`&&e.candidateId===void 0&&await t.telegram.startTyping(),e.candidateId!==void 0)return;let r=t.state.pendingAuthMessageIds??{},i=r[e.name];if(i===void 0)return;let a=formatTelegramAuthorizationDisplayName(e.name,e.authorization?.displayName);try{await t.telegram.editMessageText({messageId:i,replyMarkup:{inline_keyboard:[]},text:renderTelegramAuthorizationCompleted({displayName:a,outcome:e.outcome,reason:e.reason})})}catch(t){log.error(`Telegram authorization status edit failed`,{error:t,name:e.name})}let o={...r};delete o[e.name],t.state.pendingAuthMessageIds=o},async"actions.requested"(e,t,n){await t.telegram.startTyping()},async"input.requested"(e,t,n){for(let n of e.requests){let e=renderTelegramInputRequest(n,t.state),r=await t.telegram.post({reply_markup:e.replyMarkup,text:e.text});r.id&&(e.freeformRequestId===void 0?registerTelegramHitlPrompt(t.state,n,{messageId:r.id,text:e.text}):registerTelegramFreeformPrompt(t.state,{messageId:r.id,requestId:e.freeformRequestId}))}},async"input.resolved"(e,t,n){for(let n of e.resolutions){let e=takeTelegramResolvedPrompt(t.state,n);if(e!==void 0)try{await t.telegram.editMessageText({...e,replyMarkup:{inline_keyboard:[]}})}catch(e){log.warn(`Telegram answered prompt edit failed`,{error:e,requestId:n.requestId})}}},async"message.completed"(e,t,n){e.finishReason!==`tool-calls`&&e.message&&await t.telegram.post(e.message)},async"turn.failed"(e,t,n){let r=formatErrorHint(e),i=extractErrorId(e.details);await t.telegram.post([`I hit an error while handling your request${r}.`,``,`Please try again, rephrase, or reach out if it keeps failing.`,...i?[``,`Error id: ${i}`]:[]].join(`
|
|
2
2
|
`))},async"session.failed"(e,t){let n=formatErrorHint(e),r=extractErrorId(e.details);await t.telegram.post([`This session could not recover from an error${n}.`,``,`Start a new message to continue.`,...r?[``,`Error id: ${r}`]:[]].join(`
|
|
3
3
|
`))}};function shouldDispatchTelegramMessage(e,t){if(e.from?.isBot===!0||e.chat.type===`channel`)return!1;let n=e.text||e.caption;return n.trim().length>0||e.attachments.length>0?!!(e.chat.type===`private`||e.replyToMessage?.from?.isBot===!0||isBotCommand(n,t)||t!==void 0&&mentionsBotUsername(n,t)):!1}function isBotCommand(e,t){let n=/^\/(?<command>[A-Za-z0-9_]+)(?:@(?<target>[A-Za-z0-9_]+))?(?:\s|$)/u.exec(e);if(!n)return!1;let r=n.groups?.target;return r===void 0||t!==void 0&&r.toLowerCase()===t.toLowerCase()}function isTargetedBotCommand(e,t){return/^\/[A-Za-z0-9_]+@(?<target>[A-Za-z0-9_]+)(?:\s|$)/u.exec(e)?.groups?.target?.toLowerCase()===t.toLowerCase()}function mentionsBotUsername(e,t){return e.toLowerCase().includes(`@${t.toLowerCase()}`)}export{defaultEvents,defaultOnMessage,defaultTelegramAuth,isTelegramBotMentioned};
|
|
@@ -6,7 +6,8 @@
|
|
|
6
6
|
* them back to full input responses inside the channel deliver hook.
|
|
7
7
|
*/
|
|
8
8
|
import type { UserContent } from "ai";
|
|
9
|
-
import
|
|
9
|
+
import type { InputResolution } from "#protocol/message.js";
|
|
10
|
+
import { type InputOption, type InputRequest, type InputResponse, type ValidatedInputResponse } from "#shared/input.js";
|
|
10
11
|
/** Prefix used in Telegram callback_data values generated by eve. */
|
|
11
12
|
export declare const TELEGRAM_HITL_CALLBACK_PREFIX = "eve:";
|
|
12
13
|
/** Synthetic request id prefix sent through `send()` for callback queries. */
|
|
@@ -23,6 +24,14 @@ export interface TelegramHitlState {
|
|
|
23
24
|
hitlCallbacks?: Record<string, InputResponse>;
|
|
24
25
|
nextHitlCallbackId?: number;
|
|
25
26
|
pendingFreeformReplies?: Record<string, string>;
|
|
27
|
+
/** Posted prompts with inline keyboards, keyed by requestId, until eve resolves them. */
|
|
28
|
+
hitlPrompts?: Record<string, TelegramHitlPrompt>;
|
|
29
|
+
}
|
|
30
|
+
/** What a posted prompt needs so its message can be edited once eve resolves it. */
|
|
31
|
+
export interface TelegramHitlPrompt {
|
|
32
|
+
readonly messageId: string;
|
|
33
|
+
readonly options: readonly Pick<InputOption, "id" | "label">[];
|
|
34
|
+
readonly text: string;
|
|
26
35
|
}
|
|
27
36
|
/**
|
|
28
37
|
* Rendered Telegram message body for one pending input request.
|
|
@@ -42,6 +51,19 @@ export declare function registerTelegramFreeformPrompt(state: TelegramHitlState,
|
|
|
42
51
|
readonly messageId: string;
|
|
43
52
|
readonly requestId: string;
|
|
44
53
|
}): void;
|
|
54
|
+
/** Records a posted inline-keyboard prompt so {@link takeTelegramResolvedPrompt} can edit it. */
|
|
55
|
+
export declare function registerTelegramHitlPrompt(state: TelegramHitlState, request: InputRequest, posted: {
|
|
56
|
+
readonly messageId: string;
|
|
57
|
+
readonly text: string;
|
|
58
|
+
}): void;
|
|
59
|
+
/**
|
|
60
|
+
* Forgets a resolved prompt, returning the edit that
|
|
61
|
+
* replaces its keyboard with the outcome, or `undefined` when eve never posted it.
|
|
62
|
+
*/
|
|
63
|
+
export declare function takeTelegramResolvedPrompt(state: TelegramHitlState, resolution: InputResolution): {
|
|
64
|
+
readonly messageId: string;
|
|
65
|
+
readonly text: string;
|
|
66
|
+
} | undefined;
|
|
45
67
|
/**
|
|
46
68
|
* Wraps Telegram callback data as a synthetic `InputResponse` (requestId prefixed
|
|
47
69
|
* with `telegram_callback:`, optionId hardcoded to `"selected"`). It is a
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{parseInputResponse,parseInputResponses}from"#shared/input.js";const TELEGRAM_HITL_CALLBACK_PREFIX=`eve:`,TELEGRAM_CALLBACK_RESPONSE_PREFIX=`telegram_callback:`,TELEGRAM_REPLY_RESPONSE_PREFIX=`telegram_reply:`,TELEGRAM_PROMPT_MAX_LENGTH=4e3;function renderTelegramInputRequest(e,t){let n=e.options;return n&&n.length>0?{replyMarkup:{inline_keyboard:chunk(n.map(n=>({callback_data:registerTelegramCallback(t,{optionId:n.id,requestId:e.requestId}),text:truncate(n.label,64)})),2)},text:truncate(e.prompt,TELEGRAM_PROMPT_MAX_LENGTH)}:{freeformRequestId:e.requestId,replyMarkup:{force_reply:!0,input_field_placeholder:truncate(`Type your answer`,64),selective:!0},text:truncate(e.prompt,TELEGRAM_PROMPT_MAX_LENGTH)}}function registerTelegramFreeformPrompt(e,t){e.pendingFreeformReplies={...e.pendingFreeformReplies,[t.messageId]:t.requestId}}function telegramCallbackInputResponse(e){return parseInputResponse({optionId:`selected`,requestId:`${TELEGRAM_CALLBACK_RESPONSE_PREFIX}${e}`})}function telegramReplyInputResponse(e){return parseInputResponse({requestId:`${TELEGRAM_REPLY_RESPONSE_PREFIX}${e.messageId}`,text:e.text})}function telegramReplyInputResponses(e,t){if(typeof e!=`string`)return[];let n=typeof t==`string`?t:(t??[]).flatMap(e=>e.type===`text`?[e.text]:[]).join(`
|
|
2
|
-
`);return n.trim().length===0?[]:[telegramReplyInputResponse({messageId:e,text:n})]}function isTelegramSyntheticResponse(e){return e.requestId.startsWith(`telegram_callback:`)||e.requestId.startsWith(`telegram_reply:`)}function resolveTelegramInputResponses(e,t){let n=[];for(let r of t){if(r.requestId.startsWith(`telegram_callback:`)){let t=r.requestId.slice(18),i=e.hitlCallbacks?.[t];i!==void 0&&
|
|
1
|
+
import{parseInputResponse,parseInputResponses}from"#shared/input.js";import{resolvedPromptLabel}from"#channel/resolved-prompt.js";const TELEGRAM_HITL_CALLBACK_PREFIX=`eve:`,TELEGRAM_CALLBACK_RESPONSE_PREFIX=`telegram_callback:`,TELEGRAM_REPLY_RESPONSE_PREFIX=`telegram_reply:`,TELEGRAM_PROMPT_MAX_LENGTH=4e3;function renderTelegramInputRequest(e,t){let n=e.options;return n&&n.length>0?{replyMarkup:{inline_keyboard:chunk(n.map(n=>({callback_data:registerTelegramCallback(t,{optionId:n.id,requestId:e.requestId}),text:truncate(n.label,64)})),2)},text:truncate(e.prompt,TELEGRAM_PROMPT_MAX_LENGTH)}:{freeformRequestId:e.requestId,replyMarkup:{force_reply:!0,input_field_placeholder:truncate(`Type your answer`,64),selective:!0},text:truncate(e.prompt,TELEGRAM_PROMPT_MAX_LENGTH)}}function registerTelegramFreeformPrompt(e,t){e.pendingFreeformReplies={...e.pendingFreeformReplies,[t.messageId]:t.requestId}}function registerTelegramHitlPrompt(e,t,n){e.hitlPrompts={...e.hitlPrompts,[t.requestId]:{...n,options:(t.options??[]).map(({id:e,label:t})=>({id:e,label:t}))}}}function takeTelegramResolvedPrompt(e,t){let n=e.hitlPrompts?.[t.requestId];if(n===void 0)return;let{[t.requestId]:r,...i}=e.hitlPrompts??{};e.hitlPrompts=i;let a=truncate(resolvedPromptLabel(t,n.options),90);return{messageId:n.messageId,text:`${n.text}\n\n${a}`}}function telegramCallbackInputResponse(e){return parseInputResponse({optionId:`selected`,requestId:`${TELEGRAM_CALLBACK_RESPONSE_PREFIX}${e}`})}function telegramReplyInputResponse(e){return parseInputResponse({requestId:`${TELEGRAM_REPLY_RESPONSE_PREFIX}${e.messageId}`,text:e.text})}function telegramReplyInputResponses(e,t){if(typeof e!=`string`)return[];let n=typeof t==`string`?t:(t??[]).flatMap(e=>e.type===`text`?[e.text]:[]).join(`
|
|
2
|
+
`);return n.trim().length===0?[]:[telegramReplyInputResponse({messageId:e,text:n})]}function isTelegramSyntheticResponse(e){return e.requestId.startsWith(`telegram_callback:`)||e.requestId.startsWith(`telegram_reply:`)}function resolveTelegramInputResponses(e,t){let n=[];for(let r of t){if(r.requestId.startsWith(`telegram_callback:`)){let t=r.requestId.slice(18),i=e.hitlCallbacks?.[t];i!==void 0&&n.push(i);continue}if(r.requestId.startsWith(`telegram_reply:`)){let t=r.requestId.slice(15),i=e.pendingFreeformReplies?.[t];i!==void 0&&r.text!==void 0&&(n.push({requestId:i,text:r.text}),delete e.pendingFreeformReplies?.[t]);continue}n.push(r)}return[...parseInputResponses(n)]}function registerTelegramCallback(e,t){let n=e.nextHitlCallbackId??0;e.nextHitlCallbackId=n+1;let r=`${TELEGRAM_HITL_CALLBACK_PREFIX}${n.toString(36)}`;return e.hitlCallbacks={...e.hitlCallbacks,[r]:t},r}function truncate(e,t){if(e.length<=t)return e;let n=Math.max(0,t-3);return`${e.slice(0,n).trimEnd()}...`}function chunk(e,t){let n=[];for(let r=0;r<e.length;r+=t)n.push(e.slice(r,r+t));return n}export{TELEGRAM_CALLBACK_RESPONSE_PREFIX,TELEGRAM_HITL_CALLBACK_PREFIX,TELEGRAM_REPLY_RESPONSE_PREFIX,isTelegramSyntheticResponse,registerTelegramFreeformPrompt,registerTelegramHitlPrompt,renderTelegramInputRequest,resolveTelegramInputResponses,takeTelegramResolvedPrompt,telegramCallbackInputResponse,telegramReplyInputResponse,telegramReplyInputResponses};
|
|
@@ -81,6 +81,7 @@ export interface TelegramChannelEvents {
|
|
|
81
81
|
readonly "message.completed"?: TelegramEventHandler<"message.completed">;
|
|
82
82
|
readonly "message.appended"?: TelegramEventHandler<"message.appended">;
|
|
83
83
|
readonly "input.requested"?: TelegramEventHandler<"input.requested">;
|
|
84
|
+
readonly "input.resolved"?: TelegramEventHandler<"input.resolved">;
|
|
84
85
|
readonly "turn.failed"?: TelegramEventHandler<"turn.failed">;
|
|
85
86
|
readonly "turn.completed"?: TelegramEventHandler<"turn.completed">;
|
|
86
87
|
readonly "turn.cancelled"?: TelegramEventHandler<"turn.cancelled">;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createLogger,logError}from"#internal/logging.js";import{isCompiledChannel}from"#channel/compiled-channel.js";import{defaultDeliverResult}from"#channel/adapter.js";import{parseJsonObject}from"#shared/json.js";import{POST,defineChannel}from"#public/definitions/channel.js";import{mergeUploadPolicy}from"#public/channels/upload-policy.js";import{formatTelegramContextBlock,parseTelegramUpdate}from"#public/channels/telegram/inbound.js";import{answerTelegramCallbackQuery,callTelegramApi,editTelegramMessageReplyMarkup,editTelegramMessageText,sendTelegramChatAction,sendTelegramMessage,splitTelegramMessageText,telegramContinuationToken}from"#public/channels/telegram/api.js";import{TELEGRAM_AUTHORIZATION_CALLBACK_PREFIX}from"#public/channels/telegram/authorization.js";import{TELEGRAM_HITL_CALLBACK_PREFIX,isTelegramSyntheticResponse,resolveTelegramInputResponses,telegramCallbackInputResponse,telegramReplyInputResponses}from"#public/channels/telegram/hitl.js";import{buildTelegramTurnMessage,collectTelegramFileParts,createTelegramFetchFile}from"#public/channels/telegram/attachments.js";import{defaultEvents,defaultOnMessage,isTelegramBotMentioned}from"#public/channels/telegram/defaults.js";import{verifyTelegramRequest}from"#public/channels/telegram/verify.js";import{dispatchTelegramAuthorizationCallback}from"#public/channels/telegram/authorization-callback.js";import{initialTelegramState,stateFromTelegramCallbackQuery,stateFromTelegramMessage,telegramContinuationTokenFromState}from"#public/channels/telegram/state.js";import{telegramInstrumentation}from"#public/channels/telegram/audience.js";const log=createLogger(`telegram.channel`);function telegramChannel(e={}){let t=mergeUploadPolicy(e.uploadPolicy),n=e.onMessage??defaultOnMessage,r={...defaultEvents,...e.events},i=defineChannel({kindHint:`telegram`,turnPolicy:e.turnPolicy,state:initialTelegramState(e.botUsername),...telegramInstrumentation,fetchFile:createTelegramFetchFile({api:e.api,credentials:e.credentials,policy:t}),context(t,n){return rebuildTelegramContext(t,n,e)},routes:[POST(e.route??`/eve/v1/telegram`,async(r,{from:i,resolveSession:a,waitUntil:o})=>{let s=await verifyInbound(r,e.credentials);if(s===null)return new Response(`unauthorized`,{status:401});let c;try{c=parseJsonObject(JSON.parse(s))}catch(e){return log.warn(`inbound Telegram body is not valid JSON`,{error:e}),new Response(`ok`)}let l=parseTelegramUpdate(c);return l===null?new Response(`ok`):l.kind===`message`?(o(dispatchMessage({config:e,message:l.message,onMessage:n,uploadPolicy:t,from:i})),new Response(`ok`)):(o(dispatchCallbackQuery({config:e,query:l.callbackQuery,from:i,resolveSession:a})),new Response(`ok`))})],async receive(t,{from:n}){let r=t.target,i=readChatId(r.chatId);if(i===void 0)throw Error(`telegramChannel().receive requires target.chatId.`);let a=typeof r.messageThreadId==`number`?r.messageThreadId:void 0,o=readChatId(r.conversationId),s=r.initialMessage;if(s!==void 0&&o!==void 0)throw Error("telegramChannel().receive: `conversationId` and `initialMessage` are mutually exclusive.");let c={...initialTelegramState(e.botUsername),chatId:i,conversationId:o??null,messageThreadId:a??null};return s!==void 0&&await buildTelegramHandle({config:e,state:c}).sendMessage(s),n(telegramContinuationTokenFromState(c)).send(t.message,{auth:t.auth,state:c})},events:r});return attachTelegramDeliver(i),i}function rebuildTelegramContext(e,t,n){return{state:e,telegram:buildTelegramHandle({config:n,session:t,state:e})}}function buildTelegramHandle(e){let t=e.config.api,n=e.state,r=e.config.credentials;function anchor(t){let r=n.chatType??t.chatType??null;n.chatType===null&&t.chatType!==void 0&&(n.chatType=t.chatType),t.id&&shouldAnchorTelegramConversation(r)&&(n.conversationId=t.id,n.chatId&&e.session?.continuation?.alias(telegramContinuationToken({chatId:n.chatId,conversationId:t.id,messageThreadId:n.messageThreadId??void 0})))}async function sendOne(e){let t=await sendMessage(e);return anchor(t),t}async function sendMessage(e){let i=n.chatId??``;if(!i)throw Error(`telegramChannel: missing chat id for outbound message.`);return sendTelegramMessage({apiBaseUrl:t?.apiBaseUrl,body:{...e,message_thread_id:e.message_thread_id??n.messageThreadId??void 0},credentials:r,fetch:t?.fetch,fileBaseUrl:t?.fileBaseUrl,chatId:i})}return{botUsername:n.botUsername??e.config.botUsername,chatId:n.chatId??``,chatType:n.chatType??void 0,conversationId:n.conversationId??void 0,messageThreadId:n.messageThreadId??void 0,answerCallbackQuery(e){return answerTelegramCallbackQuery({apiBaseUrl:t?.apiBaseUrl,callbackQueryId:e.callbackQueryId,credentials:r,fetch:t?.fetch,showAlert:e.showAlert,text:e.text})},editMessageReplyMarkup(e){let i=n.chatId??``;if(!i)throw Error(`telegramChannel: missing chat id for reply-markup edit.`);return editTelegramMessageReplyMarkup({apiBaseUrl:t?.apiBaseUrl,chatId:i,credentials:r,fetch:t?.fetch,messageId:e.messageId,replyMarkup:e.replyMarkup})},editMessageText(e){let i=n.chatId??``;if(!i)throw Error(`telegramChannel: missing chat id for text edit.`);return editTelegramMessageText({apiBaseUrl:t?.apiBaseUrl,chatId:i,credentials:r,fetch:t?.fetch,messageId:e.messageId,replyMarkup:e.replyMarkup,text:e.text})},post(e){return postTelegramMessage(e,sendOne)},postEphemeral(e,t,n){return postTelegramMessage({...typeof t==`string`?{text:t}:t,ephemeral_message_parameters:{...n?.callbackQueryId===void 0?{}:{callback_query_id:n.callbackQueryId},receiver_user_id:e}},sendMessage)},request(e,n){return callTelegramApi({apiBaseUrl:t?.apiBaseUrl,body:n,botToken:r?.botToken,fetch:t?.fetch,method:e})},sendMessage(e){return postTelegramMessage(e,sendOne)},async startTyping(e=`typing`){let i=n.chatId??``;if(i)try{await sendTelegramChatAction({action:e,apiBaseUrl:t?.apiBaseUrl,chatId:i,credentials:r,fetch:t?.fetch,messageThreadId:n.messageThreadId??void 0})}catch(e){logError(log,`Telegram typing indicator failed — swallowed`,e,{chatId:i})}}}}function shouldAnchorTelegramConversation(e){return e===`group`||e===`supergroup`}async function postTelegramMessage(e,t){let n=typeof e==`string`?{text:e}:e,r=splitTelegramMessageText(n.text),i;for(let[e,a]of r.entries()){let r=await t(e===0?{...n,text:a}:{...n.ephemeral_message_parameters===void 0?{}:{ephemeral_message_parameters:n.ephemeral_message_parameters},text:a});i===void 0&&(i=r)}return i??{id:``,raw:null}}async function verifyInbound(e,t){try{return await verifyTelegramRequest(e,{secretToken:t?.webhookVerifier?void 0:t?.webhookSecretToken,webhookVerifier:t?.webhookVerifier})}catch(e){return log.warn(`telegram inbound verification failed`,{error:e}),null}}async function dispatchMessage(e){if(e.message.from?.isBot===!0)return;let t=stateFromTelegramMessage(e.message,e.config.botUsername),n={telegram:buildTelegramHandle({config:e.config,state:t})},r;try{r=await e.onMessage(n,e.message)}catch(e){log.error(`message handler failed`,{error:e});return}if(r==null)return;let i=collectTelegramFileParts(e.message.attachments,e.uploadPolicy),a=buildTelegramTurnMessage(e.message,i),o=formatTelegramContextBlock({botUsername:e.config.botUsername,chatId:e.message.chat.id,chatTitle:e.message.chat.title,chatType:e.message.chat.type,isMentioned:isTelegramBotMentioned(e.message,e.config.botUsername),messageId:e.message.messageId,messageThreadId:e.message.messageThreadId,userId:e.message.from?.id,username:e.message.from?.username}),s=r.context??[];try{await e.from(telegramContinuationTokenFromState(t)).send(a,{auth:r.auth,context:[o,...s],state:t,title:r.title})}catch(e){log.error(`message delivery failed`,{error:e})}}async function dispatchCallbackQuery(e){let t=stateFromTelegramCallbackQuery(e.query,e.config.botUsername),n={telegram:buildTelegramHandle({config:e.config,state:t})};if(e.query.data?.startsWith(TELEGRAM_AUTHORIZATION_CALLBACK_PREFIX)===!0){await dispatchTelegramAuthorizationCallback({continuationToken:telegramContinuationTokenFromState(t),query:e.query,resolveSession:e.resolveSession,state:t,telegram:n});return}if(e.query.data?.startsWith(TELEGRAM_HITL_CALLBACK_PREFIX)===!0){try{await n.telegram.answerCallbackQuery({callbackQueryId:e.query.id,text:`Answer received.`})}catch(e){log.warn(`Telegram callback-query acknowledgement failed`,{error:e})}if(!e.query.message||!t.chatId)return;try{await e.from(telegramContinuationTokenFromState(t)).respond([telegramCallbackInputResponse(e.query.data)],{auth:
|
|
1
|
+
import{createLogger,logError}from"#internal/logging.js";import{isCompiledChannel}from"#channel/compiled-channel.js";import{defaultDeliverResult}from"#channel/adapter.js";import{parseJsonObject}from"#shared/json.js";import{POST,defineChannel}from"#public/definitions/channel.js";import{mergeUploadPolicy}from"#public/channels/upload-policy.js";import{formatTelegramContextBlock,parseTelegramUpdate}from"#public/channels/telegram/inbound.js";import{answerTelegramCallbackQuery,callTelegramApi,editTelegramMessageReplyMarkup,editTelegramMessageText,sendTelegramChatAction,sendTelegramMessage,splitTelegramMessageText,telegramContinuationToken}from"#public/channels/telegram/api.js";import{TELEGRAM_AUTHORIZATION_CALLBACK_PREFIX}from"#public/channels/telegram/authorization.js";import{TELEGRAM_HITL_CALLBACK_PREFIX,isTelegramSyntheticResponse,resolveTelegramInputResponses,telegramCallbackInputResponse,telegramReplyInputResponses}from"#public/channels/telegram/hitl.js";import{buildTelegramTurnMessage,collectTelegramFileParts,createTelegramFetchFile}from"#public/channels/telegram/attachments.js";import{defaultEvents,defaultOnMessage,defaultTelegramAuth,isTelegramBotMentioned}from"#public/channels/telegram/defaults.js";import{verifyTelegramRequest}from"#public/channels/telegram/verify.js";import{dispatchTelegramAuthorizationCallback}from"#public/channels/telegram/authorization-callback.js";import{initialTelegramState,stateFromTelegramCallbackQuery,stateFromTelegramMessage,telegramContinuationTokenFromState}from"#public/channels/telegram/state.js";import{telegramInstrumentation}from"#public/channels/telegram/audience.js";const log=createLogger(`telegram.channel`);function telegramChannel(e={}){let t=mergeUploadPolicy(e.uploadPolicy),n=e.onMessage??defaultOnMessage,r={...defaultEvents,...e.events},i=defineChannel({kindHint:`telegram`,turnPolicy:e.turnPolicy,state:initialTelegramState(e.botUsername),...telegramInstrumentation,fetchFile:createTelegramFetchFile({api:e.api,credentials:e.credentials,policy:t}),context(t,n){return rebuildTelegramContext(t,n,e)},routes:[POST(e.route??`/eve/v1/telegram`,async(r,{from:i,resolveSession:a,waitUntil:o})=>{let s=await verifyInbound(r,e.credentials);if(s===null)return new Response(`unauthorized`,{status:401});let c;try{c=parseJsonObject(JSON.parse(s))}catch(e){return log.warn(`inbound Telegram body is not valid JSON`,{error:e}),new Response(`ok`)}let l=parseTelegramUpdate(c);return l===null?new Response(`ok`):l.kind===`message`?(o(dispatchMessage({config:e,message:l.message,onMessage:n,uploadPolicy:t,from:i})),new Response(`ok`)):(o(dispatchCallbackQuery({config:e,query:l.callbackQuery,from:i,resolveSession:a})),new Response(`ok`))})],async receive(t,{from:n}){let r=t.target,i=readChatId(r.chatId);if(i===void 0)throw Error(`telegramChannel().receive requires target.chatId.`);let a=typeof r.messageThreadId==`number`?r.messageThreadId:void 0,o=readChatId(r.conversationId),s=r.initialMessage;if(s!==void 0&&o!==void 0)throw Error("telegramChannel().receive: `conversationId` and `initialMessage` are mutually exclusive.");let c={...initialTelegramState(e.botUsername),chatId:i,conversationId:o??null,messageThreadId:a??null};return s!==void 0&&await buildTelegramHandle({config:e,state:c}).sendMessage(s),n(telegramContinuationTokenFromState(c)).send(t.message,{auth:t.auth,state:c})},events:r});return attachTelegramDeliver(i),i}function rebuildTelegramContext(e,t,n){return{state:e,telegram:buildTelegramHandle({config:n,session:t,state:e})}}function buildTelegramHandle(e){let t=e.config.api,n=e.state,r=e.config.credentials;function anchor(t){let r=n.chatType??t.chatType??null;n.chatType===null&&t.chatType!==void 0&&(n.chatType=t.chatType),t.id&&shouldAnchorTelegramConversation(r)&&(n.conversationId=t.id,n.chatId&&e.session?.continuation?.alias(telegramContinuationToken({chatId:n.chatId,conversationId:t.id,messageThreadId:n.messageThreadId??void 0})))}async function sendOne(e){let t=await sendMessage(e);return anchor(t),t}async function sendMessage(e){let i=n.chatId??``;if(!i)throw Error(`telegramChannel: missing chat id for outbound message.`);return sendTelegramMessage({apiBaseUrl:t?.apiBaseUrl,body:{...e,message_thread_id:e.message_thread_id??n.messageThreadId??void 0},credentials:r,fetch:t?.fetch,fileBaseUrl:t?.fileBaseUrl,chatId:i})}return{botUsername:n.botUsername??e.config.botUsername,chatId:n.chatId??``,chatType:n.chatType??void 0,conversationId:n.conversationId??void 0,messageThreadId:n.messageThreadId??void 0,answerCallbackQuery(e){return answerTelegramCallbackQuery({apiBaseUrl:t?.apiBaseUrl,callbackQueryId:e.callbackQueryId,credentials:r,fetch:t?.fetch,showAlert:e.showAlert,text:e.text})},editMessageReplyMarkup(e){let i=n.chatId??``;if(!i)throw Error(`telegramChannel: missing chat id for reply-markup edit.`);return editTelegramMessageReplyMarkup({apiBaseUrl:t?.apiBaseUrl,chatId:i,credentials:r,fetch:t?.fetch,messageId:e.messageId,replyMarkup:e.replyMarkup})},editMessageText(e){let i=n.chatId??``;if(!i)throw Error(`telegramChannel: missing chat id for text edit.`);return editTelegramMessageText({apiBaseUrl:t?.apiBaseUrl,chatId:i,credentials:r,fetch:t?.fetch,messageId:e.messageId,replyMarkup:e.replyMarkup,text:e.text})},post(e){return postTelegramMessage(e,sendOne)},postEphemeral(e,t,n){return postTelegramMessage({...typeof t==`string`?{text:t}:t,ephemeral_message_parameters:{...n?.callbackQueryId===void 0?{}:{callback_query_id:n.callbackQueryId},receiver_user_id:e}},sendMessage)},request(e,n){return callTelegramApi({apiBaseUrl:t?.apiBaseUrl,body:n,botToken:r?.botToken,fetch:t?.fetch,method:e})},sendMessage(e){return postTelegramMessage(e,sendOne)},async startTyping(e=`typing`){let i=n.chatId??``;if(i)try{await sendTelegramChatAction({action:e,apiBaseUrl:t?.apiBaseUrl,chatId:i,credentials:r,fetch:t?.fetch,messageThreadId:n.messageThreadId??void 0})}catch(e){logError(log,`Telegram typing indicator failed — swallowed`,e,{chatId:i})}}}}function shouldAnchorTelegramConversation(e){return e===`group`||e===`supergroup`}async function postTelegramMessage(e,t){let n=typeof e==`string`?{text:e}:e,r=splitTelegramMessageText(n.text),i;for(let[e,a]of r.entries()){let r=await t(e===0?{...n,text:a}:{...n.ephemeral_message_parameters===void 0?{}:{ephemeral_message_parameters:n.ephemeral_message_parameters},text:a});i===void 0&&(i=r)}return i??{id:``,raw:null}}async function verifyInbound(e,t){try{return await verifyTelegramRequest(e,{secretToken:t?.webhookVerifier?void 0:t?.webhookSecretToken,webhookVerifier:t?.webhookVerifier})}catch(e){return log.warn(`telegram inbound verification failed`,{error:e}),null}}async function dispatchMessage(e){if(e.message.from?.isBot===!0)return;let t=stateFromTelegramMessage(e.message,e.config.botUsername),n={telegram:buildTelegramHandle({config:e.config,state:t})},r;try{r=await e.onMessage(n,e.message)}catch(e){log.error(`message handler failed`,{error:e});return}if(r==null)return;let i=collectTelegramFileParts(e.message.attachments,e.uploadPolicy),a=buildTelegramTurnMessage(e.message,i),o=formatTelegramContextBlock({botUsername:e.config.botUsername,chatId:e.message.chat.id,chatTitle:e.message.chat.title,chatType:e.message.chat.type,isMentioned:isTelegramBotMentioned(e.message,e.config.botUsername),messageId:e.message.messageId,messageThreadId:e.message.messageThreadId,userId:e.message.from?.id,username:e.message.from?.username}),s=r.context??[];try{await e.from(telegramContinuationTokenFromState(t)).send(a,{auth:r.auth,context:[o,...s],state:t,title:r.title})}catch(e){log.error(`message delivery failed`,{error:e})}}async function dispatchCallbackQuery(e){let t=stateFromTelegramCallbackQuery(e.query,e.config.botUsername),n={telegram:buildTelegramHandle({config:e.config,state:t})};if(e.query.data?.startsWith(TELEGRAM_AUTHORIZATION_CALLBACK_PREFIX)===!0){await dispatchTelegramAuthorizationCallback({continuationToken:telegramContinuationTokenFromState(t),query:e.query,resolveSession:e.resolveSession,state:t,telegram:n});return}if(e.query.data?.startsWith(TELEGRAM_HITL_CALLBACK_PREFIX)===!0){try{await n.telegram.answerCallbackQuery({callbackQueryId:e.query.id,text:`Answer received.`})}catch(e){log.warn(`Telegram callback-query acknowledgement failed`,{error:e})}if(!e.query.message||!t.chatId)return;try{await e.from(telegramContinuationTokenFromState(t)).respond([telegramCallbackInputResponse(e.query.data)],{auth:defaultTelegramAuth({...e.query.message,from:e.query.from})})}catch(e){log.error(`callback query delivery failed`,{error:e})}return}if(e.config.onCallbackQuery!==void 0){try{await e.config.onCallbackQuery(n,e.query)}catch(e){log.error(`custom callback-query handler failed`,{error:e})}return}try{await n.telegram.answerCallbackQuery({callbackQueryId:e.query.id,text:`Unsupported action.`})}catch(e){log.warn(`Telegram unsupported callback-query acknowledgement failed`,{error:e})}}function attachTelegramDeliver(e){if(!isCompiledChannel(e))return;let t=e.adapter;t.deliver=(e,t)=>{let n=e.state,r=[...e.inputResponses??[],...telegramReplyInputResponses(n?.replyToBotMessageId,e.message)];if(r.some(isTelegramSyntheticResponse)){let n=resolveTelegramInputResponses(t.state,r);return n.length>0?{inputResponses:n,context:e.context}:e.message===void 0?void 0:{message:e.message,context:e.context}}return defaultDeliverResult(e)}}function readChatId(e){if(typeof e==`string`&&e.length>0)return e;if(typeof e==`number`&&Number.isFinite(e))return String(e)}export{telegramChannel};
|
|
@@ -6,5 +6,5 @@ export declare function defaultOnText(_ctx: TwilioContext, message: TwilioTextMe
|
|
|
6
6
|
export declare function defaultOnVoice(_ctx: TwilioContext, _call: TwilioVoiceCall): TwilioVoiceResult;
|
|
7
7
|
/** Default inbound voice hook: dispatch with Twilio phone-number auth. */
|
|
8
8
|
export declare function defaultOnVoiceTranscription(_ctx: TwilioContext, transcription: TwilioVoiceTranscription): TwilioInboundResult;
|
|
9
|
-
/** Built-in Twilio event handlers for text delivery and terminal errors. */
|
|
9
|
+
/** Built-in Twilio event handlers for text delivery, sign-ins, and terminal errors. */
|
|
10
10
|
export declare const defaultEvents: TwilioChannelEvents;
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import{extractErrorId,formatErrorHint}from"#internal/logging.js";import{renderTextInputRequest}from"#channel/resolve-text.js";function defaultTwilioAuth(e){let t={channel:e.channel,from:e.from};return e.to!==void 0&&(t.to=e.to),{attributes:t,authenticator:`twilio-webhook`,issuer:`twilio`,principalId:`twilio:${e.from}`,principalType:`user`}}function defaultOnText(e,t){return{auth:defaultTwilioAuth({channel:`text`,from:t.from,to:t.to})}}function defaultOnVoice(e,t){return{}}function defaultOnVoiceTranscription(e,t){return{auth:defaultTwilioAuth({channel:`voice`,from:t.from,to:t.to})}}const defaultEvents={async"message.completed"(e,t,n){e.finishReason!==`tool-calls`&&e.message&&await t.twilio.sendMessage(e.message)},async"input.requested"(e,t,n){e.requests.length!==0&&await t.twilio.sendMessage(renderTwilioInputRequests(e.requests))},async"
|
|
1
|
+
import{extractErrorId,formatErrorHint}from"#internal/logging.js";import{displayProperName}from"#shared/display-name.js";import{renderTextInputRequest}from"#channel/resolve-text.js";function defaultTwilioAuth(e){let t={channel:e.channel,from:e.from};return e.to!==void 0&&(t.to=e.to),{attributes:t,authenticator:`twilio-webhook`,issuer:`twilio`,principalId:`twilio:${e.from}`,principalType:`user`}}function defaultOnText(e,t){return{auth:defaultTwilioAuth({channel:`text`,from:t.from,to:t.to})}}function defaultOnVoice(e,t){return{}}function defaultOnVoiceTranscription(e,t){return{auth:defaultTwilioAuth({channel:`voice`,from:t.from,to:t.to})}}const defaultEvents={async"message.completed"(e,t,n){e.finishReason!==`tool-calls`&&e.message&&await t.twilio.sendMessage(e.message)},async"input.requested"(e,t,n){e.requests.length!==0&&await t.twilio.sendMessage(renderTwilioInputRequests(e.requests))},async"authorization.required"(e,t,n){if(e.candidateId!==void 0)return;let r=e.authorization;await t.twilio.sendMessage([`Sign in to ${r?.displayName??displayProperName(e.name)} to continue.`,r?.instructions,r?.userCode?`Code: ${r.userCode}`:void 0,r?.url].filter(e=>e!==void 0&&e.length>0).join(`
|
|
2
|
+
|
|
3
|
+
`))},async"authorization.completed"(e,t,n){e.candidateId===void 0&&await t.twilio.sendMessage(renderAuthorizationOutcome({displayName:e.authorization?.displayName??displayProperName(e.name),outcome:e.outcome,reason:e.reason}))},async"turn.failed"(e,t,n){let r=formatErrorHint(e),i=extractErrorId(e.details);await t.twilio.sendMessage([`I hit an error while handling your request${r}.`,``,`Please try again, rephrase, or reach out if it keeps failing.`,...i?[``,`Error id: ${i}`]:[]].join(`
|
|
2
4
|
`))},async"session.failed"(e,t){let n=formatErrorHint(e),r=extractErrorId(e.details);await t.twilio.sendMessage([`This session could not recover from an error${n}.`,``,`Start a new message to continue.`,...r?[``,`Error id: ${r}`]:[]].join(`
|
|
3
5
|
`))}};function renderTwilioInputRequests(e){let t=e.map(renderTextInputRequest);if(e.some(e=>(e.options??[]).length>0)){let n=e.some(e=>e.allowFreeform===!0);t.push([n?`Reply with a number, or with your own answer.`:`Reply with a number to choose.`,...e.length>1?[`Your reply answers each of these.`]:[]].join(` `))}return t.join(`
|
|
4
6
|
|
|
5
|
-
`)}export{defaultEvents,defaultOnText,defaultOnVoice,defaultOnVoiceTranscription};
|
|
7
|
+
`)}function renderAuthorizationOutcome(e){if(e.outcome===`authorized`)return`${e.displayName} connected.`;if(e.outcome===`declined`)return`${e.displayName} sign-in cancelled.`;let t=e.outcome===`timed-out`?`timed out`:e.outcome,n=e.reason===void 0?``:` (${e.reason})`;return`${e.displayName} sign-in ${t}${n}.`}export{defaultEvents,defaultOnText,defaultOnVoice,defaultOnVoiceTranscription};
|
|
@@ -15,6 +15,7 @@ export type { AudienceCaller, AudienceContext, AudienceInput, AudiencePrincipal,
|
|
|
15
15
|
export type { SessionRespondOptions, SessionSendOptions } from "#channel/session.js";
|
|
16
16
|
export type { ChannelFrom, ChannelReceiveContext, ChannelResolveSession, ChannelRespondOptions, ChannelSendOptions, ChannelSource, };
|
|
17
17
|
export type { ChannelCors, ChannelCorsOptions } from "#channel/cors.js";
|
|
18
|
+
export type { AgentDescription, AgentToolDescription } from "#channel/agent-description.js";
|
|
18
19
|
export { DELETE, GET, HEAD, OPTIONS, PATCH, POST, PUT, WS } from "#channel/routes.js";
|
|
19
20
|
export type { AttachSessionFn, HttpRouteDefinition, RouteDefinition, RouteHandlerArgs, WebSocketMessage, WebSocketPeer, WebSocketRouteDefinition, WebSocketRouteHandler, WebSocketRouteHooks, WebSocketUpgradeRequest, WebSocketUpgradeResult, } from "#channel/routes.js";
|
|
20
21
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{readDefinitionSource}from"#internal/authored-definition/source-identity.js";const toolResultFrom=toolResultFromImpl;function toolResultFromImpl(e,t){if(e.kind!==`tool-result`||e.isError===!0)return;let n=readDefinitionSource(t);if(n
|
|
1
|
+
import{readDefinitionSource}from"#internal/authored-definition/source-identity.js";const toolResultFrom=toolResultFromImpl;function toolResultFromImpl(e,t){if(e.kind!==`tool-result`||e.isError===!0)return;let n=readDefinitionSource(t);if(n!==void 0&&n.kind!==`ambiguous`){if(n.kind===`tool`)return n.names.has(e.toolName)?{callId:e.callId,output:e.output,toolName:e.toolName}:void 0;for(let t of n.names){let n=t+`__`;if(e.toolName.startsWith(n))return{callId:e.callId,connectionToolName:e.toolName.slice(n.length),output:e.output,toolName:e.toolName}}}}export{toolResultFrom};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{expectObjectRecord}from"#internal/authored-module.js";import{toErrorMessage}from"#shared/errors.js";import{normalizeMcpClientConnectionDefinition,normalizeOpenApiConnectionDefinition}from"#internal/authored-definition/connection.js";import{readStampedConnectionProtocol}from"#public/definitions/connections/protocol.js";import{registerDefinitionSource
|
|
1
|
+
import{expectObjectRecord}from"#internal/authored-module.js";import{toErrorMessage}from"#shared/errors.js";import{normalizeMcpClientConnectionDefinition,normalizeOpenApiConnectionDefinition}from"#internal/authored-definition/connection.js";import{readStampedConnectionProtocol}from"#public/definitions/connections/protocol.js";import{registerDefinitionSource}from"#internal/authored-definition/source-identity.js";import{normalizeAuthorizationSpec}from"#shared/validate-authorization.js";import{ResolveAgentError,loadResolvedModuleExport}from"#runtime/resolve-helpers.js";import{createConnectionInstanceId}from"#runtime/connections/instance-identity.js";async function resolveConnectionDefinition(e,t,n){try{let r=await loadResolvedModuleExport({definition:e,kindLabel:`connection`,moduleMap:t,nodeId:n}),i=expectObjectRecord(r,`Expected the connection export "${e.exportName??`default`}" from "${e.logicalPath}" to return an object.`);registerDefinitionSource(i,{kind:`connection`,logicalPath:e.logicalPath,name:e.connectionName},`connection:${e.url}`);let a=i.auth!==void 0,o=i.headers!==void 0,s=e.protocol===`openapi`?i.operations:i.tools,c={connectionName:e.connectionName,description:e.description,exportName:e.exportName,logicalPath:e.logicalPath,instanceId:createConnectionInstanceId({connectionName:e.connectionName,instanceKey:typeof i.instanceKey==`string`?i.instanceKey:void 0,protocol:e.protocol,sourceId:e.sourceId,url:e.url}),protocol:e.protocol,sourceId:e.sourceId,sourceKind:`module`,url:e.url};if(a){if(typeof i.auth==`function`)c.authorization=i.auth;else try{c.authorization=normalizeAuthorizationSpec(i.auth,`Connection "${e.connectionName}" at "${e.logicalPath}":`)}catch(t){throw new ResolveAgentError(toErrorMessage(t),{logicalPath:e.logicalPath,sourceId:e.sourceId})}}if(e.protocol===`mcp`&&i.protocolVersionDiscovery!==void 0){if(typeof i.protocolVersionDiscovery!=`boolean`)throw Error(`"protocolVersionDiscovery" must be a boolean.`);c.protocolVersionDiscovery=i.protocolVersionDiscovery}return o&&(c.headers=i.headers),i.toolCall!==void 0&&(c.toolCall=i.toolCall),s!==void 0&&(c.tools=s),e.protocol===`openapi`&&i.spec!==void 0&&(c.spec=i.spec),typeof i.approval==`function`&&(c.approval=i.approval),c}catch(t){throw t instanceof ResolveAgentError?t:new ResolveAgentError(`Failed to resolve connection "${e.connectionName}" from "${e.logicalPath}": ${toErrorMessage(t)}`,{logicalPath:e.logicalPath,sourceId:e.sourceId})}}function resolveDynamicConnectionValue(e,t){let n=readStampedConnectionProtocol(e),r=`Dynamic connection "${t.connectionName}" from "${t.logicalPath}" must be created by defineMcpClientConnection() or defineOpenAPIConnection().`;if(n===void 0)throw Error(r);if(registerDefinitionSource(e,{kind:`connection`,logicalPath:t.logicalPath,name:t.connectionName}),n===`openapi`){let i=normalizeOpenApiConnectionDefinition(e,r);return assertAuthenticatedDynamicInstanceKey(i.auth,i.instanceKey,r),omitUndefined({approval:i.approval,authorization:i.auth,connectionName:t.connectionName,description:i.description,exportName:t.exportName,headers:i.headers,instanceId:createConnectionInstanceId({connectionName:t.connectionName,instanceKey:i.instanceKey,protocol:n,sourceId:t.sourceId,url:i.baseUrl??``}),logicalPath:t.logicalPath,protocol:n,sourceId:t.sourceId,sourceKind:`module`,spec:i.spec,toolCall:i.toolCall,tools:i.operations,url:i.baseUrl??``})}let i=normalizeMcpClientConnectionDefinition(e,r);return assertAuthenticatedDynamicInstanceKey(i.auth,i.instanceKey,r),omitUndefined({approval:i.approval,authorization:i.auth,connectionName:t.connectionName,description:i.description,exportName:t.exportName,headers:i.headers,instanceId:createConnectionInstanceId({connectionName:t.connectionName,instanceKey:i.instanceKey,protocol:n,sourceId:t.sourceId,url:i.url}),logicalPath:t.logicalPath,protocol:n,sourceId:t.sourceId,sourceKind:`module`,toolCall:i.toolCall,protocolVersionDiscovery:i.protocolVersionDiscovery,tools:i.tools,url:i.url})}function assertAuthenticatedDynamicInstanceKey(e,t,n){if(e!==void 0&&t===void 0)throw Error(`${n} Authenticated dynamic connections must set "instanceKey" to a stable, non-secret account or tenant identifier.`)}function omitUndefined(e){return Object.fromEntries(Object.entries(e).filter(([,e])=>e!==void 0))}export{resolveConnectionDefinition,resolveDynamicConnectionValue};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{expectFunction,expectObjectRecord}from"#internal/authored-module.js";import{toErrorMessage}from"#shared/errors.js";import{isDynamicSentinel}from"#dynamic/definition.js";import{registerDefinitionSource
|
|
1
|
+
import{expectFunction,expectObjectRecord}from"#internal/authored-module.js";import{toErrorMessage}from"#shared/errors.js";import{isDynamicSentinel}from"#dynamic/definition.js";import{registerDefinitionSource}from"#internal/authored-definition/source-identity.js";import{ResolveAgentError,loadResolvedModuleExport}from"#runtime/resolve-helpers.js";async function resolveDynamicToolDefinition(e,t,n){try{return resolveLoadedDynamicToolDefinition(await loadResolvedModuleExport({definition:e,kindLabel:`dynamic-tool`,moduleMap:t,nodeId:n}),e,e.eventNames)}catch(t){throw t instanceof ResolveAgentError?t:new ResolveAgentError(`Failed to resolve dynamic tool from "${e.logicalPath}": ${toErrorMessage(t)}`,{logicalPath:e.logicalPath,sourceId:e.sourceId})}}function resolveLoadedDynamicToolDefinition(e,t,n){let r=expectDynamicToolValue(e,t);return createResolvedDynamicToolResolver(r,t,n??Object.keys(r.events))}function createResolvedDynamicToolResolver(e,t,n){let r={};for(let i of n)r[i]=expectFunction(e.events[i],describe(t,`to provide a handler for event "${i}"`));return registerDefinitionSource(e,{kind:`tool`,logicalPath:t.logicalPath,name:t.slug}),{eventNames:[...n],events:r,exportName:t.exportName,extensionNamespace:t.extensionNamespace,logicalPath:t.logicalPath,rebindMissingCallbacks:t.rebindMissingCallbacks,slug:t.slug,sourceId:t.sourceId,sourceKind:`module`}}function expectDynamicToolValue(e,t){let n=expectObjectRecord(e,describe(t,`to return an object`));if(!isDynamicSentinel(n))throw Error(describe(t,`to be created by defineDynamic()`));return expectObjectRecord(n.events,describe(t,`to provide an events object`)),n}function describe(e,t){return`Expected the dynamic tool export "${e.exportName??`default`}" from "${e.logicalPath}" ${t}.`}export{resolveDynamicToolDefinition};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{expectFunction,expectObjectRecord}from"#internal/authored-module.js";import{toErrorMessage}from"#shared/errors.js";import{isToolSchema,toInputSchema,toOutputSchema}from"#tools/schema.js";import{registerDefinitionSource
|
|
1
|
+
import{expectFunction,expectObjectRecord}from"#internal/authored-module.js";import{toErrorMessage}from"#shared/errors.js";import{isToolSchema,toInputSchema,toOutputSchema}from"#tools/schema.js";import{registerDefinitionSource}from"#internal/authored-definition/source-identity.js";import{normalizeApproval}from"#internal/authored-definition/approval.js";import{createWorkflowProgramExecuteInput}from"#tools/workflow-program-input.js";import{ResolveAgentError,loadResolvedModuleExport}from"#runtime/resolve-helpers.js";async function resolveToolDefinition(e,t,n,r){if(!e.hasExecute)return{availableInSubagents:e.availableInSubagents,behavior:e.behavior,description:e.description,inputSchema:toInputSchema(e.inputSchema),logicalPath:e.logicalPath,name:e.name,outputSchema:toOutputSchema(e.outputSchema),owner:r,sourceId:e.sourceId,sourceKind:`module`};try{let i=await loadResolvedModuleExport({definition:e,kindLabel:`tool`,moduleMap:t,nodeId:n}),a=expectObjectRecord(i,describe(e,`to return an object`));registerDefinitionSource(a,{kind:`tool`,logicalPath:e.logicalPath,name:e.name},`tool:${a.description}`);let o=e.behavior?.handling?.kind===`workflow-tool`?void 0:expectFunction(a.execute,describe(e,`to provide an execute function`)),s=isToolSchema(a.inputSchema)?a.inputSchema:toInputSchema(e.inputSchema),c=isToolSchema(a.outputSchema)?a.outputSchema:toOutputSchema(e.outputSchema),l=e.workflowProgram,u=l===void 0?void 0:e=>createWorkflowProgramExecuteInput(l,e);return{availableInSubagents:e.availableInSubagents,behavior:e.behavior,description:e.description,execute:o,executeInput:u,exportName:e.exportName,inputSchema:s,logicalPath:e.logicalPath,name:e.name,owner:r,outputSchema:c,sourceId:e.sourceId,sourceKind:`module`,...extractOptionalHooks(a,e)}}catch(t){throw t instanceof ResolveAgentError?t:new ResolveAgentError(`Failed to attach the tool execute function from "${e.logicalPath}": ${toErrorMessage(t)}`,{logicalPath:e.logicalPath,sourceId:e.sourceId})}}function extractOptionalHooks(e,t){let n={};if(e.label!==void 0){let r=expectObjectRecord(e.label,describe(t,`to provide a valid label definition`));n.label={complete:r.complete===void 0?void 0:expectFunction(r.complete,describe(t,`to provide an label complete function`)),delta:r.delta===void 0?void 0:expectFunction(r.delta,describe(t,`to provide an label delta function`)),start:expectFunction(r.start,describe(t,`to provide a label start callback function`))}}return e.approval!==void 0&&(n.approval=normalizeApproval(e.approval,describe(t,`to provide a valid approval definition`))),e.approvalKey!==void 0&&(n.approvalKey=expectFunction(e.approvalKey,describe(t,`to provide an approvalKey function`))),e.endsTurn!==void 0&&(n.endsTurn=typeof e.endsTurn==`boolean`?e.endsTurn:expectFunction(e.endsTurn,describe(t,`to provide endsTurn as a boolean or a function`))),e.toModelOutput!==void 0&&(n.toModelOutput=expectFunction(e.toModelOutput,describe(t,`to provide a toModelOutput function`))),n}function describe(e,t){return`Expected the tool export "${e.exportName??`default`}" from "${e.logicalPath}" ${t}.`}export{resolveToolDefinition};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{resolvePackageSourceFilePath}from"#internal/application/package.js";import{pathToFileURL}from"node:url";import{
|
|
1
|
+
import{loadCompiledManifest}from"#runtime/loaders/manifest.js";import{resolvePackageSourceFilePath}from"#internal/application/package.js";import{pathToFileURL}from"node:url";import{getResolvedRuntimeAgentNode}from"#runtime/graph.js";import{getRuntimeCompiledArtifactsCacheKey}from"#runtime/compiled-artifacts-source.js";import{resolveRuntimeAgentGraph}from"#runtime/resolve-agent-graph.js";import{resolveRuntimeCompiledArtifactsVersionedCacheKey}from"#runtime/cache-key.js";import{getActiveRuntimeSession}from"#runtime/sessions/runtime-session.js";import{createRuntimeAdapterRegistry}from"#runtime/channels/registry.js";import{loadCompiledModuleMap}from"#runtime/loaders/module-map.js";const isCacheDisabled=process.env.EVE_DISABLE_AGENT_CACHE===`1`;function isDevelopmentRuntimeSnapshotRoot(e){return e.replaceAll(`\\`,`/`).includes(`/.eve/dev-runtime/snapshots/`)}function normalizeCompiledArtifactsSource(e){return e.kind!==`disk`||e.moduleMapLoaderPath!==void 0||!isDevelopmentRuntimeSnapshotRoot(e.appRoot)?e:{...e,moduleMapLoaderPath:resolvePackageSourceFilePath(`src/internal/authored-module-map-loader.ts`)}}async function loadFullBundle(e){let t=normalizeCompiledArtifactsSource(e),[n,r]=await Promise.all([loadCompiledManifest({compiledArtifactsSource:t}),loadRuntimeCompiledModuleMap(t)]),i=await resolveRuntimeAgentGraph({manifest:n,moduleMap:r}),a=i.root;return{adapterRegistry:createRuntimeAdapterRegistry({channels:collectResolvedChannels(i)}),compiledArtifactsSource:t,graph:i,hookRegistry:a.hookRegistry,moduleMap:r,resolvedAgent:a.agent,subagentRegistry:a.subagentRegistry,toolRegistry:a.toolRegistry,turnAgent:a.turnAgent}}async function loadRuntimeCompiledModuleMap(e){return e.kind===`disk`&&e.moduleMapLoaderPath!==void 0?await loadAuthoredSourceCompiledModuleMap(e):await loadCompiledModuleMap({compiledArtifactsSource:e})}async function loadAuthoredSourceCompiledModuleMap(e){if(e.moduleMapLoaderPath===void 0)throw Error(`Authored-source module map loading requires "moduleMapLoaderPath" in the compiled artifacts source.`);return await(await import(pathToFileURL(e.moduleMapLoaderPath).href)).loadCompiledModuleMapFromAuthoredSource({compiledArtifactsSource:e})}async function getOrLoadFullBundle(e){let t=normalizeCompiledArtifactsSource(e);if(isCacheDisabled)return loadFullBundle(t);let n=getActiveRuntimeSession(),r=getRuntimeCompiledArtifactsCacheKey(t),i=await resolveRuntimeCompiledArtifactsVersionedCacheKey(t),a=n.bundleCacheKeyBySourceKey.get(r);a!==void 0&&a!==i&&n.bundleCache.delete(a),n.bundleCacheKeyBySourceKey.set(r,i);let o=n.bundleCache.get(i);if(o!==void 0)return o;let s=loadFullBundle(t).catch(e=>{throw n.bundleCache.delete(i),n.bundleCacheKeyBySourceKey.get(r)===i&&n.bundleCacheKeyBySourceKey.delete(r),e});return n.bundleCache.set(i,s),s}async function getCompiledRuntimeAgentBundle(e){let t=await getOrLoadFullBundle(e.compiledArtifactsSource);if(e.nodeId===void 0)return t;let n=getResolvedRuntimeAgentNode(t.graph,e.nodeId);return{adapterRegistry:t.adapterRegistry,compiledArtifactsSource:t.compiledArtifactsSource,graph:{nodesByNodeId:t.graph.nodesByNodeId,root:n},hookRegistry:n.hookRegistry,moduleMap:t.moduleMap,nodeId:e.nodeId,resolvedAgent:n.agent,subagentRegistry:n.subagentRegistry,toolRegistry:n.toolRegistry,turnAgent:n.turnAgent}}function clearCompiledRuntimeAgentBundleCache(){let e=getActiveRuntimeSession();e.bundleCache.clear(),e.bundleCacheKeyBySourceKey.clear()}function collectResolvedChannels(e){let t=new Map;for(let n of e.nodesByNodeId.values())for(let e of n.channels)t.set(`${e.sourceId}:${e.name}`,e);return[...t.values()]}export{clearCompiledRuntimeAgentBundleCache,getCompiledRuntimeAgentBundle};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{pinnedNodeEngineMajor}from"../../node-engine.js";import{parseChatGptModelSelection}from"../../../shared/chatgpt-model.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{DEFAULT_CONNECT_PACKAGE_VERSION,resolveVersionToken}from"../version-tokens.js";import{applyPackageManagerWorkspaceConfiguration,isPackageManagerWorkspaceMember,patchWorkspaceRootPackageJson}from"../workspace-root.js";import{WEB_CHANNEL_TEMPLATES}from"./web-template.js";import{AGENT_INSTRUCTIONS_TEMPLATE}from"./instructions-template.js";import{SCAFFOLDED_AGENT_PATHS}from"./agent-paths.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.105`,DEFAULT_ZOD_PACKAGE_VERSION=`4.5.4`,DEFAULT_EVE_PACKAGE_CONTRACT={version:`0.71.
|
|
1
|
+
import{pinnedNodeEngineMajor}from"../../node-engine.js";import{parseChatGptModelSelection}from"../../../shared/chatgpt-model.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{DEFAULT_CONNECT_PACKAGE_VERSION,resolveVersionToken}from"../version-tokens.js";import{applyPackageManagerWorkspaceConfiguration,isPackageManagerWorkspaceMember,patchWorkspaceRootPackageJson}from"../workspace-root.js";import{WEB_CHANNEL_TEMPLATES}from"./web-template.js";import{AGENT_INSTRUCTIONS_TEMPLATE}from"./instructions-template.js";import{SCAFFOLDED_AGENT_PATHS}from"./agent-paths.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.105`,DEFAULT_ZOD_PACKAGE_VERSION=`4.5.4`,DEFAULT_EVE_PACKAGE_CONTRACT={version:`0.71.2`,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,t){return{[SCAFFOLDED_AGENT_PATHS.config]:renderAgentTemplate(e,t),[SCAFFOLDED_AGENT_PATHS.channel]:WEB_CHANNEL_TEMPLATES.default,[SCAFFOLDED_AGENT_PATHS.instructions]:AGENT_INSTRUCTIONS_TEMPLATE}}function renderAgentTemplate(e,t){let n=parseChatGptModelSelection(e);return n===void 0?BASE_AGENT_TEMPLATE.replaceAll(`__EVE_INIT_MODEL__`,e).replaceAll(`__EVE_INIT_REASONING__`,reasoningTemplateLine(t)):`import { defineAgent } from "eve";\nimport { chatgpt } from "eve/models/openai";\n\nexport default defineAgent({\n model: chatgpt(${JSON.stringify(n)}),\n${reasoningTemplateLine(t)}});\n`}function reasoningTemplateLine(e){return e===void 0||e===`provider-default`?``:` reasoning: "${e}",\n`}function renderTemplate(e,t){return e===BASE_AGENT_TEMPLATE&&parseChatGptModelSelection(t.model)!==void 0?renderAgentTemplate(t.model,t.reasoning):e.replaceAll(`__EVE_INIT_APP_NAME__`,t.appName).replaceAll(`__EVE_INIT_MODEL__`,t.model).replaceAll(`__EVE_INIT_REASONING__`,reasoningTemplateLine(t.reasoning)).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__",
|
|
@@ -36,6 +36,8 @@ export interface RoutedChildDelivery {
|
|
|
36
36
|
readonly inputSource?: string;
|
|
37
37
|
readonly childContinuationToken: string;
|
|
38
38
|
readonly childSessionInbox?: SessionInboxAddress;
|
|
39
|
+
/** The person's message whose text answered this bucket's question. */
|
|
40
|
+
readonly message?: DeliverPayload["message"];
|
|
39
41
|
readonly payload: {
|
|
40
42
|
readonly inputResponses: readonly InputResponse[];
|
|
41
43
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{inputTextKey,readAnswerText}from"#internal/input-text.js";import{createInputRequestedEvent,createTurnWaitingEvent}from"#protocol/message.js";import{resolveTextToResponse}from"#channel/resolve-text.js";import{getHarnessEmissionState}from"#harness/emission.js";import{getSessionUsage}from"#harness/turn-tag-state.js";import{getProxyInputRequests,toProxyInputRequestEntries}from"#harness/proxy-input-requests.js";import{resolveInputOutcome}from"#harness/input-request-resolution.js";import{SESSION_LIMIT_STOP_OPTION_ID}from"#harness/session-limit-continuation.js";async function emitProxiedInputRequest(e){return await e.emit(createInputRequestedEvent({requests:e.hookPayload.event.requests,sequence:e.hookPayload.event.sequence,stepIndex:e.hookPayload.event.stepIndex,taskId:e.hookPayload.event.taskId,turnId:e.hookPayload.event.turnId})),await e.emit(createTurnWaitingOnInputEvent(e.session)),toProxyInputRequestEntries(e.hookPayload)}async function emitProxiedAuthorizationEvent(e){await e.emit(e.hookPayload.event),e.hookPayload.event.type===`authorization.required`&&await e.emit(createTurnWaitingOnInputEvent(e.session))}function createTurnWaitingOnInputEvent(e){let t=getHarnessEmissionState(e.state);return createTurnWaitingEvent({on:`input`,sequence:t.sequence,turnId:t.turnId,usage:getSessionUsage(e)})}const CONSUMED_MESSAGE_KEYS=new Set([`context`,`message`,inputTextKey]);function routeDeliverPayload(e){let t=getProxyInputRequests(e.state),routable=(t,n)=>n!==void 0&&e.allowRoute?.(t,n)!==!1,n=resolveMessageAgainstQuestions({enabled:e.resolveMessage===!0,entries:t,payload:e.payload,routable}),r=[...e.payload.inputResponses??[],...n.responses],
|
|
1
|
+
import{inputTextKey,readAnswerText}from"#internal/input-text.js";import{createInputRequestedEvent,createTurnWaitingEvent}from"#protocol/message.js";import{resolveTextToResponse}from"#channel/resolve-text.js";import{getHarnessEmissionState}from"#harness/emission.js";import{getSessionUsage}from"#harness/turn-tag-state.js";import{getProxyInputRequests,toProxyInputRequestEntries}from"#harness/proxy-input-requests.js";import{resolveInputOutcome}from"#harness/input-request-resolution.js";import{SESSION_LIMIT_STOP_OPTION_ID}from"#harness/session-limit-continuation.js";async function emitProxiedInputRequest(e){return await e.emit(createInputRequestedEvent({requests:e.hookPayload.event.requests,sequence:e.hookPayload.event.sequence,stepIndex:e.hookPayload.event.stepIndex,taskId:e.hookPayload.event.taskId,turnId:e.hookPayload.event.turnId})),await e.emit(createTurnWaitingOnInputEvent(e.session)),toProxyInputRequestEntries(e.hookPayload)}async function emitProxiedAuthorizationEvent(e){await e.emit(e.hookPayload.event),e.hookPayload.event.type===`authorization.required`&&await e.emit(createTurnWaitingOnInputEvent(e.session))}function createTurnWaitingOnInputEvent(e){let t=getHarnessEmissionState(e.state);return createTurnWaitingEvent({on:`input`,sequence:t.sequence,turnId:t.turnId,usage:getSessionUsage(e)})}const CONSUMED_MESSAGE_KEYS=new Set([`context`,`message`,inputTextKey]);function routeDeliverPayload(e){let t=getProxyInputRequests(e.state),routable=(t,n)=>n!==void 0&&e.allowRoute?.(t,n)!==!1,n=resolveMessageAgainstQuestions({enabled:e.resolveMessage===!0,entries:t,payload:e.payload,routable}),[r]=n.responses,i=[...e.payload.inputResponses??[],...n.responses],a=new Map,o=[],s,bucketFor=e=>{let t=JSON.stringify([e.childContinuationToken,e.childSessionInbox?.sessionId??``,e.remote?.sessionId??``,e.event.sequence,e.event.stepIndex,e.event.turnId,e.inputSource??null]),n=a.get(t);if(n!==void 0)return n;let r={childContinuationToken:e.childContinuationToken,remote:e.remote,event:e.event,parentRequestIds:[],responses:[],routes:[],...e.childSessionInbox!==void 0&&{childSessionInbox:e.childSessionInbox},...e.workflowAsk!==void 0&&{workflowAsk:e.workflowAsk}};return a.set(t,r),r},c=new Set;for(let e of i){let n=t.get(e.requestId);if(n===void 0||!routable(e.requestId,n)){o.push(e);continue}if(c.has(e.requestId))continue;c.add(e.requestId),n.kind===`session-limit`&&e.optionId===SESSION_LIMIT_STOP_OPTION_ID&&(s={kind:`cancel-turn`});let r=bucketFor(n);r.parentRequestIds.push(e.requestId),r.responses.push(e),r.routes.push(n)}let l=[...a.values()].map(({workflowAsk:n,remote:i,childContinuationToken:a,childSessionInbox:o,event:s,parentRequestIds:c,responses:l,routes:u})=>{let d=new Set(c),f=new Set(d);for(let e of u)if(e.batch!==void 0&&batchResolves({batch:e.batch,childContinuationToken:a,entries:t,responseIds:d}))for(let t of e.batch.requestIds)f.add(t);return{childContinuationToken:a,payload:{inputResponses:l},resolved:{event:s,resolutions:resolveRetiredRequests({entries:t,responses:l,retireRequestIds:f})},...o!==void 0&&{childSessionInbox:o},...r!==void 0&&l.includes(r)&&{message:e.payload.message},...n!==void 0&&{workflowAsk:n},...i!==void 0&&{remote:i},...u[0]?.inputSource!==void 0&&{inputSource:u[0].inputSource}}}),u={};for(let[t,r]of Object.entries(e.payload))t!==`inputResponses`&&r!==void 0&&(n.consumed&&CONSUMED_MESSAGE_KEYS.has(t)||(u[t]=r));return o.length>0&&(u.inputResponses=o),{forChildren:l,forSelf:Object.keys(u).length>0?u:void 0,parentAction:s}}function resolveRetiredRequests(e){let t=new Map(e.responses.map(e=>[e.requestId,e])),n=[];for(let r of e.retireRequestIds){let i=e.entries.get(r);i!==void 0&&n.push(toInputResolution(r,i,t.get(r)))}return n}function toInputResolution(e,t,n){let r=resolveInputOutcome(t.kind,n),i={kind:t.kind,outcome:r,requestId:e};return n===void 0?i:{...i,response:n}}function resolveMessageAgainstQuestions(e){let t={consumed:!1,responses:[]};if(!e.enabled||(e.payload.inputResponses?.length??0)>0||e.payload.message===void 0)return t;let n=[...e.entries].filter(([t,n])=>n.kind===`question`&&e.routable(t,n)),r=n.flatMap(([e,t])=>{let n=t.workflowAsk?.question??t.question;return n===void 0?[]:[{requestId:e,...n}]});if(r.length===0)return t;let[i]=r,a=readAnswerText(e.payload),o=n.length===1&&i!==void 0&&a!==void 0?resolveTextToResponse(a,i):void 0;return o===void 0?t:{consumed:!0,responses:[o]}}function batchResolves(e){return e.batch.approvalRequestIds.length===0||e.batch.approvalRequestIds.every(t=>{let n=e.entries.get(t);return n===void 0||!sameBatch(n,e)||e.responseIds.has(t)})}function sameBatch(e,t){return e.childContinuationToken===t.childContinuationToken&&e.batch?.requestIds.length===t.batch.requestIds.length&&e.batch.requestIds.every((e,n)=>e===t.batch.requestIds[n])}export{createTurnWaitingOnInputEvent,emitProxiedAuthorizationEvent,emitProxiedInputRequest,routeDeliverPayload};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
async function executeAskQuestionTool(e,t){"use workflow";return toAskQuestionOutput(await t.ask(toAskQuestionRequest(e)))}function toAskQuestionRequest(e){let t=e.options?.map(e=>({description:e.description,id:e.label,label:e.label}));return{allowFreeform:!0,display:t===void 0?`text`:`select`,prompt:e.question,...t!==void 0&&{options:t}}}function toAskQuestionOutput(e){switch(e.status){case`answered`:return{answer:e.optionId??e.text??``,status:`answered`};case`cancelled`:return{interrupted:!0};case`unavailable`:return{status:`unavailable`}}}executeAskQuestionTool.workflowId=`workflow//eve@0.71.
|
|
1
|
+
async function executeAskQuestionTool(e,t){"use workflow";return toAskQuestionOutput(await t.ask(toAskQuestionRequest(e)))}function toAskQuestionRequest(e){let t=e.options?.map(e=>({description:e.description,id:e.label,label:e.label}));return{allowFreeform:!0,display:t===void 0?`text`:`select`,prompt:e.question,...t!==void 0&&{options:t}}}function toAskQuestionOutput(e){switch(e.status){case`answered`:return{answer:e.optionId??e.text??``,status:`answered`};case`cancelled`:return{interrupted:!0};case`unavailable`:return{status:`unavailable`}}}executeAskQuestionTool.workflowId=`workflow//eve@0.71.2//executeAskQuestionTool`;export{executeAskQuestionTool,toAskQuestionOutput,toAskQuestionRequest};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import{contextStorage}from"#context/container.js";import{SandboxKey}from"#context/keys.js";import{basename}from"node:path";import{defineJsonSchema}from"#tools/schema.js";import{resolveAbsoluteFilePath}from"#execution/sandbox/require-sandbox.js";import{defineTool}from"#tools/definition.js";import{toolLabel}from"#tools/tool-label.js";import{toolOutput,toolOutputPart}from"#tools/model-output.js";import{executeReadFileOnSandbox}from"#execution/sandbox/read-file.js";const READ_FILE_INPUT_SCHEMA=defineJsonSchema({type:`object`,properties:{filePath:{type:`string`,description:`The absolute path to the file to read. A leading $HOME is supported.`},limit:{type:`integer`,minimum:1,description:`Maximum number of lines to return. Defaults to 2000.`},offset:{type:`integer`,minimum:1,description:`1-based line number to start from. Defaults to 1.`}},required:[`filePath`],additionalProperties:!1}),READ_FILE_OUTPUT_SCHEMA=defineJsonSchema({type:`object`,properties:{content:{type:`string`},image:{type:`object`,properties:{height:{type:`integer`,minimum:1},mediaType:{type:`string`},size:{type:`integer`,minimum:0},width:{type:`integer`,minimum:1}},required:[`mediaType`,`size`],additionalProperties:!1},nextOffset:{type:`integer`,minimum:1},path:{type:`string`},totalLines:{type:`integer`,minimum:0},truncated:{type:`boolean`}},required:[`content`,`path`,`totalLines`,`truncated`],additionalProperties:!1}),readFile=defineTool({label:{start:e=>toolLabel(`Read`,e.filePath)},description:[`Read a file from the local filesystem. If the path does not exist, an error is returned.`,``,`Usage:`,`- The filePath parameter should be an absolute path or begin with $HOME/.`,`- By default, this tool returns up to 2000 lines from the start of the file.`,`- The offset parameter is the line number to start from (1-indexed).`,`- To read later sections, call this tool again with a larger offset.`,'- Contents are returned with each line prefixed by its line number as `<line>: <content>`. For example, if a file has contents "foo\\n", you will receive "1: foo\\n".',`- Any line longer than 2000 characters is truncated.`,"- PNG, JPEG, GIF, and WebP files up to 3 MiB are shown to you as images, including files named in `Attached file <path>` references.",`- Call this tool in parallel when you know there are multiple files you want to read.`,`- Avoid tiny repeated slices (30 line chunks). If you need more context, read a larger window.`].join(`
|
|
2
|
-
`),async execute(e,t){return await executeReadFileOnSandbox(await t.getSandbox(),e)},inputSchema:READ_FILE_INPUT_SCHEMA,outputSchema:READ_FILE_OUTPUT_SCHEMA,async toModelOutput(e){if(e.image===void 0)return toolOutput.json(e);let t=await contextStorage.getStore()?.get(SandboxKey)?.get(),n=t==null?null:await t.readBinaryFile({path:await resolveAbsoluteFilePath(t,e.path)});return n===null?toolOutput.text(`${e.content} The image could not be loaded.`):toolOutput.content([toolOutputPart.text(e.content),toolOutputPart.file(Buffer.from(n).toString(`base64`),{filename:basename(e.path),mediaType:e.image.mediaType})])}});export{READ_FILE_INPUT_SCHEMA,READ_FILE_OUTPUT_SCHEMA,readFile as default,readFile};
|
|
2
|
+
`),async execute(e,t){return await executeReadFileOnSandbox(await t.getSandbox(),e)},inputSchema:READ_FILE_INPUT_SCHEMA,outputSchema:READ_FILE_OUTPUT_SCHEMA,async toModelOutput(e){if(e.image===void 0)return toolOutput.json(e);let t=await contextStorage.getStore()?.get(SandboxKey)?.get(),n=t==null?null:await t.readBinaryFile({path:await resolveAbsoluteFilePath(t,e.path)});return n===null?toolOutput.text(`${e.content} The image could not be loaded.`):n.byteLength===e.image.size?toolOutput.content([toolOutputPart.text(e.content),toolOutputPart.file(Buffer.from(n).toString(`base64`),{filename:basename(e.path),mediaType:e.image.mediaType})]):toolOutput.text(`${e.content} The image changed after it was read; read it again.`)}});export{READ_FILE_INPUT_SCHEMA,READ_FILE_OUTPUT_SCHEMA,readFile as default,readFile};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{sleep}from"#compiled/@workflow/core/index.js";async function executeSleepTool(e,t){"use workflow";let n=new Promise(e=>t.abortSignal.addEventListener(`abort`,()=>e(`interrupted`),{once:!0})),r=sleep(Math.ceil(e.seconds*1e3)).then(()=>`elapsed`);return await Promise.race([r,n])===`elapsed`?{waitedSeconds:e.seconds}:{interrupted:!0}}executeSleepTool.workflowId=`workflow//eve@0.71.
|
|
1
|
+
import{sleep}from"#compiled/@workflow/core/index.js";async function executeSleepTool(e,t){"use workflow";let n=new Promise(e=>t.abortSignal.addEventListener(`abort`,()=>e(`interrupted`),{once:!0})),r=sleep(Math.ceil(e.seconds*1e3)).then(()=>`elapsed`);return await Promise.race([r,n])===`elapsed`?{waitedSeconds:e.seconds}:{interrupted:!0}}executeSleepTool.workflowId=`workflow//eve@0.71.2//executeSleepTool`;export{executeSleepTool};
|
package/docs/channels/custom.mdx
CHANGED
|
@@ -67,6 +67,7 @@ Each route receives these operation surfaces:
|
|
|
67
67
|
- `attachSession(sessionId)` creates an I/O-free handle pinned to one durable session ID.
|
|
68
68
|
- `to(channel, target).send(message, options)` hands work to another authored channel.
|
|
69
69
|
- `params`, `waitUntil`, and `requestIp` provide request metadata and lifetime control.
|
|
70
|
+
- `describe()` returns the agent's name, description, and the compiled tools a caller can run outside a turn, with their JSON schemas, sorted by name. It carries no paths, config, or other inspection detail, so a channel can publish it to its callers. Tools that need a turn (framework tools, workflow and provider tools, tools without `execute`) and tools added by dynamic resolvers or subagents are left out.
|
|
70
71
|
|
|
71
72
|
Event handlers receive `(eventData, channel, ctx)`. `ctx.session.id` identifies
|
|
72
73
|
the exact session, while `channel.continuation` exposes the current address and
|
|
@@ -81,7 +81,7 @@ export default disableTool();
|
|
|
81
81
|
|
|
82
82
|
### `read_file`
|
|
83
83
|
|
|
84
|
-
`read_file` reads text files from the sandbox with line-numbered output, and shows PNG, JPEG, GIF, and WebP images up to 3 MiB to the model as images. It accepts absolute paths and paths beginning with `$HOME/`.
|
|
84
|
+
`read_file` reads text files from the sandbox with line-numbered output, and shows PNG, JPEG, GIF, and WebP images up to 3 MiB to the model as images. Images are detected from their bytes, so a missing or mismatched filename extension does not matter, and text files are always read as text. It accepts absolute paths and paths beginning with `$HOME/`.
|
|
85
85
|
|
|
86
86
|
```sh
|
|
87
87
|
eve add tool/read_file
|
|
@@ -219,7 +219,7 @@ Message sends default to `"steer"`. Before assistant output begins, eve interrup
|
|
|
219
219
|
|
|
220
220
|
If the session is waiting on a human-in-the-loop approval, respond with the channel’s Approve or Cancel controls. Text that doesn't match an option doesn't approve the call. From the person the turn serves, it steers the turn and cancels the approval, even when sent with `turnPolicy: "queue"`, since the turn can't end until that person acts; from anyone else, it waits until the turn ends. If they had already approved some calls in the batch, those calls still run. Cancelling the turn withdraws the approval, and a later answer to it approves nothing.
|
|
221
221
|
|
|
222
|
-
A pending `ctx.ask()` question from a tool, such as `ask_question`, can be answered with plain text. When it is the only pending question, a message that matches an option answers it, and so does any message when the question allows free text. Otherwise eve does not guess which question the text addresses: the message follows the normal `turnPolicy`. A steering message withdraws the questions of the `execute` workflow tool calls the turn waits on, which resolve as `cancelled`; a task's questions stay open. Questions from subagents always need a structured response. Use structured responses to target requests unambiguously.
|
|
222
|
+
A pending `ctx.ask()` question from a tool, such as `ask_question`, can be answered with plain text. When it is the only pending question, a message that matches an option answers it, and so does any message when the question allows free text. The stream records that message as `message.received`, carrying its delivery id, just before the `input.resolved` it produces. Otherwise eve does not guess which question the text addresses: the message follows the normal `turnPolicy`. A steering message withdraws the questions of the `execute` workflow tool calls the turn waits on, which resolve as `cancelled`; a task's questions stay open. Questions from subagents always need a structured response. Use structured responses to target requests unambiguously.
|
|
223
223
|
|
|
224
224
|
A structured response matches any currently pending request by ID, not only the newest batch. It becomes stale only after that request was answered, cleared, or cancelled. eve delivers a stale response to the model as a new user message, and the model decides whether the old selection still matters. A stale approval never authorizes the earlier tool call; the model must request the action and approval again if they are still needed.
|
|
225
225
|
|
package/docs/extensions.md
CHANGED
|
@@ -357,7 +357,7 @@ export default defineHook({
|
|
|
357
357
|
});
|
|
358
358
|
```
|
|
359
359
|
|
|
360
|
-
`toolResultFrom` recognizes the mounted `crm__search` result from the original definition, not the namespaced string. Publishers should keep
|
|
360
|
+
`toolResultFrom` recognizes the mounted `crm__search` result from the original definition, not the namespaced string. Publishers should keep descriptions distinct across different tool definitions so eve can assign each definition an unambiguous identity. Re-exporting the same definition, such as from a subagent's `tools/` directory, does not conflict.
|
|
361
361
|
|
|
362
362
|
### Bundled development extensions
|
|
363
363
|
|
package/docs/guides/hooks.md
CHANGED
|
@@ -135,6 +135,8 @@ import { search } from "@acme/crm/tools";
|
|
|
135
135
|
const crmSearch = toolResultFrom(event.data.result, search); // typed; matches crm__search
|
|
136
136
|
```
|
|
137
137
|
|
|
138
|
+
When one definition is mounted under more than one tool name, for example when a subagent re-exports an extension tool, `toolResultFrom` matches results from every mounted name.
|
|
139
|
+
|
|
138
140
|
### Persist events to your own database
|
|
139
141
|
|
|
140
142
|
Every event carries a `meta` envelope with `meta.id`, a unique, sortable identifier for that event. It makes a natural primary key for an events table:
|