eve 0.30.7 → 0.31.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +36 -0
- package/README.md +5 -6
- package/dist/src/acp/adapter.d.ts +10 -4
- package/dist/src/acp/adapter.js +1 -1
- package/dist/src/channel/adapter-context.d.ts +1 -1
- package/dist/src/channel/adapter.d.ts +2 -4
- package/dist/src/channel/adapter.js +1 -1
- package/dist/src/channel/channel-address.d.ts +58 -0
- package/dist/src/channel/channel-address.js +1 -0
- package/dist/src/channel/channel-operations.d.ts +72 -0
- package/dist/src/channel/channel-operations.js +1 -0
- package/dist/src/channel/compiled-channel.d.ts +10 -6
- package/dist/src/channel/cross-channel-receive.d.ts +13 -25
- package/dist/src/channel/cross-channel-receive.js +2 -2
- package/dist/src/channel/receive-target.d.ts +1 -2
- package/dist/src/channel/routes.d.ts +21 -149
- package/dist/src/channel/schedule.d.ts +1 -1
- package/dist/src/channel/schedule.js +1 -1
- package/dist/src/channel/send-input.d.ts +6 -0
- package/dist/src/channel/send-input.js +1 -0
- package/dist/src/channel/session.d.ts +44 -30
- package/dist/src/channel/session.js +1 -1
- package/dist/src/channel/types.d.ts +8 -35
- package/dist/src/chunks/{use-eve-agent-k-XHfrJT.js → use-eve-agent-CF5D6jSV.js} +361 -367
- package/dist/src/chunks/{use-eve-agent-BXMIf5fR.js → use-eve-agent-DbYZLG0h.js} +364 -368
- package/dist/src/cli/commands/agent-prompt/build-and-verify.md +1 -2
- package/dist/src/cli/commands/channel-add-conflicts.js +1 -1
- package/dist/src/cli/commands/info.d.ts +1 -1
- package/dist/src/cli/commands/info.js +1 -1
- package/dist/src/cli/commands/registry-metadata.d.ts +15 -0
- package/dist/src/cli/commands/registry-metadata.js +1 -0
- package/dist/src/cli/commands/registry-package.d.ts +46 -0
- package/dist/src/cli/commands/registry-package.js +1 -0
- package/dist/src/cli/commands/registry.d.ts +1 -1
- package/dist/src/cli/commands/registry.js +4 -4
- package/dist/src/cli/dev/tui/runner.d.ts +1 -1
- package/dist/src/cli/dev/tui/runner.js +1 -1
- package/dist/src/cli/dev/tui/subagent-pump.js +1 -1
- package/dist/src/cli/dev/tui/terminal-renderer.js +2 -2
- package/dist/src/cli/dev/tui/tui.js +1 -1
- package/dist/src/cli/invoke/invoke.d.ts +1 -1
- package/dist/src/cli/invoke/invoke.js +1 -1
- package/dist/src/cli/invoke/result.d.ts +0 -11
- package/dist/src/cli/invoke/result.js +1 -1
- package/dist/src/client/client-error.d.ts +2 -0
- package/dist/src/client/client-error.js +1 -1
- package/dist/src/client/client.d.ts +7 -14
- package/dist/src/client/client.js +1 -1
- package/dist/src/client/eve-agent-store.d.ts +4 -4
- package/dist/src/client/eve-agent-store.js +1 -1
- package/dist/src/client/index.d.ts +3 -2
- package/dist/src/client/index.js +1 -1
- package/dist/src/client/message-reducer-types.d.ts +3 -0
- package/dist/src/client/message-reducer.js +1 -1
- package/dist/src/client/message-response.d.ts +2 -7
- package/dist/src/client/message-response.js +1 -1
- package/dist/src/client/open-stream.js +1 -1
- package/dist/src/client/session-controls.d.ts +29 -0
- package/dist/src/client/session-controls.js +1 -0
- package/dist/src/client/session-utils.d.ts +0 -20
- package/dist/src/client/session-utils.js +1 -1
- package/dist/src/client/session.d.ts +26 -90
- package/dist/src/client/session.js +1 -1
- package/dist/src/client/sessions.d.ts +20 -0
- package/dist/src/client/sessions.js +1 -0
- package/dist/src/client/types.d.ts +26 -47
- package/dist/src/compiler/extension-compatibility.d.ts +10 -10
- package/dist/src/compiler/extension-compatibility.js +1 -1
- package/dist/src/compiler/normalize-subagent.js +1 -1
- package/dist/src/evals/cli/eval-client.js +1 -1
- package/dist/src/evals/context.js +1 -1
- package/dist/src/evals/session.d.ts +7 -6
- package/dist/src/evals/session.js +1 -1
- package/dist/src/evals/types.d.ts +9 -9
- package/dist/src/execution/agent-handle-dispatch.js +1 -1
- package/dist/src/execution/cancel-descendant-turns-step.js +1 -1
- package/dist/src/execution/dispatch-runtime-actions-step.js +1 -1
- package/dist/src/execution/remote-agent-dispatch.d.ts +1 -3
- package/dist/src/execution/remote-agent-dispatch.js +1 -1
- package/dist/src/execution/runtime-context.js +1 -1
- package/dist/src/execution/runtime-errors.d.ts +1 -1
- package/dist/src/execution/session-command-token.d.ts +2 -0
- package/dist/src/execution/session-command-token.js +1 -1
- package/dist/src/execution/settle-cancelled-turn-step.js +1 -1
- package/dist/src/execution/subagent-hitl-proxy.js +1 -1
- package/dist/src/execution/tool-auth.d.ts +1 -1
- package/dist/src/execution/tool-auth.js +1 -1
- package/dist/src/execution/turn-control-receiver.d.ts +2 -2
- package/dist/src/execution/turn-workflow.js +1 -1
- package/dist/src/execution/workflow-entry.js +1 -1
- package/dist/src/execution/workflow-runtime.js +1 -1
- package/dist/src/harness/cancelled-turn-emission.d.ts +1 -1
- package/dist/src/harness/cancelled-turn-emission.js +1 -1
- package/dist/src/harness/emission-state.d.ts +25 -0
- package/dist/src/harness/emission-state.js +1 -0
- package/dist/src/harness/emission.d.ts +5 -37
- package/dist/src/harness/emission.js +1 -1
- package/dist/src/harness/handles/prompt.d.ts +22 -3
- package/dist/src/harness/handles/prompt.js +1 -1
- package/dist/src/harness/handles/store.d.ts +0 -5
- package/dist/src/harness/handles/store.js +1 -1
- package/dist/src/harness/ordered-stream-emitter.d.ts +3 -2
- package/dist/src/harness/ordered-stream-emitter.js +1 -1
- package/dist/src/harness/runtime-actions.js +1 -1
- package/dist/src/harness/session-limit-enforcement.js +1 -1
- package/dist/src/harness/tool-loop.js +1 -1
- package/dist/src/harness/tools.d.ts +1 -1
- package/dist/src/harness/tools.js +1 -1
- package/dist/src/internal/application/package.js +1 -1
- package/dist/src/internal/nitro/dev-runtime-artifacts.js +1 -1
- package/dist/src/internal/nitro/dev-runtime-source-snapshot-copy.js +1 -1
- package/dist/src/internal/nitro/dev-runtime-source-snapshot-local-roots.d.ts +15 -0
- package/dist/src/internal/nitro/dev-runtime-source-snapshot-local-roots.js +1 -0
- package/dist/src/internal/nitro/dev-runtime-source-snapshot.d.ts +14 -2
- package/dist/src/internal/nitro/dev-runtime-source-snapshot.js +1 -1
- package/dist/src/internal/nitro/host/dev-server-http.js +1 -1
- package/dist/src/internal/nitro/routes/channel-dispatch.d.ts +2 -5
- package/dist/src/internal/nitro/routes/channel-dispatch.js +1 -1
- package/dist/src/internal/nitro/routes/channel-route-context.d.ts +4 -3
- package/dist/src/internal/nitro/routes/channel-route-context.js +1 -1
- package/dist/src/packages/eve-catalog/src/index.js +1 -1
- package/dist/src/protocol/cancel-turn.d.ts +9 -4
- package/dist/src/protocol/cancel-turn.js +1 -1
- package/dist/src/protocol/message.d.ts +27 -17
- package/dist/src/protocol/message.js +2 -2
- package/dist/src/protocol/reset-session.d.ts +1 -1
- package/dist/src/protocol/routes.d.ts +27 -47
- package/dist/src/protocol/routes.js +1 -1
- package/dist/src/public/channels/chat-sdk/chatSdkChannel.d.ts +19 -21
- package/dist/src/public/channels/chat-sdk/chatSdkChannel.js +2 -2
- package/dist/src/public/channels/discord/discordChannel.d.ts +5 -4
- package/dist/src/public/channels/discord/discordChannel.js +1 -1
- package/dist/src/public/channels/eve.d.ts +11 -10
- package/dist/src/public/channels/eve.js +1 -1
- package/dist/src/public/channels/github/dispatch.d.ts +8 -8
- package/dist/src/public/channels/github/dispatch.js +1 -1
- package/dist/src/public/channels/github/githubChannel.d.ts +4 -3
- package/dist/src/public/channels/github/githubChannel.js +1 -1
- package/dist/src/public/channels/github/pr-context.d.ts +1 -1
- package/dist/src/public/channels/index.d.ts +1 -1
- package/dist/src/public/channels/linear/linearChannel.d.ts +4 -3
- package/dist/src/public/channels/linear/linearChannel.js +1 -1
- package/dist/src/public/channels/slack/index.d.ts +1 -1
- package/dist/src/public/channels/slack/interactions.d.ts +3 -4
- package/dist/src/public/channels/slack/interactions.js +1 -1
- package/dist/src/public/channels/slack/session-operations.d.ts +37 -0
- package/dist/src/public/channels/slack/session-operations.js +1 -0
- package/dist/src/public/channels/slack/slackChannel.d.ts +56 -74
- package/dist/src/public/channels/slack/slackChannel.js +1 -1
- package/dist/src/public/channels/teams/teamsChannel.d.ts +4 -3
- package/dist/src/public/channels/teams/teamsChannel.js +1 -1
- package/dist/src/public/channels/telegram/telegramChannel.d.ts +5 -4
- package/dist/src/public/channels/telegram/telegramChannel.js +1 -1
- package/dist/src/public/channels/twilio/twilioChannel.d.ts +4 -3
- package/dist/src/public/channels/twilio/twilioChannel.js +1 -1
- package/dist/src/public/definitions/callback-context.d.ts +1 -2
- package/dist/src/public/definitions/channel.d.ts +22 -86
- package/dist/src/public/definitions/channel.js +1 -1
- package/dist/src/public/definitions/hook.d.ts +1 -0
- package/dist/src/public/definitions/remote-agent.js +1 -1
- package/dist/src/public/definitions/schedule.d.ts +16 -16
- package/dist/src/public/definitions/tool.d.ts +5 -5
- package/dist/src/public/schedules/index.d.ts +1 -1
- package/dist/src/react/use-eve-agent.d.ts +7 -4
- package/dist/src/react/use-eve-agent.js +1 -1
- package/dist/src/runtime/agent/bootstrap-model-utils.d.ts +11 -0
- package/dist/src/runtime/agent/bootstrap-model-utils.js +1 -1
- package/dist/src/runtime/agent/mock-model-adapter.js +1 -1
- package/dist/src/runtime/agent/mock-model-fixtures.js +2 -2
- package/dist/src/runtime/prompt/compose.js +1 -1
- package/dist/src/runtime/subagents/dynamic-remote-agent-config.js +1 -1
- package/dist/src/runtime/types.d.ts +2 -2
- package/dist/src/services/inspect-application.d.ts +1 -1
- package/dist/src/services/inspect-application.js +1 -1
- package/dist/src/setup/channel-add-conflicts.js +1 -1
- package/dist/src/setup/integrations/linear/setup.js +1 -1
- package/dist/src/setup/scaffold/create/project.js +1 -1
- package/dist/src/setup/scaffold/create/web-template.d.ts +1 -1
- package/dist/src/setup/scaffold/create/web-template.js +29 -17
- package/dist/src/shared/async-iterable.d.ts +2 -0
- package/dist/src/shared/async-iterable.js +1 -0
- package/dist/src/shared/channel-definition.d.ts +7 -7
- package/dist/src/shared/schedule-definition.d.ts +2 -2
- package/dist/src/shared/tool-definition.d.ts +1 -1
- package/dist/src/svelte/index.js +1 -1
- package/dist/src/svelte/use-eve-agent.d.ts +8 -5
- package/dist/src/svelte/use-eve-agent.js +1 -1
- package/dist/src/vue/index.js +1 -1
- package/dist/src/vue/use-eve-agent.d.ts +8 -5
- package/dist/src/vue/use-eve-agent.js +1 -1
- package/docs/README.md +6 -6
- package/docs/channels/chat-sdk.mdx +5 -6
- package/docs/channels/custom.mdx +116 -144
- package/docs/channels/discord.mdx +1 -1
- package/docs/channels/eve.mdx +76 -30
- package/docs/channels/github.mdx +1 -1
- package/docs/channels/linear.mdx +10 -10
- package/docs/channels/overview.mdx +2 -2
- package/docs/channels/slack.mdx +46 -15
- package/docs/channels/telegram.mdx +1 -1
- package/docs/channels/twilio.mdx +1 -1
- package/docs/concepts/default-harness.md +11 -3
- package/docs/concepts/execution-model-and-durability.mdx +17 -5
- package/docs/concepts/sessions-runs-and-streaming.md +45 -16
- package/docs/evals/cases.mdx +3 -3
- package/docs/evals/targets.mdx +1 -1
- package/docs/guides/auth-and-route-protection.md +2 -1
- package/docs/guides/client/continuations.mdx +50 -77
- package/docs/guides/client/messages.mdx +29 -33
- package/docs/guides/client/output-schema.mdx +7 -14
- package/docs/guides/client/overview.mdx +40 -11
- package/docs/guides/client/streaming.mdx +18 -23
- package/docs/guides/frontend/nuxt.mdx +1 -1
- package/docs/guides/frontend/overview.mdx +40 -36
- package/docs/guides/frontend/sveltekit.mdx +1 -1
- package/docs/guides/frontend/use-eve-agent-svelte.mdx +19 -23
- package/docs/guides/frontend/use-eve-agent-vue.mdx +21 -25
- package/docs/guides/hooks.md +1 -1
- package/docs/guides/instrumentation.md +1 -1
- package/docs/install-integrations.mdx +4 -2
- package/docs/patterns/dynamic-scheduling.md +16 -15
- package/docs/reference/cli.md +4 -1
- package/docs/schedules.mdx +10 -11
- package/docs/subagents.mdx +1 -1
- package/docs/tools/human-in-the-loop.md +1 -1
- package/docs/tools/overview.mdx +26 -2
- package/docs/tutorial/ship-it.mdx +1 -1
- package/package.json +1 -1
- package/dist/src/channel/cancel.d.ts +0 -6
- package/dist/src/channel/cancel.js +0 -1
- package/dist/src/channel/clear-session.d.ts +0 -4
- package/dist/src/channel/clear-session.js +0 -1
- package/dist/src/channel/compact-session.d.ts +0 -4
- package/dist/src/channel/compact-session.js +0 -1
- package/dist/src/channel/reset-session.d.ts +0 -6
- package/dist/src/channel/reset-session.js +0 -1
- package/dist/src/channel/resolve-active-session.d.ts +0 -4
- package/dist/src/channel/resolve-active-session.js +0 -1
- package/dist/src/channel/send.d.ts +0 -6
- package/dist/src/channel/send.js +0 -1
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
import { z } from "#compiled/zod/index.js";
|
|
2
2
|
/** Outcome of requesting cooperative turn cancellation. */
|
|
3
3
|
export type CancelTurnStatus = "accepted" | "no_active_turn";
|
|
4
|
+
/** Transport-independent result of requesting cooperative turn cancellation. */
|
|
5
|
+
export type CancelTurnResult = {
|
|
6
|
+
readonly sessionId: string;
|
|
7
|
+
readonly status: "accepted";
|
|
8
|
+
} | {
|
|
9
|
+
readonly status: "no_active_turn";
|
|
10
|
+
};
|
|
4
11
|
/** Successful standard turn-cancellation response. */
|
|
5
|
-
export
|
|
12
|
+
export type CancelTurnResponse = CancelTurnResult & {
|
|
6
13
|
readonly ok: true;
|
|
7
|
-
|
|
8
|
-
readonly status: CancelTurnStatus;
|
|
9
|
-
}
|
|
14
|
+
};
|
|
10
15
|
/** Successful response returned by the standard turn-cancellation route. */
|
|
11
16
|
export declare const CancelTurnResponseSchema: z.ZodType<CancelTurnResponse>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{z}from"#compiled/zod/index.js";const CancelTurnResponseSchema=z.
|
|
1
|
+
import{z}from"#compiled/zod/index.js";const CancelTurnResponseSchema=z.discriminatedUnion(`status`,[z.strictObject({ok:z.literal(!0),sessionId:z.string().min(1),status:z.literal(`accepted`)}),z.strictObject({ok:z.literal(!0),status:z.literal(`no_active_turn`)})]);export{CancelTurnResponseSchema};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { FileUIPart, ProviderMetadata, TextUIPart, UserContent } from "ai";
|
|
2
2
|
import type { ConnectionAuthorizationChallenge } from "#public/connections/errors.js";
|
|
3
|
-
import type { RuntimeActionRequest, RuntimeActionResult } from "#runtime/actions/types.js";
|
|
3
|
+
import type { RuntimeActionRequest, RuntimeActionResult, RuntimeToolResultActionResult } from "#runtime/actions/types.js";
|
|
4
4
|
import type { InputRequest, InputResponse } from "#runtime/input/types.js";
|
|
5
5
|
import type { JsonObject, JsonValue } from "#shared/json.js";
|
|
6
6
|
export declare const EVE_SESSION_ID_HEADER = "x-eve-session-id";
|
|
@@ -9,7 +9,7 @@ export declare const EVE_STREAM_TAIL_INDEX_HEADER = "x-eve-stream-tail-index";
|
|
|
9
9
|
export declare const EVE_STREAM_VERSION_HEADER = "x-eve-stream-version";
|
|
10
10
|
export declare const EVE_MESSAGE_STREAM_CONTENT_TYPE = "application/x-ndjson; charset=utf-8";
|
|
11
11
|
export declare const EVE_MESSAGE_STREAM_FORMAT = "ndjson";
|
|
12
|
-
export declare const EVE_MESSAGE_STREAM_VERSION = "
|
|
12
|
+
export declare const EVE_MESSAGE_STREAM_VERSION = "21";
|
|
13
13
|
/**
|
|
14
14
|
* eve-owned finish reason for one completed assistant step.
|
|
15
15
|
*
|
|
@@ -102,23 +102,13 @@ export interface RuntimeIdentity {
|
|
|
102
102
|
* client/page context; the channel converts it into internal model context.
|
|
103
103
|
*/
|
|
104
104
|
export type HandleMessageRequestBody = {
|
|
105
|
+
readonly inputResponses?: never;
|
|
105
106
|
readonly message: string | UserContent;
|
|
106
107
|
readonly clientContext?: string | readonly string[] | JsonObject;
|
|
107
108
|
readonly outputSchema?: JsonObject;
|
|
108
109
|
} | {
|
|
109
|
-
readonly continuationToken: string;
|
|
110
|
-
readonly message: string | UserContent;
|
|
111
|
-
readonly clientContext?: string | readonly string[] | JsonObject;
|
|
112
|
-
readonly outputSchema?: JsonObject;
|
|
113
|
-
} | {
|
|
114
|
-
readonly continuationToken: string;
|
|
115
|
-
readonly inputResponses: readonly InputResponse[];
|
|
116
|
-
readonly clientContext?: string | readonly string[] | JsonObject;
|
|
117
|
-
readonly outputSchema?: JsonObject;
|
|
118
|
-
} | {
|
|
119
|
-
readonly continuationToken: string;
|
|
120
110
|
readonly inputResponses: readonly InputResponse[];
|
|
121
|
-
readonly message
|
|
111
|
+
readonly message?: never;
|
|
122
112
|
readonly clientContext?: string | readonly string[] | JsonObject;
|
|
123
113
|
readonly outputSchema?: JsonObject;
|
|
124
114
|
};
|
|
@@ -215,6 +205,19 @@ export interface ActionResultStreamEvent {
|
|
|
215
205
|
};
|
|
216
206
|
type: "action.result";
|
|
217
207
|
}
|
|
208
|
+
/**
|
|
209
|
+
* Stream event emitted for a preliminary snapshot from a locally executed
|
|
210
|
+
* tool generator. The final snapshot is emitted as `action.result`.
|
|
211
|
+
*/
|
|
212
|
+
export interface ActionPartialStreamEvent {
|
|
213
|
+
data: {
|
|
214
|
+
result: RuntimeToolResultActionResult;
|
|
215
|
+
sequence: number;
|
|
216
|
+
stepIndex: number;
|
|
217
|
+
turnId: string;
|
|
218
|
+
};
|
|
219
|
+
type: "action.partial";
|
|
220
|
+
}
|
|
218
221
|
/**
|
|
219
222
|
* Stream event emitted when the parent workflow starts a child subagent session.
|
|
220
223
|
*/
|
|
@@ -516,7 +519,7 @@ export interface AuthorizationCompletedStreamEvent {
|
|
|
516
519
|
*/
|
|
517
520
|
export interface SessionWaitingStreamEvent {
|
|
518
521
|
data: {
|
|
519
|
-
/** Channel-
|
|
522
|
+
/** Channel-local continuation token, or the immutable session ID for an ID-only session. */
|
|
520
523
|
continuationToken: string;
|
|
521
524
|
wait: "next-user-message";
|
|
522
525
|
};
|
|
@@ -546,7 +549,7 @@ export interface SessionCompletedStreamEvent {
|
|
|
546
549
|
* Internal emitters use this type while constructing events. Public stream
|
|
547
550
|
* consumers receive {@link MessageStreamEvent}.
|
|
548
551
|
*/
|
|
549
|
-
export type UnstampedMessageStreamEvent = ContextClearedStreamEvent | CompactionCompletedStreamEvent | CompactionRequestedStreamEvent | AuthorizationCompletedStreamEvent | AuthorizationRequiredStreamEvent | MessageAppendedStreamEvent | MessageCompletedStreamEvent | MessageReceivedStreamEvent | ReasoningAppendedStreamEvent | SessionCompletedStreamEvent | SessionFailedStreamEvent | SessionStartedStreamEvent | SessionWaitingStreamEvent | ResultCompletedStreamEvent | SubagentCalledStreamEvent | SubagentChildEventStreamEvent | SubagentCompletedStreamEvent | SubagentStartedStreamEvent | ActionsRequestedStreamEvent | InputRequestedStreamEvent | ActionResultStreamEvent | ReasoningCompletedStreamEvent | StepCompletedStreamEvent | StepFailedStreamEvent | StepStartedStreamEvent | TurnCancelledStreamEvent | TurnCompletedStreamEvent | TurnFailedStreamEvent | TurnStartedStreamEvent;
|
|
552
|
+
export type UnstampedMessageStreamEvent = ContextClearedStreamEvent | CompactionCompletedStreamEvent | CompactionRequestedStreamEvent | AuthorizationCompletedStreamEvent | AuthorizationRequiredStreamEvent | MessageAppendedStreamEvent | MessageCompletedStreamEvent | MessageReceivedStreamEvent | ReasoningAppendedStreamEvent | SessionCompletedStreamEvent | SessionFailedStreamEvent | SessionStartedStreamEvent | SessionWaitingStreamEvent | ResultCompletedStreamEvent | SubagentCalledStreamEvent | SubagentChildEventStreamEvent | SubagentCompletedStreamEvent | SubagentStartedStreamEvent | ActionsRequestedStreamEvent | InputRequestedStreamEvent | ActionPartialStreamEvent | ActionResultStreamEvent | ReasoningCompletedStreamEvent | StepCompletedStreamEvent | StepFailedStreamEvent | StepStartedStreamEvent | TurnCancelledStreamEvent | TurnCompletedStreamEvent | TurnFailedStreamEvent | TurnStartedStreamEvent;
|
|
550
553
|
/**
|
|
551
554
|
* Stream events that represent an unrecovered turn/session failure.
|
|
552
555
|
*/
|
|
@@ -667,6 +670,13 @@ export declare function createActionResultEvent(input: {
|
|
|
667
670
|
readonly stepIndex: number;
|
|
668
671
|
readonly turnId: string;
|
|
669
672
|
}): ActionResultStreamEvent;
|
|
673
|
+
/** Creates an `action.partial` event for one preliminary tool-result snapshot. */
|
|
674
|
+
export declare function createActionPartialEvent(input: {
|
|
675
|
+
readonly result: RuntimeToolResultActionResult;
|
|
676
|
+
readonly sequence: number;
|
|
677
|
+
readonly stepIndex: number;
|
|
678
|
+
readonly turnId: string;
|
|
679
|
+
}): ActionPartialStreamEvent;
|
|
670
680
|
/**
|
|
671
681
|
* Creates the `subagent.called` event for one started child workflow session.
|
|
672
682
|
*/
|
|
@@ -818,7 +828,7 @@ export declare function createCompactionCompletedEvent(input: {
|
|
|
818
828
|
* Creates the `session.waiting` event for the only supported between-turn
|
|
819
829
|
* wait.
|
|
820
830
|
*/
|
|
821
|
-
export declare function createSessionWaitingEvent(namespacedContinuationToken
|
|
831
|
+
export declare function createSessionWaitingEvent(namespacedContinuationToken?: string): SessionWaitingStreamEvent;
|
|
822
832
|
/**
|
|
823
833
|
* Creates the `session.failed` event for one terminal session failure.
|
|
824
834
|
*/
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{
|
|
2
|
-
`)}function projectUserContentParts(e){if(typeof e==`string`)return[{text:e,type:`text`}];let t=[];for(let n of e)n.type===`text`?t.push({text:n.text,type:`text`}):n.type===`file`?t.push(projectFileLikePart(n.data,n.mediaType,n.filename)):n.type===`image`&&t.push(projectFileLikePart(n.image,n.mediaType??`application/octet-stream`,void 0));return t}function projectFileLikePart(e,t,n){if(isSandboxRefUrl(e)){let t=decodeSandboxRef(e);return createProjectedFilePart({filename:basenameOf(n??t.path),mediaType:t.mediaType,size:t.size})}let r=projectTaggedFileData(e,t,n);if(r!==void 0)return r;let i=byteLengthOf(e);return createProjectedFilePart(i===void 0?{filename:n,mediaType:t,...clientUrlFragment(e)}:{filename:n,mediaType:t,size:i})}function projectTaggedFileData(e,t,n){if(isTaggedFileData(e))switch(e.type){case`data`:{let r=byteLengthOf(e.data);return createProjectedFilePart(r===void 0?{filename:n,mediaType:t}:{filename:n,mediaType:t,size:r})}case`reference`:case`text`:return createProjectedFilePart({filename:n,mediaType:t});case`url`:return createProjectedFilePart({filename:n,mediaType:t,...clientUrlFragment(e.url)})}}function createProjectedFilePart(e){let t={mediaType:e.mediaType,type:`file`};return e.filename!==void 0&&(t.filename=e.filename),e.size!==void 0&&(t.size=e.size),e.url!==void 0&&(t.url=e.url),t}function isTaggedFileData(e){if(typeof e!=`object`||!e)return!1;let t=e.type;return t===`data`||t===`reference`||t===`text`||t===`url`}function byteLengthOf(e){if(e instanceof Uint8Array||e instanceof ArrayBuffer)return e.byteLength}function clientUrlFragment(
|
|
1
|
+
import{deserializeUrlFilePart,hasInternalRefScheme,isSerializedUrlFilePart}from"#internal/attachments/url-refs.js";import{toChannelLocalContinuationToken}from"#shared/continuation-token.js";import{decodeSandboxRef,isSandboxRefUrl}from"#internal/attachments/sandbox-refs.js";import{createEventId}from"#protocol/event-id.js";const EVE_SESSION_ID_HEADER=`x-eve-session-id`,EVE_STREAM_FORMAT_HEADER=`x-eve-stream-format`,EVE_STREAM_TAIL_INDEX_HEADER=`x-eve-stream-tail-index`,EVE_STREAM_VERSION_HEADER=`x-eve-stream-version`,EVE_MESSAGE_STREAM_CONTENT_TYPE=`application/x-ndjson; charset=utf-8`,EVE_MESSAGE_STREAM_FORMAT=`ndjson`,EVE_MESSAGE_STREAM_VERSION=`21`,textEncoder=new TextEncoder;function isCurrentTurnBoundaryEvent(e){return e.type===`session.completed`||e.type===`session.failed`||e.type===`session.waiting`}function isTurnFailureEvent(e){return e.type===`session.failed`||e.type===`step.failed`||e.type===`turn.failed`}function createSessionStartedEvent(e){let t={};return e?.invocation!==void 0&&(t.invocation=e.invocation),e?.runtime!==void 0&&(t.runtime=e.runtime),{data:t,type:`session.started`}}function createTurnStartedEvent(e){return{data:{sequence:e.sequence,turnId:e.turnId},type:`turn.started`}}function createMessageReceivedEvent(e){return{data:{message:summarizeUserContent(e.message),parts:projectUserContentParts(e.message),sequence:e.sequence,turnId:e.turnId},type:`message.received`}}function summarizeUserContent(e){if(typeof e==`string`)return e;let t=[];for(let n of e)if(n.type===`text`)t.push(n.text);else if(n.type===`file`){let e=n.filename??n.mediaType;t.push(`[file: ${e} (${n.mediaType})]`)}else n.type===`image`&&t.push(`[image: ${n.mediaType??`image`}]`);return t.join(`
|
|
2
|
+
`)}function projectUserContentParts(e){if(typeof e==`string`)return[{text:e,type:`text`}];let t=[];for(let n of e)n.type===`text`?t.push({text:n.text,type:`text`}):n.type===`file`?t.push(projectFileLikePart(n.data,n.mediaType,n.filename)):n.type===`image`&&t.push(projectFileLikePart(n.image,n.mediaType??`application/octet-stream`,void 0));return t}function projectFileLikePart(e,t,n){if(isSandboxRefUrl(e)){let t=decodeSandboxRef(e);return createProjectedFilePart({filename:basenameOf(n??t.path),mediaType:t.mediaType,size:t.size})}let r=projectTaggedFileData(e,t,n);if(r!==void 0)return r;let i=byteLengthOf(e);return createProjectedFilePart(i===void 0?{filename:n,mediaType:t,...clientUrlFragment(e)}:{filename:n,mediaType:t,size:i})}function projectTaggedFileData(e,t,n){if(isTaggedFileData(e))switch(e.type){case`data`:{let r=byteLengthOf(e.data);return createProjectedFilePart(r===void 0?{filename:n,mediaType:t}:{filename:n,mediaType:t,size:r})}case`reference`:case`text`:return createProjectedFilePart({filename:n,mediaType:t});case`url`:return createProjectedFilePart({filename:n,mediaType:t,...clientUrlFragment(e.url)})}}function createProjectedFilePart(e){let t={mediaType:e.mediaType,type:`file`};return e.filename!==void 0&&(t.filename=e.filename),e.size!==void 0&&(t.size=e.size),e.url!==void 0&&(t.url=e.url),t}function isTaggedFileData(e){if(typeof e!=`object`||!e)return!1;let t=e.type;return t===`data`||t===`reference`||t===`text`||t===`url`}function byteLengthOf(e){if(e instanceof Uint8Array||e instanceof ArrayBuffer)return e.byteLength}function clientUrlFragment(r){if(isSerializedUrlFilePart(r))try{let t=deserializeUrlFilePart(r);return isClientResolvableUrl(t)?{url:t.href}:{}}catch{return{}}if(r instanceof URL)return isClientResolvableUrl(r)?{url:r.href}:{};if(typeof r!=`string`||hasInternalRefScheme(r))return{};if(r.startsWith(`data:`))return{url:r};try{let e=new URL(r);return isClientResolvableUrl(e)?{url:e.href}:{}}catch{return{}}}function isClientResolvableUrl(e){return e.protocol===`http:`||e.protocol===`https:`||e.protocol===`data:`}function basenameOf(e){let t=e.replaceAll(`\\`,`/`),n=t.slice(t.lastIndexOf(`/`)+1);return n.length>0?n:e}function createActionsRequestedEvent(e){return{data:{actions:e.actions,sequence:e.sequence,stepIndex:e.stepIndex,turnId:e.turnId},type:`actions.requested`}}function createAuthorizationRequiredEvent(e){let t={description:e.description,name:e.name,sequence:e.sequence,stepIndex:e.stepIndex,turnId:e.turnId};return e.authorization!==void 0&&(t.authorization=e.authorization),e.webhookUrl!==void 0&&(t.webhookUrl=e.webhookUrl),{data:t,type:`authorization.required`}}function createAuthorizationCompletedEvent(e){let t={name:e.name,outcome:e.outcome,sequence:e.sequence,stepIndex:e.stepIndex,turnId:e.turnId};return e.authorization!==void 0&&(t.authorization=e.authorization),e.reason!==void 0&&(t.reason=e.reason),{data:t,type:`authorization.completed`}}function createInputRequestedEvent(e){return{data:{requests:e.requests,sequence:e.sequence,stepIndex:e.stepIndex,turnId:e.turnId},type:`input.requested`}}function createActionResultEvent(e){let t=e.rejected===!0?{error:buildActionResultError(e.result),status:`rejected`}:normalizeActionResultOutcome(e.result);return{data:{error:t.error,result:e.result,sequence:e.sequence,stepIndex:e.stepIndex,status:t.status,turnId:e.turnId},type:`action.result`}}function createActionPartialEvent(e){return{data:{result:e.result,sequence:e.sequence,stepIndex:e.stepIndex,turnId:e.turnId},type:`action.partial`}}function createSubagentCalledEvent(e){return{data:{callId:e.callId,childSessionId:e.childSessionId,sessionId:e.sessionId,sequence:e.sequence,name:e.name,remote:e.remote,toolName:e.toolName,turnId:e.turnId,workflowId:e.workflowId},type:`subagent.called`}}function createMessageAppendedEvent(e){return{data:{messageDelta:e.messageDelta,messageSoFar:e.messageSoFar,sequence:e.sequence,stepIndex:e.stepIndex,turnId:e.turnId},type:`message.appended`}}function createReasoningAppendedEvent(e){return{data:{reasoningDelta:e.reasoningDelta,reasoningSoFar:e.reasoningSoFar,sequence:e.sequence,stepIndex:e.stepIndex,turnId:e.turnId},type:`reasoning.appended`}}function createMessageCompletedEvent(e){return{data:{finishReason:e.finishReason??`stop`,message:e.message,sequence:e.sequence,stepIndex:e.stepIndex,turnId:e.turnId},type:`message.completed`}}function createReasoningCompletedEvent(e){return{data:{reasoning:e.reasoning,sequence:e.sequence,stepIndex:e.stepIndex,turnId:e.turnId},type:`reasoning.completed`}}function createResultCompletedEvent(e){return{data:{result:e.result,sequence:e.sequence,stepIndex:e.stepIndex,turnId:e.turnId},type:`result.completed`}}function createStepStartedEvent(e){return{data:{sequence:e.sequence,stepIndex:e.stepIndex,turnId:e.turnId},type:`step.started`}}function createStepCompletedEvent(e){let t={finishReason:e.finishReason,sequence:e.sequence,stepIndex:e.stepIndex,turnId:e.turnId};return e.usage!==void 0&&(t.usage=e.usage),e.providerMetadata!==void 0&&(t.providerMetadata=e.providerMetadata),{data:t,type:`step.completed`}}function createStepFailedEvent(e){return{data:{code:e.code,details:e.details,message:e.message,sequence:e.sequence,stepIndex:e.stepIndex,turnId:e.turnId},type:`step.failed`}}function createTurnCompletedEvent(e){return{data:{sequence:e.sequence,turnId:e.turnId},type:`turn.completed`}}function createTurnFailedEvent(e){return{data:{code:e.code,details:e.details,message:e.message,sequence:e.sequence,turnId:e.turnId},type:`turn.failed`}}function createTurnCancelledEvent(e){return{data:{sequence:e.sequence,turnId:e.turnId},type:`turn.cancelled`}}function createContextClearedEvent(e){return{data:{sequence:e.sequence,sessionId:e.sessionId,turnId:e.turnId},type:`context.cleared`}}function createCompactionRequestedEvent(e){return{data:{modelId:e.modelId,sequence:e.sequence,sessionId:e.sessionId,turnId:e.turnId,usageInputTokens:e.usageInputTokens??null},type:`compaction.requested`}}function createCompactionCompletedEvent(e){return{data:{modelId:e.modelId,sequence:e.sequence,sessionId:e.sessionId,turnId:e.turnId},type:`compaction.completed`}}function createSessionWaitingEvent(e=``){return{data:{continuationToken:toChannelLocalContinuationToken(e),wait:`next-user-message`},type:`session.waiting`}}function createSessionFailedEvent(e){return{data:{code:e.code,details:e.details,message:e.message,sessionId:e.sessionId},type:`session.failed`}}function createSessionCompletedEvent(){return{type:`session.completed`}}function stampMessageStreamEvent(e){return{...e,meta:{at:new Date().toISOString(),id:createEventId()}}}function encodeMessageStreamEvent(e){return textEncoder.encode(`${JSON.stringify(e)}\n`)}function normalizeActionResultOutcome(e){if(e.isError===!0)return{error:buildActionResultError(e),status:`failed`};let t=readActionResultOutputError(e.output);return t===void 0?{status:`completed`}:{error:t,status:`failed`}}function buildActionResultError(e){let t=readActionResultOutputError(e.output);return t===void 0?{code:`ACTION_RESULT_FAILED`,message:formatActionResultOutput(e.output)}:t}function readActionResultOutputError(e){let t=parseActionResultOutputRecord(e);if(t===void 0)return;let n=typeof t.code==`string`&&t.code.length>0?t.code:void 0,r=typeof t.message==`string`&&t.message.length>0?t.message:void 0;if(!(n===void 0||r===void 0))return{code:n,message:r}}function parseActionResultOutputRecord(e){if(typeof e==`object`&&e)return e;if(typeof e!=`string`)return;let t=e.trim();if(t.length!==0)try{let e=JSON.parse(t);if(typeof e==`object`&&e)return e}catch{return}}function formatActionResultOutput(e){if(typeof e==`string`)return e;let t=JSON.stringify(e);return typeof t==`string`&&t.length>0?t:`Action failed.`}export{EVE_MESSAGE_STREAM_CONTENT_TYPE,EVE_MESSAGE_STREAM_FORMAT,EVE_MESSAGE_STREAM_VERSION,EVE_SESSION_ID_HEADER,EVE_STREAM_FORMAT_HEADER,EVE_STREAM_TAIL_INDEX_HEADER,EVE_STREAM_VERSION_HEADER,createActionPartialEvent,createActionResultEvent,createActionsRequestedEvent,createAuthorizationCompletedEvent,createAuthorizationRequiredEvent,createCompactionCompletedEvent,createCompactionRequestedEvent,createContextClearedEvent,createInputRequestedEvent,createMessageAppendedEvent,createMessageCompletedEvent,createMessageReceivedEvent,createReasoningAppendedEvent,createReasoningCompletedEvent,createResultCompletedEvent,createSessionCompletedEvent,createSessionFailedEvent,createSessionStartedEvent,createSessionWaitingEvent,createStepCompletedEvent,createStepFailedEvent,createStepStartedEvent,createSubagentCalledEvent,createTurnCancelledEvent,createTurnCompletedEvent,createTurnFailedEvent,createTurnStartedEvent,encodeMessageStreamEvent,isCurrentTurnBoundaryEvent,isTurnFailureEvent,stampMessageStreamEvent};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from "#compiled/zod/index.js";
|
|
2
|
-
/** Outcome of retiring
|
|
2
|
+
/** Outcome of retiring one exact durable session. */
|
|
3
3
|
export type ResetStatus = "no_active_session" | "reset";
|
|
4
4
|
/** Successful response returned by the standard session-reset route. */
|
|
5
5
|
export type ResetResponse = {
|
|
@@ -13,40 +13,20 @@ export declare const EVE_HEALTH_ROUTE_PATH = "/eve/v1/health";
|
|
|
13
13
|
* with the same `auth` input as its session routes.
|
|
14
14
|
*/
|
|
15
15
|
export declare const EVE_INFO_ROUTE_PATH = "/eve/v1/info";
|
|
16
|
-
/**
|
|
17
|
-
|
|
18
|
-
*/
|
|
19
|
-
export declare const
|
|
20
|
-
/**
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
*/
|
|
29
|
-
export declare const
|
|
30
|
-
/**
|
|
31
|
-
* Stable framework-owned route for clearing the model history of the session
|
|
32
|
-
* that owns a client continuation token.
|
|
33
|
-
*/
|
|
34
|
-
export declare const EVE_CLEAR_SESSION_ROUTE_PATH = "/eve/v1/session/clear";
|
|
35
|
-
/**
|
|
36
|
-
* Stable framework-owned route pattern for sending a message to an existing
|
|
37
|
-
* session.
|
|
38
|
-
*/
|
|
39
|
-
export declare const EVE_CONTINUE_SESSION_ROUTE_PATTERN = "/eve/v1/session/:sessionId";
|
|
40
|
-
/**
|
|
41
|
-
* Stable framework-owned message stream route pattern.
|
|
42
|
-
*/
|
|
43
|
-
export declare const EVE_MESSAGE_STREAM_ROUTE_PATTERN = "/eve/v1/session/:sessionId/stream";
|
|
44
|
-
/**
|
|
45
|
-
* Stable framework-owned route pattern for cancelling a session's
|
|
46
|
-
* in-flight turn. Accepts an optional `{ turnId }` body guard scoping
|
|
47
|
-
* the cancel to the turn the caller observed.
|
|
48
|
-
*/
|
|
49
|
-
export declare const EVE_CANCEL_TURN_ROUTE_PATTERN = "/eve/v1/session/:sessionId/cancel";
|
|
16
|
+
/** Stable route for creating ID-addressed sessions. */
|
|
17
|
+
export declare const EVE_SESSION_ROUTE_PATH = "/eve/v1/session";
|
|
18
|
+
/** Stable route pattern for sending a message to one exact session ID. */
|
|
19
|
+
export declare const EVE_SESSION_ROUTE_PATTERN = "/eve/v1/session/:sessionId";
|
|
20
|
+
/** Stable route pattern for cancelling one exact session ID. */
|
|
21
|
+
export declare const EVE_SESSION_CANCEL_ROUTE_PATTERN = "/eve/v1/session/:sessionId/cancel";
|
|
22
|
+
/** Stable route pattern for compacting one exact session ID. */
|
|
23
|
+
export declare const EVE_SESSION_COMPACT_ROUTE_PATTERN = "/eve/v1/session/:sessionId/compact";
|
|
24
|
+
/** Stable route pattern for clearing one exact session ID. */
|
|
25
|
+
export declare const EVE_SESSION_CLEAR_ROUTE_PATTERN = "/eve/v1/session/:sessionId/clear";
|
|
26
|
+
/** Stable route pattern for resetting one exact session ID. */
|
|
27
|
+
export declare const EVE_SESSION_RESET_ROUTE_PATTERN = "/eve/v1/session/:sessionId/reset";
|
|
28
|
+
/** Stable event-stream route pattern for one exact session ID. */
|
|
29
|
+
export declare const EVE_SESSION_STREAM_ROUTE_PATTERN = "/eve/v1/session/:sessionId/stream";
|
|
50
30
|
/**
|
|
51
31
|
* Framework-owned route pattern for dispatching one authored schedule
|
|
52
32
|
* exactly once from the dev server.
|
|
@@ -55,7 +35,7 @@ export declare const EVE_CANCEL_TURN_ROUTE_PATTERN = "/eve/v1/session/:sessionId
|
|
|
55
35
|
* never mount this route. Smoke tests and human developers use it to
|
|
56
36
|
* trigger a schedule out-of-band (without a cron firing) and recover the
|
|
57
37
|
* resulting `{ scheduleId, sessionIds }` payload as JSON so they can
|
|
58
|
-
* subscribe to {@link
|
|
38
|
+
* subscribe to {@link EVE_SESSION_STREAM_ROUTE_PATTERN} for each session.
|
|
59
39
|
*
|
|
60
40
|
* `:scheduleId` is the authored schedule's filesystem-derived name (e.g.
|
|
61
41
|
* `agent/schedules/heartbeat.ts` -> `"heartbeat"`).
|
|
@@ -107,18 +87,18 @@ export declare const EVE_CONNECTION_CALLBACK_ROUTE_PATTERN = "/eve/v1/connection
|
|
|
107
87
|
* is unauthenticated by design and resumes the matching parked runtime action.
|
|
108
88
|
*/
|
|
109
89
|
export declare const EVE_CALLBACK_ROUTE_PATTERN = "/eve/v1/callback/:token";
|
|
110
|
-
/**
|
|
111
|
-
|
|
112
|
-
*/
|
|
113
|
-
export declare function
|
|
114
|
-
/**
|
|
115
|
-
|
|
116
|
-
*/
|
|
117
|
-
export declare function
|
|
118
|
-
/**
|
|
119
|
-
|
|
120
|
-
*/
|
|
121
|
-
export declare function
|
|
90
|
+
/** Builds the ID-addressed message route for one session. */
|
|
91
|
+
export declare function createEveSessionRoutePath(sessionId: string): string;
|
|
92
|
+
/** Builds the ID-addressed cancel route for one session. */
|
|
93
|
+
export declare function createEveSessionCancelRoutePath(sessionId: string): string;
|
|
94
|
+
/** Builds the ID-addressed compact route for one session. */
|
|
95
|
+
export declare function createEveSessionCompactRoutePath(sessionId: string): string;
|
|
96
|
+
/** Builds the ID-addressed clear route for one session. */
|
|
97
|
+
export declare function createEveSessionClearRoutePath(sessionId: string): string;
|
|
98
|
+
/** Builds the ID-addressed reset route for one session. */
|
|
99
|
+
export declare function createEveSessionResetRoutePath(sessionId: string): string;
|
|
100
|
+
/** Builds the ID-addressed event-stream route for one session. */
|
|
101
|
+
export declare function createEveSessionStreamRoutePath(sessionId: string): string;
|
|
122
102
|
/**
|
|
123
103
|
* Creates the stable framework-owned connection callback route path for
|
|
124
104
|
* one (`name`, `token`) pair.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
const EVE_ROUTE_PREFIX=`/eve/v1`,EVE_HEALTH_ROUTE_PATH=`${EVE_ROUTE_PREFIX}/health`,EVE_INFO_ROUTE_PATH=`${EVE_ROUTE_PREFIX}/info`,
|
|
1
|
+
const EVE_ROUTE_PREFIX=`/eve/v1`,EVE_HEALTH_ROUTE_PATH=`${EVE_ROUTE_PREFIX}/health`,EVE_INFO_ROUTE_PATH=`${EVE_ROUTE_PREFIX}/info`,EVE_SESSION_ROUTE_PATH=`${EVE_ROUTE_PREFIX}/session`,EVE_SESSION_ROUTE_PATTERN=`${EVE_SESSION_ROUTE_PATH}/:sessionId`,EVE_SESSION_CANCEL_ROUTE_PATTERN=`${EVE_SESSION_ROUTE_PATH}/:sessionId/cancel`,EVE_SESSION_COMPACT_ROUTE_PATTERN=`${EVE_SESSION_ROUTE_PATH}/:sessionId/compact`,EVE_SESSION_CLEAR_ROUTE_PATTERN=`${EVE_SESSION_ROUTE_PATH}/:sessionId/clear`,EVE_SESSION_RESET_ROUTE_PATTERN=`${EVE_SESSION_ROUTE_PATH}/:sessionId/reset`,EVE_SESSION_STREAM_ROUTE_PATTERN=`${EVE_SESSION_ROUTE_PATH}/:sessionId/stream`,EVE_DEV_DISPATCH_SCHEDULE_ROUTE_PATTERN=`${EVE_ROUTE_PREFIX}/dev/schedules/:scheduleId`,EVE_DEV_RUNTIME_ARTIFACTS_ROUTE_PATH=`${EVE_ROUTE_PREFIX}/dev/runtime-artifacts`,EVE_DEV_RUNTIME_ARTIFACTS_REBUILD_ROUTE_PATH=`${EVE_DEV_RUNTIME_ARTIFACTS_ROUTE_PATH}/rebuild`,EVE_DEV_RUNTIME_ARTIFACTS_SUSPEND_ROUTE_PATH=`${EVE_DEV_RUNTIME_ARTIFACTS_ROUTE_PATH}/suspend`,EVE_DEV_RUNTIME_ARTIFACTS_RESUME_ROUTE_PATH=`${EVE_DEV_RUNTIME_ARTIFACTS_ROUTE_PATH}/resume`;function createEveDevDispatchSchedulePath(t){return`${EVE_ROUTE_PREFIX}/dev/schedules/${encodeURIComponent(t)}`}const EVE_CONNECTION_CALLBACK_ROUTE_PATTERN=`${EVE_ROUTE_PREFIX}/connections/:name/callback/:token`,EVE_CALLBACK_ROUTE_PATTERN=`${EVE_ROUTE_PREFIX}/callback/:token`;function createEveSessionRoutePath(e){return`${EVE_SESSION_ROUTE_PATH}/${encodeURIComponent(e)}`}function createEveSessionCancelRoutePath(e){return`${EVE_SESSION_ROUTE_PATH}/${encodeURIComponent(e)}/cancel`}function createEveSessionCompactRoutePath(e){return`${EVE_SESSION_ROUTE_PATH}/${encodeURIComponent(e)}/compact`}function createEveSessionClearRoutePath(e){return`${EVE_SESSION_ROUTE_PATH}/${encodeURIComponent(e)}/clear`}function createEveSessionResetRoutePath(e){return`${EVE_SESSION_ROUTE_PATH}/${encodeURIComponent(e)}/reset`}function createEveSessionStreamRoutePath(e){return`${EVE_SESSION_ROUTE_PATH}/${encodeURIComponent(e)}/stream`}function createEveConnectionCallbackRoutePath(t,n){return`${EVE_ROUTE_PREFIX}/connections/${encodeURIComponent(t)}/callback/${encodeURIComponent(n)}`}function createEveCallbackRoutePath(t){return`${EVE_ROUTE_PREFIX}/callback/${encodeURIComponent(t)}`}export{EVE_CALLBACK_ROUTE_PATTERN,EVE_CONNECTION_CALLBACK_ROUTE_PATTERN,EVE_DEV_DISPATCH_SCHEDULE_ROUTE_PATTERN,EVE_DEV_RUNTIME_ARTIFACTS_REBUILD_ROUTE_PATH,EVE_DEV_RUNTIME_ARTIFACTS_RESUME_ROUTE_PATH,EVE_DEV_RUNTIME_ARTIFACTS_ROUTE_PATH,EVE_DEV_RUNTIME_ARTIFACTS_SUSPEND_ROUTE_PATH,EVE_HEALTH_ROUTE_PATH,EVE_INFO_ROUTE_PATH,EVE_ROUTE_PREFIX,EVE_SESSION_CANCEL_ROUTE_PATTERN,EVE_SESSION_CLEAR_ROUTE_PATTERN,EVE_SESSION_COMPACT_ROUTE_PATTERN,EVE_SESSION_RESET_ROUTE_PATTERN,EVE_SESSION_ROUTE_PATH,EVE_SESSION_ROUTE_PATTERN,EVE_SESSION_STREAM_ROUTE_PATTERN,createEveCallbackRoutePath,createEveConnectionCallbackRoutePath,createEveDevDispatchSchedulePath,createEveSessionCancelRoutePath,createEveSessionClearRoutePath,createEveSessionCompactRoutePath,createEveSessionResetRoutePath,createEveSessionRoutePath,createEveSessionStreamRoutePath};
|
|
@@ -1,15 +1,13 @@
|
|
|
1
|
+
import type { UserContent } from "ai";
|
|
2
|
+
import type { ChannelAddressDeliveryOptions } from "#channel/channel-address.js";
|
|
3
|
+
import type { SendPayload } from "#channel/routes.js";
|
|
1
4
|
import type { SessionAuthContext } from "#channel/types.js";
|
|
2
5
|
import type { ActionEvent, Adapter, ChatConfig, SerializedThread, Thread, WebhookOptions } from "#compiled/chat/index.js";
|
|
3
6
|
import { Chat } from "#compiled/chat/index.js";
|
|
4
|
-
import { type Channel, type ChannelEvents, type
|
|
7
|
+
import { type Channel, type ChannelEvents, type ChannelContinuationOps, type Session } from "#public/definitions/channel.js";
|
|
5
8
|
type ChatSdkAdapters = Record<string, Adapter>;
|
|
6
|
-
type ChatSdkSendInput =
|
|
7
|
-
/**
|
|
8
|
-
* Durable channel state used by `chatSdkChannel`. Stores the last Chat SDK
|
|
9
|
-
* thread for the Eve session so event handlers can post replies without
|
|
10
|
-
* depending on hidden Chat SDK subscription state, plus the bookkeeping the
|
|
11
|
-
* default handlers use to stream assistant output and surface typing status.
|
|
12
|
-
*/
|
|
9
|
+
type ChatSdkSendInput = string | UserContent | SendPayload;
|
|
10
|
+
/** Durable Chat SDK thread state plus default-handler streaming bookkeeping. */
|
|
13
11
|
export interface ChatSdkChannelState extends Record<string, unknown> {
|
|
14
12
|
thread: SerializedThread | null;
|
|
15
13
|
/** Message id of the in-flight streamed assistant post (edit fallback). */
|
|
@@ -38,7 +36,7 @@ export interface ChatSdkReceiveTarget {
|
|
|
38
36
|
readonly threadId?: string;
|
|
39
37
|
}
|
|
40
38
|
/**
|
|
41
|
-
* Channel-owned metadata exposed to
|
|
39
|
+
* Channel-owned metadata exposed to eve instrumentation.
|
|
42
40
|
*/
|
|
43
41
|
export interface ChatSdkInstrumentationMetadata extends Record<string, unknown> {
|
|
44
42
|
readonly adapterName: string | null;
|
|
@@ -60,8 +58,8 @@ export interface ChatSdkChannelContext<TAdapters extends ChatSdkAdapters = ChatS
|
|
|
60
58
|
/** Minimum interval between streaming edits, in ms. */
|
|
61
59
|
readonly streamingEditIntervalMs: number;
|
|
62
60
|
}
|
|
63
|
-
/** Event-handler context for `chatSdkChannel`, including
|
|
64
|
-
export interface ChatSdkEventContext<TAdapters extends ChatSdkAdapters = ChatSdkAdapters> extends ChatSdkChannelContext<TAdapters>,
|
|
61
|
+
/** Event-handler context for `chatSdkChannel`, including continuation routing. */
|
|
62
|
+
export interface ChatSdkEventContext<TAdapters extends ChatSdkAdapters = ChatSdkAdapters> extends ChatSdkChannelContext<TAdapters>, ChannelContinuationOps {
|
|
65
63
|
}
|
|
66
64
|
/**
|
|
67
65
|
* Per-event handlers for `chatSdkChannel({ events })`. Each supplied handler
|
|
@@ -70,12 +68,12 @@ export interface ChatSdkEventContext<TAdapters extends ChatSdkAdapters = ChatSdk
|
|
|
70
68
|
export type ChatSdkChannelEvents<TAdapters extends ChatSdkAdapters = ChatSdkAdapters> = ChannelEvents<ChatSdkChannelContext<TAdapters>>;
|
|
71
69
|
/**
|
|
72
70
|
* Options for `bridge.send(...)` inside Chat SDK handlers. The `thread`
|
|
73
|
-
* determines the
|
|
71
|
+
* determines the eve continuation token and the persisted channel state.
|
|
74
72
|
*/
|
|
75
73
|
export interface ChatSdkSendOptions {
|
|
76
74
|
readonly auth?: SessionAuthContext | null;
|
|
77
|
-
readonly callback?:
|
|
78
|
-
readonly mode?:
|
|
75
|
+
readonly callback?: ChannelAddressDeliveryOptions<ChatSdkChannelState>["callback"];
|
|
76
|
+
readonly mode?: ChannelAddressDeliveryOptions<ChatSdkChannelState>["mode"];
|
|
79
77
|
readonly thread: SerializedThread | Thread | string;
|
|
80
78
|
readonly title?: string;
|
|
81
79
|
/**
|
|
@@ -94,7 +92,7 @@ export interface ChatSdkSendOptions {
|
|
|
94
92
|
}
|
|
95
93
|
/**
|
|
96
94
|
* Configuration for {@link chatSdkChannel}. It accepts normal Chat SDK
|
|
97
|
-
* `ChatConfig` fields, plus
|
|
95
|
+
* `ChatConfig` fields, plus eve route and event settings.
|
|
98
96
|
*/
|
|
99
97
|
export interface ChatSdkChannelConfig<TAdapters extends ChatSdkAdapters = ChatSdkAdapters> extends Omit<ChatConfig<TAdapters>, "adapters"> {
|
|
100
98
|
/** Map of Chat SDK adapter name to adapter instance. */
|
|
@@ -110,12 +108,12 @@ export interface ChatSdkChannelConfig<TAdapters extends ChatSdkAdapters = ChatSd
|
|
|
110
108
|
* settings.
|
|
111
109
|
*/
|
|
112
110
|
readonly routes?: Partial<Record<Extract<keyof TAdapters, string>, string>>;
|
|
113
|
-
/** Extra Chat SDK webhook options.
|
|
111
|
+
/** Extra Chat SDK webhook options. eve owns `waitUntil`. */
|
|
114
112
|
readonly webhook?: Omit<WebhookOptions, "waitUntil">;
|
|
115
|
-
/** Optional
|
|
113
|
+
/** Optional eve event handlers. Supplied handlers replace built-in defaults. */
|
|
116
114
|
readonly events?: ChatSdkChannelEvents<TAdapters>;
|
|
117
115
|
/**
|
|
118
|
-
* Prefix for default
|
|
116
|
+
* Prefix for default eve HITL button action ids. Change this if your Chat SDK
|
|
119
117
|
* app already uses the `eve_input:` prefix.
|
|
120
118
|
*/
|
|
121
119
|
readonly inputActionPrefix?: string;
|
|
@@ -143,20 +141,20 @@ export interface ChatSdkChannel extends Channel<ChatSdkChannelState, ChatSdkRece
|
|
|
143
141
|
/**
|
|
144
142
|
* Return value of {@link chatSdkChannel}. Export `channel` from
|
|
145
143
|
* `agent/channels/<name>.ts`, then register handlers on `bot` and call `send`
|
|
146
|
-
* from those handlers to hand work to
|
|
144
|
+
* from those handlers to hand work to eve.
|
|
147
145
|
*/
|
|
148
146
|
export interface ChatSdkChannelBridge<TAdapters extends ChatSdkAdapters = ChatSdkAdapters> {
|
|
149
147
|
readonly bot: Chat<TAdapters>;
|
|
150
148
|
readonly channel: ChatSdkChannel;
|
|
151
149
|
/**
|
|
152
|
-
* Starts or resumes an
|
|
150
|
+
* Starts or resumes an eve session from inside a Chat SDK webhook handler.
|
|
153
151
|
* Use `channel.receive(...)` for proactive sends that are not handling an
|
|
154
152
|
* inbound Chat SDK webhook.
|
|
155
153
|
*/
|
|
156
154
|
send(input: ChatSdkSendInput, options: ChatSdkSendOptions): Promise<Session>;
|
|
157
155
|
}
|
|
158
156
|
/**
|
|
159
|
-
* Creates an
|
|
157
|
+
* Creates an eve channel backed by one Chat SDK runtime and its adapters.
|
|
160
158
|
*
|
|
161
159
|
* @example
|
|
162
160
|
* ```ts
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{createLogger,extractErrorId,formatErrorHint}from"#internal/logging.js";import{GET,POST,defineChannel}from"#public/definitions/channel.js";import{ContextContainer,contextStorage}from"#context/container.js";import{ContextKey}from"#context/key.js";import{Actions,Button,Card,CardText,Chat,Message,ThreadImpl}from"#compiled/chat/index.js";import{isNotImplemented}from"#public/channels/chat-sdk/notImplemented.js";const log=createLogger(`chat-sdk.channel`),ActiveWebhookKey=new ContextKey(`chat-sdk.active-webhook`);function chatSdkChannel(e){let t=new Chat(e),n=e.inputActionPrefix??`eve_input:`,
|
|
1
|
+
import{createLogger,extractErrorId,formatErrorHint}from"#internal/logging.js";import{normalizeSendInput}from"#channel/send-input.js";import{INTERNAL_CHANNEL_DELIVER}from"#channel/channel-operations.js";import{GET,POST,defineChannel}from"#public/definitions/channel.js";import{ContextContainer,contextStorage}from"#context/container.js";import{ContextKey}from"#context/key.js";import{Actions,Button,Card,CardText,Chat,Message,ThreadImpl}from"#compiled/chat/index.js";import{isNotImplemented}from"#public/channels/chat-sdk/notImplemented.js";const log=createLogger(`chat-sdk.channel`),ActiveWebhookKey=new ContextKey(`chat-sdk.active-webhook`);function chatSdkChannel(e){let t=new Chat(e),n=e.inputActionPrefix??`eve_input:`,r=e.streaming??!0,i=e.streamingEditIntervalMs??1e3,l={...defaultEvents(n),...e.events};return t.onAction(async r=>{let i=decodeInputAction(r.actionId,n,r.value);if(i){if(!r.thread)throw Error(`chatSdkChannel input actions require a thread on the Chat SDK action event.`);await bridgeSend(t,{inputResponses:[i]},{auth:e.resolveInputAuth?await e.resolveInputAuth(r):null,thread:r.thread})}}),{bot:t,channel:defineChannel({kindHint:`chat-sdk`,state:initialState(),metadata:metadataFromState,context(e){return{bot:t,state:e,streaming:r,streamingEditIntervalMs:i,thread:threadFromState(t,e)}},routes:adapterNames(e.adapters).flatMap(n=>{let r=routeForAdapter(n,e),handler=async(r,i)=>{let a=t.webhooks[n],o=new ContextContainer;return o.setVirtualContext(ActiveWebhookKey,{from:i.from}),contextStorage.run(o,()=>a(r,{...e.webhook,waitUntil(e){i.waitUntil(e)}}))};return[GET(r,handler),POST(r,handler)]}),async receive(e,{from:n}){let r=serializeReceiveTarget(t,e.target);return n(r.id).send(e.message,{auth:e.auth,state:{thread:r}})},events:l}),send(e,n){return bridgeSend(t,e,n)}}}function defaultEvents(e){return{async"turn.started"(e,t,n){t.state.pendingToolCallMessage=null,clearStream(t.state),await safeStartTyping(t.thread,`Working...`)},async"actions.requested"(e,t,n){let r=t.state.pendingToolCallMessage;if(t.state.pendingToolCallMessage=null,r){await safeStartTyping(t.thread,truncate(r));return}let i=e.actions.map(e=>e.kind===`tool-call`?e.toolName:e.kind);await safeStartTyping(t.thread,truncate(`Running ${i.join(`, `)}...`))},async"message.appended"(e,t,n){if(!t.thread||!e.messageSoFar||!canStream(t))return;let r=t.state.anchorMessageId;if(!r||t.state.streamStepIndex!==e.stepIndex){let n=await t.thread.post({markdown:e.messageSoFar});t.state.anchorMessageId=n.id,t.state.streamStepIndex=e.stepIndex,t.state.lastEditAtMs=Date.now();return}let i=t.state.lastEditAtMs??0;if(!(Date.now()-i<t.streamingEditIntervalMs))try{await editMessage(t.thread,r,e.messageSoFar),t.state.lastEditAtMs=Date.now()}catch(e){if(!isNotImplemented(e))throw e;t.state.editSupported=!1,clearStream(t.state)}},async"input.requested"(t,n,r){!n.thread||t.requests.length===0||await n.thread.post(renderInputRequests(t.requests,e))},async"message.completed"(e,t,n){if(e.finishReason===`tool-calls`){t.state.pendingToolCallMessage=e.message?firstNonEmptyLine(e.message)??null:null,e.message?await finalizeStreamedMessage(t,e.message,!1):clearStream(t.state);return}if(t.state.pendingToolCallMessage=null,!e.message){clearStream(t.state);return}await finalizeStreamedMessage(t,e.message,!0)},async"turn.failed"(e,t,n){await postFailure(t.thread,`I hit an error while handling your request`,e)},async"session.failed"(e,t){await postFailure(t.thread,`This session could not recover from an error`,e)}}}async function safeStartTyping(e,t){if(e)try{await e.startTyping(t)}catch(e){if(!isNotImplemented(e))throw e}}async function editMessage(e,t,n){await e.adapter.editMessage(e.id,t,{markdown:n})}async function finalizeStreamedMessage(e,t,n){let r=e.thread;if(!r){clearStream(e.state);return}let i=e.state.anchorMessageId;if(canStream(e)&&i)try{await editMessage(r,i,t)}catch(i){if(!isNotImplemented(i))throw i;e.state.editSupported=!1,n&&await r.post({markdown:t})}else n&&await r.post({markdown:t});clearStream(e.state)}function canStream(e){return e.streaming&&e.state.editSupported!==!1}function clearStream(e){e.anchorMessageId=null,e.lastEditAtMs=null,e.streamStepIndex=null}function firstNonEmptyLine(e){for(let t of e.split(/\r?\n/u)){let e=t.trim();if(e.length>0)return e}}function truncate(e,t=80){return e.length<=t?e:`${e.slice(0,t-1)}\u2026`}function renderInputRequests(e,t){return Card({children:e.flatMap(e=>renderInputRequest(e,t))})}function renderInputRequest(e,t){let n=[CardText(e.prompt)];return e.options&&e.options.length>0?(n.push(Actions(e.options.map(n=>Button({id:encodeInputAction(t,e.requestId,n.id),label:n.label,style:n.style,value:n.id})))),n):(n.push(CardText(`This request needs a freeform answer. Continue from the eve session UI.`)),n)}async function postFailure(e,r,i){if(!e)return;let a=formatErrorHint(i),o=extractErrorId(i.details);await e.post([`${r}${a}.`,`Please try again, rephrase, or reach out if it keeps failing.`,...o?[`Error id: ${o}`]:[]].join(`
|
|
2
2
|
|
|
3
|
-
`))}async function bridgeSend(e,t,n){let
|
|
3
|
+
`))}async function bridgeSend(e,t,n){let a=contextStorage.getStore()?.get(ActiveWebhookKey);if(!a)throw Error(`chatSdkChannel().send can only run during a Chat SDK webhook handler for this bridge.`);let o=serializeThread(e,n.thread,n.adapterName),s=normalizeSendInput(t),c={auth:n.auth??null,state:{thread:o}};n.callback!==void 0&&(c.callback=n.callback),n.mode!==void 0&&(c.mode=n.mode),n.title!==void 0&&(c.title=n.title);let l=a.from(o.id);return n.turnPolicy===`experimental-steer`&&hasMessageInput(t)&&await l.cancel(),l[INTERNAL_CHANNEL_DELIVER](s,c)}function hasMessageInput(e){return typeof e==`string`||Array.isArray(e)||e.message!==void 0}function initialState(){return{thread:null}}function metadataFromState(e){return{adapterName:e.thread?.adapterName??null,channelId:e.thread?.channelId??null,isDM:e.thread?.isDM??null,threadId:e.thread?.id??null}}function threadFromState(e,t){if(!t.thread)return null;try{let n=t.thread;return new ThreadImpl({adapter:e.getAdapter(n.adapterName),channelId:n.channelId,channelVisibility:n.channelVisibility,currentMessage:n.currentMessage?Message.fromJSON(n.currentMessage):void 0,id:n.id,isDM:n.isDM,stateAdapter:e.getState()})}catch(e){return log.warn(`failed to rebuild Chat SDK thread from channel state`,{error:e}),null}}function serializeReceiveTarget(e,t){if(t.thread)return t.thread;if(!t.threadId)throw Error(`chatSdkChannel().receive requires target.thread or target.threadId.`);return serializeThread(e,t.threadId,t.adapterName)}function serializeThread(e,t,n){if(typeof t==`string`){let r=n??inferAdapterName(t),i=e.getAdapter(r);return{_type:`chat:Thread`,adapterName:r,channelId:i.channelIdFromThreadId(t),channelVisibility:i.getChannelVisibility?.(t),id:t,isDM:!1}}return isSerializedThread(t)?t:t.toJSON()}function isSerializedThread(e){return`_type`in e&&e._type===`chat:Thread`}function inferAdapterName(e){let t=e.indexOf(`:`);if(t<=0)throw Error(`chatSdkChannel string thread references require options.adapterName.`);return e.slice(0,t)}function adapterNames(e){return Object.keys(e)}function routeForAdapter(e,t){return t.routes?.[e]||`${(t.route??`/eve/v1`).replace(/\/$/u,``)}/${e}`}function encodeInputAction(e,t,n){return`${e}${encodeURIComponent(t)}:${encodeURIComponent(n)}`}function decodeInputAction(e,t,n){if(!e.startsWith(t))return null;let r=e.slice(t.length),i=r.indexOf(`:`);if(i<=0)return null;try{let e=decodeURIComponent(r.slice(0,i));return{optionId:n??decodeURIComponent(r.slice(i+1)),requestId:e}}catch{return null}}export{chatSdkChannel};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { DiscordInstrumentationMetadata } from "#public/channels/discord/index.js";
|
|
2
2
|
import type { SessionAuthContext } from "#channel/types.js";
|
|
3
3
|
import type { SessionContext } from "#public/definitions/callback-context.js";
|
|
4
|
-
import type {
|
|
4
|
+
import type { ChannelContinuationOps } from "#public/definitions/channel.js";
|
|
5
5
|
import type { UnstampedMessageStreamEvent } from "#protocol/message.js";
|
|
6
6
|
import { type DiscordApiOptions, type DiscordApiResponse, type DiscordCredentials, type DiscordMessageBody, type DiscordPostedMessage } from "#public/channels/discord/api.js";
|
|
7
7
|
import { type DiscordCommandInteraction } from "#public/channels/discord/inbound.js";
|
|
@@ -21,8 +21,8 @@ export interface DiscordContext {
|
|
|
21
21
|
export type DiscordChannelContext = DiscordContext & {
|
|
22
22
|
state: DiscordChannelState;
|
|
23
23
|
};
|
|
24
|
-
/** Event-handler Discord context, including
|
|
25
|
-
export interface DiscordEventContext extends DiscordChannelContext,
|
|
24
|
+
/** Event-handler Discord context, including continuation routing. */
|
|
25
|
+
export interface DiscordEventContext extends DiscordChannelContext, ChannelContinuationOps {
|
|
26
26
|
}
|
|
27
27
|
/** JSON-serializable Discord channel state. */
|
|
28
28
|
export interface DiscordChannelState {
|
|
@@ -68,10 +68,11 @@ export type DiscordCommandResult = {
|
|
|
68
68
|
export type DiscordCommandResultOrPromise = DiscordCommandResult | Promise<DiscordCommandResult>;
|
|
69
69
|
type DiscordEventHandler<T extends UnstampedMessageStreamEvent["type"]> = (data: EventData<T>, channel: DiscordEventContext, ctx: SessionContext) => void | Promise<void>;
|
|
70
70
|
type DiscordSessionFailedHandler = (data: EventData<"session.failed">, channel: DiscordEventContext) => void | Promise<void>;
|
|
71
|
-
/** Per-event handlers for `discordChannel({ events })`. Supplied handlers override built-in defaults per key; unspecified events keep their defaults. `session.failed` receives only `(data, channel)`; every other handler also gets the session `ctx`. */
|
|
71
|
+
/** Per-event handlers for `discordChannel({ events })`. Supplied handlers override built-in defaults per key; unspecified events keep their defaults. `session.failed` receives only `(data, channel)` and exposes the ID as `data.sessionId`; every other handler also gets the session `ctx`. */
|
|
72
72
|
export interface DiscordChannelEvents {
|
|
73
73
|
readonly "turn.started"?: DiscordEventHandler<"turn.started">;
|
|
74
74
|
readonly "actions.requested"?: DiscordEventHandler<"actions.requested">;
|
|
75
|
+
readonly "action.partial"?: DiscordEventHandler<"action.partial">;
|
|
75
76
|
readonly "action.result"?: DiscordEventHandler<"action.result">;
|
|
76
77
|
readonly "message.completed"?: DiscordEventHandler<"message.completed">;
|
|
77
78
|
readonly "message.appended"?: DiscordEventHandler<"message.appended">;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createLogger,logError}from"#internal/logging.js";import{readNonEmptyString}from"#shared/guards.js";import{parseJsonObject}from"#shared/json.js";import{POST,defineChannel}from"#public/definitions/channel.js";import"#public/channels/discord/verify.js";import{callDiscordApi,createDiscordFollowupMessage,discordContinuationToken,editDiscordOriginalResponse,resolveDiscordBotToken,sendDiscordChannelMessage,splitDiscordMessageContent,triggerDiscordTypingIndicator}from"#public/channels/discord/api.js";import{buildFreeformModalResponse,deriveComponentInputResponses,deriveModalInputResponses,isDiscordFreeformComponent}from"#public/channels/discord/hitl.js";import{defaultEvents,defaultOnCommand}from"#public/channels/discord/defaults.js";import{DISCORD_INTERACTION_RESPONSE_TYPE,DISCORD_INTERACTION_TYPE,commandInteractionMessage,formatDiscordContextBlock,parseDiscordInteraction}from"#public/channels/discord/inbound.js";import{discordDeferredJson,discordJson,discordJsonBody,readMessageContent}from"#public/channels/discord/responses.js";import{verifyDiscordInbound}from"#public/channels/discord/verifyInbound.js";const log=createLogger(`discord.channel`);function discordChannel(e={}){let t=e.onCommand??defaultOnCommand,o={...defaultEvents,...e.events};return defineChannel({kindHint:`discord`,state:initialDiscordState(),metadata:e=>({channelId:e.channelId,guildId:e.guildId}),context(t,n){return rebuildDiscordContext(t,n,e)},routes:[POST(e.route??`/eve/v1/discord`,async(n,{
|
|
1
|
+
import{createLogger,logError}from"#internal/logging.js";import{readNonEmptyString}from"#shared/guards.js";import{parseJsonObject}from"#shared/json.js";import{POST,defineChannel}from"#public/definitions/channel.js";import"#public/channels/discord/verify.js";import{callDiscordApi,createDiscordFollowupMessage,discordContinuationToken,editDiscordOriginalResponse,resolveDiscordBotToken,sendDiscordChannelMessage,splitDiscordMessageContent,triggerDiscordTypingIndicator}from"#public/channels/discord/api.js";import{buildFreeformModalResponse,deriveComponentInputResponses,deriveModalInputResponses,isDiscordFreeformComponent}from"#public/channels/discord/hitl.js";import{defaultEvents,defaultOnCommand}from"#public/channels/discord/defaults.js";import{DISCORD_INTERACTION_RESPONSE_TYPE,DISCORD_INTERACTION_TYPE,commandInteractionMessage,formatDiscordContextBlock,parseDiscordInteraction}from"#public/channels/discord/inbound.js";import{discordDeferredJson,discordJson,discordJsonBody,readMessageContent}from"#public/channels/discord/responses.js";import{verifyDiscordInbound}from"#public/channels/discord/verifyInbound.js";const log=createLogger(`discord.channel`);function discordChannel(e={}){let t=e.onCommand??defaultOnCommand,o={...defaultEvents,...e.events};return defineChannel({kindHint:`discord`,state:initialDiscordState(),metadata:e=>({channelId:e.channelId,guildId:e.guildId}),context(t,n){return rebuildDiscordContext(t,n,e)},routes:[POST(e.route??`/eve/v1/discord`,async(n,{from:i,waitUntil:a})=>{let o=await verifyDiscordInbound(n,e.credentials);if(o===null)return new Response(`unauthorized`,{status:401});let s;try{s=parseJsonObject(JSON.parse(o))}catch(e){return log.warn(`inbound Discord body is not valid JSON`,{error:e}),discordJson({content:`invalid request`,ephemeral:!0})}if(s.type===DISCORD_INTERACTION_TYPE.PING)return discordJson({type:DISCORD_INTERACTION_RESPONSE_TYPE.PONG});let c=parseDiscordInteraction(s);return c===null?discordJson({content:`Unsupported Discord interaction.`,ephemeral:!0}):handleInteraction({config:e,interaction:c,onCommand:t,from:i,waitUntil:a})})],async receive(t,{from:r}){let i=t.target,a=readNonEmptyString(i.channelId);if(!a)throw Error(`discordChannel().receive requires target.channelId.`);let o=readNonEmptyString(i.conversationId),s=i.initialMessage;if(s!==void 0&&o!==void 0)throw Error("discordChannel().receive: `conversationId` and `initialMessage` are mutually exclusive.");let l=o??``,u=o!==void 0;if(s!==void 0){let t=await buildDiscordHandle({config:e,state:{...initialDiscordState(),channelId:a}}).sendChannelMessage(s);l=t.id,u=t.id.length>0}return r(discordContinuationToken(a,l)).send(t.message,{auth:t.auth,state:{applicationId:null,channelId:a,conversationId:l||null,guildId:null,hasMessageAnchor:u,initialResponseSent:!0,interactionToken:null}})},events:o})}function rebuildDiscordContext(e,t,n){return{discord:buildDiscordHandle({config:n,session:t,state:e}),state:e}}function buildDiscordHandle(e){let n=e.config.api,r=e.state,i=mergeCredentials(e.config.credentials,r);function anchor(t){!t.id||r.hasMessageAnchor||(r.conversationId=t.id,r.hasMessageAnchor=!0,r.channelId&&e.session?.continuation?.rekey(discordContinuationToken(r.channelId,t.id)))}async function sendViaChannel(e){let t=r.channelId??``;if(!t)throw Error(`discordChannel: missing channel id for outbound message.`);let a=await sendDiscordChannelMessage({apiBaseUrl:n?.apiBaseUrl,body:normalizePostInput(e),credentials:i,fetch:n?.fetch,channelId:t});return anchor(a),a}async function editOriginal(e){let t=r.interactionToken??``;if(!t)throw Error(`discordChannel: missing interaction token for original response edit.`);let a=await editDiscordOriginalResponse({apiBaseUrl:n?.apiBaseUrl,body:normalizePostInput(e),credentials:i,fetch:n?.fetch,interactionToken:t});return r.initialResponseSent=!0,anchor(a),a}async function followup(e){let t=r.interactionToken??``;if(!t)throw Error(`discordChannel: missing interaction token for followup message.`);let a=await createDiscordFollowupMessage({apiBaseUrl:n?.apiBaseUrl,body:normalizePostInput(e),credentials:i,fetch:n?.fetch,interactionToken:t});return anchor(a),a}async function startTyping(){let e=r.channelId??``;if(e)try{await triggerDiscordTypingIndicator({apiBaseUrl:n?.apiBaseUrl,credentials:i,fetch:n?.fetch,channelId:e})}catch(n){logError(log,`Discord typing indicator failed — swallowed`,n,{channelId:e})}}return{applicationId:r.applicationId??void 0,channelId:r.channelId??``,conversationId:r.conversationId??``,guildId:r.guildId??void 0,interactionToken:r.interactionToken??void 0,request(e,t,r){return callDiscordApi({apiBaseUrl:n?.apiBaseUrl,body:t,botToken:r?.botAuth===!0?i.botToken:void 0,fetch:n?.fetch,method:r?.method,path:e})},async post(e){let t=expandPostBodies(normalizePostInput(e)),n;for(let e of t){let t=await postOne({body:e,editOriginal,followup,sendViaChannel,state:r});n===void 0&&(n=t)}return n??{id:``,raw:null}},editOriginalResponse:editOriginal,followup,sendChannelMessage:sendViaChannel,startTyping}}async function postOne(e){if(e.state.interactionToken&&e.state.applicationId)try{return e.state.initialResponseSent?await e.followup(e.body):await e.editOriginal(e.body)}catch(e){log.warn(`Discord interaction-token delivery failed, falling back to channel message`,{error:e})}return e.sendViaChannel(e.body)}async function handleInteraction(e){return e.interaction.type===DISCORD_INTERACTION_TYPE.APPLICATION_COMMAND?handleCommandInteraction({config:e.config,interaction:e.interaction,onCommand:e.onCommand,from:e.from,waitUntil:e.waitUntil}):e.interaction.type===DISCORD_INTERACTION_TYPE.MESSAGE_COMPONENT?handleComponentInteraction({interaction:e.interaction,from:e.from,waitUntil:e.waitUntil}):handleModalSubmitInteraction({interaction:e.interaction,from:e.from,waitUntil:e.waitUntil})}async function handleCommandInteraction(e){let t=stateFromInteraction(e.interaction,{conversationId:e.interaction.id,hasMessageAnchor:!1,initialResponseSent:!1}),n={discord:buildDiscordHandle({config:e.config,state:t})},r;try{r=await e.onCommand(n,e.interaction)}catch(e){return log.error(`command handler failed`,{error:e}),discordJson({content:`The Discord command handler failed.`,ephemeral:!0})}return r==null?discordJson({content:`Command ignored.`,ephemeral:!0}):(e.waitUntil(dispatchCommand({interaction:e.interaction,result:r,from:e.from,state:t})),discordDeferredJson(r.ephemeral===!0))}function handleComponentInteraction(e){if(isDiscordFreeformComponent(e.interaction.customId)){let t=readMessageContent(e.interaction.raw);return discordJsonBody(buildFreeformModalResponse({customId:e.interaction.customId,prompt:t}))}let t=deriveComponentInputResponses(e.interaction);return t.length>0&&e.waitUntil(dispatchInputResponses({conversationId:e.interaction.messageId,inputResponses:t,interaction:e.interaction,from:e.from})),discordJsonBody({type:DISCORD_INTERACTION_RESPONSE_TYPE.DEFERRED_UPDATE_MESSAGE})}function handleModalSubmitInteraction(e){let t=deriveModalInputResponses(e.interaction);return t.length>0&&e.waitUntil(dispatchInputResponses({conversationId:e.interaction.messageId??e.interaction.id,inputResponses:t,interaction:e.interaction,from:e.from})),discordJson({content:`Answer received.`,ephemeral:!0})}async function dispatchCommand(e){let t=commandInteractionMessage(e.interaction),n=formatDiscordContextBlock({channelId:e.interaction.channelId,commandName:e.interaction.commandName,guildId:e.interaction.guildId,interactionId:e.interaction.id,userId:e.interaction.user.id,username:e.interaction.user.username}),r=e.result.context??[];try{await e.from(discordContinuationToken(e.interaction.channelId,e.interaction.id)).send(t,{auth:e.result.auth,context:[n,...r],state:e.state})}catch(e){log.error(`command delivery failed`,{error:e})}}async function dispatchInputResponses(e){try{await e.from(discordContinuationToken(e.interaction.channelId,e.conversationId)).respond(e.inputResponses,{auth:null})}catch(e){log.error(`interaction response delivery failed`,{error:e})}}function stateFromInteraction(e,t){return{applicationId:e.applicationId,channelId:e.channelId,conversationId:t.conversationId,guildId:e.guildId??null,hasMessageAnchor:t.hasMessageAnchor,initialResponseSent:t.initialResponseSent,interactionToken:e.token}}function initialDiscordState(){return{applicationId:null,channelId:null,conversationId:null,guildId:null,hasMessageAnchor:!1,initialResponseSent:!1,interactionToken:null}}function mergeCredentials(e,t){return{applicationId:t.applicationId??e?.applicationId,botToken:e?.botToken??(()=>resolveDiscordBotToken()),publicKey:e?.publicKey,webhookVerifier:e?.webhookVerifier}}function normalizePostInput(e){return typeof e==`string`?{content:e}:e}function expandPostBodies(e){return typeof e.content==`string`?splitDiscordMessageContent(e.content).map((t,n)=>n===0?{...e,content:t}:{allowed_mentions:e.allowed_mentions,content:t}):[e]}export{discordChannel};
|
|
@@ -3,13 +3,14 @@ import type { SessionAuthContext } from "#channel/types.js";
|
|
|
3
3
|
import { type TrustedForwarders } from "#channel/forwarded-principal.js";
|
|
4
4
|
import { type AuthFn } from "#public/channels/auth.js";
|
|
5
5
|
import { type UploadPolicyInput } from "#public/channels/upload-policy.js";
|
|
6
|
-
import { type Channel, type ChannelEvents, type
|
|
6
|
+
import { type Channel, type ChannelEvents, type ChannelContinuationOps } from "#public/definitions/channel.js";
|
|
7
7
|
import type { ChannelMethod } from "#public/definitions/channel.js";
|
|
8
8
|
/**
|
|
9
9
|
* Event-handler channel context exposed by `eveChannel({ events })`. The default eve HTTP channel
|
|
10
|
-
* has no platform-specific state, so handlers receive
|
|
10
|
+
* has no platform-specific state, so handlers receive optional continuation routing here and the
|
|
11
|
+
* `SessionContext` third argument from {@link ChannelEvents}.
|
|
11
12
|
*/
|
|
12
|
-
export type EveEventContext =
|
|
13
|
+
export type EveEventContext = ChannelContinuationOps;
|
|
13
14
|
/** Runtime stream-event handlers supported by `eveChannel({ events })`. */
|
|
14
15
|
export type EveChannelEvents = ChannelEvents<EveEventContext>;
|
|
15
16
|
export interface EveChannelCorsOptions {
|
|
@@ -41,7 +42,7 @@ export interface EveHandle {
|
|
|
41
42
|
/** Route-auth result for the request; `onMessage` chooses session auth by returning `{ auth }`. */
|
|
42
43
|
readonly caller: SessionAuthContext | null;
|
|
43
44
|
readonly request: Request;
|
|
44
|
-
/** Existing runtime session id for
|
|
45
|
+
/** Existing runtime session id for follow-up requests. */
|
|
45
46
|
readonly sessionId?: string;
|
|
46
47
|
}
|
|
47
48
|
/** Pre-dispatch context passed to `eveChannel({ onMessage })`. */
|
|
@@ -49,13 +50,13 @@ export interface EveMessageContext {
|
|
|
49
50
|
readonly eve: EveHandle;
|
|
50
51
|
}
|
|
51
52
|
/**
|
|
52
|
-
* Result of `eveChannel({ onMessage })`.
|
|
53
|
-
* optionally prepending `context` strings as user messages
|
|
53
|
+
* Result of `eveChannel({ onMessage })`. The object dispatches the inbound message,
|
|
54
|
+
* optionally prepending `context` strings as user messages.
|
|
54
55
|
*/
|
|
55
56
|
export type EveMessageResult = {
|
|
56
57
|
readonly auth: SessionAuthContext | null;
|
|
57
58
|
readonly context?: readonly string[];
|
|
58
|
-
}
|
|
59
|
+
};
|
|
59
60
|
/** Synchronous or asynchronous `onMessage` result. */
|
|
60
61
|
export type EveMessageResultOrPromise = EveMessageResult | Promise<EveMessageResult>;
|
|
61
62
|
/**
|
|
@@ -124,9 +125,9 @@ export interface EveChannel extends Channel {
|
|
|
124
125
|
}
|
|
125
126
|
/**
|
|
126
127
|
* Builds the default eve HTTP channel: a {@link defineChannel} instance serving the
|
|
127
|
-
* built-in `/eve/v1` routes (GET inspects the agent, POST creates a session,
|
|
128
|
-
*
|
|
129
|
-
*
|
|
128
|
+
* built-in `/eve/v1` routes (GET inspects the agent, POST creates a session,
|
|
129
|
+
* ID-addressed POST routes deliver follow-ups and controls, and GET streams a
|
|
130
|
+
* session's NDJSON event feed). Every route
|
|
130
131
|
* runs {@link EveChannelInput.auth} via {@link routeAuth} before dispatching.
|
|
131
132
|
* Default-export the result as your `agent/channels/eve.ts` channel; reach for
|
|
132
133
|
* {@link defineChannel} directly only for a custom transport.
|