eve 0.26.2 → 0.27.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +33 -0
- package/dist/src/channel/resolve-active-session.d.ts +4 -0
- package/dist/src/channel/resolve-active-session.js +1 -0
- package/dist/src/channel/routes.d.ts +11 -0
- package/dist/src/cli/dev/tui/vercel-trusted-sources-policy.d.ts +1 -1
- package/dist/src/cli/dev/tui/vercel-trusted-sources.js +1 -1
- package/dist/src/compiled/.vendor-stamp.json +16 -16
- package/dist/src/compiled/@ai-sdk/anthropic/index.js +2 -2
- package/dist/src/compiled/@ai-sdk/google/index.d.ts +9 -2
- package/dist/src/compiled/@ai-sdk/google/index.js +6 -6
- package/dist/src/compiled/@ai-sdk/mcp/index.d.ts +18 -3
- package/dist/src/compiled/@ai-sdk/mcp/index.js +1 -1
- package/dist/src/compiled/@ai-sdk/openai/index.d.ts +285 -24
- package/dist/src/compiled/@ai-sdk/openai/index.js +2 -2
- package/dist/src/compiled/@ai-sdk/otel/index.js +1 -1
- package/dist/src/compiled/@ai-sdk/provider-utils/index.d.ts +7 -3
- package/dist/src/compiled/@vercel/oidc/index.js +28 -2
- package/dist/src/compiled/@vercel/sandbox/api-client/api-client.d.ts +11 -0
- package/dist/src/compiled/@vercel/sandbox/api-client/validators.d.ts +7 -0
- package/dist/src/compiled/@vercel/sandbox/command.d.ts +8 -0
- package/dist/src/compiled/@vercel/sandbox/execution-context.d.ts +116 -0
- package/dist/src/compiled/@vercel/sandbox/index.d.ts +3 -1
- package/dist/src/compiled/@vercel/sandbox/index.js +20 -19
- package/dist/src/compiled/@vercel/sandbox/network-policy.d.ts +13 -5
- package/dist/src/compiled/@vercel/sandbox/sandbox-user.d.ts +212 -0
- package/dist/src/compiled/@vercel/sandbox/sandbox.d.ts +133 -2
- package/dist/src/compiled/@vercel/sandbox/session.d.ts +2 -1
- package/dist/src/compiled/@vercel/sandbox/snapshot.d.ts +1 -1
- package/dist/src/compiled/@workflow/core/create-hook.d.ts +41 -22
- package/dist/src/compiled/@workflow/core/flushable-stream.d.ts +29 -0
- package/dist/src/compiled/@workflow/core/global.d.ts +2 -0
- package/dist/src/compiled/@workflow/core/index.js +2 -2
- package/dist/src/compiled/@workflow/core/private.d.ts +6 -17
- package/dist/src/compiled/@workflow/core/private.js +1 -1
- package/dist/src/compiled/@workflow/core/replay-payload-cache.d.ts +56 -0
- package/dist/src/compiled/@workflow/core/runtime/constants.d.ts +11 -0
- package/dist/src/compiled/@workflow/core/runtime/helpers.d.ts +6 -4
- package/dist/src/compiled/@workflow/core/runtime/resume-hook.d.ts +4 -1
- package/dist/src/compiled/@workflow/core/runtime/step-executor.d.ts +39 -0
- package/dist/src/compiled/@workflow/core/runtime.js +3 -3
- package/dist/src/compiled/@workflow/core/serialization.d.ts +44 -4
- package/dist/src/compiled/@workflow/core/symbols.d.ts +13 -0
- package/dist/src/compiled/@workflow/core/version.d.ts +1 -1
- package/dist/src/compiled/@workflow/core/workflow.js +1 -1
- package/dist/src/compiled/@workflow/errors/error-codes.d.ts +2 -0
- package/dist/src/compiled/@workflow/errors/index.d.ts +14 -0
- package/dist/src/compiled/@workflow/errors/index.js +1 -1
- package/dist/src/compiled/@workflow/world/events.d.ts +15 -0
- package/dist/src/compiled/@workflow/world/hooks.d.ts +2 -1
- package/dist/src/compiled/@workflow/world/interfaces.d.ts +77 -4
- package/dist/src/compiled/@workflow/world-local/index.js +4 -4
- package/dist/src/compiled/@workflow/world-vercel/index.js +16 -16
- package/dist/src/compiled/_chunks/node/{auth-BuQkq4Gr.js → auth-l7F2PF2b.js} +2 -2
- package/dist/src/compiled/_chunks/node/{version-DD-FX9rK.js → version-CjHTLx2a.js} +1 -1
- package/dist/src/compiled/_chunks/node/virtual-loader-Cwgujv7l.js +1 -0
- package/dist/src/compiled/_chunks/workflow/attribute-changes-Dk1fP6vt.js +20 -0
- package/dist/src/compiled/_chunks/workflow/{chunk-BHKSVoKr.js → chunk-BTyA9uPd.js} +1 -1
- package/dist/src/compiled/_chunks/workflow/dist-B3qkUnLJ.js +3 -0
- package/dist/src/compiled/_chunks/workflow/{dist-CSfKNxQW.js → dist-BX517Nmz.js} +2 -2
- package/dist/src/compiled/_chunks/workflow/{dist-zLevmMyU.js → dist-C_VDTghO.js} +10 -10
- package/dist/src/compiled/_chunks/workflow/{dist-CttsoN4D.js → dist-CrxV2rsR.js} +1 -1
- package/dist/src/compiled/_chunks/workflow/{functions-PT9ri9Hu.js → functions-Dv8dc_-I.js} +1 -1
- package/dist/src/compiled/_chunks/workflow/resume-hook-czpG5xnP.js +1 -0
- package/dist/src/compiled/_chunks/workflow/run-6zaMjFY6.js +1 -0
- package/dist/src/compiled/_chunks/workflow/sleep-B2u06FWc.js +1 -0
- package/dist/src/compiled/_chunks/workflow/{src-CQuMexnO.js → src-D1EltLDA.js} +1 -1
- package/dist/src/compiled/_chunks/workflow/{token-CaY0nA5J.js → token-Cz223z3C.js} +1 -1
- package/dist/src/compiled/_chunks/workflow/token-DWqA5-DA.js +1 -0
- package/dist/src/compiled/_chunks/workflow/token-util-B6qBs3-0.js +27 -0
- package/dist/src/compiled/_chunks/workflow/{undici-fb54XL8i.js → undici-C2ZhYnV9.js} +1 -1
- package/dist/src/compiled/_chunks/workflow/wrapper-Cc2otuUR.js +6 -0
- package/dist/src/compiled/env-runner/index.js +1 -1
- package/dist/src/compiled/env-runner/node-worker.js +1 -1
- package/dist/src/compiled/eventsource-parser/stream/index.d.ts +16 -3
- package/dist/src/compiled/jose/index.js +1 -1
- package/dist/src/compiler/compile-from-memory.d.ts +5 -0
- package/dist/src/compiler/compile-from-memory.js +1 -1
- package/dist/src/compiler/extension-compatibility.d.ts +10 -10
- package/dist/src/compiler/extension-compatibility.js +1 -1
- package/dist/src/execution/deliver-payloads.d.ts +1 -1
- package/dist/src/execution/deliver-payloads.js +1 -1
- package/dist/src/execution/workflow-entry.js +1 -1
- package/dist/src/execution/workflow-steps.js +1 -1
- package/dist/src/harness/compaction-prompt.d.ts +19 -1
- package/dist/src/harness/compaction-prompt.js +7 -5
- package/dist/src/harness/compaction.d.ts +4 -11
- package/dist/src/harness/compaction.js +1 -1
- package/dist/src/harness/prompt-cache.d.ts +16 -5
- package/dist/src/harness/prompt-cache.js +1 -1
- package/dist/src/harness/session-limit-continuation.d.ts +8 -0
- package/dist/src/harness/session-limit-continuation.js +1 -1
- package/dist/src/harness/session-limit-enforcement.d.ts +9 -6
- package/dist/src/harness/session-limit-enforcement.js +1 -1
- package/dist/src/harness/stale-input-responses.d.ts +21 -3
- package/dist/src/harness/stale-input-responses.js +2 -2
- package/dist/src/harness/token-estimate.d.ts +9 -0
- package/dist/src/harness/token-estimate.js +1 -0
- package/dist/src/harness/tool-loop.js +2 -2
- package/dist/src/harness/turn-cancellation.d.ts +13 -0
- package/dist/src/harness/turn-cancellation.js +1 -1
- package/dist/src/internal/application/package.js +1 -1
- package/dist/src/internal/nitro/host/copy-host-middleware.js +1 -1
- package/dist/src/internal/nitro/routes/channel-dispatch.js +1 -1
- package/dist/src/internal/workflow-bundle/vercel-workflow-output.js +1 -1
- package/dist/src/node_modules/.pnpm/@vercel_sdk@1.28.8/node_modules/@vercel/sdk/esm/models/updateprojectblock.js +1 -0
- package/dist/src/node_modules/.pnpm/@vercel_sdk@1.28.8/node_modules/@vercel/sdk/esm/models/updateprojectprojectsbranchmatcher.js +1 -0
- package/dist/src/packages/eve-catalog/src/index.js +1 -1
- package/dist/src/public/channels/auth.d.ts +59 -9
- package/dist/src/public/channels/auth.js +1 -1
- package/dist/src/public/channels/discord/defaults.js +1 -1
- package/dist/src/public/channels/linear/api.d.ts +2 -0
- package/dist/src/public/channels/linear/api.js +3 -1
- package/dist/src/public/channels/linear/defaults.js +2 -2
- package/dist/src/public/channels/linear/hitl.d.ts +8 -13
- package/dist/src/public/channels/linear/hitl.js +3 -3
- package/dist/src/public/channels/linear/index.d.ts +1 -1
- package/dist/src/public/channels/linear/index.js +1 -1
- package/dist/src/public/channels/linear/linearChannel.js +1 -1
- package/dist/src/public/channels/slack/api.d.ts +20 -0
- package/dist/src/public/channels/slack/api.js +1 -1
- package/dist/src/public/channels/slack/defaults.js +1 -1
- package/dist/src/public/channels/slack/inbound.d.ts +31 -0
- package/dist/src/public/channels/slack/inbound.js +1 -1
- package/dist/src/public/channels/slack/index.d.ts +2 -2
- package/dist/src/public/channels/slack/slackChannel.d.ts +72 -4
- package/dist/src/public/channels/slack/slackChannel.js +1 -1
- package/dist/src/public/channels/teams/defaults.js +2 -2
- package/dist/src/public/channels/teams/index.d.ts +1 -1
- package/dist/src/public/channels/teams/teamsChannel.d.ts +7 -2
- package/dist/src/public/channels/teams/teamsChannel.js +1 -1
- package/dist/src/public/channels/telegram/defaults.js +1 -1
- package/dist/src/public/definitions/channel.d.ts +1 -1
- package/dist/src/public/next/index.js +1 -1
- package/dist/src/public/nuxt/index.d.ts +1 -1
- package/dist/src/public/nuxt/index.js +1 -1
- package/dist/src/public/nuxt/module.d.ts +10 -24
- package/dist/src/public/nuxt/module.js +1 -1
- package/dist/src/public/nuxt/routing.d.ts +5 -39
- package/dist/src/public/nuxt/routing.js +1 -1
- package/dist/src/public/nuxt/vercel-services.d.ts +117 -0
- package/dist/src/public/nuxt/vercel-services.js +1 -0
- package/dist/src/runtime/framework-tools/connection-search-dynamic.js +2 -1
- package/dist/src/runtime/framework-tools/todo.js +1 -1
- package/dist/src/runtime/governance/auth/http-basic.js +1 -1
- package/dist/src/setup/scaffold/create/add-to-project.js +1 -1
- package/dist/src/setup/scaffold/create/project.js +2 -2
- package/dist/src/setup/scaffold/create/web-template.d.ts +1 -1
- package/dist/src/setup/scaffold/create/web-template.js +90 -5
- package/dist/src/setup/scaffold/update/channels.js +2 -2
- package/dist/src/setup/scaffold/update/connections.js +1 -1
- package/dist/src/{public/next → shared}/resolve-eve-binary.d.ts +1 -1
- package/docs/agent-config.md +10 -5
- package/docs/channels/slack.mdx +76 -10
- package/docs/channels/teams.mdx +10 -3
- package/docs/extensions.md +115 -77
- package/docs/guides/auth-and-route-protection.md +14 -1
- package/docs/guides/deployment/vercel.mdx +1 -1
- package/docs/guides/frontend/nuxt.mdx +22 -1
- package/docs/guides/frontend/overview.mdx +2 -0
- package/docs/meta.json +1 -0
- package/package.json +22 -22
- package/dist/src/compiled/@workflow/core/step-hydration-cache.d.ts +0 -148
- package/dist/src/compiled/_chunks/node/virtual-loader-B8K8w9cr.js +0 -1
- package/dist/src/compiled/_chunks/workflow/attribute-changes-CXiYB8h9.js +0 -20
- package/dist/src/compiled/_chunks/workflow/dist-BYo8Gno2.js +0 -3
- package/dist/src/compiled/_chunks/workflow/resume-hook-CHXbXuRZ.js +0 -1
- package/dist/src/compiled/_chunks/workflow/run-BjtAGa3_.js +0 -1
- package/dist/src/compiled/_chunks/workflow/sleep-BJAv0MFP.js +0 -1
- package/dist/src/compiled/_chunks/workflow/token-D4VIwGlD.js +0 -1
- package/dist/src/compiled/_chunks/workflow/wrapper-ulTvoTdW.js +0 -6
- package/dist/src/node_modules/.pnpm/@vercel_sdk@1.28.1/node_modules/@vercel/sdk/esm/models/updateprojectprojectsaction.js +0 -1
- package/dist/src/node_modules/.pnpm/@vercel_sdk@1.28.1/node_modules/@vercel/sdk/esm/models/updateprojectprojectsoptionsallowlist.js +0 -1
- package/dist/src/public/nuxt/vercel-json.d.ts +0 -17
- package/dist/src/public/nuxt/vercel-json.js +0 -1
- /package/dist/src/node_modules/.pnpm/{@vercel_sdk@1.28.1 → @vercel_sdk@1.28.8}/node_modules/@vercel/sdk/esm/lib/primitives.js +0 -0
- /package/dist/src/node_modules/.pnpm/{@vercel_sdk@1.28.1 → @vercel_sdk@1.28.8}/node_modules/@vercel/sdk/esm/lib/schemas.js +0 -0
- /package/dist/src/node_modules/.pnpm/{@vercel_sdk@1.28.1 → @vercel_sdk@1.28.8}/node_modules/@vercel/sdk/esm/models/aclaction.js +0 -0
- /package/dist/src/node_modules/.pnpm/{@vercel_sdk@1.28.1 → @vercel_sdk@1.28.8}/node_modules/@vercel/sdk/esm/models/sdkvalidationerror.js +0 -0
- /package/dist/src/node_modules/.pnpm/{@vercel_sdk@1.28.1 → @vercel_sdk@1.28.8}/node_modules/@vercel/sdk/esm/types/defaultToZeroValue.js +0 -0
- /package/dist/src/node_modules/.pnpm/{@vercel_sdk@1.28.1 → @vercel_sdk@1.28.8}/node_modules/@vercel/sdk/esm/types/fp.js +0 -0
- /package/dist/src/node_modules/.pnpm/{@vercel_sdk@1.28.1 → @vercel_sdk@1.28.8}/node_modules/@vercel/sdk/esm/types/primitives.js +0 -0
- /package/dist/src/node_modules/.pnpm/{@vercel_sdk@1.28.1 → @vercel_sdk@1.28.8}/node_modules/@vercel/sdk/esm/types/rfcdate.js +0 -0
- /package/dist/src/node_modules/.pnpm/{@vercel_sdk@1.28.1 → @vercel_sdk@1.28.8}/node_modules/@vercel/sdk/esm/types/smartUnion.js +0 -0
- /package/dist/src/node_modules/.pnpm/{@vercel_sdk@1.28.1 → @vercel_sdk@1.28.8}/node_modules/@vercel/sdk/esm/types/unrecognized.js +0 -0
- /package/dist/src/{public/next → shared}/resolve-eve-binary.js +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
import{slackMrkdwnToGfm}from"#public/channels/slack/mrkdwn.js";function parseAppMentionEvent(e){if(e.type!==`event_callback`)return null;let t=e.event;return!t||t.type!==`app_mention`?null:buildSlackMessage(t,e.team_id)}function parseDirectMessageEvent(e){if(e.type!==`event_callback`)return null;let t=e.event;if(!t||t.type!==`message`)return null;let n=t;return n.channel_type!==`im
|
|
1
|
+
import{isObject}from"#shared/guards.js";import{slackMrkdwnToGfm}from"#public/channels/slack/mrkdwn.js";function parseSlackEventEnvelope(t){let n=JSON.parse(t);if(!isObject(n)||n.type!==`event_callback`)return null;let r=n.event;return!isObject(r)||typeof r.type!=`string`||r.type.length===0?null:n}function parseAppMentionEvent(e){if(e.type!==`event_callback`)return null;let t=e.event;return!t||t.type!==`app_mention`?null:buildSlackMessage(t,e.team_id)}function slackEventBotUserId(e){return e.authorizations?.find(e=>e.is_bot===!0&&typeof e.user_id==`string`)?.user_id}function parseMessageEvent(e){if(e.type!==`event_callback`)return null;let t=e.event;return!t||t.type!==`message`?null:buildSlackMessage(t,e.team_id)}function parseDirectMessageEvent(e){if(e.type!==`event_callback`)return null;let t=e.event;if(!t||t.type!==`message`)return null;let n=t;return n.channel_type!==`im`||!isHumanMessage(n)?null:buildSlackMessage(n,e.team_id)}function isHumanMessage(e){return typeof e.subtype==`string`&&e.subtype.length>0&&e.subtype!==`file_share`?!1:!(typeof e.bot_id==`string`&&e.bot_id.length>0)}function slackMessageFromWebhookPayload(e){return e.kind===`direct_message`&&(typeof e.subtype==`string`&&e.subtype.length>0&&e.subtype!==`file_share`||typeof e.botId==`string`&&e.botId.length>0)||!e.channelId||!e.ts?null:{text:e.text,markdown:slackMrkdwnToGfm(e.text),ts:e.ts,threadTs:e.threadTs,channelId:e.channelId,teamId:e.teamId,author:parsePayloadAuthor(e),attachments:parsePayloadAttachments(e.files),raw:e.raw}}function buildSlackMessage(e,n){let r=typeof e.channel==`string`?e.channel:``,i=typeof e.ts==`string`?e.ts:``;if(!r||!i)return null;let a=typeof e.text==`string`?e.text:``,o=typeof e.thread_ts==`string`?e.thread_ts:i,s=typeof n==`string`?n:void 0;return{text:a,markdown:slackMrkdwnToGfm(a),ts:i,threadTs:o,channelId:r,teamId:s,author:parseAuthor(e),attachments:parseAttachments(e.files),raw:e}}function parseAuthor(e){let t=typeof e.user==`string`?e.user:``;if(t)return{userId:t,userName:typeof e.username==`string`?e.username:void 0,fullName:void 0,isBot:typeof e.bot_id==`string`&&e.bot_id.length>0,isMe:!1}}function parseAttachments(e){return Array.isArray(e)?e.map(toAttachment):[]}function toAttachment(e){let t=typeof e.mimetype==`string`?e.mimetype:void 0,n=typeof e.url_private==`string`?e.url_private:void 0;return{id:typeof e.id==`string`?e.id:``,type:inferAttachmentType(t),url:n,name:typeof e.name==`string`?e.name:void 0,mimeType:t,size:typeof e.size==`number`?e.size:void 0}}function toPayloadAttachment(e){return{id:e.id,type:e.type,url:e.url,name:e.name,mimeType:e.mimeType,size:e.size}}function inferAttachmentType(e){return e===void 0?`file`:e.startsWith(`image/`)?`image`:e.startsWith(`video/`)?`video`:e.startsWith(`audio/`)?`audio`:`file`}function parsePayloadAuthor(e){if(!e.userId)return;let t=e.raw;return{userId:e.userId,userName:typeof t.username==`string`?t.username:void 0,fullName:void 0,isBot:typeof t.bot_id==`string`&&t.bot_id.length>0,isMe:!1}}function parsePayloadAttachments(e){return Array.isArray(e)?e.map(toPayloadAttachment):[]}export{parseAppMentionEvent,parseDirectMessageEvent,parseMessageEvent,parseSlackEventEnvelope,slackEventBotUserId,slackMessageFromWebhookPayload};
|
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
* without taking a direct `ai` dependency.
|
|
6
6
|
*/
|
|
7
7
|
export type { ModelMessage } from "ai";
|
|
8
|
-
export { slackChannel, type SlackApiResponse, type SlackAuthorizationEventContext, type SlackAuthorizationRequiredHandler, type SlackBotToken, type SlackChannel, type SlackChannelConfig, type SlackChannelCredentials, type SlackChannelEvents, type SlackChannelState, type SlackContext, type SlackEventContext, type SlackHandle, type SlackInboundResult, type SlackInboundResultOrPromise, type
|
|
9
|
-
export type { SlackAttachment, SlackAuthor, SlackInboundContext, SlackMessage, } from "#public/channels/slack/inbound.js";
|
|
8
|
+
export { slackChannel, type SlackApiResponse, type SlackAuthorizationEventContext, type SlackAuthorizationRequiredHandler, type SlackBotToken, type SlackChannel, type SlackChannelConfig, type SlackChannelCredentials, type SlackChannelEvents, type SlackChannelState, type SlackContext, type SlackEventContext, type SlackEventReceiveFn, type SlackEventReceiveOptions, type SlackHandle, type SlackInboundEventContext, type SlackInboundResult, type SlackInboundResultOrPromise, type SlackInitialMessage, type SlackInstrumentationMetadata, type SlackInteractionAction, type SlackMentionResult, type SlackMentionResultOrPromise, type SlackReceiveTarget, type SlackThread, type SlackWebhookVerifier, type SlackWorkspaceHandle, } from "#public/channels/slack/slackChannel.js";
|
|
9
|
+
export type { SlackAttachment, SlackAuthor, SlackEvent, SlackEventEnvelope, SlackInboundContext, SlackMessage, } from "#public/channels/slack/inbound.js";
|
|
10
10
|
export { callSlackApi, resolveSlackBotToken, slackContinuationToken, type SlackPostInput, type SlackPostedMessage, type SlackThreadMessage, type SlackUploadFilesOptions, type SlackUploadFilesResult, } from "#public/channels/slack/api.js";
|
|
11
11
|
export { defaultSlackAuth } from "#public/channels/slack/defaults.js";
|
|
12
12
|
export { describeActionRequest, describeActionRequests, } from "#public/channels/slack/action-status.js";
|
|
@@ -1,10 +1,12 @@
|
|
|
1
|
+
import type { CrossChannelReceiveOptions } from "#channel/cross-channel-receive.js";
|
|
2
|
+
import type { Session } from "#channel/session.js";
|
|
1
3
|
import type { SessionAuthContext } from "#channel/types.js";
|
|
2
4
|
import type { CardElement } from "#compiled/chat/index.js";
|
|
3
5
|
import type { SessionContext } from "#public/definitions/callback-context.js";
|
|
4
6
|
import type { ChannelSessionOps } from "#public/definitions/channel.js";
|
|
5
7
|
import type { HandleMessageStreamEvent } from "#protocol/message.js";
|
|
6
|
-
import { type SlackBotToken, type SlackHandle, type SlackThread } from "#public/channels/slack/api.js";
|
|
7
|
-
import { type SlackMessage } from "#public/channels/slack/inbound.js";
|
|
8
|
+
import { type SlackBotToken, type SlackHandle, type SlackThread, type SlackWorkspaceHandle } from "#public/channels/slack/api.js";
|
|
9
|
+
import { type SlackEvent, type SlackEventEnvelope, type SlackMessage } from "#public/channels/slack/inbound.js";
|
|
8
10
|
import { type LoadThreadContextMessagesOptions } from "#public/channels/slack/thread.js";
|
|
9
11
|
import { type UploadPolicyInput } from "#public/channels/upload-policy.js";
|
|
10
12
|
import { type SlackWebhookVerifier } from "#public/channels/slack/verify.js";
|
|
@@ -43,7 +45,7 @@ export interface SlackChannelContext extends SlackContext {
|
|
|
43
45
|
*/
|
|
44
46
|
export interface SlackEventContext extends SlackChannelContext, ChannelSessionOps {
|
|
45
47
|
}
|
|
46
|
-
export type { SlackApiResponse, SlackBotToken, SlackHandle, SlackThread, } from "#public/channels/slack/api.js";
|
|
48
|
+
export type { SlackApiResponse, SlackBotToken, SlackHandle, SlackThread, SlackWorkspaceHandle, } from "#public/channels/slack/api.js";
|
|
47
49
|
export type { SlackWebhookVerifier } from "#public/channels/slack/verify.js";
|
|
48
50
|
type SlackEventHandler<T extends HandleMessageStreamEvent["type"]> = (data: EventData<T>, channel: SlackEventContext, ctx: SessionContext) => void | Promise<void>;
|
|
49
51
|
/**
|
|
@@ -182,6 +184,47 @@ export interface SlackInitialMessage {
|
|
|
182
184
|
readonly card: CardElement;
|
|
183
185
|
readonly fallbackText?: string;
|
|
184
186
|
}
|
|
187
|
+
/**
|
|
188
|
+
* One imperative turn start requested by a generic Slack event handler.
|
|
189
|
+
* The schedule API's `receive(slack, options)` payload with the Slack
|
|
190
|
+
* channel already bound by the inbound webhook.
|
|
191
|
+
*/
|
|
192
|
+
export type SlackEventReceiveOptions = CrossChannelReceiveOptions<SlackReceiveTarget>;
|
|
193
|
+
/**
|
|
194
|
+
* Starts a session on the current Slack channel from `onEvent`. Call it zero,
|
|
195
|
+
* one, or many times; each invocation returns the resulting session.
|
|
196
|
+
*/
|
|
197
|
+
export type SlackEventReceiveFn = (options: SlackEventReceiveOptions) => Promise<Session>;
|
|
198
|
+
/**
|
|
199
|
+
* Imperative surface handed to `slackChannel({ onEvent })`. Generic Events API
|
|
200
|
+
* payloads are not necessarily tied to one thread, so the context exposes a
|
|
201
|
+
* workspace API handle plus a Slack-bound `receive` function rather than the
|
|
202
|
+
* thread-scoped {@link SlackContext} used by message handlers.
|
|
203
|
+
*/
|
|
204
|
+
export interface SlackInboundEventContext {
|
|
205
|
+
/** The complete signed Events API callback envelope. */
|
|
206
|
+
readonly envelope: SlackEventEnvelope;
|
|
207
|
+
/** Starts a turn on this Slack channel using the proactive receive contract. */
|
|
208
|
+
readonly receive: SlackEventReceiveFn;
|
|
209
|
+
/** Resolves the active eve session for a Slack channel thread. */
|
|
210
|
+
readonly resolveActiveSession: (target: {
|
|
211
|
+
readonly channelId: string;
|
|
212
|
+
readonly threadTs: string;
|
|
213
|
+
}) => Promise<{
|
|
214
|
+
readonly sessionId: string;
|
|
215
|
+
} | undefined>;
|
|
216
|
+
/** Workspace-scoped Slack identity and raw Web API escape hatch. */
|
|
217
|
+
readonly slack: SlackWorkspaceHandle;
|
|
218
|
+
/** Keeps detached handler work alive after the Slack webhook is acknowledged. */
|
|
219
|
+
readonly waitUntil: (task: Promise<unknown>) => void;
|
|
220
|
+
}
|
|
221
|
+
/** Message-scoped context handed to `slackChannel({ onMessage })`. */
|
|
222
|
+
export interface SlackInboundMessageContext extends SlackContext {
|
|
223
|
+
/** Returns whether this message belongs to a thread with an active eve session. */
|
|
224
|
+
isSubscribed(): Promise<boolean>;
|
|
225
|
+
/** Returns whether the inbound event explicitly mentions this bot. */
|
|
226
|
+
isBotMentioned(): boolean;
|
|
227
|
+
}
|
|
185
228
|
export interface SlackInteractionAction {
|
|
186
229
|
readonly actionId: string;
|
|
187
230
|
readonly value?: string;
|
|
@@ -300,6 +343,12 @@ export interface SlackChannelConfig {
|
|
|
300
343
|
* option to avoid fetching thread history.
|
|
301
344
|
*/
|
|
302
345
|
readonly threadContext?: LoadThreadContextMessagesOptions;
|
|
346
|
+
/**
|
|
347
|
+
* Handles human-authored Slack messages. Specialized `onAppMention` and
|
|
348
|
+
* `onDirectMessage` handlers take precedence for their event types. Other
|
|
349
|
+
* channel messages are ignored when this hook is omitted.
|
|
350
|
+
*/
|
|
351
|
+
onMessage?(ctx: SlackInboundMessageContext, message: SlackMessage): SlackInboundResultOrPromise;
|
|
303
352
|
/**
|
|
304
353
|
* Invoked when a Slack `app_mention` event arrives (only `app_mention`;
|
|
305
354
|
* other event types are ignored). Decides whether to dispatch and with
|
|
@@ -333,6 +382,23 @@ export interface SlackChannelConfig {
|
|
|
333
382
|
* `im:history` scope.
|
|
334
383
|
*/
|
|
335
384
|
onDirectMessage?(ctx: SlackContext, message: SlackMessage): SlackInboundResultOrPromise;
|
|
385
|
+
/**
|
|
386
|
+
* Fallback handler for signed Slack Events API callbacks. An authored
|
|
387
|
+
* `onAppMention` or `onDirectMessage` takes precedence for events accepted
|
|
388
|
+
* by that specialized handler; otherwise the raw event arrives here. When
|
|
389
|
+
* neither a specialized handler nor `onEvent` is authored, mentions and DMs
|
|
390
|
+
* retain their built-in defaults and other event types are ignored.
|
|
391
|
+
*
|
|
392
|
+
* The handler owns control flow. Call `ctx.receive(...)` zero, one, or many
|
|
393
|
+
* times to start turns on Slack, and use `ctx.waitUntil(...)` for detached
|
|
394
|
+
* work. The return value is ignored. Runs after the webhook has been
|
|
395
|
+
* acknowledged through the host's `waitUntil` mechanism. Errors are caught
|
|
396
|
+
* and logged and never fall through to another handler.
|
|
397
|
+
*
|
|
398
|
+
* URL verification, slash commands, and interactive payloads are not Events
|
|
399
|
+
* API callbacks and do not reach this handler.
|
|
400
|
+
*/
|
|
401
|
+
onEvent?(ctx: SlackInboundEventContext, event: SlackEvent): void | Promise<void>;
|
|
336
402
|
/**
|
|
337
403
|
* Handler for Slack `block_actions` interactive callbacks (button
|
|
338
404
|
* clicks, select changes, etc.) **not** consumed by the framework's
|
|
@@ -367,7 +433,9 @@ export interface SlackChannel extends Channel<SlackChannelState, SlackReceiveTar
|
|
|
367
433
|
* connection-auth event handlers. Defaults apply per field: pass
|
|
368
434
|
* `onAppMention` to fully replace the default mention pipeline (auth
|
|
369
435
|
* derivation plus `"Thinking..."` typing), or an `events[type]` handler to
|
|
370
|
-
* replace only that one event.
|
|
436
|
+
* replace only that one event. When `onEvent` is authored it becomes the
|
|
437
|
+
* fallback ahead of unsupplied mention and DM defaults; otherwise unsupplied
|
|
438
|
+
* fields keep their defaults.
|
|
371
439
|
*/
|
|
372
440
|
export declare function slackChannel(config?: SlackChannelConfig): SlackChannel;
|
|
373
441
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{markEventHandled}from"./utils.js";import{createLogger,logError}from"#internal/logging.js";import{POST,defineChannel}from"#public/definitions/channel.js";import{mergeUploadPolicy}from"#public/channels/upload-policy.js";import{buildSlackBinding,slackContinuationToken}from"#public/channels/slack/api.js";import{slackUserIdFromAuthContext}from"#public/channels/slack/auth.js";import{defaultEvents,defaultInputRequestedHandler,defaultOnAppMention,defaultOnDirectMessage}from"#public/channels/slack/defaults.js";import{loadThreadContextMessages}from"#public/channels/slack/thread.js";import{parseSlackWebhookBody}from"#compiled/@chat-adapter/slack/webhook.js";import{buildSlackTurnMessage,collectInboundFileParts,createSlackFetchFile}from"#public/channels/slack/attachments.js";import{slackMessageFromWebhookPayload}from"#public/channels/slack/inbound.js";import{formatSlackInboundMessage,formatSlackThreadContext}from"#public/channels/slack/model-context.js";import{SLACK_CHANNEL_DEFAULT_ROUTE}from"#public/channels/slack/constants.js";import{handleInteractionPost}from"#public/channels/slack/interactions.js";import{verifySlackRequest as verifySlackRequest$1}from"#public/channels/slack/verify.js";const log=createLogger(`slack.channel`);function rebuildSlackContext(e,t,n){let{thread:r,slack:i}=buildSlackBinding({botToken:n?.botToken,channelId:e.channelId??``,threadTs:e.threadTs??``,teamId:e.teamId??void 0,onThreadTsChanged(n){e.threadTs=n,e.channelId&&t.setContinuationToken(slackContinuationToken(e.channelId,n))}});return{thread:r,slack:i,state:e}}function slackChannel(e={}){let t=mergeUploadPolicy(e.uploadPolicy),n=createSlackFetchFile({botToken:e.credentials?.botToken}),
|
|
1
|
+
import{markEventHandled}from"./utils.js";import{createLogger,logError}from"#internal/logging.js";import{POST,defineChannel}from"#public/definitions/channel.js";import{mergeUploadPolicy}from"#public/channels/upload-policy.js";import{buildSlackBinding,buildSlackWorkspaceHandle,slackContinuationToken}from"#public/channels/slack/api.js";import{slackUserIdFromAuthContext}from"#public/channels/slack/auth.js";import{defaultEvents,defaultInputRequestedHandler,defaultOnAppMention,defaultOnDirectMessage}from"#public/channels/slack/defaults.js";import{loadThreadContextMessages}from"#public/channels/slack/thread.js";import{parseSlackWebhookBody}from"#compiled/@chat-adapter/slack/webhook.js";import{buildSlackTurnMessage,collectInboundFileParts,createSlackFetchFile}from"#public/channels/slack/attachments.js";import{parseMessageEvent,parseSlackEventEnvelope,slackEventBotUserId,slackMessageFromWebhookPayload}from"#public/channels/slack/inbound.js";import{formatSlackInboundMessage,formatSlackThreadContext}from"#public/channels/slack/model-context.js";import{SLACK_CHANNEL_DEFAULT_ROUTE}from"#public/channels/slack/constants.js";import{handleInteractionPost}from"#public/channels/slack/interactions.js";import{verifySlackRequest as verifySlackRequest$1}from"#public/channels/slack/verify.js";const log=createLogger(`slack.channel`);function rebuildSlackContext(e,t,n){let{thread:r,slack:i}=buildSlackBinding({botToken:n?.botToken,channelId:e.channelId??``,threadTs:e.threadTs??``,teamId:e.teamId??void 0,onThreadTsChanged(n){e.threadTs=n,e.channelId&&t.setContinuationToken(slackContinuationToken(e.channelId,n))}});return{thread:r,slack:i,state:e}}function slackChannel(e={}){let t=mergeUploadPolicy(e.uploadPolicy),n=createSlackFetchFile({botToken:e.credentials?.botToken}),o=e.events?.[`authorization.required`],s=e.events?.[`turn.started`]??defaultEvents[`turn.started`],c={...defaultEvents,...e.events,async"turn.started"(e,t,n){let r=slackUserIdFromAuthContext(n.session.auth.current);r!==void 0&&(t.state.triggeringUserId=r),await s(e,t,n)},"input.requested":e.events?.[`input.requested`]??defaultInputRequestedHandler(),"authorization.required":o===void 0?defaultEvents[`authorization.required`]:constrainAuthorizationRequired(o)},u=new Set;return defineChannel({kindHint:`slack`,state:{channelId:null,threadTs:null,teamId:null,triggeringUserId:null,pendingToolCallMessage:null,lastReasoningTypingAtMs:null,lastReasoningTypingStatus:null,pendingAuthMessageTs:{}},fetchFile:n,metadata(e){return{channelId:e.channelId,teamId:e.teamId,threadTs:e.threadTs,triggeringUserId:e.triggeringUserId??null}},context(t,n){return rebuildSlackContext(t,n,e.credentials)},routes:[POST(e.route??SLACK_CHANNEL_DEFAULT_ROUTE,async(n,{resolveActiveSession:r,send:i,waitUntil:a})=>{let o=await verifyInbound(n,e.credentials);return o===null?new Response(`unauthorized`,{status:401}):shouldDropSlackHttpTimeoutRetry(n.headers)?new Response(`ok`):(n.headers.get(`content-type`)??``).includes(`application/x-www-form-urlencoded`)?handleInteractionPost(o,{send:i,waitUntil:a},{config:e}):handleEventPost({body:o,send:i,resolveActiveSession:r,waitUntil:a,config:e,uploadPolicy:t,handledEvents:u,headers:n.headers})})],receive(t,{send:n}){return receiveOnSlack(t,{credentials:e.credentials,send:n})},events:c})}async function receiveOnSlack(e,t){let n=e.target,r=n.channelId;if(!r||typeof r!=`string`)throw Error(`slackChannel().receive requires target.channelId.`);let i=typeof n.threadTs==`string`?n.threadTs:``,a=n.initialMessage;if(a&&i.length>0)throw Error("slackChannel().receive: `threadTs` and `initialMessage` are mutually exclusive.");let s=i;if(a){let{thread:e}=buildSlackBinding({botToken:t.credentials?.botToken,channelId:r,threadTs:``,teamId:t.teamId}),n={card:a.card};a.fallbackText!==void 0&&(n.fallbackText=a.fallbackText),s=(await e.post(n)).id}let l=s||crypto.randomUUID();return t.send(e.message,{auth:e.auth,continuationToken:slackContinuationToken(r,l),state:{channelId:r,threadTs:s||null,teamId:t.teamId??null,triggeringUserId:null}})}function constrainAuthorizationRequired(e){return(t,n,r)=>e(t,{postEphemeral:(e,t)=>n.thread.postEphemeral(e,t),postDirectMessage:(e,t)=>n.thread.postDirectMessage(e,t),state:n.state},r)}function shouldDropSlackHttpTimeoutRetry(e){return Number(e.get(`x-slack-retry-num`)??`0`)>=1&&e.get(`x-slack-retry-reason`)===`http_timeout`}async function handleEventPost(t){let{config:n}=t,r,i;try{r=parseSlackWebhookBody(t.body,{headers:t.headers}),i=parseSlackEventEnvelope(t.body)}catch(e){return log.warn(`inbound webhook body is not valid JSON`,{error:e}),new Response(`ok`)}if(r.kind===`url_verification`)return new Response(r.challenge,{status:200,headers:{"content-type":`text/plain`}});if(i===null)return new Response(`ok`);let dispatch=null,a=null;if(r.kind===`app_mention`||r.kind===`direct_message`){let e=r.kind,o=slackMessageFromWebhookPayload(r);if(o!==null){let dispatchMessageWith=r=>()=>dispatchInboundMessage({credentials:n.credentials,handler:r,kind:e,message:o,send:t.send,threadContext:n.threadContext,uploadPolicy:t.uploadPolicy}),r=(e===`app_mention`?n.onAppMention:n.onDirectMessage)??n.onMessage;r===void 0?a=dispatchMessageWith(e===`app_mention`?defaultOnAppMention:defaultOnDirectMessage):dispatch=()=>dispatchSlackMessage({botUserId:slackEventBotUserId(i),credentials:n.credentials,handler:r,kind:e,message:o,resolveActiveSession:t.resolveActiveSession,send:t.send,threadContext:n.threadContext,uploadPolicy:t.uploadPolicy})}}if(dispatch===null&&n.onMessage!==void 0){let e=parseMessageEvent(i);if(e!==null){let r=slackEventBotUserId(i);(r===void 0||!e.text.includes(`<@${r}`))&&(dispatch=()=>dispatchSlackMessage({botUserId:r,credentials:n.credentials,handler:n.onMessage,kind:`channel_message`,message:e,resolveActiveSession:t.resolveActiveSession,send:t.send,threadContext:n.threadContext,uploadPolicy:t.uploadPolicy}))}}let o=n.onEvent;if(dispatch===null&&o!==void 0&&(dispatch=()=>dispatchSlackEvent({credentials:n.credentials,envelope:i,handler:o,resolveActiveSession:t.resolveActiveSession,send:t.send})),dispatch??=a,dispatch===null)return new Response(`ok`);let s=i.event_id;if(s){if(t.handledEvents.has(s))return log.warn(`received a duplicate event`,{event_id:s,event_time:i.event_time,retry_num:r.retry?.num??`(null)`,retry_reason:r.retry?.reason??`(null)`}),new Response(`ok`);markEventHandled(s,t.handledEvents)}return t.waitUntil(dispatch()),new Response(`ok`)}async function dispatchSlackMessage(e){let{thread:t,slack:r}=buildSlackBinding({botToken:e.credentials?.botToken,channelId:e.message.channelId,threadTs:e.message.threadTs,teamId:e.message.teamId}),i={isBotMentioned:()=>e.kind===`app_mention`||e.botUserId!==void 0&&e.message.text.includes(`<@${e.botUserId}`),isSubscribed:async()=>await e.resolveActiveSession({continuationToken:slackContinuationToken(e.message.channelId,e.message.threadTs)})!==void 0,slack:r,thread:t},a;try{a=await e.handler(i,e.message)}catch(t){logError(log,`${e.kind} handler failed`,t,{channelId:e.message.channelId});return}a!=null&&await deliverSlackMessage({credentials:e.credentials,kind:e.kind,message:e.message,result:a,send:e.send,thread:t,threadContext:e.threadContext,uploadPolicy:e.uploadPolicy})}async function dispatchSlackEvent(e){let t=e.envelope.event.team_id,r=typeof t==`string`?t:typeof e.envelope.team_id==`string`?e.envelope.team_id:void 0,i=[],a={envelope:e.envelope,receive:t=>receiveOnSlack(t,{credentials:e.credentials,send:e.send,teamId:r}),resolveActiveSession:({channelId:t,threadTs:n})=>e.resolveActiveSession({continuationToken:slackContinuationToken(t,n)}),slack:buildSlackWorkspaceHandle({botToken:e.credentials?.botToken,teamId:r}),waitUntil(e){i.push(e)}};try{await e.handler(a,e.envelope.event)}catch(t){logError(log,`event handler failed`,t,{eventId:e.envelope.event_id,eventType:e.envelope.event.type})}await Promise.allSettled(i)}async function verifyInbound(e,t){try{return await verifySlackRequest$1(e,{signingSecret:t?.signingSecret??(t?.webhookVerifier?void 0:process.env.SLACK_SIGNING_SECRET),webhookVerifier:t?.webhookVerifier})}catch(e){return log.warn(`slack inbound verification failed`,{error:e}),null}}async function dispatchInboundMessage(e){let{message:t,kind:r}=e,{thread:i,slack:a}=buildSlackBinding({botToken:e.credentials?.botToken,channelId:t.channelId,threadTs:t.threadTs,teamId:t.teamId}),s={thread:i,slack:a},c;try{c=await e.handler(s,t)}catch(e){logError(log,`${r} handler failed`,e,{channelId:t.channelId});return}c!=null&&await deliverSlackMessage({credentials:e.credentials,kind:r,message:t,result:c,send:e.send,thread:i,threadContext:e.threadContext,uploadPolicy:e.uploadPolicy})}async function deliverSlackMessage(e){let{message:t,thread:r}=e;try{let n=formatSlackThreadContext(e.threadContext===void 0?[]:await loadThreadContextMessages(r,t,e.threadContext)),i=await collectInboundFileParts({mention:t,thread:r,policy:e.uploadPolicy}),a={channelId:t.channelId,fullName:t.author?.fullName,teamId:t.teamId,threadTs:t.threadTs,userId:t.author?.userId??``,userName:t.author?.userName},o=formatSlackInboundMessage(a,t),s=buildSlackTurnMessage(n===void 0?o:`${n}\n\n${o}`,i),l=e.result.context??[];await e.send(l.length===0?{message:s}:{message:s,context:l},{auth:e.result.auth,continuationToken:slackContinuationToken(t.channelId,t.threadTs),state:{channelId:t.channelId,threadTs:t.threadTs,teamId:t.teamId??null,triggeringUserId:a.userId||null},title:t.markdown})}catch(r){logError(log,`${e.kind} delivery failed`,r,{channelId:t.channelId})}}export{constrainAuthorizationRequired,slackChannel};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{extractErrorId,formatErrorHint}from"#internal/logging.js";import{parseJsonObject}from"#shared/json.js";import{splitTeamsMessageText}from"#public/channels/teams/api.js";import{renderAnsweredInputRequestMessage,renderInputRequestMessage}from"#public/channels/teams/hitl.js";function defaultTeamsAuth(e){let t=e.tenantId,n={activity_id:e.id,conversation_id:e.conversation.id,scope:e.scope,user_id:e.from.id};e.from.name!==void 0&&(n.user_name=e.from.name),e.from.aadObjectId!==void 0&&(n.aad_object_id=e.from.aadObjectId),t!==void 0&&(n.tenant_id=t),e.teamId!==void 0&&(n.team_id=e.teamId),e.teamsChannelId!==void 0&&(n.channel_id=e.teamsChannelId);let r=t?`teams:${t}:${e.from.id}`:`teams:${e.from.id}`;return{attributes:n,authenticator:`teams-activity`,issuer:t?`teams:${t}`:`teams`,principalId:r,principalType:e.from.role===`bot`?`service`:`user`,subject:e.from.aadObjectId}}async function defaultOnMessage(e,t){return t.scope!==`personal`&&!t.isBotMentioned?null:(await e.thread.startTyping(),{auth:defaultTeamsAuth(t)})}const defaultEvents={async"turn.started"(e,t,n){await t.thread.startTyping()},async"actions.requested"(e,t,n){await t.thread.startTyping()},async"input.requested"(e,t,n){for(let n of e.requests)await t.thread.post(renderInputRequestMessage(n,{adaptiveCardVersion:t.adaptiveCardVersion,replyToActivityId:t.teams.replyToActivityId}))},async"message.completed"(e,t,n){if(!(e.finishReason===`tool-calls`||!e.message))for(let n of splitTeamsMessageText(e.message))await t.thread.post(n)},async"session.failed"(n,r){let i=formatErrorHint(n),a=extractErrorId(n.details);await r.thread.post([`This session could not recover from an error${i}.`,``,`Start a new Teams conversation to continue.`,...a?[``,`Error id: ${a}`]:[]].join(`
|
|
1
|
+
import{extractErrorId,formatErrorHint}from"#internal/logging.js";import{parseJsonObject}from"#shared/json.js";import{splitTeamsMessageText}from"#public/channels/teams/api.js";import{renderAnsweredInputRequestMessage,renderInputRequestMessage}from"#public/channels/teams/hitl.js";function defaultTeamsAuth(e){let t=e.tenantId,n={activity_id:e.id,conversation_id:e.conversation.id,scope:e.scope,user_id:e.from.id};e.from.name!==void 0&&(n.user_name=e.from.name),e.from.aadObjectId!==void 0&&(n.aad_object_id=e.from.aadObjectId),t!==void 0&&(n.tenant_id=t),e.teamId!==void 0&&(n.team_id=e.teamId),e.teamsChannelId!==void 0&&(n.channel_id=e.teamsChannelId);let r=t?`teams:${t}:${e.from.id}`:`teams:${e.from.id}`;return{attributes:n,authenticator:`teams-activity`,issuer:t?`teams:${t}`:`teams`,principalId:r,principalType:e.from.role===`bot`?`service`:`user`,subject:e.from.aadObjectId}}async function defaultOnMessage(e,t){return t.from.role===`bot`||t.from.id===t.recipient.id||t.scope!==`personal`&&!t.isBotMentioned?null:(await e.thread.startTyping(),{auth:defaultTeamsAuth(t)})}const defaultEvents={async"turn.started"(e,t,n){await t.thread.startTyping()},async"actions.requested"(e,t,n){await t.thread.startTyping()},async"input.requested"(e,t,n){for(let n of e.requests)await t.thread.post(renderInputRequestMessage(n,{adaptiveCardVersion:t.adaptiveCardVersion,replyToActivityId:t.teams.replyToActivityId}))},async"message.completed"(e,t,n){if(!(e.finishReason===`tool-calls`||!e.message))for(let n of splitTeamsMessageText(e.message))await t.thread.post(n)},async"session.failed"(n,r){let i=formatErrorHint(n),a=extractErrorId(n.details);await r.thread.post([`This session could not recover from an error${i}.`,``,`Start a new Teams conversation to continue.`,...a?[``,`Error id: ${a}`]:[]].join(`
|
|
2
2
|
`))},async"turn.failed"(n,r,i){let a=formatErrorHint(n),o=extractErrorId(n.details);await r.thread.post([`I hit an error while handling your request${a}.`,``,`Please try again, rephrase, or reach out if it keeps failing.`,...o?[``,`Error id: ${o}`]:[]].join(`
|
|
3
|
-
`))},async"authorization.required"(e,t,r){let i=e.authorization?.displayName??formatConnectionDisplayName(e.name),a=e.authorization?.url,o=a?`Authorization required for ${i}: ${a}`:`Authorization required for ${i}.`,s=await t.thread.post({attachments:[{content:parseJsonObject({$schema:`http://adaptivecards.io/schemas/adaptive-card.json`,actions:a?[{title:`Sign in with ${i}`,type:`Action.OpenUrl`,url:a}]:[],body:[{text:`Authorization required for ${i}`,type:`TextBlock`,weight:`Bolder`,wrap:!0},{text:t.state.triggeringUser?`Requested by ${t.state.triggeringUser.name??t.state.triggeringUser.id}.`:`No triggering user is available for a private prompt.`,type:`TextBlock`,wrap:!0}],type:`AdaptiveCard`,version:t.adaptiveCardVersion}),contentType:`application/vnd.microsoft.card.adaptive`}],text:o});s.id&&(t.state.pendingAuthActivityId=s.id)},async"authorization.completed"(e,t,n){let r=t.state.pendingAuthActivityId;if(!r)return;let a=buildAuthCompletedText({displayName:e.authorization?.displayName??formatConnectionDisplayName(e.name),outcome:e.outcome,reason:e.reason});await t.thread.update(r,renderAnsweredInputRequestMessage({prompt:a})),t.state.pendingAuthActivityId=null}};function formatConnectionDisplayName(e){return e.length===0?e:e.charAt(0).toUpperCase()+e.slice(1)}function buildAuthCompletedText(e){if(e.outcome===`authorized`)return`${e.displayName} connected.`;let t=e.reason===void 0?``:` (${e.reason})`;return`${e.displayName} authorization ${e.outcome}${t}.`}function teamsMentionUser(e){let t=e.name??e.id;return{mentioned:{id:e.id,name:e.name},text:`<at>${t}</at>`,type:`mention`}}export{buildAuthCompletedText,defaultEvents,defaultOnMessage,defaultTeamsAuth,formatConnectionDisplayName,teamsMentionUser};
|
|
3
|
+
`))},async"authorization.required"(e,t,r){let i=e.authorization?.displayName??formatConnectionDisplayName(e.name),a=e.authorization?.url,o=a?`Authorization required for ${i}: ${a}`:`Authorization required for ${i}.`,s=await t.thread.post({attachments:[{content:parseJsonObject({$schema:`http://adaptivecards.io/schemas/adaptive-card.json`,actions:a?[{title:`Sign in with ${i}`,type:`Action.OpenUrl`,url:a}]:[],body:[{text:`Authorization required for ${i}`,type:`TextBlock`,weight:`Bolder`,wrap:!0},{text:t.state.triggeringUser?`Requested by ${t.state.triggeringUser.name??t.state.triggeringUser.id}.`:`No triggering user is available for a private prompt.`,type:`TextBlock`,wrap:!0}],type:`AdaptiveCard`,version:t.adaptiveCardVersion}),contentType:`application/vnd.microsoft.card.adaptive`}],text:o});s.id&&(t.state.pendingAuthActivityId=s.id)},async"authorization.completed"(e,t,n){e.outcome===`authorized`&&await t.thread.startTyping();let r=t.state.pendingAuthActivityId;if(!r)return;let a=buildAuthCompletedText({displayName:e.authorization?.displayName??formatConnectionDisplayName(e.name),outcome:e.outcome,reason:e.reason});await t.thread.update(r,renderAnsweredInputRequestMessage({prompt:a})),t.state.pendingAuthActivityId=null}};function formatConnectionDisplayName(e){return e.length===0?e:e.charAt(0).toUpperCase()+e.slice(1)}function buildAuthCompletedText(e){if(e.outcome===`authorized`)return`${e.displayName} connected.`;let t=e.reason===void 0?``:` (${e.reason})`;return`${e.displayName} authorization ${e.outcome}${t}.`}function teamsMentionUser(e){let t=e.name??e.id;return{mentioned:{id:e.id,name:e.name},text:`<at>${t}</at>`,type:`mention`}}export{buildAuthCompletedText,defaultEvents,defaultOnMessage,defaultTeamsAuth,formatConnectionDisplayName,teamsMentionUser};
|
|
@@ -10,7 +10,7 @@ export interface TeamsInstrumentationMetadata extends Record<string, unknown> {
|
|
|
10
10
|
readonly conversationType: string | null;
|
|
11
11
|
readonly teamId: string | null;
|
|
12
12
|
}
|
|
13
|
-
export { teamsChannel, type TeamsChannel, type TeamsChannelConfig, type TeamsChannelCredentials, type TeamsChannelEvents, type TeamsChannelState, type TeamsContext, type TeamsEventContext, type TeamsHandle, type TeamsInboundResult, type TeamsInboundResultOrPromise, type TeamsInputResponseResult, type TeamsInvokeResult, type TeamsInvokeResultOrPromise, type TeamsReceiveTarget, type TeamsRequestOptions, type TeamsThread, } from "#public/channels/teams/teamsChannel.js";
|
|
13
|
+
export { teamsChannel, type TeamsChannel, type TeamsChannelConfig, type TeamsChannelCredentials, type TeamsChannelEvents, type TeamsChannelState, type TeamsContext, type TeamsEventContext, type TeamsHandle, type TeamsInboundMessageContext, type TeamsInboundResult, type TeamsInboundResultOrPromise, type TeamsInputResponseResult, type TeamsInvokeResult, type TeamsInvokeResultOrPromise, type TeamsReceiveTarget, type TeamsRequestOptions, type TeamsThread, } from "#public/channels/teams/teamsChannel.js";
|
|
14
14
|
export { callTeamsConnectorApi, normalizeTeamsPostInput, replyToTeamsActivity, resolveTeamsAccessToken, resolveTeamsAppId, resolveTeamsAppPassword, resolveTeamsTenantId, sendTeamsActivity, splitTeamsMessageText, teamsContinuationToken, triggerTeamsTypingIndicator, updateTeamsActivity, TEAMS_MESSAGE_TEXT_MAX_LENGTH, type TeamsAccessTokenResult, type TeamsApiOptions, type TeamsApiResponse, type TeamsAppId, type TeamsAppPassword, type TeamsAttachment, type TeamsChannelAccount, type TeamsCredentials, type TeamsFetch, type TeamsMention, type TeamsMessageBody, type TeamsOutboundActivity, type TeamsPostedActivity, type TeamsTenantId, type TeamsTokenProvider, } from "#public/channels/teams/api.js";
|
|
15
15
|
export { formatTeamsContextBlock, isTeamsPersonalMessage, parseTeamsActivity, teamsThreadRootActivityId, type TeamsActivity, type TeamsActivityBase, type TeamsConversationAccount, type TeamsConversationScope, type TeamsConversationUpdateActivity, type TeamsInboundContext, type TeamsInvokeActivity, type TeamsMessageActivity, } from "#public/channels/teams/inbound.js";
|
|
16
16
|
export { deriveTeamsInputResponses, isTeamsInputResponseActivity, renderAnsweredInputRequestMessage, renderInputRequestAttachment, renderInputRequestMessage, teamsInvokeResponse, TEAMS_ADAPTIVE_CARD_CONTENT_TYPE, TEAMS_HITL_CHOICE_INPUT_ID, TEAMS_HITL_DATA_KEY, TEAMS_HITL_FREEFORM_INPUT_ID, } from "#public/channels/teams/hitl.js";
|
|
@@ -14,11 +14,16 @@ type EventData<T extends HandleMessageStreamEvent["type"]> = Extract<HandleMessa
|
|
|
14
14
|
}> extends {
|
|
15
15
|
data: infer D;
|
|
16
16
|
} ? D : undefined;
|
|
17
|
-
/** Pre-dispatch Teams context passed to
|
|
17
|
+
/** Pre-dispatch Teams context passed to invoke hooks. */
|
|
18
18
|
export interface TeamsContext {
|
|
19
19
|
readonly teams: TeamsHandle;
|
|
20
20
|
readonly thread: TeamsThread;
|
|
21
21
|
}
|
|
22
|
+
/** Message-scoped context handed to `teamsChannel({ onMessage })`. */
|
|
23
|
+
export interface TeamsInboundMessageContext extends TeamsContext {
|
|
24
|
+
/** Returns whether this message belongs to a thread with an active eve session. */
|
|
25
|
+
isSubscribed(): Promise<boolean>;
|
|
26
|
+
}
|
|
22
27
|
/** Channel-owned Teams context returned by `context()`. */
|
|
23
28
|
export interface TeamsChannelContext extends TeamsContext {
|
|
24
29
|
readonly adaptiveCardVersion: string;
|
|
@@ -121,7 +126,7 @@ export interface TeamsChannelConfig {
|
|
|
121
126
|
/** Override the default webhook route path (`/eve/v1/teams`). */
|
|
122
127
|
readonly route?: string;
|
|
123
128
|
/** Inbound message hook. Defaults to user-scoped auth and mention-gated dispatch outside personal chats. */
|
|
124
|
-
onMessage?(ctx:
|
|
129
|
+
onMessage?(ctx: TeamsInboundMessageContext, message: TeamsMessageActivity): TeamsInboundResultOrPromise;
|
|
125
130
|
/** Authorizes HITL card submissions. Defaults to the submitting Teams user. */
|
|
126
131
|
onInputResponse?(ctx: TeamsContext, activity: TeamsInvokeActivity | TeamsMessageActivity): TeamsInputResponseResult | Promise<TeamsInputResponseResult>;
|
|
127
132
|
/** Handler for non-HITL Teams invoke activities. Return a body, a Response, or `null`/`undefined` for a 200 OK. */
|
|
@@ -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,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,{
|
|
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,{resolveActiveSession:i,send:s,waitUntil:c})=>{let l=await verifyInbound(r,e.credentials);if(l===null)return new Response(`unauthorized`,{status:401});let u;try{u=parseJsonObject(JSON.parse(l))}catch(e){return log.warn(`inbound Teams body is not valid JSON`,{error:e}),teamsOk()}let d=parseTeamsActivity(u);return d===null?teamsOk():d.type===`message`?(c(isTeamsInputResponseActivity(d)?dispatchInputResponses({activity:d,config:e,onInputResponse:o,send:s}):dispatchMessage({activity:d,config:e,filesPolicy:t,onMessage:a,resolveActiveSession:i,send:s})),teamsOk()):d.type===`invoke`?handleInvoke({activity:d,config:e,onInputResponse:o,send:s,waitUntil:c}):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=stateToken(t),i={...n,isSubscribed:async()=>await e.resolveActiveSession({continuationToken:r})!==void 0},a;try{a=await e.onMessage(i,e.activity)}catch(e){log.error(`Teams message handler failed`,{error:e});return}if(a==null)return;let o=collectTeamsFileParts(e.activity.attachments,e.filesPolicy),s=buildTeamsTurnMessage(e.activity.text,o),c={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},l=a.context??[];try{await e.send({message:s,context:[formatTeamsContextBlock(c),...l]},{auth:a.auth,continuationToken:r,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};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{extractErrorId,formatErrorHint}from"#internal/logging.js";import{registerTelegramFreeformPrompt,renderTelegramInputRequest}from"#public/channels/telegram/hitl.js";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}const defaultEvents={async"turn.started"(e,t,n){await t.telegram.startTyping()},async"actions.requested"(e,t,n){await t.telegram.startTyping()},async"input.requested"(e,t,i){for(let i of e.requests){let e=renderTelegramInputRequest(i,t.state),a=await t.telegram.post({reply_markup:e.replyMarkup,text:e.text});e.freeformRequestId!==void 0&&a.id&®isterTelegramFreeformPrompt(t.state,{messageId:a.id,requestId:e.freeformRequestId})}},async"message.completed"(e,t,n){e.finishReason===`tool-calls`||!e.message||await t.telegram.post(e.message)},async"turn.failed"(n,r,i){let a=formatErrorHint(n),o=extractErrorId(n.details);await r.telegram.post([`I hit an error while handling your request${a}.`,``,`Please try again, rephrase, or reach out if it keeps failing.`,...o?[``,`Error id: ${o}`]:[]].join(`
|
|
1
|
+
import{extractErrorId,formatErrorHint}from"#internal/logging.js";import{registerTelegramFreeformPrompt,renderTelegramInputRequest}from"#public/channels/telegram/hitl.js";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}const defaultEvents={async"turn.started"(e,t,n){await t.telegram.startTyping()},async"authorization.completed"(e,t,n){e.outcome===`authorized`&&await t.telegram.startTyping()},async"actions.requested"(e,t,n){await t.telegram.startTyping()},async"input.requested"(e,t,i){for(let i of e.requests){let e=renderTelegramInputRequest(i,t.state),a=await t.telegram.post({reply_markup:e.replyMarkup,text:e.text});e.freeformRequestId!==void 0&&a.id&®isterTelegramFreeformPrompt(t.state,{messageId:a.id,requestId:e.freeformRequestId})}},async"message.completed"(e,t,n){e.finishReason===`tool-calls`||!e.message||await t.telegram.post(e.message)},async"turn.failed"(n,r,i){let a=formatErrorHint(n),o=extractErrorId(n.details);await r.telegram.post([`I hit an error while handling your request${a}.`,``,`Please try again, rephrase, or reach out if it keeps failing.`,...o?[``,`Error id: ${o}`]:[]].join(`
|
|
2
2
|
`))},async"session.failed"(n,r){let i=formatErrorHint(n),a=extractErrorId(n.details);await r.telegram.post([`This session could not recover from an error${i}.`,``,`Start a new message to continue.`,...a?[``,`Error id: ${a}`]:[]].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&&mentionsBot(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?!0:t!==void 0&&r.toLowerCase()===t.toLowerCase()}function mentionsBot(e,t){return e.toLowerCase().includes(`@${t.toLowerCase()}`)}export{defaultEvents,defaultOnMessage,defaultTelegramAuth};
|
|
@@ -12,7 +12,7 @@ export type { CancelTurnInput, CancelTurnResult, GetEventStreamOptions } from "#
|
|
|
12
12
|
export type { Session, SessionHandle } from "#channel/session.js";
|
|
13
13
|
export type { ChannelCors, ChannelCorsOptions } from "#channel/cors.js";
|
|
14
14
|
export { GET, POST, PUT, PATCH, DELETE, WS } from "#channel/routes.js";
|
|
15
|
-
export type { CancelFn, CancelOptions, HttpRouteDefinition, RouteDefinition, RouteHandlerArgs, SendFn, SendOptions, SendPayload, GetSessionFn, WebSocketMessage, WebSocketPeer, WebSocketRouteDefinition, WebSocketRouteHandler, WebSocketRouteHooks, WebSocketUpgradeRequest, WebSocketUpgradeResult, } from "#channel/routes.js";
|
|
15
|
+
export type { CancelFn, CancelOptions, HttpRouteDefinition, RouteDefinition, RouteHandlerArgs, SendFn, SendOptions, SendPayload, ResolveActiveSessionFn, GetSessionFn, WebSocketMessage, WebSocketPeer, WebSocketRouteDefinition, WebSocketRouteHandler, WebSocketRouteHooks, WebSocketUpgradeRequest, WebSocketUpgradeResult, } from "#channel/routes.js";
|
|
16
16
|
/**
|
|
17
17
|
* HTTP method a route handles. Defaults to `"POST"` — almost every route
|
|
18
18
|
* is a webhook. Override only when authoring a non-webhook route such as a
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{resolveEveDestinationPrefix}from"./server.js";import{ensureEveVercelOutputConfig}from"./vercel-output-config.js";import{EVE_ROUTE_PREFIX}from"#protocol/routes.js";import{isAbsolute,relative,resolve}from"node:path";import{resolveEveBinaryPath}from"#shared/resolve-eve-binary.js";const EVE_NEXT_SERVICE_PREFIX=`/_eve_internal/eve`,EVE_NEXT_PRODUCTION_PORT_ENV=`EVE_NEXT_PRODUCTION_PORT`,AGENT_NAME_PATTERN=/^[a-z0-9][a-z0-9_-]*$/;function resolveApplicationRoot(e){return e===void 0||e.length===0?process.cwd():isAbsolute(e)?e:resolve(process.cwd(),e)}function resolveDevServerTimeout(e){if(e!==void 0){if(!Number.isFinite(e)||e<=0)throw Error(`eve Next.js development server timeout must be a positive number.`);return e}}function normalizeRoutePrefix(e){let t=(e.startsWith(`/`)?e:`/${e}`).replace(/\/+$/,``);if(t.length===0)throw Error(`eve Next.js service prefix cannot resolve to the root route.`);return t}function joinRoutePrefix(e,t){return`${e.replace(/\/+$/,``)}/${t.replace(/^\/+/,``)}`}function createNamedAgentRoutePrefix(e){return joinRoutePrefix(`/eve/agents`,e)}function createNamedAgentServicePrefix(e,t){return joinRoutePrefix(e,t)}function createAgentRewriteSource(e){return joinRoutePrefix(e,`${EVE_ROUTE_PREFIX}/:path+`)}function normalizeOrigin(e){return new URL(e.trim()).origin}function readLocalProductionPort(e){let t=process.env[EVE_NEXT_PRODUCTION_PORT_ENV],n=t===void 0||t.trim().length===0?4274:Number.parseInt(t,10);if(t!==void 0&&t.trim().length>0&&String(n)!==t.trim())throw Error(`${EVE_NEXT_PRODUCTION_PORT_ENV} must be an integer between 1 and 65535.`);let r=n+e;if(r<1||r>65535)throw Error(`${EVE_NEXT_PRODUCTION_PORT_ENV} plus the eve agent count exceeds 65535.`);return r}function resolveProductionDestination(e){if(process.env.VERCEL)return{destinationPrefix:e.servicePrefix};let t=process.env.EVE_NEXT_PRODUCTION_ORIGIN;if(t!==void 0&&t.trim().length>0)return{destinationPrefix:joinRoutePrefix(normalizeOrigin(t),e.servicePrefix)};let n=`http://127.0.0.1:${String(readLocalProductionPort(e.localProductionPortOffset))}`;return{destinationPrefix:n,localServerOrigin:n}}function createEveRewriteRule(e){let t=createAgentRewriteSource(e.publicRoutePrefix);return{destination:joinRoutePrefix(e.destinationPrefix,`${EVE_ROUTE_PREFIX}/:path+`),source:t}}async function resolveExistingRewrites(e){return await e?.()}function mergeRewriteRules(e,t){return e===void 0?{beforeFiles:t}:isRewriteSections(e)?{...e,beforeFiles:[...t,...e.beforeFiles??[]]}:{afterFiles:e,beforeFiles:t}}function isRewriteSections(e){return!Array.isArray(e)}async function resolveNextConfig(e,t,n){return typeof e==`function`?await e(t,n):e}function assertValidAgentName(e){if(!AGENT_NAME_PATTERN.test(e))throw Error(`eve Next.js agent name ${JSON.stringify(e)} is invalid. Use lowercase letters, numbers, underscores, or hyphens, starting with a letter or number.`)}function quoteShellArg(e){return`'${e.replaceAll(`'`,`'\\''`)}'`}function toPosixPath(e){return e.replaceAll(`\\`,`/`)}function createDefaultBuildCommand(e){return`node ${quoteShellArg(toPosixPath(relative(e.agentRoot,resolveEveBinaryPath(e.nextRoot))))} build`}function normalizeAgentsConfig(e,t){let n=normalizeRoutePrefix(e.servicePrefix??`/_eve_internal/eve`),resolveBuildCommand=(n,r)=>r??e.eveBuildCommand??createDefaultBuildCommand({agentRoot:n,nextRoot:t});if(e.agents===void 0){let t=resolveApplicationRoot(e.eveRoot);return[{appRoot:t,buildCommand:resolveBuildCommand(t,void 0),localProductionPortOffset:0,publicRoutePrefix:``,servicePrefix:n}]}if(e.eveRoot!==void 0)throw Error(`withEve cannot combine eveRoot with agents. Use one configuration form.`);let r=Object.entries(e.agents);if(r.length===0)throw Error(`withEve agents must contain at least one named eve agent.`);return r.map(([e,t],r)=>{assertValidAgentName(e);let i=typeof t==`string`?{root:t}:t,a=resolveApplicationRoot(i.root);return{appRoot:a,buildCommand:resolveBuildCommand(a,i.buildCommand),localProductionPortOffset:r,name:e,publicRoutePrefix:createNamedAgentRoutePrefix(e),servicePrefix:normalizeRoutePrefix(i.servicePrefix??createNamedAgentServicePrefix(n,e))}})}function withEve(n,r={}){let i=process.cwd(),a=resolveDevServerTimeout(r.devServerTimeoutMs),o=normalizeAgentsConfig(r,i);return async function(r,s){let c=await resolveNextConfig(n,r,s),l=c.rewrites,u=await ensureEveVercelOutputConfig({agents:o.map(e=>({appRoot:e.appRoot,buildCommand:e.buildCommand,name:e.name,publicRoutePrefix:e.publicRoutePrefix,servicePrefix:e.servicePrefix})),nextRoot:i});if(process.env.VERCEL)return c;let d=new Map(u.agents.map(e=>[e.name,e])),f=o.map(e=>{let t=d.get(e.name),n=resolveProductionDestination({localProductionPortOffset:e.localProductionPortOffset,servicePrefix:t?.servicePrefix??e.servicePrefix});return{...e,productionDestination:n}});return{...c,async rewrites(){let[t,n]=await Promise.all([resolveExistingRewrites(l),Promise.all(f.map(async t=>createEveRewriteRule({destinationPrefix:await resolveEveDestinationPrefix({appRoot:t.appRoot,devServerTimeoutMs:a,logLabel:t.name,phase:r,productionDestinationPrefix:t.productionDestination.destinationPrefix,productionServerOrigin:t.productionDestination.localServerOrigin}),publicRoutePrefix:t.publicRoutePrefix})))]);return mergeRewriteRules(t,n)}}}}export{EVE_NEXT_SERVICE_PREFIX,withEve};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { default,
|
|
1
|
+
export { default, type EveNuxtModuleOptions } from "./module.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import
|
|
1
|
+
import module_default from"./module.js";export{module_default as default};
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { EVE_NUXT_SERVICE_PREFIX } from "./routing.js";
|
|
2
|
-
export { EVE_NUXT_SERVICE_PREFIX };
|
|
3
1
|
/**
|
|
4
2
|
* Options for the eve Nuxt module.
|
|
5
3
|
*/
|
|
@@ -7,37 +5,25 @@ export interface EveNuxtModuleOptions {
|
|
|
7
5
|
/**
|
|
8
6
|
* Path to the eve application root, resolved relative to the Nuxt project
|
|
9
7
|
* root unless absolute. Defaults to the Nuxt project root. The dev server is
|
|
10
|
-
* spawned here and
|
|
11
|
-
*
|
|
8
|
+
* spawned here, and on Vercel it is the root the generated eve service
|
|
9
|
+
* builds from.
|
|
12
10
|
*/
|
|
13
11
|
eveRoot?: string;
|
|
14
12
|
/**
|
|
15
|
-
*
|
|
13
|
+
* Command that builds the eve app inside the generated Vercel eve service.
|
|
14
|
+
* Defaults to running the installed eve binary from the Nuxt app's
|
|
15
|
+
* dependencies (`node <path-to>/eve/bin/eve.js build`).
|
|
16
16
|
*/
|
|
17
17
|
eveBuildCommand?: string;
|
|
18
|
-
/**
|
|
19
|
-
* Set to `false` to skip creating or updating `vercel.json`. By default the
|
|
20
|
-
* module ensures `vercel.json` contains `experimentalServices` for the Nuxt
|
|
21
|
-
* app and eve app.
|
|
22
|
-
*/
|
|
23
|
-
configureVercelJson?: boolean;
|
|
24
|
-
/**
|
|
25
|
-
* Private Vercel service prefix eve transport is proxied to. Defaults to
|
|
26
|
-
* {@link EVE_NUXT_SERVICE_PREFIX}. When `configureVercelJson` is enabled, it
|
|
27
|
-
* is written as the eve service `routePrefix`, but an existing `routePrefix`
|
|
28
|
-
* in `vercel.json` takes precedence. Normalized to a leading-slash,
|
|
29
|
-
* no-trailing-slash route; cannot resolve to `/`.
|
|
30
|
-
*/
|
|
31
|
-
servicePrefix?: string;
|
|
32
18
|
}
|
|
33
19
|
/**
|
|
34
20
|
* Nuxt module that wires an eve agent into a Nuxt app. Register under `modules`
|
|
35
21
|
* (configured via the `eve` config key). It auto-imports the `useEveAgent()`
|
|
36
|
-
* composable
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
22
|
+
* composable and routes eve transport requests (`/eve/v1/**`) to the eve
|
|
23
|
+
* service: a shared dev server spawned on demand in dev, a generated Vercel
|
|
24
|
+
* service on Vercel deployments, and a configured origin/port in non-Vercel
|
|
25
|
+
* production. Requires Nuxt >= 4.0.0. Configure via
|
|
26
|
+
* {@link EveNuxtModuleOptions}.
|
|
41
27
|
*/
|
|
42
28
|
declare const _default: import("nuxt/schema").NuxtModule<EveNuxtModuleOptions, EveNuxtModuleOptions, false>;
|
|
43
29
|
export default _default;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{joinRoutePrefix,normalizeOrigin,resolveProductionTarget}from"./routing.js";import{EVE_BASE_URL_ENV,resolveSharedEveDevServer}from"./dev-server.js";import{ensureEveVercelServicesConfig,mergeEveVercelConfig}from"./vercel-services.js";import{EVE_ROUTE_PREFIX}from"#protocol/routes.js";import{isAbsolute,resolve}from"node:path";import{addImports,defineNuxtModule,extendRouteRules}from"@nuxt/kit";function resolveApplicationRoot(e,t){return t===void 0||t.length===0?e:isAbsolute(t)?t:resolve(e,t)}async function resolveEveProxyTarget(a){if(!a.dev)return resolveProductionTarget();let o=process.env[EVE_BASE_URL_ENV]?.trim();if(o&&o.length>0)return joinRoutePrefix(normalizeOrigin(o),EVE_ROUTE_PREFIX);let s=await resolveSharedEveDevServer(a.appRoot);return s.process!==void 0&&a.onDevServerSpawned?.(s.process),joinRoutePrefix(s.origin,EVE_ROUTE_PREFIX)}var module_default=defineNuxtModule({meta:{name:`eve`,configKey:`eve`,compatibility:{nuxt:`>=4.0.0`}},defaults:{},async setup(e,t){let n=t.options.rootDir,r=resolveApplicationRoot(n,e.eveRoot);if(addImports({name:`useEveAgent`,from:`eve/vue`}),!t.options.dev&&process.env.VERCEL){let i=await ensureEveVercelServicesConfig({appRoot:r,eveBuildCommand:e.eveBuildCommand,nuxtRoot:n});if(i.mode===`generated`){let e=t.options.nitro;e.vercel={...e.vercel,config:mergeEveVercelConfig(e.vercel?.config,i)}}}else t.hook(`modules:done`,async()=>{let e=await resolveEveProxyTarget({appRoot:r,dev:t.options.dev,onDevServerSpawned:e=>{t.hook(`close`,()=>{e.killed||e.kill()})}});extendRouteRules(`${EVE_ROUTE_PREFIX}/**`,{proxy:`${e}/**`})})}});export{module_default as default};
|
|
@@ -1,14 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Private route namespace used when a Vercel deployment hosts eve as a
|
|
3
|
-
* separate experimental service behind the Nuxt app.
|
|
4
|
-
*/
|
|
5
|
-
export declare const EVE_NUXT_SERVICE_PREFIX = "/_eve_internal/eve";
|
|
6
|
-
/**
|
|
7
|
-
* Normalize a user-supplied service prefix into a leading-slash, no-trailing-
|
|
8
|
-
* slash route. Throws when the prefix resolves to the root route, which would
|
|
9
|
-
* collide with the Nuxt web service.
|
|
10
|
-
*/
|
|
11
|
-
export declare function normalizeRoutePrefix(prefix: string): string;
|
|
12
1
|
/**
|
|
13
2
|
* Join a route prefix and a path with exactly one separating slash.
|
|
14
3
|
*/
|
|
@@ -24,32 +13,9 @@ export declare function normalizeOrigin(origin: string): string;
|
|
|
24
13
|
*/
|
|
25
14
|
export declare function readLocalProductionPort(): number;
|
|
26
15
|
/**
|
|
27
|
-
*
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
readonly dest: string;
|
|
32
|
-
/**
|
|
33
|
-
* Re-run route matching against the rewritten `dest`. Required so the
|
|
34
|
-
* rewritten eve service path is routed to the sibling eve service instead of
|
|
35
|
-
* being resolved inside the host service's own filesystem (which 404s).
|
|
36
|
-
*/
|
|
37
|
-
readonly check: true;
|
|
38
|
-
}
|
|
39
|
-
/**
|
|
40
|
-
* Build the edge-level Vercel rewrite that forwards eve transport requests
|
|
41
|
-
* (`/eve/v1/**`) to the eve service prefix (`/_eve_internal/eve/eve/v1/**`).
|
|
42
|
-
*
|
|
43
|
-
* Mirrors the Next.js integration's `beforeFiles` rewrite. A Nitro runtime
|
|
44
|
-
* `proxy` route rule cannot reach a sibling Vercel service — the proxied
|
|
45
|
-
* request loops back into the Nuxt function and 404s — so production routing
|
|
46
|
-
* must happen at the edge via the build output config instead.
|
|
47
|
-
*/
|
|
48
|
-
export declare function createEveVercelRewriteRoute(servicePrefix: string): EveVercelRewriteRoute;
|
|
49
|
-
/**
|
|
50
|
-
* Resolve the proxy destination for eve routes in production.
|
|
51
|
-
*
|
|
52
|
-
* On Vercel the destination is the private service prefix. Off Vercel it is an
|
|
53
|
-
* explicit origin override (`EVE_NUXT_PRODUCTION_ORIGIN`) or a local port.
|
|
16
|
+
* Resolve the proxy destination for eve routes in non-Vercel production: an
|
|
17
|
+
* explicit origin override (`EVE_NUXT_PRODUCTION_ORIGIN`) or a local port. On
|
|
18
|
+
* Vercel the module routes at the edge via a Build Output service route
|
|
19
|
+
* instead of proxying.
|
|
54
20
|
*/
|
|
55
|
-
export declare function resolveProductionTarget(
|
|
21
|
+
export declare function resolveProductionTarget(): string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{EVE_ROUTE_PREFIX}from"#protocol/routes.js";const
|
|
1
|
+
import{EVE_ROUTE_PREFIX}from"#protocol/routes.js";const EVE_NUXT_PRODUCTION_PORT_ENV=`EVE_NUXT_PRODUCTION_PORT`;function joinRoutePrefix(e,t){return`${e.replace(/\/+$/,``)}/${t.replace(/^\/+/,``)}`}function normalizeOrigin(e){return new URL(e.trim()).origin}function readLocalProductionPort(){let e=process.env[EVE_NUXT_PRODUCTION_PORT_ENV];if(e===void 0||e.trim().length===0)return 4274;let n=Number.parseInt(e,10);if(String(n)!==e.trim()||n<1||n>65535)throw Error(`${EVE_NUXT_PRODUCTION_PORT_ENV} must be an integer between 1 and 65535.`);return n}function resolveProductionTarget(){let t=process.env.EVE_NUXT_PRODUCTION_ORIGIN;return t!==void 0&&t.trim().length>0?joinRoutePrefix(normalizeOrigin(t),EVE_ROUTE_PREFIX):joinRoutePrefix(`http://127.0.0.1:${String(readLocalProductionPort())}`,EVE_ROUTE_PREFIX)}export{joinRoutePrefix,normalizeOrigin,readLocalProductionPort,resolveProductionTarget};
|