eve 0.24.4 → 0.24.6
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 +31 -0
- package/dist/src/channel/cancel.d.ts +8 -0
- package/dist/src/channel/cancel.js +1 -0
- package/dist/src/channel/routes.d.ts +25 -4
- package/dist/src/channel/session.d.ts +10 -1
- package/dist/src/channel/session.js +1 -1
- package/dist/src/channel/types.d.ts +21 -0
- package/dist/src/chunks/{use-eve-agent-Dwa2j1wE.js → use-eve-agent-6BO9gFVq.js} +61 -6
- package/dist/src/chunks/{use-eve-agent-BP9FpQsJ.js → use-eve-agent-B1MJNRE-.js} +61 -6
- package/dist/src/cli/commands/build.d.ts +14 -0
- package/dist/src/cli/commands/build.js +1 -0
- package/dist/src/cli/commands/channels.js +1 -1
- package/dist/src/cli/commands/link.d.ts +6 -5
- package/dist/src/cli/commands/link.js +1 -1
- package/dist/src/cli/run.d.ts +3 -2
- package/dist/src/cli/run.js +1 -1
- package/dist/src/client/index.d.ts +1 -1
- package/dist/src/client/ndjson.js +1 -1
- package/dist/src/client/open-stream.d.ts +3 -2
- package/dist/src/client/open-stream.js +1 -1
- package/dist/src/client/session.d.ts +19 -3
- package/dist/src/client/session.js +1 -1
- package/dist/src/client/types.d.ts +8 -0
- package/dist/src/compiled/.vendor-stamp.json +5 -5
- package/dist/src/compiled/@workflow/core/index.js +2 -2
- package/dist/src/compiled/@workflow/core/runtime/helpers.d.ts +55 -0
- package/dist/src/compiled/@workflow/core/runtime/run-id-time.d.ts +9 -0
- package/dist/src/compiled/@workflow/core/runtime/step-executor.d.ts +2 -0
- package/dist/src/compiled/@workflow/core/runtime/step-latency.d.ts +70 -4
- package/dist/src/compiled/@workflow/core/runtime/suspension-handler.d.ts +10 -1
- package/dist/src/compiled/@workflow/core/runtime.js +3 -3
- package/dist/src/compiled/@workflow/core/step/context-storage.d.ts +6 -0
- package/dist/src/compiled/@workflow/core/telemetry/semantic-conventions.d.ts +25 -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/index.d.ts +16 -0
- package/dist/src/compiled/@workflow/errors/index.js +1 -1
- package/dist/src/compiled/@workflow/world/attributes.d.ts +7 -0
- package/dist/src/compiled/@workflow/world/events.d.ts +16 -0
- package/dist/src/compiled/@workflow/world/index.d.ts +1 -1
- package/dist/src/compiled/@workflow/world-local/index.js +3 -3
- package/dist/src/compiled/@workflow/world-vercel/index.js +16 -16
- package/dist/src/compiled/_chunks/workflow/attribute-changes-DXbmITuI.js +20 -0
- package/dist/src/compiled/_chunks/workflow/{dist-DpDDcpTl.js → dist-BYo8Gno2.js} +1 -1
- package/dist/src/compiled/_chunks/workflow/{dist-Blxnyb7-.js → dist-CSfKNxQW.js} +1 -1
- package/dist/src/compiled/_chunks/workflow/resume-hook-DvvgYsRt.js +1 -0
- package/dist/src/compiled/_chunks/workflow/run-BdvQmV5a.js +1 -0
- package/dist/src/compiled/_chunks/workflow/run-id-BdE0MZz9.js +1 -0
- package/dist/src/compiled/_chunks/workflow/sleep-DzxrwWTs.js +1 -0
- package/dist/src/evals/assertions/run.d.ts +3 -3
- package/dist/src/evals/context.js +1 -1
- package/dist/src/evals/index.d.ts +2 -1
- package/dist/src/evals/match.d.ts +4 -0
- package/dist/src/evals/match.js +1 -1
- package/dist/src/evals/runner/derive-run-facts.js +1 -1
- package/dist/src/evals/session.d.ts +10 -2
- package/dist/src/evals/session.js +1 -1
- package/dist/src/evals/target.js +1 -1
- package/dist/src/evals/types.d.ts +52 -2
- package/dist/src/execution/cancel-descendant-turns-step.d.ts +6 -0
- package/dist/src/execution/cancel-descendant-turns-step.js +1 -0
- package/dist/src/execution/create-session-step.js +1 -1
- package/dist/src/execution/dispatch-runtime-actions-step.js +1 -1
- package/dist/src/execution/dispatch-workflow-runtime-actions-step.js +1 -1
- package/dist/src/execution/node-step.js +1 -1
- package/dist/src/execution/remote-agent-dispatch.d.ts +6 -0
- package/dist/src/execution/remote-agent-dispatch.js +1 -1
- package/dist/src/execution/settle-cancelled-turn-step.js +1 -1
- package/dist/src/execution/subagent-event-proxy-step.js +1 -1
- package/dist/src/execution/turn-cancellation-control.d.ts +0 -13
- package/dist/src/execution/turn-cancellation-control.js +1 -1
- package/dist/src/execution/turn-cancellation-token.d.ts +9 -0
- package/dist/src/execution/turn-cancellation-token.js +1 -0
- package/dist/src/execution/turn-workflow.js +1 -1
- package/dist/src/execution/workflow-runtime.d.ts +3 -1
- package/dist/src/execution/workflow-runtime.js +1 -1
- package/dist/src/execution/workflow-steps.js +1 -1
- package/dist/src/harness/advertised-tools.js +1 -1
- package/dist/src/harness/execute-tool.d.ts +0 -1
- package/dist/src/harness/runtime-actions.d.ts +16 -12
- package/dist/src/harness/runtime-actions.js +1 -1
- package/dist/src/internal/application/build-profile.d.ts +64 -0
- package/dist/src/internal/application/build-profile.js +1 -0
- package/dist/src/internal/application/package.js +1 -1
- package/dist/src/internal/authored-module-loader.d.ts +10 -0
- package/dist/src/internal/authored-module-loader.js +2 -2
- package/dist/src/internal/authored-module-map-loader.js +1 -1
- package/dist/src/internal/materialized-authored-modules.d.ts +2 -4
- package/dist/src/internal/materialized-authored-modules.js +1 -1
- package/dist/src/internal/nitro/dev-runtime-artifacts.js +1 -1
- package/dist/src/internal/nitro/host/build-application.js +1 -1
- package/dist/src/internal/nitro/host/types.d.ts +2 -0
- package/dist/src/internal/nitro/routes/agent-info/build-agent-info-response-from-manifest.js +1 -1
- package/dist/src/internal/nitro/routes/agent-info/build-agent-info-response.d.ts +7 -1
- package/dist/src/internal/nitro/routes/agent-info/build-agent-info-response.js +1 -1
- package/dist/src/internal/nitro/routes/channel-dispatch.js +1 -1
- package/dist/src/internal/nitro/routes/channel-route-context.d.ts +3 -0
- package/dist/src/internal/nitro/routes/channel-route-context.js +1 -1
- package/dist/src/internal/nitro/routes/runtime-stack.js +1 -1
- package/dist/src/internal/nitro/routes/schedule-task.js +1 -1
- package/dist/src/protocol/cancel-turn.d.ts +11 -0
- package/dist/src/protocol/cancel-turn.js +1 -0
- package/dist/src/protocol/routes.d.ts +10 -0
- package/dist/src/protocol/routes.js +1 -1
- package/dist/src/public/channels/eve.d.ts +2 -1
- package/dist/src/public/channels/eve.js +1 -1
- package/dist/src/public/channels/index.d.ts +1 -1
- package/dist/src/public/channels/linear/api.d.ts +0 -1
- package/dist/src/public/channels/linear/api.js +17 -22
- package/dist/src/public/channels/linear/linearChannel.js +1 -1
- package/dist/src/public/definitions/channel.d.ts +21 -11
- package/dist/src/public/next/index.js +1 -1
- package/dist/src/public/next/resolve-eve-binary.d.ts +12 -0
- package/dist/src/public/next/resolve-eve-binary.js +1 -0
- package/dist/src/runtime/agent/mock-model-adapter.js +1 -1
- package/dist/src/runtime/framework-tools/agent.d.ts +13 -0
- package/dist/src/runtime/framework-tools/agent.js +1 -0
- package/dist/src/runtime/framework-tools/index.d.ts +7 -2
- package/dist/src/runtime/framework-tools/index.js +1 -1
- package/dist/src/runtime/resolve-agent-graph.js +1 -1
- package/dist/src/runtime/types.d.ts +2 -1
- package/dist/src/setup/boxes/reconcile-host-framework-preset.d.ts +26 -0
- package/dist/src/setup/boxes/reconcile-host-framework-preset.js +1 -0
- package/dist/src/setup/boxes/resolve-provisioning.js +1 -1
- package/dist/src/setup/index.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 +1 -0
- package/dist/src/setup/scaffold/index.d.ts +1 -1
- package/dist/src/setup/scaffold/index.js +1 -1
- package/dist/src/setup/scaffold/update/channels.d.ts +7 -1
- package/dist/src/setup/scaffold/update/channels.js +2 -2
- package/dist/src/setup/scaffold/update/connections.js +3 -3
- package/dist/src/setup/vercel-project-framework.d.ts +12 -0
- package/dist/src/setup/vercel-project-framework.js +1 -1
- package/dist/src/svelte/index.js +1 -1
- 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.js +1 -1
- package/docs/channels/custom.mdx +32 -2
- package/docs/channels/eve.mdx +11 -1
- package/docs/concepts/default-harness.md +2 -0
- package/docs/concepts/sessions-runs-and-streaming.md +13 -0
- package/docs/evals/assertions.mdx +2 -2
- package/docs/evals/cases.mdx +31 -0
- package/docs/evals/overview.mdx +1 -1
- package/docs/evals/targets.mdx +2 -1
- package/docs/guides/client/continuations.mdx +2 -0
- package/docs/guides/client/streaming.mdx +17 -1
- package/docs/guides/frontend/overview.mdx +4 -2
- package/docs/guides/frontend/use-eve-agent-svelte.mdx +2 -2
- package/docs/guides/frontend/use-eve-agent-vue.mdx +2 -2
- package/docs/guides/remote-agents.md +2 -0
- package/docs/reference/cli.md +15 -2
- package/docs/subagents.mdx +10 -0
- package/package.json +7 -7
- package/dist/src/compiled/_chunks/workflow/attribute-changes-MGTOG_uX.js +0 -20
- package/dist/src/compiled/_chunks/workflow/resume-hook-DHP5ql3-.js +0 -1
- package/dist/src/compiled/_chunks/workflow/run-D8hv1ptT.js +0 -1
- package/dist/src/compiled/_chunks/workflow/sleep-uA9pS-PT.js +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,36 @@
|
|
|
1
1
|
# eve
|
|
2
2
|
|
|
3
|
+
## 0.24.6
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 3029647: Update the generated Web Chat template for Next.js 16.3 preview type declarations.
|
|
8
|
+
- b97f1d1: Custom channel routes can now cancel a session's in-flight turn: route handlers receive a `cancel({ continuationToken, turnId? })` helper addressed by the channel-local continuation token, and `Session` handles returned by `send()` and `getSession()` expose `cancel({ turnId? })` for session-id-addressed cancellation. `ClientSession.cancel()` accepts the same optional `turnId` stale-request guard.
|
|
9
|
+
|
|
10
|
+
## 0.24.5
|
|
11
|
+
|
|
12
|
+
### Patch Changes
|
|
13
|
+
|
|
14
|
+
- bfbbe92: Add `eve build --profile <path>` for a machine-readable build-timing and final-output-size report. Profile collection is best-effort, so reporting failures do not fail an otherwise successful build.
|
|
15
|
+
- dab9889: Allow agents to remove the root-only built-in `agent` delegation tool with `disableTool()` from `agent/tools/agent.ts`.
|
|
16
|
+
- e1cb505: Retry transient network failures while reopening client session streams so active turns remain attached.
|
|
17
|
+
- 2568387: Cancel active local, nested, and remote subagent turns when their parent turn is cancelled. Client and eval sessions can now cancel active turns directly, and eval live-turn handles can wait for typed mid-turn events before cancellation or settlement.
|
|
18
|
+
- 20cd9a1: Added `POST /eve/v1/session/:sessionId/cancel` to the eve HTTP channel for requesting cancellation of an in-flight turn. The optional `{ turnId }` body limits the request to the turn the caller observed; the response reports `"accepted"` when a cancellation hook accepts it or the benign `"no_active_turn"` when no resumable target exists.
|
|
19
|
+
- 02698fd: Fix Vercel deploys for the Next.js web channel. `eve` no longer scaffolds a
|
|
20
|
+
`vercel.json` `experimentalServices` block, which the Vercel platform now
|
|
21
|
+
rejects (it requires the `services` key and a stricter schema). For Next.js the
|
|
22
|
+
block was also redundant — `withEve()` generates the eve service and
|
|
23
|
+
`/eve/v1/*` routes into the Build Output at build time — so the scaffold now
|
|
24
|
+
writes a minimal `vercel.json`.
|
|
25
|
+
- e45a066: `eve link` now lets you create a Vercel project or link an existing one, matching the project setup available through `/model` usage.
|
|
26
|
+
- 5f8818b: `eve channels add web` now updates the Vercel Framework Preset when adding a
|
|
27
|
+
Next.js web channel to an already-linked eve project to prevent deployment
|
|
28
|
+
failures.
|
|
29
|
+
- 887908c: Bundle authored modules in each development generation as one shared graph, avoiding repeated parsing and emission of dependencies for every tool.
|
|
30
|
+
- 376a82f: Report the root-only `agent` action alongside other framework tools in agent info, including whether it is active, disabled, or replaced.
|
|
31
|
+
- 4f2863d: Update the bundled Workflow runtime dependencies to their latest 5.0 beta releases.
|
|
32
|
+
- d9d3226: Fix `withEve` producing a broken Vercel build command in npm workspaces, where the `eve` module is located in the workspace root.
|
|
33
|
+
|
|
3
34
|
## 0.24.4
|
|
4
35
|
|
|
5
36
|
### Patch Changes
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { CancelFn } from "#channel/routes.js";
|
|
2
|
+
import type { Runtime } from "#channel/types.js";
|
|
3
|
+
/**
|
|
4
|
+
* Builds the route-handler `cancel` helper for one channel. Resolves the
|
|
5
|
+
* channel-local continuation token to its owning session without delivering
|
|
6
|
+
* input, then delegates to the runtime's session-id-addressed cancellation.
|
|
7
|
+
*/
|
|
8
|
+
export declare function createCancelFn(runtime: Runtime, channelName: string): CancelFn;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function createCancelFn(e,t){return async n=>{let r=`${t}:${n.continuationToken}`,i=await e.resolveSession(r);return i===void 0?{status:`no_active_turn`}:await e.cancelTurn({sessionId:i.sessionId,turnId:n.turnId})}}export{createCancelFn};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { UserContent } from "ai";
|
|
2
2
|
import type { CrossChannelReceiveFn } from "#channel/cross-channel-receive.js";
|
|
3
|
-
import type { SessionAuthContext, SessionCallback } from "#channel/types.js";
|
|
3
|
+
import type { CancelTurnResult, SessionAuthContext, SessionCallback } from "#channel/types.js";
|
|
4
4
|
import type { InputResponse } from "#runtime/input/types.js";
|
|
5
5
|
import type { Session } from "#channel/session.js";
|
|
6
6
|
import type { RunMode } from "#shared/run-mode.js";
|
|
@@ -9,13 +9,15 @@ import type { ChannelMethod } from "#public/definitions/channel.js";
|
|
|
9
9
|
type WebSocketHeaders = Headers | readonly (readonly [string, string])[] | Record<string, string>;
|
|
10
10
|
/**
|
|
11
11
|
* Second argument passed to every route handler. `send` starts or continues a
|
|
12
|
-
* session on this channel; `
|
|
13
|
-
*
|
|
14
|
-
*
|
|
12
|
+
* session on this channel; `cancel` stops the active turn on a session
|
|
13
|
+
* addressed by continuation token; `getSession` looks one up by id; `receive`
|
|
14
|
+
* hands inbound work to a different channel; `params` contains the matched
|
|
15
|
+
* path parameters; `waitUntil` keeps background work alive past the response;
|
|
15
16
|
* `requestIp` is the client IP, or `null` when the host cannot provide it.
|
|
16
17
|
*/
|
|
17
18
|
export interface RouteHandlerArgs<TState = undefined> {
|
|
18
19
|
send: SendFn<TState>;
|
|
20
|
+
cancel: CancelFn;
|
|
19
21
|
getSession: GetSessionFn;
|
|
20
22
|
/**
|
|
21
23
|
* Starts a session on a different channel to hand off inbound work (e.g. an
|
|
@@ -78,6 +80,25 @@ export type SendOptions<TState = undefined> = [TState] extends [undefined] ? Bas
|
|
|
78
80
|
* stream from within a route handler.
|
|
79
81
|
*/
|
|
80
82
|
export type GetSessionFn = (sessionId: string) => Session;
|
|
83
|
+
/**
|
|
84
|
+
* Options for {@link CancelFn}. `continuationToken` is the channel-local raw
|
|
85
|
+
* token, exactly as passed to {@link SendFn}. `turnId` limits the request to
|
|
86
|
+
* the turn the caller observed; a stale guard is consumed as a benign no-op.
|
|
87
|
+
*/
|
|
88
|
+
export interface CancelOptions {
|
|
89
|
+
readonly continuationToken: string;
|
|
90
|
+
readonly turnId?: string;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Requests cancellation of the active turn on the session that owns the
|
|
94
|
+
* continuation token. Never starts a session, sends input, or clears history.
|
|
95
|
+
*
|
|
96
|
+
* Both statuses are successful: `"accepted"` means the request was consumed,
|
|
97
|
+
* and `"no_active_turn"` covers an unknown token and a session with nothing
|
|
98
|
+
* to cancel. Confirmation is `turn.cancelled` followed by `session.waiting`
|
|
99
|
+
* on the event stream.
|
|
100
|
+
*/
|
|
101
|
+
export type CancelFn = (options: CancelOptions) => Promise<CancelTurnResult>;
|
|
81
102
|
export type RouteHandler<TState = undefined> = (req: Request, args: RouteHandlerArgs<TState>) => Promise<Response>;
|
|
82
103
|
/**
|
|
83
104
|
* A connected WebSocket peer passed to every {@link WebSocketRouteHooks}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ContextAccessor } from "#context/key.js";
|
|
2
2
|
import type { HandleMessageStreamEvent } from "#protocol/message.js";
|
|
3
|
-
import type { Runtime } from "#channel/types.js";
|
|
3
|
+
import type { CancelTurnResult, Runtime } from "#channel/types.js";
|
|
4
4
|
import type { SessionAuth } from "#context/keys.js";
|
|
5
5
|
/**
|
|
6
6
|
* Result of starting or delivering to a session. Exposes the session
|
|
@@ -14,6 +14,15 @@ import type { SessionAuth } from "#context/keys.js";
|
|
|
14
14
|
export interface Session {
|
|
15
15
|
readonly id: string;
|
|
16
16
|
readonly continuationToken: string;
|
|
17
|
+
/**
|
|
18
|
+
* Requests cancellation of this session's in-flight turn. `turnId` limits
|
|
19
|
+
* the request to the turn the caller observed. Both statuses are
|
|
20
|
+
* successful; confirmation is `turn.cancelled` followed by
|
|
21
|
+
* `session.waiting` on the event stream.
|
|
22
|
+
*/
|
|
23
|
+
cancel(options?: {
|
|
24
|
+
turnId?: string;
|
|
25
|
+
}): Promise<CancelTurnResult>;
|
|
17
26
|
/**
|
|
18
27
|
* Opens the durable event stream. Negative start indexes read relative to
|
|
19
28
|
* the current tail (`-1` starts at the latest event).
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{AuthKey,ContinuationTokenKey,InitiatorAuthKey,SessionIdKey}from"#context/keys.js";function createSession(e,t,n){return{id:e,continuationToken:t,async getEventStream(t){return n.getEventStream(e,t)}}}function createGetSessionFn(e){return t=>createSession(t,``,e)}function buildSessionHandle(i){return{get id(){return i.get(SessionIdKey)??``},get continuationToken(){return i.get(ContinuationTokenKey)??``},get auth(){return{current:i.get(AuthKey)??null,initiator:i.get(InitiatorAuthKey)??null}},setContinuationToken(e){let n=i.get(ContinuationTokenKey)??``,r=namespaceContinuationToken(n,e);n!==r&&i.set(ContinuationTokenKey,r)}}}function namespaceContinuationToken(e,t){let n=e.indexOf(`:`);if(n<=0)throw Error(`Cannot set session continuation token without an existing namespaced continuation token. Start the session with a placeholder continuationToken.`);return`${e.slice(0,n+1)}${t}`}export{buildSessionHandle,createGetSessionFn,createSession};
|
|
1
|
+
import{AuthKey,ContinuationTokenKey,InitiatorAuthKey,SessionIdKey}from"#context/keys.js";function createSession(e,t,n){return{id:e,continuationToken:t,async cancel(t){return n.cancelTurn({sessionId:e,turnId:t?.turnId})},async getEventStream(t){return n.getEventStream(e,t)}}}function createGetSessionFn(e){return t=>createSession(t,``,e)}function buildSessionHandle(i){return{get id(){return i.get(SessionIdKey)??``},get continuationToken(){return i.get(ContinuationTokenKey)??``},get auth(){return{current:i.get(AuthKey)??null,initiator:i.get(InitiatorAuthKey)??null}},setContinuationToken(e){let n=i.get(ContinuationTokenKey)??``,r=namespaceContinuationToken(n,e);n!==r&&i.set(ContinuationTokenKey,r)}}}function namespaceContinuationToken(e,t){let n=e.indexOf(`:`);if(n<=0)throw Error(`Cannot set session continuation token without an existing namespaced continuation token. Start the session with a placeholder continuationToken.`);return`${e.slice(0,n+1)}${t}`}export{buildSessionHandle,createGetSessionFn,createSession};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { UserContent } from "ai";
|
|
2
2
|
import type { HandleMessageStreamEvent } from "#protocol/message.js";
|
|
3
|
+
import type { CancelTurnStatus } from "#protocol/cancel-turn.js";
|
|
3
4
|
import type { RunMode } from "#shared/run-mode.js";
|
|
4
5
|
import type { RuntimeActionResult } from "#runtime/actions/types.js";
|
|
5
6
|
import type { InputRequest, InputResponse } from "#runtime/input/types.js";
|
|
@@ -10,6 +11,16 @@ export type { ContextAccessor } from "#context/key.js";
|
|
|
10
11
|
export type { ChannelInstrumentationProjection } from "#channel/instrumentation.js";
|
|
11
12
|
import type { ChannelInstrumentationProjection } from "#channel/instrumentation.js";
|
|
12
13
|
export type RunSessionLimits = Pick<AgentLimitsDefinition, "maxInputTokensPerSession" | "maxOutputTokensPerSession">;
|
|
14
|
+
/** Identifies the session turn to cancel. */
|
|
15
|
+
export interface CancelTurnInput {
|
|
16
|
+
readonly sessionId: string;
|
|
17
|
+
/** Limits the request to the turn the caller observed. */
|
|
18
|
+
readonly turnId?: string;
|
|
19
|
+
}
|
|
20
|
+
/** Result of requesting turn cancellation. Both statuses are successful. */
|
|
21
|
+
export interface CancelTurnResult {
|
|
22
|
+
readonly status: CancelTurnStatus;
|
|
23
|
+
}
|
|
13
24
|
/**
|
|
14
25
|
* Identifies one turn within a session.
|
|
15
26
|
*
|
|
@@ -314,12 +325,22 @@ export interface Runtime {
|
|
|
314
325
|
* completion.
|
|
315
326
|
*/
|
|
316
327
|
run(input: RunInput): Promise<RunHandle>;
|
|
328
|
+
/** Requests cancellation of a session's in-flight turn. */
|
|
329
|
+
cancelTurn(input: CancelTurnInput): Promise<CancelTurnResult>;
|
|
317
330
|
/**
|
|
318
331
|
* Delivers a follow-up message to a parked session.
|
|
319
332
|
*/
|
|
320
333
|
deliver(input: DeliverInput): Promise<{
|
|
321
334
|
sessionId: string;
|
|
322
335
|
}>;
|
|
336
|
+
/**
|
|
337
|
+
* Resolves the session that currently owns a continuation token without
|
|
338
|
+
* delivering input or starting a run. Returns `undefined` when no session
|
|
339
|
+
* owns the token.
|
|
340
|
+
*/
|
|
341
|
+
resolveSession(continuationToken: string): Promise<{
|
|
342
|
+
sessionId: string;
|
|
343
|
+
} | undefined>;
|
|
323
344
|
/**
|
|
324
345
|
* Returns a readable stream of lifecycle events for an existing session.
|
|
325
346
|
*
|
|
@@ -8,6 +8,7 @@ const EVE_INFO_ROUTE_PATH = `${EVE_ROUTE_PREFIX}/info`;
|
|
|
8
8
|
const EVE_CREATE_SESSION_ROUTE_PATH = `${EVE_ROUTE_PREFIX}/session`;
|
|
9
9
|
const EVE_CONTINUE_SESSION_ROUTE_PATTERN = `${EVE_ROUTE_PREFIX}/session/:sessionId`;
|
|
10
10
|
const EVE_MESSAGE_STREAM_ROUTE_PATTERN = `${EVE_ROUTE_PREFIX}/session/:sessionId/stream`;
|
|
11
|
+
const EVE_CANCEL_TURN_ROUTE_PATTERN = `${EVE_ROUTE_PREFIX}/session/:sessionId/cancel`;
|
|
11
12
|
const EVE_DEV_DISPATCH_SCHEDULE_ROUTE_PATTERN = `${EVE_ROUTE_PREFIX}/dev/schedules/:scheduleId`;
|
|
12
13
|
const EVE_DEV_RUNTIME_ARTIFACTS_ROUTE_PATH = `${EVE_ROUTE_PREFIX}/dev/runtime-artifacts`;
|
|
13
14
|
const EVE_DEV_RUNTIME_ARTIFACTS_REBUILD_ROUTE_PATH = `${EVE_DEV_RUNTIME_ARTIFACTS_ROUTE_PATH}/rebuild`;
|
|
@@ -19,6 +20,9 @@ function createEveMessageStreamRoutePath(sessionId) {
|
|
|
19
20
|
function createEveContinueSessionRoutePath(sessionId) {
|
|
20
21
|
return `${EVE_ROUTE_PREFIX}/session/${encodeURIComponent(sessionId)}`;
|
|
21
22
|
}
|
|
23
|
+
function createEveCancelTurnRoutePath(sessionId) {
|
|
24
|
+
return `${EVE_ROUTE_PREFIX}/session/${encodeURIComponent(sessionId)}/cancel`;
|
|
25
|
+
}
|
|
22
26
|
|
|
23
27
|
//#endregion
|
|
24
28
|
//#region src/client/agent-info-error.ts
|
|
@@ -290,6 +294,14 @@ function isCurrentTurnBoundaryEvent(event) {
|
|
|
290
294
|
return event.type === "session.completed" || event.type === "session.failed" || event.type === "session.waiting";
|
|
291
295
|
}
|
|
292
296
|
|
|
297
|
+
//#endregion
|
|
298
|
+
//#region src/protocol/cancel-turn.ts
|
|
299
|
+
const CancelTurnResponseSchema = z.object({
|
|
300
|
+
ok: z.literal(true),
|
|
301
|
+
sessionId: z.string().min(1),
|
|
302
|
+
status: z.enum(["accepted", "no_active_turn"])
|
|
303
|
+
});
|
|
304
|
+
|
|
293
305
|
//#endregion
|
|
294
306
|
//#region src/shared/json.ts
|
|
295
307
|
const INVALID_JSON_VALUE_CANDIDATE = Symbol("invalid-json-value-candidate");
|
|
@@ -442,7 +454,7 @@ function isStreamDisconnectError(error) {
|
|
|
442
454
|
if (error instanceof DOMException) return error.name === "AbortError";
|
|
443
455
|
if (!(error instanceof Error)) return false;
|
|
444
456
|
const errorCode = "code" in error && typeof error.code === "string" ? error.code : void 0;
|
|
445
|
-
return error.name === "AbortError" || error.message === "terminated" || errorCode === "UND_ERR_SOCKET" || /abort|cancel|disconnect|premature close|socket|terminated/i.test(error.message);
|
|
457
|
+
return error.name === "AbortError" || error.message === "terminated" || errorCode === "UND_ERR_SOCKET" || error instanceof TypeError && /^(?:failed to fetch|fetch failed)$/i.test(error.message) || /abort|cancel|disconnect|premature close|socket|terminated/i.test(error.message);
|
|
446
458
|
}
|
|
447
459
|
async function* readNdjsonStream(body) {
|
|
448
460
|
const reader = body.getReader();
|
|
@@ -548,11 +560,18 @@ async function openStreamBody(input) {
|
|
|
548
560
|
for (let attempt = 0; attempt < STREAM_OPEN_RETRY_ATTEMPTS; attempt += 1) {
|
|
549
561
|
const url = createClientUrl(input.host, createEveMessageStreamRoutePath(input.sessionId), input.startIndex !== 0 ? { startIndex: String(input.startIndex) } : void 0);
|
|
550
562
|
const headers = await input.resolveHeaders();
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
563
|
+
let response;
|
|
564
|
+
try {
|
|
565
|
+
response = await fetch(url, {
|
|
566
|
+
headers,
|
|
567
|
+
redirect: input.redirect,
|
|
568
|
+
signal: input.signal ?? null
|
|
569
|
+
});
|
|
570
|
+
} catch (error) {
|
|
571
|
+
if (input.signal?.aborted || !isStreamDisconnectError(error) || attempt === STREAM_OPEN_RETRY_ATTEMPTS - 1) throw error;
|
|
572
|
+
await sleep$1(STREAM_OPEN_RETRY_DELAY_MS);
|
|
573
|
+
continue;
|
|
574
|
+
}
|
|
556
575
|
if (response.ok) {
|
|
557
576
|
if (!response.body) throw new ClientError(response.status, "Response body is null.", response.headers);
|
|
558
577
|
return response.body;
|
|
@@ -587,12 +606,42 @@ var ClientSession = class {
|
|
|
587
606
|
const payload = normalizeSendTurnInput(input);
|
|
588
607
|
const state = this.#state;
|
|
589
608
|
const { continuationToken, sessionId } = await this.#postTurn(payload, state);
|
|
609
|
+
if (this.#state === state) this.#state = {
|
|
610
|
+
...state,
|
|
611
|
+
sessionId
|
|
612
|
+
};
|
|
590
613
|
return new MessageResponse({
|
|
591
614
|
continuationToken,
|
|
592
615
|
createStream: () => this.#createEventStream(sessionId, continuationToken, state, payload),
|
|
593
616
|
sessionId
|
|
594
617
|
});
|
|
595
618
|
}
|
|
619
|
+
async cancel(options) {
|
|
620
|
+
const sessionId = this.#state.sessionId;
|
|
621
|
+
if (!sessionId) throw new Error("Session has no session ID. Send a message first.");
|
|
622
|
+
const url = createClientUrl(this.#context.host, createEveCancelTurnRoutePath(sessionId));
|
|
623
|
+
const headers = await this.#context.resolveHeaders();
|
|
624
|
+
headers.set("content-type", "application/json");
|
|
625
|
+
const response = await fetch(url, withRedirectPolicy$1({
|
|
626
|
+
headers,
|
|
627
|
+
method: "POST",
|
|
628
|
+
body: options ? JSON.stringify(options) : void 0
|
|
629
|
+
}, this.#context.redirect));
|
|
630
|
+
const body = await response.text();
|
|
631
|
+
if (!response.ok) throw new ClientError(response.status, body, response.headers);
|
|
632
|
+
let payload;
|
|
633
|
+
try {
|
|
634
|
+
payload = JSON.parse(body);
|
|
635
|
+
} catch {
|
|
636
|
+
throw new Error(`Cancel route returned invalid JSON (${response.status}).`);
|
|
637
|
+
}
|
|
638
|
+
const result = CancelTurnResponseSchema.safeParse(payload);
|
|
639
|
+
if (!result.success || result.data.sessionId !== sessionId) throw new Error(`Cancel route returned an invalid response (${response.status}).`);
|
|
640
|
+
return {
|
|
641
|
+
sessionId: result.data.sessionId,
|
|
642
|
+
status: result.data.status
|
|
643
|
+
};
|
|
644
|
+
}
|
|
596
645
|
stream(options) {
|
|
597
646
|
const sessionId = this.#state.sessionId;
|
|
598
647
|
if (!sessionId) throw new Error("Session has no session ID. Send a message first.");
|
|
@@ -746,6 +795,12 @@ function createHandleMessageBody(input) {
|
|
|
746
795
|
if (input.session.continuationToken !== void 0 && body.message === void 0 && body.inputResponses === void 0) return null;
|
|
747
796
|
return body;
|
|
748
797
|
}
|
|
798
|
+
function withRedirectPolicy$1(init, redirect) {
|
|
799
|
+
return redirect === void 0 ? init : {
|
|
800
|
+
...init,
|
|
801
|
+
redirect
|
|
802
|
+
};
|
|
803
|
+
}
|
|
749
804
|
|
|
750
805
|
//#endregion
|
|
751
806
|
//#region src/client/types.ts
|
|
@@ -8,6 +8,7 @@ const EVE_INFO_ROUTE_PATH = `${EVE_ROUTE_PREFIX}/info`;
|
|
|
8
8
|
const EVE_CREATE_SESSION_ROUTE_PATH = `${EVE_ROUTE_PREFIX}/session`;
|
|
9
9
|
const EVE_CONTINUE_SESSION_ROUTE_PATTERN = `${EVE_ROUTE_PREFIX}/session/:sessionId`;
|
|
10
10
|
const EVE_MESSAGE_STREAM_ROUTE_PATTERN = `${EVE_ROUTE_PREFIX}/session/:sessionId/stream`;
|
|
11
|
+
const EVE_CANCEL_TURN_ROUTE_PATTERN = `${EVE_ROUTE_PREFIX}/session/:sessionId/cancel`;
|
|
11
12
|
const EVE_DEV_DISPATCH_SCHEDULE_ROUTE_PATTERN = `${EVE_ROUTE_PREFIX}/dev/schedules/:scheduleId`;
|
|
12
13
|
const EVE_DEV_RUNTIME_ARTIFACTS_ROUTE_PATH = `${EVE_ROUTE_PREFIX}/dev/runtime-artifacts`;
|
|
13
14
|
const EVE_DEV_RUNTIME_ARTIFACTS_REBUILD_ROUTE_PATH = `${EVE_DEV_RUNTIME_ARTIFACTS_ROUTE_PATH}/rebuild`;
|
|
@@ -19,6 +20,9 @@ function createEveMessageStreamRoutePath(sessionId) {
|
|
|
19
20
|
function createEveContinueSessionRoutePath(sessionId) {
|
|
20
21
|
return `${EVE_ROUTE_PREFIX}/session/${encodeURIComponent(sessionId)}`;
|
|
21
22
|
}
|
|
23
|
+
function createEveCancelTurnRoutePath(sessionId) {
|
|
24
|
+
return `${EVE_ROUTE_PREFIX}/session/${encodeURIComponent(sessionId)}/cancel`;
|
|
25
|
+
}
|
|
22
26
|
|
|
23
27
|
//#endregion
|
|
24
28
|
//#region src/client/agent-info-error.ts
|
|
@@ -290,6 +294,14 @@ function isCurrentTurnBoundaryEvent(event) {
|
|
|
290
294
|
return event.type === "session.completed" || event.type === "session.failed" || event.type === "session.waiting";
|
|
291
295
|
}
|
|
292
296
|
|
|
297
|
+
//#endregion
|
|
298
|
+
//#region src/protocol/cancel-turn.ts
|
|
299
|
+
const CancelTurnResponseSchema = z.object({
|
|
300
|
+
ok: z.literal(true),
|
|
301
|
+
sessionId: z.string().min(1),
|
|
302
|
+
status: z.enum(["accepted", "no_active_turn"])
|
|
303
|
+
});
|
|
304
|
+
|
|
293
305
|
//#endregion
|
|
294
306
|
//#region src/shared/json.ts
|
|
295
307
|
const INVALID_JSON_VALUE_CANDIDATE = Symbol("invalid-json-value-candidate");
|
|
@@ -442,7 +454,7 @@ function isStreamDisconnectError(error) {
|
|
|
442
454
|
if (error instanceof DOMException) return error.name === "AbortError";
|
|
443
455
|
if (!(error instanceof Error)) return false;
|
|
444
456
|
const errorCode = "code" in error && typeof error.code === "string" ? error.code : void 0;
|
|
445
|
-
return error.name === "AbortError" || error.message === "terminated" || errorCode === "UND_ERR_SOCKET" || /abort|cancel|disconnect|premature close|socket|terminated/i.test(error.message);
|
|
457
|
+
return error.name === "AbortError" || error.message === "terminated" || errorCode === "UND_ERR_SOCKET" || error instanceof TypeError && /^(?:failed to fetch|fetch failed)$/i.test(error.message) || /abort|cancel|disconnect|premature close|socket|terminated/i.test(error.message);
|
|
446
458
|
}
|
|
447
459
|
async function* readNdjsonStream(body) {
|
|
448
460
|
const reader = body.getReader();
|
|
@@ -548,11 +560,18 @@ async function openStreamBody(input) {
|
|
|
548
560
|
for (let attempt = 0; attempt < STREAM_OPEN_RETRY_ATTEMPTS; attempt += 1) {
|
|
549
561
|
const url = createClientUrl(input.host, createEveMessageStreamRoutePath(input.sessionId), input.startIndex !== 0 ? { startIndex: String(input.startIndex) } : void 0);
|
|
550
562
|
const headers = await input.resolveHeaders();
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
563
|
+
let response;
|
|
564
|
+
try {
|
|
565
|
+
response = await fetch(url, {
|
|
566
|
+
headers,
|
|
567
|
+
redirect: input.redirect,
|
|
568
|
+
signal: input.signal ?? null
|
|
569
|
+
});
|
|
570
|
+
} catch (error) {
|
|
571
|
+
if (input.signal?.aborted || !isStreamDisconnectError(error) || attempt === STREAM_OPEN_RETRY_ATTEMPTS - 1) throw error;
|
|
572
|
+
await sleep$1(STREAM_OPEN_RETRY_DELAY_MS);
|
|
573
|
+
continue;
|
|
574
|
+
}
|
|
556
575
|
if (response.ok) {
|
|
557
576
|
if (!response.body) throw new ClientError(response.status, "Response body is null.", response.headers);
|
|
558
577
|
return response.body;
|
|
@@ -587,12 +606,42 @@ var ClientSession = class {
|
|
|
587
606
|
const payload = normalizeSendTurnInput(input);
|
|
588
607
|
const state = this.#state;
|
|
589
608
|
const { continuationToken, sessionId } = await this.#postTurn(payload, state);
|
|
609
|
+
if (this.#state === state) this.#state = {
|
|
610
|
+
...state,
|
|
611
|
+
sessionId
|
|
612
|
+
};
|
|
590
613
|
return new MessageResponse({
|
|
591
614
|
continuationToken,
|
|
592
615
|
createStream: () => this.#createEventStream(sessionId, continuationToken, state, payload),
|
|
593
616
|
sessionId
|
|
594
617
|
});
|
|
595
618
|
}
|
|
619
|
+
async cancel(options) {
|
|
620
|
+
const sessionId = this.#state.sessionId;
|
|
621
|
+
if (!sessionId) throw new Error("Session has no session ID. Send a message first.");
|
|
622
|
+
const url = createClientUrl(this.#context.host, createEveCancelTurnRoutePath(sessionId));
|
|
623
|
+
const headers = await this.#context.resolveHeaders();
|
|
624
|
+
headers.set("content-type", "application/json");
|
|
625
|
+
const response = await fetch(url, withRedirectPolicy$1({
|
|
626
|
+
headers,
|
|
627
|
+
method: "POST",
|
|
628
|
+
body: options ? JSON.stringify(options) : void 0
|
|
629
|
+
}, this.#context.redirect));
|
|
630
|
+
const body = await response.text();
|
|
631
|
+
if (!response.ok) throw new ClientError(response.status, body, response.headers);
|
|
632
|
+
let payload;
|
|
633
|
+
try {
|
|
634
|
+
payload = JSON.parse(body);
|
|
635
|
+
} catch {
|
|
636
|
+
throw new Error(`Cancel route returned invalid JSON (${response.status}).`);
|
|
637
|
+
}
|
|
638
|
+
const result = CancelTurnResponseSchema.safeParse(payload);
|
|
639
|
+
if (!result.success || result.data.sessionId !== sessionId) throw new Error(`Cancel route returned an invalid response (${response.status}).`);
|
|
640
|
+
return {
|
|
641
|
+
sessionId: result.data.sessionId,
|
|
642
|
+
status: result.data.status
|
|
643
|
+
};
|
|
644
|
+
}
|
|
596
645
|
stream(options) {
|
|
597
646
|
const sessionId = this.#state.sessionId;
|
|
598
647
|
if (!sessionId) throw new Error("Session has no session ID. Send a message first.");
|
|
@@ -746,6 +795,12 @@ function createHandleMessageBody(input) {
|
|
|
746
795
|
if (input.session.continuationToken !== void 0 && body.message === void 0 && body.inputResponses === void 0) return null;
|
|
747
796
|
return body;
|
|
748
797
|
}
|
|
798
|
+
function withRedirectPolicy$1(init, redirect) {
|
|
799
|
+
return redirect === void 0 ? init : {
|
|
800
|
+
...init,
|
|
801
|
+
redirect
|
|
802
|
+
};
|
|
803
|
+
}
|
|
749
804
|
|
|
750
805
|
//#endregion
|
|
751
806
|
//#region src/client/types.ts
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Command } from "#compiled/commander/index.js";
|
|
2
|
+
import type { ApplicationBuildOptions } from "#internal/nitro/host/types.js";
|
|
3
|
+
export type BuildHost = (appRoot: string, options: ApplicationBuildOptions) => Promise<string>;
|
|
4
|
+
interface BuildCommandLogger {
|
|
5
|
+
log(message: string): void;
|
|
6
|
+
}
|
|
7
|
+
/** Registers the production application build command. */
|
|
8
|
+
export declare function registerBuildCommand(input: {
|
|
9
|
+
readonly appRoot: string;
|
|
10
|
+
readonly buildHost?: BuildHost;
|
|
11
|
+
readonly logger: BuildCommandLogger;
|
|
12
|
+
readonly program: Command;
|
|
13
|
+
}): void;
|
|
14
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{resolve}from"node:path";import{resolveInternalVercelServiceOutput}from"#cli/vercel-service-output.js";import{createCliTheme,renderCliTaggedLine}from"#cli/ui/output.js";function registerBuildCommand(t){let n=createCliTheme();t.program.command(`build`).description(`Build the current eve application.`).option(`--profile <path>`,`Write best-effort timing and output-size profile JSON to a file`).option(`--skip-sandbox-prewarm`,`Skip sandbox template prewarm for a Vercel build; output may not be deployable`).action(async e=>{let{loadDevelopmentEnvironmentFiles:r}=await import(`#cli/dev/environment.js`);r(t.appRoot);let i=t.buildHost??(await import(`#internal/nitro/host.js`)).buildApplication,a=e.profile===void 0?void 0:resolve(t.appRoot,e.profile),o={skipVercelSandboxPrewarm:e.skipSandboxPrewarm===!0,vercelServiceOutput:resolveInternalVercelServiceOutput(t.appRoot)};a!==void 0&&(o.profileOutputPath=a);let s=await i(t.appRoot,o);t.logger.log(renderCliTaggedLine(n,{message:`built output at ${s}`,tag:`build`,tone:`success`}))})}export{registerBuildCommand};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{assertCanAddSelectedChannels,inspectExistingChannelRegistrations}from"./channel-add-conflicts.js";import{NOT_AN_AGENT_MESSAGE}from"./preconditions.js";import{isEveProject,listAuthoredChannels}from"#setup/scaffold/index.js";import{interactiveAsker}from"#setup/ask.js";import{addChannels}from"#setup/boxes/add-channels.js";import{deployProject}from"#setup/boxes/deploy-project.js";import{selectChannels}from"#setup/boxes/select-channels.js";import{detectDeployment,projectResolutionFromDeployment}from"#setup/project-resolution.js";import{createPrompter}from"#setup/prompter.js";import{runInteractive}from"#setup/runner.js";import{createDefaultSetupState,snapshotSetupState}from"#setup/state.js";const KNOWN_CHANNEL_KINDS=[`slack`,`web`];function isChannelKind(e){return KNOWN_CHANNEL_KINDS.includes(e)}function parseChannelKind(e){if(!isChannelKind(e))throw Error(`Unknown channel kind "${e}". Known: ${KNOWN_CHANNEL_KINDS.join(`, `)}.`);return e}const defaultChannelsAddDependencies={detectDeployment};async function runAddChannelsFlow(n,r,i,s){if(r===void 0&&(i.yes||!process.stdin.isTTY||!process.stdout.isTTY))throw Error(`Pass a channel kind: \`eve channels add <${KNOWN_CHANNEL_KINDS.join(`|`)}>\`.`);let c=s.createPrompter?.()??createPrompter();c.intro(`Add channels to your eve agent`),c.log.message(`Checking the current Vercel project...`);let l={...createDefaultSetupState(),project:projectResolutionFromDeployment(await s.detectDeployment(n)),projectPath:{kind:`resolved`,inPlace:!0,path:n}},u;function inspectRegistrations(){return u===void 0&&(c.log.message(`Inspecting existing channel registrations...`),u=inspectExistingChannelRegistrations(n)),u}let d=r===void 0?(await inspectRegistrations()).disabledChannelReasons:void 0,f=await runInteractive([selectChannels({asker:interactiveAsker(c),variant:`channels-add`,presetChannels:r===void 0?void 0:[r],disabledChannelReasons:d,validateSelection:async t=>{!t.includes(`web`)&&!t.includes(`slack`)||assertCanAddSelectedChannels(t,await inspectRegistrations())}}),addChannels({asker:interactiveAsker(c),prompter:c,presetCreateSlackbot:i.yes?!0:void 0,force:i.force,configureVercelServices:!0,ensureLinkedProject:`interactive-vercel-link`,deps:s.addChannelsDeps}),deployProject({prompter:c,ensureLinkedProject:`interactive-vercel-link`,deps:s.deployProjectDeps})],l,{write:e=>c.log.message(e)},{snapshot:snapshotSetupState});f.kind!==`cancelled`&&c.outro(f.state.channels.length===0?`No channels added.`:`Channels added.`)}async function runChannelsAddCommand(e,t,i,a=defaultChannelsAddDependencies){if(!await isEveProject(t)){e.error(NOT_AN_AGENT_MESSAGE),process.exitCode=1;return}try{await runAddChannelsFlow(t,i.kind===void 0?void 0:parseChannelKind(i.kind),i.options,a)}catch(t){e.error(t instanceof Error?t.message:String(t)),process.exitCode=1}}async function runChannelsListCommand(e,t,a){if(!await isEveProject(t)){e.error(NOT_AN_AGENT_MESSAGE),process.exitCode=1;return}let o=await listAuthoredChannels(t);if(a.json){e.log(JSON.stringify({channels:o},null,2));return}if(o.length===0){e.log("No channels defined. Run `eve channels add` to add one.");return}for(let t of o)e.log(t)}export{runChannelsAddCommand,runChannelsListCommand};
|
|
1
|
+
import{assertCanAddSelectedChannels,inspectExistingChannelRegistrations}from"./channel-add-conflicts.js";import{NOT_AN_AGENT_MESSAGE}from"./preconditions.js";import{isEveProject,listAuthoredChannels}from"#setup/scaffold/index.js";import{interactiveAsker}from"#setup/ask.js";import{addChannels}from"#setup/boxes/add-channels.js";import{deployProject}from"#setup/boxes/deploy-project.js";import{reconcileHostFrameworkPreset}from"#setup/boxes/reconcile-host-framework-preset.js";import{selectChannels}from"#setup/boxes/select-channels.js";import{detectDeployment,projectResolutionFromDeployment}from"#setup/project-resolution.js";import{createPrompter}from"#setup/prompter.js";import{runInteractive}from"#setup/runner.js";import{createDefaultSetupState,snapshotSetupState}from"#setup/state.js";const KNOWN_CHANNEL_KINDS=[`slack`,`web`];function isChannelKind(e){return KNOWN_CHANNEL_KINDS.includes(e)}function parseChannelKind(e){if(!isChannelKind(e))throw Error(`Unknown channel kind "${e}". Known: ${KNOWN_CHANNEL_KINDS.join(`, `)}.`);return e}const defaultChannelsAddDependencies={detectDeployment};async function runAddChannelsFlow(n,r,i,s){if(r===void 0&&(i.yes||!process.stdin.isTTY||!process.stdout.isTTY))throw Error(`Pass a channel kind: \`eve channels add <${KNOWN_CHANNEL_KINDS.join(`|`)}>\`.`);let c=s.createPrompter?.()??createPrompter();c.intro(`Add channels to your eve agent`),c.log.message(`Checking the current Vercel project...`);let l={...createDefaultSetupState(),project:projectResolutionFromDeployment(await s.detectDeployment(n)),projectPath:{kind:`resolved`,inPlace:!0,path:n}},u;function inspectRegistrations(){return u===void 0&&(c.log.message(`Inspecting existing channel registrations...`),u=inspectExistingChannelRegistrations(n)),u}let d=r===void 0?(await inspectRegistrations()).disabledChannelReasons:void 0,f=await runInteractive([selectChannels({asker:interactiveAsker(c),variant:`channels-add`,presetChannels:r===void 0?void 0:[r],disabledChannelReasons:d,validateSelection:async t=>{!t.includes(`web`)&&!t.includes(`slack`)||assertCanAddSelectedChannels(t,await inspectRegistrations())}}),addChannels({asker:interactiveAsker(c),prompter:c,presetCreateSlackbot:i.yes?!0:void 0,force:i.force,configureVercelServices:!0,ensureLinkedProject:`interactive-vercel-link`,deps:s.addChannelsDeps}),reconcileHostFrameworkPreset({prompter:c}),deployProject({prompter:c,ensureLinkedProject:`interactive-vercel-link`,deps:s.deployProjectDeps})],l,{write:e=>c.log.message(e)},{snapshot:snapshotSetupState});f.kind!==`cancelled`&&c.outro(f.state.channels.length===0?`No channels added.`:`Channels added.`)}async function runChannelsAddCommand(e,t,i,a=defaultChannelsAddDependencies){if(!await isEveProject(t)){e.error(NOT_AN_AGENT_MESSAGE),process.exitCode=1;return}try{await runAddChannelsFlow(t,i.kind===void 0?void 0:parseChannelKind(i.kind),i.options,a)}catch(t){e.error(t instanceof Error?t.message:String(t)),process.exitCode=1}}async function runChannelsListCommand(e,t,a){if(!await isEveProject(t)){e.error(NOT_AN_AGENT_MESSAGE),process.exitCode=1;return}let o=await listAuthoredChannels(t);if(a.json){e.log(JSON.stringify({channels:o},null,2));return}if(o.length===0){e.log("No channels defined. Run `eve channels add` to add one.");return}for(let t of o)e.log(t)}export{runChannelsAddCommand,runChannelsListCommand};
|
|
@@ -12,10 +12,11 @@ export interface LinkCommandDependencies {
|
|
|
12
12
|
flowDeps?: Partial<LinkFlowDeps>;
|
|
13
13
|
}
|
|
14
14
|
/**
|
|
15
|
-
* `eve link`: pick a Vercel team
|
|
16
|
-
* linked), run `vercel link` for the
|
|
17
|
-
* credential lands in `.env.local`. The flow
|
|
18
|
-
*
|
|
19
|
-
*
|
|
15
|
+
* `eve link`: pick a Vercel team, then create or select a project (re-linking
|
|
16
|
+
* when one is already linked), run `vercel link` for the resolved project,
|
|
17
|
+
* then pull env so the AI Gateway credential lands in `.env.local`. The flow
|
|
18
|
+
* itself is {@link runLinkFlow}, shared with the dev TUI `/model` menu's
|
|
19
|
+
* provider row. Interactive only: the pickers are the point of the command, so
|
|
20
|
+
* a non-TTY run refuses with guidance instead of guessing a project.
|
|
20
21
|
*/
|
|
21
22
|
export declare function runLinkCommand(logger: LinkCliLogger, appRoot: string, dependencies?: LinkCommandDependencies): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{NOT_AN_AGENT_MESSAGE,hasInteractiveTerminal}from"./preconditions.js";import{isEveProject}from"#setup/scaffold/index.js";import{createPrompter}from"#setup/prompter.js";import{runLinkFlow}from"#setup/flows/link.js";const defaultDependencies={isEveProject,hasInteractiveTerminal};async function runLinkCommand(t,n,r=defaultDependencies){if(!await r.isEveProject(n)){t.error(NOT_AN_AGENT_MESSAGE),process.exitCode=1;return}if(!r.hasInteractiveTerminal()){t.error("`eve link` needs an interactive terminal to pick the team and project. In CI, run `vercel link --project <name> --yes --non-interactive` instead."),process.exitCode=1;return}let i=r.createPrompter?.()??createPrompter();i.intro(`Link your eve agent to Vercel`);try{let e=await runLinkFlow({appRoot:n,prompter:i,deps:r.flowDeps});i.outro(e.kind===`cancelled`?`Cancelled.`:`Project linked.`)}catch(e){t.error(e instanceof Error?e.message:String(e)),process.exitCode=1}}export{runLinkCommand};
|
|
1
|
+
import{NOT_AN_AGENT_MESSAGE,hasInteractiveTerminal}from"./preconditions.js";import{isEveProject}from"#setup/scaffold/index.js";import{createPrompter}from"#setup/prompter.js";import{runLinkFlow}from"#setup/flows/link.js";const defaultDependencies={isEveProject,hasInteractiveTerminal};async function runLinkCommand(t,n,r=defaultDependencies){if(!await r.isEveProject(n)){t.error(NOT_AN_AGENT_MESSAGE),process.exitCode=1;return}if(!r.hasInteractiveTerminal()){t.error("`eve link` needs an interactive terminal to pick the team and project. In CI, run `vercel link --project <name> --yes --non-interactive` instead."),process.exitCode=1;return}let i=r.createPrompter?.()??createPrompter();i.intro(`Link your eve agent to Vercel`);try{let e=await runLinkFlow({appRoot:n,prompter:i,projectSelection:`create-or-link`,deps:r.flowDeps});i.outro(e.kind===`cancelled`?`Cancelled.`:`Project linked.`)}catch(e){t.error(e instanceof Error?e.message:String(e)),process.exitCode=1}}export{runLinkCommand};
|
package/dist/src/cli/run.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import { type BuildHost } from "#cli/commands/build.js";
|
|
1
2
|
import { resolveDevUiMode, resolveTuiDisplayOptions } from "#cli/dev/ui-options.js";
|
|
2
3
|
import type { RunDevelopmentTuiInput } from "#cli/dev/tui/tui.js";
|
|
3
|
-
import type {
|
|
4
|
+
import type { DevelopmentServer, DevelopmentServerOptions, ProductionServerHandle } from "#internal/nitro/host/types.js";
|
|
4
5
|
export { resolveDevUiMode, resolveTuiDisplayOptions };
|
|
5
6
|
interface CliLogger {
|
|
6
7
|
error(message: string): void;
|
|
@@ -12,7 +13,7 @@ interface CliRuntimeDependencies {
|
|
|
12
13
|
readonly appRoot: string;
|
|
13
14
|
readonly serverUrl: string;
|
|
14
15
|
}): Promise<boolean>;
|
|
15
|
-
buildHost
|
|
16
|
+
buildHost: BuildHost;
|
|
16
17
|
printApplicationInfo(logger: CliLogger, appRoot: string, options?: {
|
|
17
18
|
json?: boolean;
|
|
18
19
|
}): Promise<void>;
|
package/dist/src/cli/run.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{createLogger}from"#internal/logging.js";import{resolveInstalledPackageInfo}from"#internal/application/package.js";import{createCliTheme,renderCliTaggedLine}from"#cli/ui/output.js";import{isCodingAgentLaunch}from"#cli/agent-detection.js";import{eveCliBanner}from"#cli/banner.js";import{startCliLiveRow}from"#cli/ui/live-row.js";import{devBootPhase}from"#internal/dev-boot-progress.js";import{Command,CommanderError,InvalidArgumentError}from"#compiled/commander/index.js";import{
|
|
1
|
+
import{createLogger}from"#internal/logging.js";import{resolveInstalledPackageInfo}from"#internal/application/package.js";import{createCliTheme,renderCliTaggedLine}from"#cli/ui/output.js";import{isCodingAgentLaunch}from"#cli/agent-detection.js";import{eveCliBanner}from"#cli/banner.js";import{startCliLiveRow}from"#cli/ui/live-row.js";import{devBootPhase}from"#internal/dev-boot-progress.js";import{Command,CommanderError,InvalidArgumentError}from"#compiled/commander/index.js";import{registerBuildCommand}from"#cli/commands/build.js";import{resolveApplicationRoot}from"#internal/application/paths.js";import{registerProjectCommands}from"#cli/commands/register-project-commands.js";import{resolveDevUiMode,resolveTuiDisplayOptions}from"#cli/dev/ui-options.js";import{parseDevelopmentHeaderOption,resolveDevelopmentUrlTarget}from"#cli/dev/url-target.js";import{LOG_DISPLAY_MODES,parseLogDisplayMode}from"#cli/dev/tui/log-display-mode.js";import{resolveTuiTitle}from"#cli/dev/tui/target.js";import{parseDevelopmentServerUrl}from"#cli/dev/url.js";const devBootLog=createLogger(`dev.boot`);function createDevBootProgressReporter(e){return t=>{switch(t.type){case`phase-started`:e?.update(`Building your agent`,t.phase),devBootLog.debug(t.phase);return;case`phase-finished`:devBootLog.debug(`${t.phase} finished`,{ms:t.elapsedMs});return;case`before-first-paint`:e?.stop();return;default:return t}}}async function loadPrintApplicationInfo(){return(await import(`#cli/commands/info.js`)).printApplicationInfo}async function loadRunDevelopmentTui(){return(await import(`#cli/dev/tui/tui.js`)).runDevelopmentTui}async function loadRunEvalCommand(){return(await import(`#evals/cli/eval.js`)).runEvalCommand}async function loadStartHost(){return(await import(`#internal/nitro/host.js`)).createDevelopmentServer}const loadIsActiveDevelopmentServerForApp=async()=>(await import(`#internal/nitro/host.js`)).isActiveDevelopmentServerForApp;async function loadStartProductionHost(){return(await import(`#internal/nitro/host.js`)).startProductionServer}function shouldPrintCliBootBanner(e){return e.name()===`info`||e.name()===`dev`||e.name()===`init`}async function waitForShutdownSignal(e){await new Promise((t,n)=>{let r=!1,cleanup=()=>{process.off(`SIGINT`,handleSignal),process.off(`SIGTERM`,handleSignal)},handleSignal=()=>{r||(r=!0,cleanup(),e.close().then(t,n))};process.once(`SIGINT`,handleSignal),process.once(`SIGTERM`,handleSignal)})}async function waitForProductionServer(e){await Promise.race([e.wait(),waitForShutdownSignal({close:()=>e.close()})])}function parsePortOption(e){if(!/^-?\d+$/.test(e))throw new InvalidArgumentError(`Expected a numeric port, received "${e}".`);let t=Number(e);if(t<0||t>65535)throw new InvalidArgumentError(`Expected a port between 0 and 65535, received "${e}".`);return t}const DISPLAY_MODES=new Set([`full`,`collapsed`,`auto-collapsed`,`hidden`]),STATS_MODES=new Set([`tokens`,`tokensPerSecond`]);function parseDisplayMode(e){if(!DISPLAY_MODES.has(e))throw new InvalidArgumentError(`Expected one of ${[...DISPLAY_MODES].join(`, `)}, received "${e}".`);return e}function parseStatsMode(e){if(!STATS_MODES.has(e))throw new InvalidArgumentError(`Expected one of ${[...STATS_MODES].join(`, `)}, received "${e}".`);return e}function parseLogsMode(e){let t=parseLogDisplayMode(e);if(t===void 0)throw new InvalidArgumentError(`Expected one of ${LOG_DISPLAY_MODES.join(`, `)}, received "${e}".`);return t}function parseContextSizeOption(e){let t=Number(e);if(!Number.isFinite(t)||t<=0)throw new InvalidArgumentError(`Expected a positive number, received "${e}".`);return t}function hasInteractiveTerminal(){return!!(process.stdin.isTTY&&process.stdout.isTTY)}function createCliProgram(e,i){let c=resolveApplicationRoot(),m=resolveInstalledPackageInfo().version,h=new Command,_=createCliTheme();h.name(`eve`).description(`Build and run an eve application.`).version(m).showHelpAfterError().exitOverride().hook(`preAction`,(t,n)=>{shouldPrintCliBootBanner(n)&&e.log(eveCliBanner())}).configureOutput({writeErr:t=>{e.error(t.trimEnd())},writeOut:t=>{e.log(t.trimEnd())}});let v=h.command(`channels`).description(`Manage user-authored channels in the current project.`);v.command(`add [kind]`).description(`Add channels interactively, or scaffold a channel kind (slack | web).`).option(`-f, --force`,`Overwrite existing channel files`).option(`-y, --yes`,`Assume yes for confirmations; requires an explicit channel kind`).action(async(t,n)=>{let{runChannelsAddCommand:r}=await import(`#cli/commands/channels.js`);await r(e,c,{kind:t,options:n})}),v.command(`list`).description(`List user-authored channels in the current project.`).option(`--json`,`Output as JSON`).action(async t=>{let{runChannelsListCommand:n}=await import(`#cli/commands/channels.js`);await n(e,c,t)});let y=h.command(`extension`).description(`Create and build reusable eve extension packages.`);return y.command(`init [target]`).description(`Create a new eve extension package.`).option(`-y, --yes`,`Accepted for compatibility; has no effect`).action(async(t,n)=>{n.yes&&e.error(`warning: --yes has no effect for eve extension init.`);let{runExtensionInitCommand:r}=await import(`#cli/commands/extension-init.js`);await r(e,c,t)}),y.command(`build`).description(`Build the current package as an eve extension.`).action(async()=>{let{loadDevelopmentEnvironmentFiles:t}=await import(`#cli/dev/environment.js`);t(c);let{runExtensionBuildCommand:n}=await import(`#cli/commands/extension-build.js`);await n(e,c)}),h.command(`init [target]`).description(`Create a new eve agent, or add one to an existing project directory.`).option(`--channel-web-nextjs`,`Add the Web Chat application (Next.js)`).option(`-y, --yes`,`Accepted for compatibility; has no effect`).action(async(t,n)=>{n.yes&&e.error(`warning: --yes has no effect for eve init.`);let{runInitCommand:r}=await import(`#cli/commands/init.js`);await r(e,c,t,{channelWebNextjs:n.channelWebNextjs})}),registerProjectCommands({program:h,logger:e,appRoot:c}),registerBuildCommand({appRoot:c,buildHost:i.buildHost,logger:e,program:h}),h.command(`start`).description(`Start a built eve application.`).option(`--host <host>`,`Host interface to bind`).option(`--port <port>`,`Port to listen on (defaults to $PORT, then 3000)`,parsePortOption).action(async t=>{let{loadDevelopmentEnvironmentFiles:n}=await import(`#cli/dev/environment.js`);n(c);let a=await(i.startProductionHost??await loadStartProductionHost())(c,{host:t.host,port:t.port});e.log(renderCliTaggedLine(_,{message:`server listening at ${a.url}`,tag:`start`,tone:`success`})),await waitForProductionServer(a)}),h.command(`dev`).description(`Start the eve development server or connect to an existing URL.`).argument(`[url]`,`Connect to an existing server URL`,parseDevelopmentServerUrl).option(`--host <host>`,`Host interface to bind`).option(`--port <port>`,`Port to listen on (defaults to $PORT, then 2000)`,parsePortOption).option(`-u, --url <url>`,`Connect to an existing server URL`,parseDevelopmentServerUrl).option(`-H, --header <header>`,`Request header for a URL target, in "Name: value" form (repeatable)`,parseDevelopmentHeaderOption).option(`--no-ui`,`Start the server without an interactive UI`).option(`--name <name>`,`Title shown in the terminal UI (defaults to the app folder name)`).option(`--input <text>`,`Pre-fill the prompt input, or start onboarding with /model`).option(`--tools <mode>`,`How tool calls render: full | collapsed | auto-collapsed | hidden`,parseDisplayMode).option(`--reasoning <mode>`,`How reasoning renders: full | collapsed | auto-collapsed | hidden`,parseDisplayMode).option(`--subagents <mode>`,`How subagent sections render: full | collapsed | auto-collapsed | hidden`,parseDisplayMode).option(`--connection-auth <mode>`,`How connection authorization renders: full | collapsed | auto-collapsed | hidden`,parseDisplayMode).option(`--assistant-response-stats <mode>`,`Assistant header statistic: tokens | tokensPerSecond`,parseStatsMode).option(`--context-size <tokens>`,`Model context window size, shown as a usage percentage`,parseContextSizeOption).option(`--logs <mode>`,`Which server/agent logs to show: all | stderr | sandbox | none`,parseLogsMode).addHelpText(`after`,`
|
|
2
2
|
You can also pass a bare URL, for example: eve dev https://example.com
|
|
3
3
|
`).action(async(t,n)=>{let a=resolveDevelopmentUrlTarget(n,t),s=a?.serverUrl,u=hasInteractiveTerminal(),d=resolveDevUiMode({options:n,interactive:u});if(n.input!==void 0&&d===`headless`)throw new InvalidArgumentError(`--input requires the interactive UI.`);let f=!1;s!==void 0&&(f=await(i.isActiveDevelopmentServerForApp??await loadIsActiveDevelopmentServerForApp())({appRoot:c,serverUrl:s}));let runInteractiveUi=async(e,t)=>{let r=await devBootPhase(`loading interactive UI`,async()=>i.runDevelopmentTui??await loadRunDevelopmentTui(),t),o=resolveTuiDisplayOptions(n),l=s===void 0||f?{kind:`local`,serverUrl:e.serverUrl,workspaceRoot:e.appRoot??c}:{kind:`remote`,serverUrl:e.serverUrl,workspaceRoot:c},u=resolveTuiTitle({name:n.name,target:l});u!==void 0&&(o.name=u);let d={target:l,initialInput:n.input,onBootProgress:t,...o};a?.headers===void 0?await r(d):await r({...d,headers:a.headers})};if(s){let{loadDevelopmentEnvironmentFiles:t}=await import(`#cli/dev/environment.js`);if(t(c),e.log(`↗ ${f?`local`:`remote`} mode targeting ${_.info(new URL(s).host)}`),d===`headless`){e.log(renderCliTaggedLine(_,{message:`Interactive UI disabled because the current terminal is not a TTY.`,tag:`dev`,tone:`warning`}));return}e.log(``),await runInteractiveUi({serverUrl:s});return}d===`tui`&&e.log(``);let p=d===`tui`?startCliLiveRow(e):void 0,m=createDevBootProgressReporter(p);p?.update(`Building your agent`);let h=!1,g,closeServer=async()=>{h||g===void 0||(h=!0,await g.close())};try{g=(i.startHost??await loadStartHost())(c,{existing:d===`tui`?`attach-if-unconfigured`:`reject`,host:n.host,onBootProgress:m,port:n.port});let t=await g.start();if(d!==`tui`&&e.log(renderCliTaggedLine(_,{message:`server listening at ${t.url}`,tag:`dev`,tone:`success`})),d===`headless`)return n.ui!==!1&&!u&&e.log(renderCliTaggedLine(_,{message:`Interactive UI disabled because the current terminal is not a TTY.`,tag:`dev`,tone:`warning`})),await waitForShutdownSignal({close:closeServer});await runInteractiveUi({appRoot:t.appRoot,serverUrl:t.url},m)}finally{p?.stop(),await closeServer()}}),h.command(`info`).description(`Print resolved application information.`).option(`--json`,`Output as JSON`).action(async t=>{await(i.printApplicationInfo??await loadPrintApplicationInfo())(e,c,t)}),h.command(`eval`).description(`Run evals against an eve agent.`).argument(`[evalIds...]`,`Eval ids (or directory prefixes) to run (all discovered evals when omitted)`).option(`--url <url>`,`Remote agent URL (skip local host startup)`,parseDevelopmentServerUrl).option(`--tag <tag...>`,`Run only evals carrying a tag`).option(`--strict`,`Fail the exit code when any score falls below its threshold`).option(`--list`,`Print discovered evals without running them`).option(`--timeout <ms>`,`Per-eval timeout in milliseconds`).option(`--max-concurrency <n>`,`Max concurrent eval executions`).option(`--json`,`Output results as JSON`).option(`--junit <path>`,`Write JUnit XML results to a file`).option(`--skip-report`,`Skip eval-defined reporters (e.g. Braintrust)`).option(`--verbose`,`Stream per-eval t.log lines to stdout`).action(async(t,n)=>{await(i.runEvalCommand??await loadRunEvalCommand())(t,n,e)}),h}async function runCli(e=process.argv.slice(2),t=console,n={}){let r=createCliProgram(t,n),a=e.length===0?[`dev`]:e;try{await r.parseAsync(a,{from:`user`})}catch(e){if(e instanceof CommanderError){if(e.exitCode===0)return;let r=await(n.isCodingAgentLaunch??isCodingAgentLaunch)();if(a[0]===`init`&&r){let{initAgentInstructions:e}=await import(`#cli/commands/agent-instructions.js`);t.log(e())}throw Error(e.message)}throw e}}export{resolveDevUiMode,resolveTuiDisplayOptions,runCli};
|
|
@@ -7,7 +7,7 @@ export { createDataUrlFilePart, createTextWithFileContent } from "#client/file-p
|
|
|
7
7
|
export { MessageResponse } from "#client/message-response.js";
|
|
8
8
|
export { ClientSession } from "#client/session.js";
|
|
9
9
|
export type { EveAgentStoreCallbacks, EveAgentStoreInit, EveAgentStoreSnapshot, EveAgentStoreStatus, PrepareSend, } from "#client/eve-agent-store.js";
|
|
10
|
-
export type { AgentInfoEntry, AgentInfoChannelEntry, AgentInfoChannels, AgentInfoConnectionEntry, AgentInfoDynamicResolverEntry, AgentInfoFrameworkChannelEntry, AgentInfoFrameworkToolEntry, AgentInfoHookEntry, AgentInfoInstructions, AgentInfoInstructionsEntry, AgentInfoResult, AgentInfoSandboxEntry, AgentInfoScheduleEntry, AgentInfoSkillEntry, AgentInfoSource, AgentInfoSubagentEntry, AgentInfoToolEntry, AgentInfoTools, ClientAuth, ClientOptions, ClientRedirectPolicy, HeadersValue, HealthResult, MessageResult, SendTurnInput, SendTurnPayload, SessionState, StreamOptions, TokenValue, } from "#client/types.js";
|
|
10
|
+
export type { AgentInfoEntry, AgentInfoChannelEntry, AgentInfoChannels, AgentInfoConnectionEntry, AgentInfoDynamicResolverEntry, AgentInfoFrameworkChannelEntry, AgentInfoFrameworkToolEntry, AgentInfoHookEntry, AgentInfoInstructions, AgentInfoInstructionsEntry, AgentInfoResult, AgentInfoSandboxEntry, AgentInfoScheduleEntry, AgentInfoSkillEntry, AgentInfoSource, AgentInfoSubagentEntry, AgentInfoToolEntry, AgentInfoTools, CancelSessionResult, ClientAuth, ClientOptions, ClientRedirectPolicy, HeadersValue, HealthResult, MessageResult, SendTurnInput, SendTurnPayload, SessionState, StreamOptions, TokenValue, } from "#client/types.js";
|
|
11
11
|
export type { EveAgentReducer, EveAgentReducerEvent, ClientInputRespondedEvent, ClientMessageFailedEvent, ClientMessageSubmittedEvent, } from "#client/reducer.js";
|
|
12
12
|
export type { EveAuthorizationChallenge, EveAuthorizationOutcome, EveAuthorizationPart, EveMessageData, EveDynamicToolPart, EveMessageInputRequest, EveMessage, EveMessageMetadata, EveMessagePart, EveMessageToolMetadata, } from "#client/message-reducer.js";
|
|
13
13
|
export type { ActionResultStreamEvent, ActionsRequestedStreamEvent, AssistantStepFinishReason, AuthorizationOutcome, CompactionCompletedStreamEvent, CompactionRequestedStreamEvent, AuthorizationCompletedStreamEvent, ConnectionAuthorizationOutcome, AuthorizationRequiredStreamEvent, HandleMessageStreamEvent, InputRequestedStreamEvent, MessageAppendedStreamEvent, MessageCompletedStreamEvent, MessageReceivedPart, MessageReceivedStreamEvent, ReasoningAppendedStreamEvent, ReasoningCompletedStreamEvent, ResultCompletedStreamEvent, SessionCompletedStreamEvent, SessionFailedStreamEvent, SessionStartedStreamEvent, SessionWaitingStreamEvent, StepCompletedStreamEvent, StepFailedStreamEvent, StepStartedStreamEvent, SubagentCalledStreamEvent, SubagentChildEventStreamEvent, SubagentCompletedStreamEvent, SubagentStartedStreamEvent, TurnCancelledStreamEvent, TurnCompletedStreamEvent, TurnFailedStreamEvent, TurnStartedStreamEvent, TurnFailureStreamEvent, } from "#protocol/message.js";
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
function isStreamDisconnectError(e){if(e instanceof DOMException)return e.name===`AbortError`;if(!(e instanceof Error))return!1;let t=`code`in e&&typeof e.code==`string`?e.code:void 0;return e.name===`AbortError`||e.message===`terminated`||t===`UND_ERR_SOCKET
|
|
1
|
+
function isStreamDisconnectError(e){if(e instanceof DOMException)return e.name===`AbortError`;if(!(e instanceof Error))return!1;let t=`code`in e&&typeof e.code==`string`?e.code:void 0;return e.name===`AbortError`||e.message===`terminated`||t===`UND_ERR_SOCKET`||e instanceof TypeError&&/^(?:failed to fetch|fetch failed)$/i.test(e.message)||/abort|cancel|disconnect|premature close|socket|terminated/i.test(e.message)}async function*readNdjsonStream(e){let t=e.getReader(),n=new TextDecoder,r=``,i=!1;try{for(;;){let e=await t.read();if(e.done){i=!0,r+=n.decode();break}e.value&&(r+=n.decode(e.value,{stream:!0}));let a=r.indexOf(`
|
|
2
2
|
`);for(;a!==-1;){let e=r.slice(0,a).trim();r=r.slice(a+1),e.length>0&&(yield JSON.parse(e)),a=r.indexOf(`
|
|
3
3
|
`)}}let e=r.trim();e.length>0&&(yield JSON.parse(e))}finally{i||await t.cancel().catch(()=>{}),t.releaseLock()}}export{isStreamDisconnectError,readNdjsonStream};
|
|
@@ -19,8 +19,9 @@ type OpenStreamBodyInput = Omit<OpenStreamInput, "maxReconnectAttempts">;
|
|
|
19
19
|
*/
|
|
20
20
|
export declare function openStreamIterable(input: OpenStreamInput): AsyncGenerator<HandleMessageStreamEvent>;
|
|
21
21
|
/**
|
|
22
|
-
* Opens one stream response body, retrying
|
|
23
|
-
* a just-acknowledged session may not yet be
|
|
22
|
+
* Opens one stream response body, retrying transient network errors and the
|
|
23
|
+
* short propagation window where a just-acknowledged session may not yet be
|
|
24
|
+
* readable from the stream route.
|
|
24
25
|
*/
|
|
25
26
|
export declare function openStreamBody(input: OpenStreamBodyInput): Promise<ReadableStream<Uint8Array>>;
|
|
26
27
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createEveMessageStreamRoutePath}from"#protocol/routes.js";import{ClientError}from"#client/client-error.js";import{createClientUrl}from"#client/url.js";import{isStreamDisconnectError,readNdjsonStream}from"#client/ndjson.js";const STREAM_OPEN_RETRYABLE_STATUS=new Set([404,409,425,500,502,503,504]);async function*openStreamIterable(e){let t=e.startIndex,n=e.startIndex<0?0:e.maxReconnectAttempts;for(;;){let
|
|
1
|
+
import{createEveMessageStreamRoutePath}from"#protocol/routes.js";import{ClientError}from"#client/client-error.js";import{createClientUrl}from"#client/url.js";import{isStreamDisconnectError,readNdjsonStream}from"#client/ndjson.js";const STREAM_OPEN_RETRYABLE_STATUS=new Set([404,409,425,500,502,503,504]);async function*openStreamIterable(e){let t=e.startIndex,n=e.startIndex<0?0:e.maxReconnectAttempts;for(;;){let i=await openStreamBody({...e,startIndex:t}),a=!1;try{for await(let e of readNdjsonStream(i))t+=1,yield e}catch(e){if(!isStreamDisconnectError(e))throw e;a=!0}if(!a||e.signal?.aborted||n<=0)return;--n}}async function openStreamBody(r){let a,o,s;for(let c=0;c<12;c+=1){let l=createClientUrl(r.host,createEveMessageStreamRoutePath(r.sessionId),r.startIndex===0?void 0:{startIndex:String(r.startIndex)}),u=await r.resolveHeaders(),d;try{d=await fetch(l,{headers:u,redirect:r.redirect,signal:r.signal??null})}catch(e){if(r.signal?.aborted||!isStreamDisconnectError(e)||c===11)throw e;await sleep(250);continue}if(d.ok){if(!d.body)throw new ClientError(d.status,`Response body is null.`,d.headers);return d.body}if(a=d.status,o=await d.text(),s=d.headers,!STREAM_OPEN_RETRYABLE_STATUS.has(d.status))throw new ClientError(d.status,o,d.headers);c<11&&await sleep(250)}throw new ClientError(a??0,o??`Failed to open message stream.`,s)}async function sleep(e){await new Promise(t=>setTimeout(t,e))}export{openStreamBody,openStreamIterable};
|