eve 0.27.6 → 0.27.7
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 +8 -0
- package/dist/src/channel/session.d.ts +5 -0
- package/dist/src/channel/session.js +1 -1
- package/dist/src/channel/types.d.ts +7 -0
- package/dist/src/chunks/{use-eve-agent-COlXhAaF.js → use-eve-agent-JPfBHZJr.js} +36 -6
- package/dist/src/chunks/{use-eve-agent-DzVlKcUV.js → use-eve-agent-r5tkzjmt.js} +36 -6
- package/dist/src/client/open-stream.d.ts +17 -2
- package/dist/src/client/open-stream.js +1 -1
- package/dist/src/client/session.d.ts +5 -1
- package/dist/src/client/session.js +1 -1
- package/dist/src/client/types.d.ts +7 -0
- package/dist/src/execution/workflow-runtime.js +1 -1
- package/dist/src/harness/emission.js +1 -1
- package/dist/src/harness/input-requests.js +1 -1
- package/dist/src/harness/runtime-actions.d.ts +4 -0
- package/dist/src/harness/runtime-actions.js +1 -1
- package/dist/src/harness/tool-call-input-errors.d.ts +20 -0
- package/dist/src/harness/tool-call-input-errors.js +1 -1
- package/dist/src/internal/application/build-workspace.d.ts +0 -1
- package/dist/src/internal/application/build-workspace.js +1 -1
- package/dist/src/internal/application/package.js +1 -1
- package/dist/src/internal/application/paths.d.ts +1 -6
- package/dist/src/internal/application/paths.js +1 -1
- package/dist/src/internal/nitro/host/build-application.js +1 -1
- package/dist/src/internal/nitro/host/configure-nitro-routes.d.ts +4 -4
- package/dist/src/internal/nitro/host/configure-nitro-routes.js +2 -2
- package/dist/src/internal/nitro/host/create-application-nitro.d.ts +11 -7
- package/dist/src/internal/nitro/host/create-application-nitro.js +1 -1
- package/dist/src/internal/nitro/host/types.d.ts +0 -4
- package/dist/src/internal/nitro/host/vercel-build-output-config.d.ts +29 -1
- package/dist/src/internal/nitro/host/vercel-build-output-config.js +1 -1
- package/dist/src/internal/workflow/queue-namespace.d.ts +8 -0
- package/dist/src/internal/workflow/queue-namespace.js +1 -1
- package/dist/src/internal/workflow-bundle/builder-support.d.ts +0 -5
- package/dist/src/internal/workflow-bundle/builder.d.ts +0 -5
- package/dist/src/internal/workflow-bundle/builder.js +2 -2
- package/dist/src/internal/workflow-bundle/vercel-workflow-output.d.ts +0 -51
- package/dist/src/internal/workflow-bundle/vercel-workflow-output.js +1 -3
- package/dist/src/internal/workflow-bundle/workflow-builders.d.ts +0 -7
- package/dist/src/internal/workflow-bundle/workflow-builders.js +1 -1
- package/dist/src/packages/eve-catalog/src/index.js +1 -1
- package/dist/src/protocol/message.d.ts +1 -0
- package/dist/src/protocol/message.js +2 -2
- package/dist/src/public/channels/eve.js +2 -2
- package/dist/src/setup/scaffold/create/project.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/README.md +21 -20
- package/docs/channels/custom.mdx +1 -1
- package/docs/channels/overview.mdx +2 -0
- package/docs/channels/slack.mdx +0 -1
- package/docs/concepts/{execution-model-and-durability.md → execution-model-and-durability.mdx} +16 -0
- package/docs/concepts/security-model.md +2 -0
- package/docs/concepts/sessions-runs-and-streaming.md +9 -0
- package/docs/getting-started.mdx +13 -196
- package/docs/guides/client/streaming.mdx +15 -0
- package/docs/installation.mdx +60 -0
- package/docs/meta.json +7 -6
- package/docs/project-structure.mdx +53 -0
- package/docs/tutorial/meta.json +1 -1
- package/package.json +1 -1
- package/docs/introduction.mdx +0 -103
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# eve
|
|
2
2
|
|
|
3
|
+
## 0.27.7
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 3c53306: Vercel builds now run a single Nitro build. The workflow flow function is emitted through Nitro's per-route `functionRules` (queue trigger, `maxDuration: "max"`, precondition guard) instead of a second standalone Nitro build that was copied and retargeted into the output, making `eve build` on Vercel roughly twice as fast.
|
|
8
|
+
- e368fcd: The client's `session.stream()` accepts `follow: false` for bounded catch-up reads (`follow` defaults to `true`, following the live stream): it consumes events from the cursor to the durable tail observed when the stream opens — surviving reconnects and still advancing the stored `streamIndex` — then returns instead of following the live stream. The HTTP stream route reports the durable tail as the `x-eve-stream-tail-index` response header when a request opts in with `includeTailIndex=1`, and channel-authoring `Session` objects gain `getStreamTailIndex()` for serving bounded reads from custom routes.
|
|
9
|
+
- 7e4f7ef: Tool calls whose arguments arrive as a raw JSON string (e.g. provider-executed server tools) are now parsed, and arguments that cannot be parsed at all — such as malformed JSON emitted by the model — surface as a failed tool result the model can react to instead of failing the whole turn.
|
|
10
|
+
|
|
3
11
|
## 0.27.6
|
|
4
12
|
|
|
5
13
|
### Patch Changes
|
|
@@ -30,6 +30,11 @@ export interface Session {
|
|
|
30
30
|
getEventStream(options?: {
|
|
31
31
|
startIndex?: number;
|
|
32
32
|
}): Promise<ReadableStream<HandleMessageStreamEvent>>;
|
|
33
|
+
/**
|
|
34
|
+
* Resolves the durable tail of the event stream: the zero-based index of
|
|
35
|
+
* the last recorded event, or `-1` before the first.
|
|
36
|
+
*/
|
|
37
|
+
getStreamTailIndex(): Promise<number>;
|
|
33
38
|
}
|
|
34
39
|
/**
|
|
35
40
|
* Live handle to the current session, exposed on `ctx.session` to
|
|
@@ -1 +1 @@
|
|
|
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
|
+
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)},async getStreamTailIndex(){return n.getStreamTailIndex(e)}}}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};
|
|
@@ -368,6 +368,13 @@ export interface Runtime {
|
|
|
368
368
|
* parameter unchanged.
|
|
369
369
|
*/
|
|
370
370
|
getEventStream(sessionId: string, options?: GetEventStreamOptions): Promise<ReadableStream<HandleMessageStreamEvent>>;
|
|
371
|
+
/**
|
|
372
|
+
* Resolves the durable tail of a session's event stream: the zero-based
|
|
373
|
+
* index of the last recorded event, or `-1` before the first. Callers use
|
|
374
|
+
* it to bound a read at the tail they observed instead of following the
|
|
375
|
+
* live stream.
|
|
376
|
+
*/
|
|
377
|
+
getStreamTailIndex(sessionId: string): Promise<number>;
|
|
371
378
|
}
|
|
372
379
|
/**
|
|
373
380
|
* Options accepted by {@link Runtime.getEventStream}.
|
|
@@ -299,6 +299,7 @@ function safeJsonStringify(value) {
|
|
|
299
299
|
//#endregion
|
|
300
300
|
//#region src/protocol/message.ts
|
|
301
301
|
const EVE_SESSION_ID_HEADER = "x-eve-session-id";
|
|
302
|
+
const EVE_STREAM_TAIL_INDEX_HEADER = "x-eve-stream-tail-index";
|
|
302
303
|
const textEncoder = new TextEncoder();
|
|
303
304
|
function isCurrentTurnBoundaryEvent(event) {
|
|
304
305
|
return event.type === "session.completed" || event.type === "session.failed" || event.type === "session.waiting";
|
|
@@ -531,32 +532,47 @@ function resolveStreamReconnectPolicy(policy) {
|
|
|
531
532
|
};
|
|
532
533
|
}
|
|
533
534
|
async function* followStreamIterable(input) {
|
|
535
|
+
if (input.follow === false && input.startIndex < 0) throw new Error("stream({ follow: false }) requires a nonnegative startIndex; a tail-relative cursor cannot be bounded.");
|
|
534
536
|
const retryPolicy = resolveStreamReconnectPolicy(input.streamReconnectPolicy);
|
|
535
537
|
const idleRetryPolicy = retryPolicy.streamIdleReconnectPolicy;
|
|
536
538
|
let startIndex = input.startIndex;
|
|
537
539
|
let reconnectDelayMs = idleRetryPolicy.baseDelayMs;
|
|
538
540
|
let idleReconnects = 0;
|
|
539
541
|
let initialConnection = true;
|
|
542
|
+
let tailIndex;
|
|
540
543
|
while (true) {
|
|
541
|
-
let
|
|
544
|
+
let connection;
|
|
542
545
|
try {
|
|
543
|
-
|
|
546
|
+
connection = await openStreamBody({
|
|
544
547
|
...input,
|
|
545
548
|
retryPolicy,
|
|
546
|
-
startIndex
|
|
549
|
+
startIndex,
|
|
550
|
+
requestTailIndex: input.follow === false && tailIndex === void 0
|
|
547
551
|
});
|
|
548
552
|
} catch (error) {
|
|
549
553
|
if (input.signal?.aborted) return;
|
|
550
554
|
throw error;
|
|
551
555
|
}
|
|
556
|
+
if (input.follow === false && tailIndex === void 0) {
|
|
557
|
+
tailIndex = connection.tailIndex;
|
|
558
|
+
if (tailIndex === void 0) {
|
|
559
|
+
await connection.body.cancel().catch(() => {});
|
|
560
|
+
throw new Error(`stream({ follow: false }) requires the server to report the ${EVE_STREAM_TAIL_INDEX_HEADER} header. The agent may be running an older eve version.`);
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
if (tailIndex !== void 0 && startIndex > tailIndex) {
|
|
564
|
+
await connection.body.cancel().catch(() => {});
|
|
565
|
+
return;
|
|
566
|
+
}
|
|
552
567
|
let deliveredEvent = false;
|
|
553
568
|
try {
|
|
554
|
-
for await (const event of readNdjsonStream(body)) {
|
|
569
|
+
for await (const event of readNdjsonStream(connection.body)) {
|
|
555
570
|
startIndex += 1;
|
|
556
571
|
deliveredEvent = true;
|
|
557
572
|
reconnectDelayMs = idleRetryPolicy.baseDelayMs;
|
|
558
573
|
idleReconnects = 0;
|
|
559
574
|
yield event;
|
|
575
|
+
if (tailIndex !== void 0 && startIndex > tailIndex) return;
|
|
560
576
|
}
|
|
561
577
|
} catch (error) {
|
|
562
578
|
if (!isStreamDisconnectError(error)) throw error;
|
|
@@ -576,8 +592,11 @@ async function openStreamBody(input) {
|
|
|
576
592
|
let lastBody;
|
|
577
593
|
let lastHeaders;
|
|
578
594
|
let retryDelayMs = openRetryPolicy.baseDelayMs;
|
|
595
|
+
const searchParams = {};
|
|
596
|
+
if (input.startIndex !== 0) searchParams.startIndex = String(input.startIndex);
|
|
597
|
+
if (input.requestTailIndex === true) searchParams.includeTailIndex = "1";
|
|
579
598
|
for (let attempt = 0; attempt < openRetryPolicy.maxAttempts; attempt += 1) {
|
|
580
|
-
const url = createClientUrl(input.host, createEveMessageStreamRoutePath(input.sessionId),
|
|
599
|
+
const url = createClientUrl(input.host, createEveMessageStreamRoutePath(input.sessionId), Object.keys(searchParams).length > 0 ? searchParams : void 0);
|
|
581
600
|
const headers = await input.resolveHeaders();
|
|
582
601
|
let response;
|
|
583
602
|
try {
|
|
@@ -594,7 +613,10 @@ async function openStreamBody(input) {
|
|
|
594
613
|
}
|
|
595
614
|
if (response.ok) {
|
|
596
615
|
if (!response.body) throw new ClientError(response.status, "Response body is null.", response.headers);
|
|
597
|
-
return
|
|
616
|
+
return {
|
|
617
|
+
body: response.body,
|
|
618
|
+
tailIndex: parseTailIndexHeader(response.headers)
|
|
619
|
+
};
|
|
598
620
|
}
|
|
599
621
|
lastStatus = response.status;
|
|
600
622
|
lastBody = await response.text();
|
|
@@ -607,6 +629,12 @@ async function openStreamBody(input) {
|
|
|
607
629
|
}
|
|
608
630
|
throw new ClientError(lastStatus ?? 0, lastBody ?? "Failed to open message stream.", lastHeaders);
|
|
609
631
|
}
|
|
632
|
+
function parseTailIndexHeader(headers) {
|
|
633
|
+
const raw = headers.get(EVE_STREAM_TAIL_INDEX_HEADER);
|
|
634
|
+
if (raw === null || !/^-?\d+$/.test(raw)) return;
|
|
635
|
+
const parsed = Number(raw);
|
|
636
|
+
return Number.isSafeInteger(parsed) ? parsed : void 0;
|
|
637
|
+
}
|
|
610
638
|
async function sleep$1(ms, signal) {
|
|
611
639
|
if (signal?.aborted) return;
|
|
612
640
|
await new Promise((resolve) => {
|
|
@@ -784,6 +812,7 @@ var ClientSession = class {
|
|
|
784
812
|
stream(options) {
|
|
785
813
|
const sessionId = this.#state.sessionId;
|
|
786
814
|
if (!sessionId) throw new Error("Session has no session ID. Send a message first.");
|
|
815
|
+
if (options?.follow === false && (options.startIndex ?? this.#state.streamIndex) < 0) throw new Error("stream({ follow: false }) requires a nonnegative startIndex; a tail-relative cursor cannot be bounded.");
|
|
787
816
|
return this.#streamAndAdvance(sessionId, options);
|
|
788
817
|
}
|
|
789
818
|
async #postTurn(input, session) {
|
|
@@ -845,6 +874,7 @@ var ClientSession = class {
|
|
|
845
874
|
const events = [];
|
|
846
875
|
try {
|
|
847
876
|
for await (const event of followStreamIterable({
|
|
877
|
+
follow: options?.follow,
|
|
848
878
|
host: this.#context.host,
|
|
849
879
|
resolveHeaders: () => this.#context.resolveHeaders(),
|
|
850
880
|
redirect: this.#context.redirect,
|
|
@@ -299,6 +299,7 @@ function safeJsonStringify(value) {
|
|
|
299
299
|
//#endregion
|
|
300
300
|
//#region src/protocol/message.ts
|
|
301
301
|
const EVE_SESSION_ID_HEADER = "x-eve-session-id";
|
|
302
|
+
const EVE_STREAM_TAIL_INDEX_HEADER = "x-eve-stream-tail-index";
|
|
302
303
|
const textEncoder = new TextEncoder();
|
|
303
304
|
function isCurrentTurnBoundaryEvent(event) {
|
|
304
305
|
return event.type === "session.completed" || event.type === "session.failed" || event.type === "session.waiting";
|
|
@@ -531,32 +532,47 @@ function resolveStreamReconnectPolicy(policy) {
|
|
|
531
532
|
};
|
|
532
533
|
}
|
|
533
534
|
async function* followStreamIterable(input) {
|
|
535
|
+
if (input.follow === false && input.startIndex < 0) throw new Error("stream({ follow: false }) requires a nonnegative startIndex; a tail-relative cursor cannot be bounded.");
|
|
534
536
|
const retryPolicy = resolveStreamReconnectPolicy(input.streamReconnectPolicy);
|
|
535
537
|
const idleRetryPolicy = retryPolicy.streamIdleReconnectPolicy;
|
|
536
538
|
let startIndex = input.startIndex;
|
|
537
539
|
let reconnectDelayMs = idleRetryPolicy.baseDelayMs;
|
|
538
540
|
let idleReconnects = 0;
|
|
539
541
|
let initialConnection = true;
|
|
542
|
+
let tailIndex;
|
|
540
543
|
while (true) {
|
|
541
|
-
let
|
|
544
|
+
let connection;
|
|
542
545
|
try {
|
|
543
|
-
|
|
546
|
+
connection = await openStreamBody({
|
|
544
547
|
...input,
|
|
545
548
|
retryPolicy,
|
|
546
|
-
startIndex
|
|
549
|
+
startIndex,
|
|
550
|
+
requestTailIndex: input.follow === false && tailIndex === void 0
|
|
547
551
|
});
|
|
548
552
|
} catch (error) {
|
|
549
553
|
if (input.signal?.aborted) return;
|
|
550
554
|
throw error;
|
|
551
555
|
}
|
|
556
|
+
if (input.follow === false && tailIndex === void 0) {
|
|
557
|
+
tailIndex = connection.tailIndex;
|
|
558
|
+
if (tailIndex === void 0) {
|
|
559
|
+
await connection.body.cancel().catch(() => {});
|
|
560
|
+
throw new Error(`stream({ follow: false }) requires the server to report the ${EVE_STREAM_TAIL_INDEX_HEADER} header. The agent may be running an older eve version.`);
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
if (tailIndex !== void 0 && startIndex > tailIndex) {
|
|
564
|
+
await connection.body.cancel().catch(() => {});
|
|
565
|
+
return;
|
|
566
|
+
}
|
|
552
567
|
let deliveredEvent = false;
|
|
553
568
|
try {
|
|
554
|
-
for await (const event of readNdjsonStream(body)) {
|
|
569
|
+
for await (const event of readNdjsonStream(connection.body)) {
|
|
555
570
|
startIndex += 1;
|
|
556
571
|
deliveredEvent = true;
|
|
557
572
|
reconnectDelayMs = idleRetryPolicy.baseDelayMs;
|
|
558
573
|
idleReconnects = 0;
|
|
559
574
|
yield event;
|
|
575
|
+
if (tailIndex !== void 0 && startIndex > tailIndex) return;
|
|
560
576
|
}
|
|
561
577
|
} catch (error) {
|
|
562
578
|
if (!isStreamDisconnectError(error)) throw error;
|
|
@@ -576,8 +592,11 @@ async function openStreamBody(input) {
|
|
|
576
592
|
let lastBody;
|
|
577
593
|
let lastHeaders;
|
|
578
594
|
let retryDelayMs = openRetryPolicy.baseDelayMs;
|
|
595
|
+
const searchParams = {};
|
|
596
|
+
if (input.startIndex !== 0) searchParams.startIndex = String(input.startIndex);
|
|
597
|
+
if (input.requestTailIndex === true) searchParams.includeTailIndex = "1";
|
|
579
598
|
for (let attempt = 0; attempt < openRetryPolicy.maxAttempts; attempt += 1) {
|
|
580
|
-
const url = createClientUrl(input.host, createEveMessageStreamRoutePath(input.sessionId),
|
|
599
|
+
const url = createClientUrl(input.host, createEveMessageStreamRoutePath(input.sessionId), Object.keys(searchParams).length > 0 ? searchParams : void 0);
|
|
581
600
|
const headers = await input.resolveHeaders();
|
|
582
601
|
let response;
|
|
583
602
|
try {
|
|
@@ -594,7 +613,10 @@ async function openStreamBody(input) {
|
|
|
594
613
|
}
|
|
595
614
|
if (response.ok) {
|
|
596
615
|
if (!response.body) throw new ClientError(response.status, "Response body is null.", response.headers);
|
|
597
|
-
return
|
|
616
|
+
return {
|
|
617
|
+
body: response.body,
|
|
618
|
+
tailIndex: parseTailIndexHeader(response.headers)
|
|
619
|
+
};
|
|
598
620
|
}
|
|
599
621
|
lastStatus = response.status;
|
|
600
622
|
lastBody = await response.text();
|
|
@@ -607,6 +629,12 @@ async function openStreamBody(input) {
|
|
|
607
629
|
}
|
|
608
630
|
throw new ClientError(lastStatus ?? 0, lastBody ?? "Failed to open message stream.", lastHeaders);
|
|
609
631
|
}
|
|
632
|
+
function parseTailIndexHeader(headers) {
|
|
633
|
+
const raw = headers.get(EVE_STREAM_TAIL_INDEX_HEADER);
|
|
634
|
+
if (raw === null || !/^-?\d+$/.test(raw)) return;
|
|
635
|
+
const parsed = Number(raw);
|
|
636
|
+
return Number.isSafeInteger(parsed) ? parsed : void 0;
|
|
637
|
+
}
|
|
610
638
|
async function sleep$1(ms, signal) {
|
|
611
639
|
if (signal?.aborted) return;
|
|
612
640
|
await new Promise((resolve) => {
|
|
@@ -784,6 +812,7 @@ var ClientSession = class {
|
|
|
784
812
|
stream(options) {
|
|
785
813
|
const sessionId = this.#state.sessionId;
|
|
786
814
|
if (!sessionId) throw new Error("Session has no session ID. Send a message first.");
|
|
815
|
+
if (options?.follow === false && (options.startIndex ?? this.#state.streamIndex) < 0) throw new Error("stream({ follow: false }) requires a nonnegative startIndex; a tail-relative cursor cannot be bounded.");
|
|
787
816
|
return this.#streamAndAdvance(sessionId, options);
|
|
788
817
|
}
|
|
789
818
|
async #postTurn(input, session) {
|
|
@@ -845,6 +874,7 @@ var ClientSession = class {
|
|
|
845
874
|
const events = [];
|
|
846
875
|
try {
|
|
847
876
|
for await (const event of followStreamIterable({
|
|
877
|
+
follow: options?.follow,
|
|
848
878
|
host: this.#context.host,
|
|
849
879
|
resolveHeaders: () => this.#context.resolveHeaders(),
|
|
850
880
|
redirect: this.#context.redirect,
|
|
@@ -21,6 +21,12 @@ interface FollowStreamInput {
|
|
|
21
21
|
readonly sessionId: string;
|
|
22
22
|
readonly signal?: AbortSignal;
|
|
23
23
|
readonly startIndex: number;
|
|
24
|
+
/** Follow the live stream after the durable tail (default). `false` bounds the read at the tail. */
|
|
25
|
+
readonly follow?: boolean;
|
|
26
|
+
}
|
|
27
|
+
/** One connection open; `requestTailIndex` asks the server to report the durable tail index. */
|
|
28
|
+
interface OpenStreamInput extends FollowStreamInput {
|
|
29
|
+
readonly requestTailIndex?: boolean;
|
|
24
30
|
}
|
|
25
31
|
/**
|
|
26
32
|
* Follows a session's durable event stream from an absolute cursor,
|
|
@@ -30,15 +36,24 @@ interface FollowStreamInput {
|
|
|
30
36
|
* idle budget; repeated empty streams eventually stop the follow. Callers own
|
|
31
37
|
* boundary handling. Negative tail-relative cursors use one connection because
|
|
32
38
|
* they cannot be advanced safely.
|
|
39
|
+
*
|
|
40
|
+
* With `follow: false`, the first connection fixes the bound: the iterator
|
|
41
|
+
* yields events until the cursor passes that tail, reconnecting as needed,
|
|
42
|
+
* then returns instead of following.
|
|
33
43
|
*/
|
|
34
44
|
export declare function followStreamIterable(input: FollowStreamInput): AsyncGenerator<HandleMessageStreamEvent>;
|
|
45
|
+
/** An opened connection: the response body plus the tail index from the response header, if any. */
|
|
46
|
+
interface OpenedStream {
|
|
47
|
+
readonly body: ReadableStream<Uint8Array>;
|
|
48
|
+
readonly tailIndex: number | undefined;
|
|
49
|
+
}
|
|
35
50
|
/**
|
|
36
51
|
* Opens one stream response body, retrying transient failures with capped
|
|
37
52
|
* exponential backoff (~35s total): brief network outages and the short
|
|
38
53
|
* propagation window where a just-acknowledged session may not yet be
|
|
39
54
|
* readable from the stream route.
|
|
40
55
|
*/
|
|
41
|
-
export declare function openStreamBody(input:
|
|
56
|
+
export declare function openStreamBody(input: OpenStreamInput & {
|
|
42
57
|
readonly retryPolicy?: ResolvedStreamReconnectPolicy;
|
|
43
|
-
}): Promise<
|
|
58
|
+
}): Promise<OpenedStream>;
|
|
44
59
|
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 DEFAULT_STREAM_RECONNECT_POLICY={retryableErrorStatuses:new Set([404,409,425,500,502,503,504]),streamIdleReconnectPolicy:{baseDelayMs:250,maxAttempts:5,maxDelayMs:4e3},streamOpenReconnectPolicy:{baseDelayMs:250,maxAttempts:12,maxDelayMs:5e3}},NO_STREAM_RECONNECT_POLICY={...DEFAULT_STREAM_RECONNECT_POLICY,streamIdleReconnectPolicy:{...DEFAULT_STREAM_RECONNECT_POLICY.streamIdleReconnectPolicy,maxAttempts:0},streamOpenReconnectPolicy:{...DEFAULT_STREAM_RECONNECT_POLICY.streamOpenReconnectPolicy,maxAttempts:1}};function resolveRetryPolicy(e,t){return{...t,...e}}function resolveStreamReconnectPolicy(e){if(e&&`reconnect`in e&&e.reconnect===!1)return NO_STREAM_RECONNECT_POLICY;let t=e;return{retryableErrorStatuses:t?.retryableErrorStatuses?new Set(t.retryableErrorStatuses):DEFAULT_STREAM_RECONNECT_POLICY.retryableErrorStatuses,streamIdleReconnectPolicy:resolveRetryPolicy(t?.streamIdleReconnectPolicy,DEFAULT_STREAM_RECONNECT_POLICY.streamIdleReconnectPolicy),streamOpenReconnectPolicy:resolveRetryPolicy(t?.streamOpenReconnectPolicy,DEFAULT_STREAM_RECONNECT_POLICY.streamOpenReconnectPolicy)}}async function*followStreamIterable(e){let
|
|
1
|
+
import{createEveMessageStreamRoutePath}from"#protocol/routes.js";import{EVE_STREAM_TAIL_INDEX_HEADER}from"#protocol/message.js";import{ClientError}from"#client/client-error.js";import{createClientUrl}from"#client/url.js";import{isStreamDisconnectError,readNdjsonStream}from"#client/ndjson.js";const DEFAULT_STREAM_RECONNECT_POLICY={retryableErrorStatuses:new Set([404,409,425,500,502,503,504]),streamIdleReconnectPolicy:{baseDelayMs:250,maxAttempts:5,maxDelayMs:4e3},streamOpenReconnectPolicy:{baseDelayMs:250,maxAttempts:12,maxDelayMs:5e3}},NO_STREAM_RECONNECT_POLICY={...DEFAULT_STREAM_RECONNECT_POLICY,streamIdleReconnectPolicy:{...DEFAULT_STREAM_RECONNECT_POLICY.streamIdleReconnectPolicy,maxAttempts:0},streamOpenReconnectPolicy:{...DEFAULT_STREAM_RECONNECT_POLICY.streamOpenReconnectPolicy,maxAttempts:1}};function resolveRetryPolicy(e,t){return{...t,...e}}function resolveStreamReconnectPolicy(e){if(e&&`reconnect`in e&&e.reconnect===!1)return NO_STREAM_RECONNECT_POLICY;let t=e;return{retryableErrorStatuses:t?.retryableErrorStatuses?new Set(t.retryableErrorStatuses):DEFAULT_STREAM_RECONNECT_POLICY.retryableErrorStatuses,streamIdleReconnectPolicy:resolveRetryPolicy(t?.streamIdleReconnectPolicy,DEFAULT_STREAM_RECONNECT_POLICY.streamIdleReconnectPolicy),streamOpenReconnectPolicy:resolveRetryPolicy(t?.streamOpenReconnectPolicy,DEFAULT_STREAM_RECONNECT_POLICY.streamOpenReconnectPolicy)}}async function*followStreamIterable(e){if(e.follow===!1&&e.startIndex<0)throw Error(`stream({ follow: false }) requires a nonnegative startIndex; a tail-relative cursor cannot be bounded.`);let n=resolveStreamReconnectPolicy(e.streamReconnectPolicy),r=n.streamIdleReconnectPolicy,a=e.startIndex,o=r.baseDelayMs,s=0,c=!0,l;for(;;){let u;try{u=await openStreamBody({...e,retryPolicy:n,startIndex:a,requestTailIndex:e.follow===!1&&l===void 0})}catch(t){if(e.signal?.aborted)return;throw t}if(e.follow===!1&&l===void 0&&(l=u.tailIndex,l===void 0))throw await u.body.cancel().catch(()=>{}),Error(`stream({ follow: false }) requires the server to report the ${EVE_STREAM_TAIL_INDEX_HEADER} header. The agent may be running an older eve version.`);if(l!==void 0&&a>l){await u.body.cancel().catch(()=>{});return}let d=!1;try{for await(let e of readNdjsonStream(u.body))if(a+=1,d=!0,o=r.baseDelayMs,s=0,yield e,l!==void 0&&a>l)return}catch(e){if(!isStreamDisconnectError(e))throw e}if(e.signal?.aborted||e.startIndex<0||r.maxAttempts===0||!d&&!c&&(s+=1)>=r.maxAttempts||(c=!1,await sleep(o,e.signal),e.signal?.aborted))return;o=Math.min(o*2,r.maxDelayMs)}}async function openStreamBody(t){let i=t.retryPolicy??DEFAULT_STREAM_RECONNECT_POLICY,o=i.streamOpenReconnectPolicy,s,c,l,u=o.baseDelayMs,d={};t.startIndex!==0&&(d.startIndex=String(t.startIndex)),t.requestTailIndex===!0&&(d.includeTailIndex=`1`);for(let a=0;a<o.maxAttempts;a+=1){let f=createClientUrl(t.host,createEveMessageStreamRoutePath(t.sessionId),Object.keys(d).length>0?d:void 0),p=await t.resolveHeaders(),m;try{m=await fetch(f,{headers:p,redirect:t.redirect,signal:t.signal??null})}catch(e){if(t.signal?.aborted||!isStreamDisconnectError(e)||a===o.maxAttempts-1)throw e;await sleep(u,t.signal),u=Math.min(u*2,o.maxDelayMs);continue}if(m.ok){if(!m.body)throw new ClientError(m.status,`Response body is null.`,m.headers);return{body:m.body,tailIndex:parseTailIndexHeader(m.headers)}}if(s=m.status,c=await m.text(),l=m.headers,!i.retryableErrorStatuses.has(m.status))throw new ClientError(m.status,c,m.headers);a<o.maxAttempts-1&&(await sleep(u,t.signal),u=Math.min(u*2,o.maxDelayMs))}throw new ClientError(s??0,c??`Failed to open message stream.`,l)}function parseTailIndexHeader(e){let n=e.get(EVE_STREAM_TAIL_INDEX_HEADER);if(n===null||!/^-?\d+$/.test(n))return;let r=Number(n);return Number.isSafeInteger(r)?r:void 0}async function sleep(e,t){t?.aborted||await new Promise(n=>{let onAbort=()=>{clearTimeout(r),n()},r=setTimeout(()=>{t?.removeEventListener(`abort`,onAbort),n()},e);t?.addEventListener(`abort`,onAbort,{once:!0})})}export{followStreamIterable,openStreamBody};
|
|
@@ -72,8 +72,12 @@ export declare class ClientSession {
|
|
|
72
72
|
* one connection. Negative indices read relative to the current tail on one connection
|
|
73
73
|
* and do not advance the stored absolute cursor.
|
|
74
74
|
*
|
|
75
|
+
* Pass `follow: false` for a bounded read: yields events up to the durable
|
|
76
|
+
* tail observed when the stream opens, then returns instead of following.
|
|
77
|
+
* The stored cursor still advances past the consumed events.
|
|
78
|
+
*
|
|
75
79
|
* @throws {Error} If the session has no session ID (no message has been sent
|
|
76
|
-
* yet)
|
|
80
|
+
* yet), or if `follow: false` is combined with a negative `startIndex`.
|
|
77
81
|
*/
|
|
78
82
|
stream(options?: StreamOptions): AsyncIterable<HandleMessageStreamEvent>;
|
|
79
83
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{EVE_CREATE_SESSION_ROUTE_PATH,EVE_RESET_SESSION_ROUTE_PATH,createEveCancelTurnRoutePath,createEveContinueSessionRoutePath}from"#protocol/routes.js";import{EVE_SESSION_ID_HEADER,isCurrentTurnBoundaryEvent}from"#protocol/message.js";import{ClientError}from"#client/client-error.js";import{advanceSession,createInitialSessionState}from"#client/session-utils.js";import{createClientUrl}from"#client/url.js";import{MessageResponse}from"#client/message-response.js";import{CancelTurnResponseSchema}from"#protocol/cancel-turn.js";import{ResetResponseSchema}from"#protocol/reset-session.js";import{followStreamIterable}from"#client/open-stream.js";import{serializeOutputSchema}from"#shared/tool-schema.js";var ClientSession=class{#e;#t;constructor(e,t){this.#e=e,this.#t=t}get state(){return this.#t}async send(e){let t=normalizeSendTurnInput(e),n=this.#t,{continuationToken:r,sessionId:i}=await this.#n(t,n);if(this.#t===n){let e={...n,sessionId:i};r!==void 0&&(e.continuationToken=r),this.#t=e}return new MessageResponse({continuationToken:r,createStream:()=>this.#r(i,r,n,t),sessionId:i})}async cancel(e){let t=this.#t.sessionId;if(!t)throw Error(`Session has no session ID. Send a message first.`);let r=createClientUrl(this.#e.host,createEveCancelTurnRoutePath(t)),i=await this.#e.resolveHeaders();i.set(`content-type`,`application/json`);let a=await fetch(r,withRedirectPolicy({headers:i,method:`POST`,body:e?JSON.stringify(e):void 0},this.#e.redirect)),s=await a.text();if(!a.ok)throw new ClientError(a.status,s,a.headers);let c;try{c=JSON.parse(s)}catch{throw Error(`Cancel route returned invalid JSON (${a.status}).`)}let l=CancelTurnResponseSchema.safeParse(c);if(!l.success||l.data.sessionId!==t)throw Error(`Cancel route returned an invalid response (${a.status}).`);return{sessionId:l.data.sessionId,status:l.data.status}}async reset(){let e=this.#t,n=e.continuationToken;if(n===void 0){if(e.sessionId!==void 0)throw Error(`Session has no continuation token. Consume its event stream before resetting.`);return this.#t=createInitialSessionState(),{status:`no_active_session`}}let r=createClientUrl(this.#e.host,EVE_RESET_SESSION_ROUTE_PATH),i=await this.#e.resolveHeaders();i.set(`content-type`,`application/json`);let a=await fetch(r,withRedirectPolicy({body:JSON.stringify({continuationToken:n}),headers:i,method:`POST`},this.#e.redirect)),s=await a.text();if(!a.ok)throw new ClientError(a.status,s,a.headers);let l;try{l=JSON.parse(s)}catch{throw Error(`Reset route returned invalid JSON (${a.status}).`)}let u=ResetResponseSchema.safeParse(l);if(!u.success||u.data.status===`reset`&&e.sessionId!==void 0&&u.data.previousSessionId!==e.sessionId)throw Error(`Reset route returned an invalid response (${a.status}).`);return this.#t===e&&(this.#t=createInitialSessionState()),u.data.status===`reset`?{previousSessionId:u.data.previousSessionId,status:`reset`}:{status:`no_active_session`}}stream(e){let t=this.#t.sessionId;if(!t)throw Error(`Session has no session ID. Send a message first.`);return this.#i(t,e)}async#n(t,n){let a=n.sessionId?createEveContinueSessionRoutePath(n.sessionId):EVE_CREATE_SESSION_ROUTE_PATH,o=createClientUrl(this.#e.host,a),s=await this.#e.resolveHeaders(t.headers);s.set(`content-type`,`application/json`);let c=createHandleMessageBody({input:t,outputSchema:serializeOutputSchema(t.outputSchema),session:n});if(c===null)throw Error(`Session.send requires a non-empty message, inputResponses, or both.`);let l=await postTurnWithRetry({body:JSON.stringify(c),headers:s,mustDeliver:(t.inputResponses?.length??0)>0,redirect:this.#e.redirect,signal:t.signal,url:o}),u=await l.json(),d=(typeof u.sessionId==`string`?u.sessionId:void 0)??l.headers.get(EVE_SESSION_ID_HEADER)?.trim()??n.sessionId;if(!d)throw Error(`Message route did not return a session id.`);return{continuationToken:typeof u.continuationToken==`string`?u.continuationToken:void 0,sessionId:d}}async*#r(e,t,n,r){let i=[];try{for await(let t of followStreamIterable({host:this.#e.host,resolveHeaders:()=>this.#e.resolveHeaders(r.headers),redirect:this.#e.redirect,streamReconnectPolicy:r.streamReconnectPolicy,sessionId:e,signal:r.signal,startIndex:n.sessionId===e?n.streamIndex:0}))if(i.push(t),yield t,isCurrentTurnBoundaryEvent(t))break}finally{this.#t=advanceSession({continuationToken:t,events:i,preserveCompletedSessions:this.#e.preserveCompletedSessions,sessionId:e,session:n})}}async*#i(e,t){let n=this.#t,r=t?.startIndex??n.streamIndex,i=[];try{for await(let n of followStreamIterable({host:this.#e.host,resolveHeaders:()=>this.#e.resolveHeaders(),redirect:this.#e.redirect,streamReconnectPolicy:t?.streamReconnectPolicy,sessionId:e,signal:t?.signal,startIndex:r}))i.push(n),yield n}finally{r>=0&&(this.#t=advanceSession({continuationToken:n.continuationToken,events:i,preserveCompletedSessions:this.#e.preserveCompletedSessions,session:{...n,sessionId:e,streamIndex:r},sessionId:e}))}}};async function postTurnWithRetry(e){let t=e.mustDeliver?10:1,n,r,i;for(let a=0;a<t;a+=1){let s=await fetch(e.url,{body:e.body,headers:e.headers,method:`POST`,redirect:e.redirect,signal:e.signal??null});if(s.ok)return s;if(n=s.status,r=await s.text(),i=s.headers,!isRetryableDeliveryFailure(s.status,r))throw new ClientError(s.status,r,s.headers);a<t-1&&await sleep(200)}throw new ClientError(n??0,r??`Failed to deliver session turn.`,i)}function isRetryableDeliveryFailure(e,t){return e===500&&/target session was not found/i.test(t)}async function sleep(e){await new Promise(t=>setTimeout(t,e))}function normalizeSendTurnInput(e){return typeof e==`string`?{message:e}:e}function createHandleMessageBody(e){let t={};return e.input.message!==void 0&&(t.message=e.input.message),e.input.inputResponses!==void 0&&e.input.inputResponses.length>0&&(t.inputResponses=e.input.inputResponses),e.input.clientContext!==void 0&&(t.clientContext=e.input.clientContext),e.outputSchema!==void 0&&(t.outputSchema=e.outputSchema),e.session.continuationToken!==void 0&&(t.continuationToken=e.session.continuationToken),Object.keys(t).length===0||e.session.continuationToken===void 0&&t.message===void 0||e.session.continuationToken!==void 0&&t.message===void 0&&t.inputResponses===void 0?null:t}function withRedirectPolicy(e,t){return t===void 0?e:{...e,redirect:t}}export{ClientSession};
|
|
1
|
+
import{EVE_CREATE_SESSION_ROUTE_PATH,EVE_RESET_SESSION_ROUTE_PATH,createEveCancelTurnRoutePath,createEveContinueSessionRoutePath}from"#protocol/routes.js";import{EVE_SESSION_ID_HEADER,isCurrentTurnBoundaryEvent}from"#protocol/message.js";import{ClientError}from"#client/client-error.js";import{advanceSession,createInitialSessionState}from"#client/session-utils.js";import{createClientUrl}from"#client/url.js";import{MessageResponse}from"#client/message-response.js";import{CancelTurnResponseSchema}from"#protocol/cancel-turn.js";import{ResetResponseSchema}from"#protocol/reset-session.js";import{followStreamIterable}from"#client/open-stream.js";import{serializeOutputSchema}from"#shared/tool-schema.js";var ClientSession=class{#e;#t;constructor(e,t){this.#e=e,this.#t=t}get state(){return this.#t}async send(e){let t=normalizeSendTurnInput(e),n=this.#t,{continuationToken:r,sessionId:i}=await this.#n(t,n);if(this.#t===n){let e={...n,sessionId:i};r!==void 0&&(e.continuationToken=r),this.#t=e}return new MessageResponse({continuationToken:r,createStream:()=>this.#r(i,r,n,t),sessionId:i})}async cancel(e){let t=this.#t.sessionId;if(!t)throw Error(`Session has no session ID. Send a message first.`);let r=createClientUrl(this.#e.host,createEveCancelTurnRoutePath(t)),i=await this.#e.resolveHeaders();i.set(`content-type`,`application/json`);let a=await fetch(r,withRedirectPolicy({headers:i,method:`POST`,body:e?JSON.stringify(e):void 0},this.#e.redirect)),s=await a.text();if(!a.ok)throw new ClientError(a.status,s,a.headers);let c;try{c=JSON.parse(s)}catch{throw Error(`Cancel route returned invalid JSON (${a.status}).`)}let l=CancelTurnResponseSchema.safeParse(c);if(!l.success||l.data.sessionId!==t)throw Error(`Cancel route returned an invalid response (${a.status}).`);return{sessionId:l.data.sessionId,status:l.data.status}}async reset(){let e=this.#t,n=e.continuationToken;if(n===void 0){if(e.sessionId!==void 0)throw Error(`Session has no continuation token. Consume its event stream before resetting.`);return this.#t=createInitialSessionState(),{status:`no_active_session`}}let r=createClientUrl(this.#e.host,EVE_RESET_SESSION_ROUTE_PATH),i=await this.#e.resolveHeaders();i.set(`content-type`,`application/json`);let a=await fetch(r,withRedirectPolicy({body:JSON.stringify({continuationToken:n}),headers:i,method:`POST`},this.#e.redirect)),s=await a.text();if(!a.ok)throw new ClientError(a.status,s,a.headers);let l;try{l=JSON.parse(s)}catch{throw Error(`Reset route returned invalid JSON (${a.status}).`)}let u=ResetResponseSchema.safeParse(l);if(!u.success||u.data.status===`reset`&&e.sessionId!==void 0&&u.data.previousSessionId!==e.sessionId)throw Error(`Reset route returned an invalid response (${a.status}).`);return this.#t===e&&(this.#t=createInitialSessionState()),u.data.status===`reset`?{previousSessionId:u.data.previousSessionId,status:`reset`}:{status:`no_active_session`}}stream(e){let t=this.#t.sessionId;if(!t)throw Error(`Session has no session ID. Send a message first.`);if(e?.follow===!1&&(e.startIndex??this.#t.streamIndex)<0)throw Error(`stream({ follow: false }) requires a nonnegative startIndex; a tail-relative cursor cannot be bounded.`);return this.#i(t,e)}async#n(t,n){let a=n.sessionId?createEveContinueSessionRoutePath(n.sessionId):EVE_CREATE_SESSION_ROUTE_PATH,o=createClientUrl(this.#e.host,a),s=await this.#e.resolveHeaders(t.headers);s.set(`content-type`,`application/json`);let c=createHandleMessageBody({input:t,outputSchema:serializeOutputSchema(t.outputSchema),session:n});if(c===null)throw Error(`Session.send requires a non-empty message, inputResponses, or both.`);let l=await postTurnWithRetry({body:JSON.stringify(c),headers:s,mustDeliver:(t.inputResponses?.length??0)>0,redirect:this.#e.redirect,signal:t.signal,url:o}),u=await l.json(),d=(typeof u.sessionId==`string`?u.sessionId:void 0)??l.headers.get(EVE_SESSION_ID_HEADER)?.trim()??n.sessionId;if(!d)throw Error(`Message route did not return a session id.`);return{continuationToken:typeof u.continuationToken==`string`?u.continuationToken:void 0,sessionId:d}}async*#r(e,t,n,r){let i=[];try{for await(let t of followStreamIterable({host:this.#e.host,resolveHeaders:()=>this.#e.resolveHeaders(r.headers),redirect:this.#e.redirect,streamReconnectPolicy:r.streamReconnectPolicy,sessionId:e,signal:r.signal,startIndex:n.sessionId===e?n.streamIndex:0}))if(i.push(t),yield t,isCurrentTurnBoundaryEvent(t))break}finally{this.#t=advanceSession({continuationToken:t,events:i,preserveCompletedSessions:this.#e.preserveCompletedSessions,sessionId:e,session:n})}}async*#i(e,t){let n=this.#t,r=t?.startIndex??n.streamIndex,i=[];try{for await(let n of followStreamIterable({follow:t?.follow,host:this.#e.host,resolveHeaders:()=>this.#e.resolveHeaders(),redirect:this.#e.redirect,streamReconnectPolicy:t?.streamReconnectPolicy,sessionId:e,signal:t?.signal,startIndex:r}))i.push(n),yield n}finally{r>=0&&(this.#t=advanceSession({continuationToken:n.continuationToken,events:i,preserveCompletedSessions:this.#e.preserveCompletedSessions,session:{...n,sessionId:e,streamIndex:r},sessionId:e}))}}};async function postTurnWithRetry(e){let t=e.mustDeliver?10:1,n,r,i;for(let a=0;a<t;a+=1){let s=await fetch(e.url,{body:e.body,headers:e.headers,method:`POST`,redirect:e.redirect,signal:e.signal??null});if(s.ok)return s;if(n=s.status,r=await s.text(),i=s.headers,!isRetryableDeliveryFailure(s.status,r))throw new ClientError(s.status,r,s.headers);a<t-1&&await sleep(200)}throw new ClientError(n??0,r??`Failed to deliver session turn.`,i)}function isRetryableDeliveryFailure(e,t){return e===500&&/target session was not found/i.test(t)}async function sleep(e){await new Promise(t=>setTimeout(t,e))}function normalizeSendTurnInput(e){return typeof e==`string`?{message:e}:e}function createHandleMessageBody(e){let t={};return e.input.message!==void 0&&(t.message=e.input.message),e.input.inputResponses!==void 0&&e.input.inputResponses.length>0&&(t.inputResponses=e.input.inputResponses),e.input.clientContext!==void 0&&(t.clientContext=e.input.clientContext),e.outputSchema!==void 0&&(t.outputSchema=e.outputSchema),e.session.continuationToken!==void 0&&(t.continuationToken=e.session.continuationToken),Object.keys(t).length===0||e.session.continuationToken===void 0&&t.message===void 0||e.session.continuationToken!==void 0&&t.message===void 0&&t.inputResponses===void 0?null:t}function withRedirectPolicy(e,t){return t===void 0?e:{...e,redirect:t}}export{ClientSession};
|
|
@@ -171,6 +171,13 @@ export interface StreamOptions {
|
|
|
171
171
|
* not reconnect automatically because their absolute cursor is unknown.
|
|
172
172
|
*/
|
|
173
173
|
readonly startIndex?: number;
|
|
174
|
+
/**
|
|
175
|
+
* Follow the live stream after the durable tail (default). Pass `false`
|
|
176
|
+
* for a bounded catch-up read: yields events until the cursor passes the
|
|
177
|
+
* tail observed when the stream opened, then returns instead of
|
|
178
|
+
* following. Requires a nonnegative start cursor.
|
|
179
|
+
*/
|
|
180
|
+
readonly follow?: boolean;
|
|
174
181
|
/**
|
|
175
182
|
* Abort signal for cancelling the stream.
|
|
176
183
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createLogger,logError}from"#internal/logging.js";import{RuntimeNoActiveSessionError}from"#execution/runtime-errors.js";import{resolveInstalledPackageInfo}from"#internal/application/package.js";import{walkCauseChain}from"#shared/errors.js";import{serializeContext}from"#context/serialize.js";import{getCompiledRuntimeAgentBundle}from"#runtime/sessions/compiled-agent-cache.js";import{cancelRun,getHookByToken,getRun,getWorld,resumeHook,start}from"#internal/workflow/runtime.js";import{ROOT_RUNTIME_AGENT_NODE_ID}from"#runtime/graph.js";import{sessionCancelHookToken}from"#execution/turn-cancellation-token.js";import{buildSessionAttributes,buildSubagentRootAttributes,readParentLineage}from"#execution/eve-workflow-attributes.js";import{EntityConflictError,HookNotFoundError,RunExpiredError,WorkflowRunNotFoundError}from"#compiled/@workflow/errors/index.js";import{isEveDevEnvironment}from"#internal/application/dev-environment.js";import{normalizeEveAttributes}from"#runtime/attributes/normalize.js";import{buildRunContext}from"#execution/runtime-context.js";import{parseNdjsonStream}from"#execution/ndjson-stream.js";const WORKFLOW_ENTRY_NAME=`workflowEntry`,TURN_WORKFLOW_NAME=`turnWorkflow`,EVE_PACKAGE_INFO=resolveInstalledPackageInfo(),LATEST_DEPLOYMENT_UNSUPPORTED_MESSAGE=`deploymentId 'latest' requires a World that implements resolveLatestDeploymentId()`,STABLE_WORKFLOW_NAMES=new Set([WORKFLOW_ENTRY_NAME,TURN_WORKFLOW_NAME]),STABLE_ID_BASE=EVE_PACKAGE_INFO.name,log=createLogger(`execution.workflow-runtime`),workflowEntryReference={workflowId:`workflow//${STABLE_ID_BASE}//${WORKFLOW_ENTRY_NAME}`},turnWorkflowReference={workflowId:`workflow//${STABLE_ID_BASE}//${TURN_WORKFLOW_NAME}`};function createWorkflowRuntime(e){return{async run(n){let r=await getCompiledRuntimeAgentBundle({compiledArtifactsSource:e.compiledArtifactsSource,nodeId:e.nodeId}),i=serializeContext(buildRunContext({bundle:r,run:n})),a=readParentLineage(i),o=a.sessionId===void 0?buildSessionAttributes({inputMessage:n.title??n.input.message,serializedContext:i}):buildSubagentRootAttributes({identity:{nodeId:r.nodeId??ROOT_RUNTIME_AGENT_NODE_ID},parentCallId:a.callId,parentSessionId:a.sessionId,parentTurnId:a.turnId,rootSessionId:a.rootSessionId??a.sessionId,serializedContext:i}),s;try{s=await startWorkflowPreferLatest(workflowEntryReference,[{input:n.input,limits:n.limits,serializedContext:i}],{allowReservedAttributes:!0,attributes:normalizeEveAttributes(o)})}catch(e){throw logError(log,`failed to start workflow run`,e,{continuationToken:n.continuationToken}),e}let c,getEvents=()=>(c??=parseNdjsonStream(()=>getRun(s.runId).getReadable()),c);return{continuationToken:n.continuationToken??s.runId,get events(){return getEvents()},sessionId:s.runId}},async cancelTurn(e){return await requestWorkflowTurnCancellation(e)},async terminateSession(e){try{return await cancelRun(await getWorld(),e.sessionId,{cancelReason:e.reason??`Session reset by channel`}),{status:`terminated`}}catch(e){if(isAlreadyTerminalSessionError(e))return{status:`already_terminal`};throw e}},async deliver(e){let r={auth:e.auth,kind:`deliver`,payloads:[e.payload],requestId:e.requestId};try{return{sessionId:normalizeWorkflowHook(await resumeHook(e.continuationToken,r)).runId}}catch(r){throw HookNotFoundError.is(r)?new RuntimeNoActiveSessionError(e.continuationToken):(logError(log,`failed to deliver to active session`,r,{continuationToken:e.continuationToken}),r)}},async getEventStream(e,t){return parseNdjsonStream(()=>getRun(e).getReadable({startIndex:t?.startIndex}))},async resolveSession(e){try{return{sessionId:(await getHookByToken(e)).runId}}catch(n){if(HookNotFoundError.is(n))return;throw logError(log,`failed to resolve session by continuation token`,n,{continuationToken:e}),n}}}}async function requestWorkflowTurnCancellation(e){let t=e.turnId===void 0?{}:{turnId:e.turnId};try{return await resumeHook(sessionCancelHookToken(e.sessionId),t),{status:`accepted`}}catch(e){if(isInactiveCancelTarget(e))return{status:`no_active_turn`};throw e}}function isInactiveCancelTarget(e){return HookNotFoundError.is(e)||WorkflowRunNotFoundError.is(e)||RunExpiredError.is(e)||EntityConflictError.is(e)}function isAlreadyTerminalSessionError(e){for(let t of walkCauseChain(e))if(WorkflowRunNotFoundError.is(t)||RunExpiredError.is(t)||EntityConflictError.is(t))return!0;return!1}async function startWorkflowPreferLatest(e,t,n){if(!shouldRouteToLatestDeployment())return n===void 0?await start(e,t):await start(e,t,n);try{return await start(e,t,{...n,deploymentId:`latest`})}catch(r){if(!isLatestDeploymentUnsupportedError(r))throw r;return n===void 0?await start(e,t):await start(e,t,n)}}function shouldRouteToLatestDeployment(){return process.env.VERCEL_ENV===`production`||isEveDevEnvironment()}function isLatestDeploymentUnsupportedError(e){return e instanceof Error&&e.message.includes(`deploymentId 'latest' requires a World that implements resolveLatestDeploymentId()`)}function normalizeWorkflowHook(e){if(typeof e!=`object`||!e||!(`runId`in e))throw Error(`Workflow hook did not include a run id.`);let t=e.runId;if(typeof t!=`string`||t.length===0)throw Error(`Workflow hook did not include a run id.`);return{runId:t}}export{LATEST_DEPLOYMENT_UNSUPPORTED_MESSAGE,STABLE_WORKFLOW_NAMES,createWorkflowRuntime,requestWorkflowTurnCancellation,startWorkflowPreferLatest,turnWorkflowReference,workflowEntryReference};
|
|
1
|
+
import{createLogger,logError}from"#internal/logging.js";import{RuntimeNoActiveSessionError}from"#execution/runtime-errors.js";import{resolveInstalledPackageInfo}from"#internal/application/package.js";import{walkCauseChain}from"#shared/errors.js";import{serializeContext}from"#context/serialize.js";import{getCompiledRuntimeAgentBundle}from"#runtime/sessions/compiled-agent-cache.js";import{cancelRun,getHookByToken,getRun,getWorld,resumeHook,start}from"#internal/workflow/runtime.js";import{ROOT_RUNTIME_AGENT_NODE_ID}from"#runtime/graph.js";import{sessionCancelHookToken}from"#execution/turn-cancellation-token.js";import{buildSessionAttributes,buildSubagentRootAttributes,readParentLineage}from"#execution/eve-workflow-attributes.js";import{EntityConflictError,HookNotFoundError,RunExpiredError,WorkflowRunNotFoundError}from"#compiled/@workflow/errors/index.js";import{isEveDevEnvironment}from"#internal/application/dev-environment.js";import{normalizeEveAttributes}from"#runtime/attributes/normalize.js";import{buildRunContext}from"#execution/runtime-context.js";import{parseNdjsonStream}from"#execution/ndjson-stream.js";const WORKFLOW_ENTRY_NAME=`workflowEntry`,TURN_WORKFLOW_NAME=`turnWorkflow`,EVE_PACKAGE_INFO=resolveInstalledPackageInfo(),LATEST_DEPLOYMENT_UNSUPPORTED_MESSAGE=`deploymentId 'latest' requires a World that implements resolveLatestDeploymentId()`,STABLE_WORKFLOW_NAMES=new Set([WORKFLOW_ENTRY_NAME,TURN_WORKFLOW_NAME]),STABLE_ID_BASE=EVE_PACKAGE_INFO.name,log=createLogger(`execution.workflow-runtime`),workflowEntryReference={workflowId:`workflow//${STABLE_ID_BASE}//${WORKFLOW_ENTRY_NAME}`},turnWorkflowReference={workflowId:`workflow//${STABLE_ID_BASE}//${TURN_WORKFLOW_NAME}`};function createWorkflowRuntime(e){return{async run(n){let r=await getCompiledRuntimeAgentBundle({compiledArtifactsSource:e.compiledArtifactsSource,nodeId:e.nodeId}),i=serializeContext(buildRunContext({bundle:r,run:n})),a=readParentLineage(i),o=a.sessionId===void 0?buildSessionAttributes({inputMessage:n.title??n.input.message,serializedContext:i}):buildSubagentRootAttributes({identity:{nodeId:r.nodeId??ROOT_RUNTIME_AGENT_NODE_ID},parentCallId:a.callId,parentSessionId:a.sessionId,parentTurnId:a.turnId,rootSessionId:a.rootSessionId??a.sessionId,serializedContext:i}),s;try{s=await startWorkflowPreferLatest(workflowEntryReference,[{input:n.input,limits:n.limits,serializedContext:i}],{allowReservedAttributes:!0,attributes:normalizeEveAttributes(o)})}catch(e){throw logError(log,`failed to start workflow run`,e,{continuationToken:n.continuationToken}),e}let c,getEvents=()=>(c??=parseNdjsonStream(()=>getRun(s.runId).getReadable()),c);return{continuationToken:n.continuationToken??s.runId,get events(){return getEvents()},sessionId:s.runId}},async cancelTurn(e){return await requestWorkflowTurnCancellation(e)},async terminateSession(e){try{return await cancelRun(await getWorld(),e.sessionId,{cancelReason:e.reason??`Session reset by channel`}),{status:`terminated`}}catch(e){if(isAlreadyTerminalSessionError(e))return{status:`already_terminal`};throw e}},async deliver(e){let r={auth:e.auth,kind:`deliver`,payloads:[e.payload],requestId:e.requestId};try{return{sessionId:normalizeWorkflowHook(await resumeHook(e.continuationToken,r)).runId}}catch(r){throw HookNotFoundError.is(r)?new RuntimeNoActiveSessionError(e.continuationToken):(logError(log,`failed to deliver to active session`,r,{continuationToken:e.continuationToken}),r)}},async getEventStream(e,t){return parseNdjsonStream(()=>getRun(e).getReadable({startIndex:t?.startIndex}))},async getStreamTailIndex(e){let t=getRun(e).getReadable();try{return await t.getTailIndex()}finally{await t.cancel().catch(()=>{})}},async resolveSession(e){try{return{sessionId:(await getHookByToken(e)).runId}}catch(n){if(HookNotFoundError.is(n))return;throw logError(log,`failed to resolve session by continuation token`,n,{continuationToken:e}),n}}}}async function requestWorkflowTurnCancellation(e){let t=e.turnId===void 0?{}:{turnId:e.turnId};try{return await resumeHook(sessionCancelHookToken(e.sessionId),t),{status:`accepted`}}catch(e){if(isInactiveCancelTarget(e))return{status:`no_active_turn`};throw e}}function isInactiveCancelTarget(e){return HookNotFoundError.is(e)||WorkflowRunNotFoundError.is(e)||RunExpiredError.is(e)||EntityConflictError.is(e)}function isAlreadyTerminalSessionError(e){for(let t of walkCauseChain(e))if(WorkflowRunNotFoundError.is(t)||RunExpiredError.is(t)||EntityConflictError.is(t))return!0;return!1}async function startWorkflowPreferLatest(e,t,n){if(!shouldRouteToLatestDeployment())return n===void 0?await start(e,t):await start(e,t,n);try{return await start(e,t,{...n,deploymentId:`latest`})}catch(r){if(!isLatestDeploymentUnsupportedError(r))throw r;return n===void 0?await start(e,t):await start(e,t,n)}}function shouldRouteToLatestDeployment(){return process.env.VERCEL_ENV===`production`||isEveDevEnvironment()}function isLatestDeploymentUnsupportedError(e){return e instanceof Error&&e.message.includes(`deploymentId 'latest' requires a World that implements resolveLatestDeploymentId()`)}function normalizeWorkflowHook(e){if(typeof e!=`object`||!e||!(`runId`in e))throw Error(`Workflow hook did not include a run id.`);let t=e.runId;if(typeof t!=`string`||t.length===0)throw Error(`Workflow hook did not include a run id.`);return{runId:t}}export{LATEST_DEPLOYMENT_UNSUPPORTED_MESSAGE,STABLE_WORKFLOW_NAMES,createWorkflowRuntime,requestWorkflowTurnCancellation,startWorkflowPreferLatest,turnWorkflowReference,workflowEntryReference};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createActionResultEvent,createActionsRequestedEvent,createMessageAppendedEvent,createMessageCompletedEvent,createMessageReceivedEvent,createReasoningAppendedEvent,createReasoningCompletedEvent,createSessionCompletedEvent,createSessionFailedEvent,createSessionStartedEvent,createSessionWaitingEvent,createStepFailedEvent,createStepStartedEvent,createTurnCompletedEvent,createTurnFailedEvent,createTurnStartedEvent}from"#protocol/message.js";import{createRuntimeActionRequestFromToolCall
|
|
1
|
+
import{createActionResultEvent,createActionsRequestedEvent,createMessageAppendedEvent,createMessageCompletedEvent,createMessageReceivedEvent,createReasoningAppendedEvent,createReasoningCompletedEvent,createSessionCompletedEvent,createSessionFailedEvent,createSessionStartedEvent,createSessionWaitingEvent,createStepFailedEvent,createStepStartedEvent,createTurnCompletedEvent,createTurnFailedEvent,createTurnStartedEvent}from"#protocol/message.js";import{createRuntimeActionRequestFromToolCall}from"#harness/runtime-actions.js";import{hasEmptyDeliverySentinel}from"#shared/empty-delivery.js";import{createRuntimeToolResultFromStepResult,createRuntimeToolResultFromToolError,createToolResultMessagePartFromToolError}from"#harness/action-result-helpers.js";import{createInvalidToolCallInputError,isInvalidToolCall,resolveProviderToolCallRequest}from"#harness/tool-call-input-errors.js";import{createProviderStreamActionBatch}from"#harness/stream-actions.js";import{normalizeModelStreamError}from"#harness/model-call-error.js";import{createOrderedStreamEmitter}from"#harness/ordered-stream-emitter.js";import{interruptStreamOnFailure}from"#harness/interruptible-stream.js";import{isInlineAuthorizationToolResult}from"#harness/inline-tool-authorization.js";const HARNESS_EMISSION_STATE_KEY=`eve.harness.emission`,DEFAULT_EMISSION_STATE={sessionStarted:!1,sequence:0,stepIndex:0,turnId:``};function getHarnessEmissionState(e){return e?.[HARNESS_EMISSION_STATE_KEY]??DEFAULT_EMISSION_STATE}function isHarnessBetweenTurns(e){return getHarnessEmissionState(e.state).turnId===``}function setHarnessEmissionState(e,t){return{...e,state:{...e.state,[HARNESS_EMISSION_STATE_KEY]:t}}}async function emitTurnPreamble(e,t,n,r){let a=`turn_${n.sequence}`;return n.sessionStarted||await e(createSessionStartedEvent({runtime:r})),await e(createTurnStartedEvent({sequence:n.sequence,turnId:a})),t.message!==void 0&&await e(createMessageReceivedEvent({message:t.message,sequence:n.sequence,turnId:a})),{sessionStarted:!0,sequence:n.sequence,stepIndex:0,turnId:a}}async function emitStepStarted(e,t,n){await e(createStepStartedEvent({sequence:t.sequence,stepIndex:t.stepIndex,turnId:t.turnId}),n)}async function emitStepAndTurnFailed(e,t,n){await e(createStepFailedEvent({...n,sequence:t.sequence,stepIndex:t.stepIndex,turnId:t.turnId})),await e(createTurnFailedEvent({...n,sequence:t.sequence,turnId:t.turnId}))}async function emitFailedStep(e,t,n){await emitStepAndTurnFailed(e,t,n),await e(createSessionFailedEvent(n))}async function emitRecoverableFailedTurn(e,t,n){return await emitStepAndTurnFailed(e,t,n),await e(createSessionWaitingEvent(n.continuationToken)),{sessionStarted:t.sessionStarted,sequence:t.sequence+1,stepIndex:0,turnId:``}}function advanceStep(e){return{...e,stepIndex:e.stepIndex+1}}async function emitTurnEpilogue(e,t,n,r){return await e(createTurnCompletedEvent({sequence:t.sequence,turnId:t.turnId})),n===`conversation`?await e(createSessionWaitingEvent(r)):await e(createSessionCompletedEvent()),{sessionStarted:t.sessionStarted,sequence:t.sequence+1,stepIndex:0,turnId:``}}function normalizeAssistantStepFinishReason(e){switch(e){case`content-filter`:case`error`:case`length`:case`stop`:case`tool-calls`:return e;default:return`other`}}async function emitStreamContent(e,t,n,r){let i=createOrderedStreamEmitter(e),a=createProviderStreamActionBatch({emitFn:i.emit,state:t});try{return await consumeStreamContent(i.emit,t,interruptStreamOnFailure(n,i.failureSignal),a,r)}finally{try{await a.cancel()}finally{await i.closeAndDrain()}}}async function consumeStreamContent(i,o,s,c,l){let u=``,d=``,f=`stop`,p,m=new Set,h=new Set,g=new Set,_=new Set,v=new Set,y=new Set,b=[],x=[],flushCurrentMessage=async()=>{d.length!==0&&(await i(createMessageCompletedEvent({finishReason:`tool-calls`,message:d,sequence:o.sequence,stepIndex:o.stepIndex,turnId:o.turnId})),d=``)},emitActionRequest=async e=>{h.has(e.callId)||(d.trim().length>0&&await flushCurrentMessage(),h.add(e.callId),await i(createActionsRequestedEvent({actions:[e],sequence:o.sequence,stepIndex:o.stepIndex,turnId:o.turnId})))},collectProviderToolCall=async e=>{if(_.has(e.toolCallId)||(_.add(e.toolCallId),h.has(e.toolCallId)))return;h.add(e.toolCallId),d.trim().length>0&&await flushCurrentMessage();let t=resolveProviderToolCallRequest(e);if(t.toolError!==void 0){y.add(e.toolCallId),await emitActionResult(createRuntimeToolResultFromToolError(t.toolError)),v.add(e.toolCallId);return}c.observe(t.request)},emitActionResult=async t=>{g.has(t.callId)||(g.add(t.callId),await i(createActionResultEvent({result:t,sequence:o.sequence,stepIndex:o.stepIndex,turnId:o.turnId})))},emitToolCall=async e=>{if(isInvalidToolCall(e)){y.add(e.toolCallId);return}if(!(l===void 0||l.excludedActionToolNames.has(e.toolName)))try{await emitActionRequest(createRuntimeActionRequestFromToolCall({toolCall:e,tools:l.tools}))}catch(t){if(t instanceof TypeError){let n=createInvalidToolCallInputError({error:t,toolCall:e});y.add(e.toolCallId),d.trim().length>0&&await flushCurrentMessage(),await emitActionResult(createRuntimeToolResultFromToolError(n)),v.add(e.toolCallId),x.push(createToolResultMessagePartFromToolError(n));return}throw t}};for await(let e of s)if(p===void 0)switch(e.type){case`reasoning-delta`:await c.flush(),u+=e.text,await i(createReasoningAppendedEvent({reasoningDelta:e.text,reasoningSoFar:u,sequence:o.sequence,stepIndex:o.stepIndex,turnId:o.turnId}));break;case`text-delta`:await c.flush(),u.trim().length>0&&(await i(createReasoningCompletedEvent({reasoning:u,sequence:o.sequence,stepIndex:o.stepIndex,turnId:o.turnId})),u=``),d+=e.text,await i(createMessageAppendedEvent({messageDelta:e.text,messageSoFar:d,sequence:o.sequence,stepIndex:o.stepIndex,turnId:o.turnId}));break;case`tool-call`:{let t=e;m.add(t.toolCallId),t.providerExecuted===!0?await collectProviderToolCall(t):(await c.flush(),await emitToolCall(t));break}case`tool-result`:{let t=e;if(t.preliminary===!0)break;if(t.providerExecuted===!0){await collectProviderToolCall({input:`input`in t?t.input:void 0,toolCallId:t.toolCallId,toolName:t.toolName}),await c.flush(),await emitActionResult(createRuntimeToolResultFromStepResult(t));break}if(m.has(e.toolCallId)){if(isInlineAuthorizationToolResult(t))break;h.has(e.toolCallId)&&(await emitActionResult(createRuntimeToolResultFromStepResult(t)),v.add(e.toolCallId));break}if(await c.flush(),await flushCurrentMessage(),isInlineAuthorizationToolResult(t)){v.add(e.toolCallId),b.push(t);break}await emitActionResult(createRuntimeToolResultFromStepResult(t)),v.add(e.toolCallId);break}case`tool-error`:{let t=e;t.providerExecuted===!0?(await collectProviderToolCall(t),await c.flush(),await emitActionResult(createRuntimeToolResultFromToolError(t))):h.has(t.toolCallId)&&(await emitActionResult(createRuntimeToolResultFromToolError(t)),v.add(t.toolCallId),x.push(createToolResultMessagePartFromToolError(t)));break}case`finish-step`:f=normalizeAssistantStepFinishReason(e.finishReason),await c.flush();break;case`error`:p=normalizeModelStreamError(e.error);break;case`abort`:throw new DOMException(e.reason??`The model stream was aborted.`,`AbortError`);default:break}if(await c.flush(),p!==void 0)throw p;return u.trim().length>0&&await i(createReasoningCompletedEvent({reasoning:u,sequence:o.sequence,stepIndex:o.stepIndex,turnId:o.turnId})),f!==`tool-calls`&&hasEmptyDeliverySentinel(d)?await i(createMessageCompletedEvent({finishReason:f,message:null,sequence:o.sequence,stepIndex:o.stepIndex,turnId:o.turnId})):d.trim().length>0&&await i(createMessageCompletedEvent({finishReason:f,message:d,sequence:o.sequence,stepIndex:o.stepIndex,turnId:o.turnId})),{emittedActionCallIds:h,handledInlineToolResultCallIds:v,invalidInputToolCallIds:y,inlineAuthorizationResults:b,trailingInlineToolResultParts:x}}export{advanceStep,emitFailedStep,emitRecoverableFailedTurn,emitStepStarted,emitStreamContent,emitTurnEpilogue,emitTurnPreamble,getHarnessEmissionState,isHarnessBetweenTurns,normalizeAssistantStepFinishReason,setHarnessEmissionState};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{resolveTextToResponses}from"#channel/resolve-text.js";import{
|
|
1
|
+
import{resolveTextToResponses}from"#channel/resolve-text.js";import{resolveToolCallInputObject}from"#harness/runtime-actions.js";import{coalesceTurnInputs}from"#harness/messages.js";import{isSessionLimitContinuationRequest,resolveSessionLimitContinuation}from"#harness/session-limit-continuation.js";const PENDING_INPUT_BATCH_KEY=`eve.runtime.pendingInputBatch`,APPROVED_TOOLS_KEY=`eve.runtime.hitl.approvedTools`,DEFERRED_STEP_INPUT_KEY=`eve.runtime.deferredStepInput`,TOOL_EXECUTION_DENIED_MESSAGE=`Tool execution was denied.`;function hasStepInput(e){return e===void 0?!1:e.message!==void 0||(e.inputResponses?.length??0)>0}function consumeDeferredStepInput(e){let t=getDeferredStepInput(e.session);if(t===void 0)return e;let r=clearDeferredStepInput(e.session);return e.input===void 0?{input:t,session:r}:{input:coalesceTurnInputs(t,e.input),session:r}}function hasDeferredStepInput(e){return getDeferredStepInput(e)!==void 0}function resolvePendingInput(e){let{stepInput:t}=e,n=e.session,r=[...e.history??n.history],a=getPendingInputBatch(n.state);if(a===void 0)return{outcome:`continue`,messages:r,session:n};let o=resolveTextMessageInput(a,t),s=o?.inputResponses??[],c=a.requests.some(e=>isApprovalRequest(e));if(s.length===0&&o?.message===void 0)return{outcome:`unresolved`,messages:r,session:n};if(c&&hasUnansweredApproval({pendingBatch:a,responses:s}))return n=queueDeferredStepInput(n,compactStepInput(o)),{deferredMessage:!0,outcome:`unresolved`,messages:r,session:n};if(s.length===0&&o?.message!==void 0){let e=buildToolResponseParts(a,[]),t=[...r,...a.responseMessages];e.length>0&&t.push({content:e,role:`tool`});let i=buildRejectedActionBatch(a,[]);return n=clearPendingInputBatch(n),{consumedMessage:o?.messageConsumed,outcome:`resolved`,messages:t,rejectedActions:i,session:n}}let l=resolveSessionLimitContinuation({requests:a.requests,responses:s});n=recordApprovedTools({pendingBatch:a,resolveApprovalKey:e.resolveApprovalKey,responses:s,session:n});let u=buildToolResponseParts(a,s),d=[...r,...a.responseMessages];u.length>0&&d.push({content:u,role:`tool`});let f=buildRejectedActionBatch(a,s);if(n=clearPendingInputBatch(n),c){let e={};if((o?.context?.length??0)>0&&(e.context=o?.context),o?.message!==void 0&&(e.message=o.message),e.context!==void 0||e.message!==void 0)return n=queueDeferredStepInput(n,e),{consumedMessage:o?.messageConsumed,deferredContext:e.context===void 0?void 0:!0,deferredMessage:e.message===void 0?void 0:!0,limitContinuation:l,outcome:`resolved`,messages:d,rejectedActions:f,session:n}}return{consumedMessage:o?.messageConsumed,limitContinuation:l,outcome:`resolved`,messages:d,rejectedActions:f,session:n}}function resolveTextMessageInput(t,n){if(typeof n?.message!=`string`||(n.inputResponses?.length??0)>0)return n;let r=resolveTextToResponses(n.message,t.requests);return r.length===0?n:compactStepInput({...n,inputResponses:r,messageConsumed:!0,message:void 0})}function compactStepInput(e){if(e===void 0)return{};let t={};return(e.context?.length??0)>0&&(t.context=e.context),(e.inputResponses?.length??0)>0&&(t.inputResponses=e.inputResponses),e.message!==void 0&&(t.message=e.message),e.messageConsumed===!0&&(t.messageConsumed=!0),e.outputSchema!==void 0&&(t.outputSchema=e.outputSchema),t}function hasUnansweredApproval(e){let t=new Set(e.responses.map(e=>e.requestId));return e.pendingBatch.requests.some(e=>isApprovalRequest(e)&&!t.has(e.requestId))}function hasPendingInputBatch(e){return getPendingInputBatch(e)!==void 0}function getPendingInputRequestIds(e){return new Set(getPendingInputBatch(e)?.requests.map(e=>e.requestId))}function getPendingInputBatch(e){let t=e?.[PENDING_INPUT_BATCH_KEY];if(typeof t!=`object`||!t)return;let n=t;if(!(!Array.isArray(n.requests)||!Array.isArray(n.responseMessages)))return n}function setPendingInputBatch(e){let t={...e.session.state};return t[PENDING_INPUT_BATCH_KEY]={event:e.event,requests:[...e.requests],responseMessages:[...e.responseMessages]},{...e.session,state:t}}function clearPendingInputBatch(e){if(e.state?.[PENDING_INPUT_BATCH_KEY]===void 0)return e;let t={...e.state};return delete t[PENDING_INPUT_BATCH_KEY],{...e,state:Object.keys(t).length>0?t:void 0}}function getDeferredStepInput(e){return e.state?.[DEFERRED_STEP_INPUT_KEY]}function queueDeferredStepInput(e,t){let r=getDeferredStepInput(e),i=r===void 0?t:coalesceTurnInputs(r,t),a={...e.state};return a[DEFERRED_STEP_INPUT_KEY]=i,{...e,state:a}}function clearDeferredStepInput(e){if(e.state?.[DEFERRED_STEP_INPUT_KEY]===void 0)return e;let t={...e.state};return delete t[DEFERRED_STEP_INPUT_KEY],{...e,state:Object.keys(t).length>0?t:void 0}}function getApprovedTools(e){let t=e.state?.[APPROVED_TOOLS_KEY];return Array.isArray(t)?new Set(t):new Set}function recordApprovedTools(e){let t=new Set(e.responses.filter(e=>e.optionId===`approve`).map(e=>e.requestId)),n=e.pendingBatch.requests.filter(e=>t.has(e.requestId)).map(t=>e.resolveApprovalKey?.(t)??t.action.toolName);if(n.length===0)return e.session;let r=getApprovedTools(e.session),i=[...new Set([...r,...n])],a={...e.session.state};return a[APPROVED_TOOLS_KEY]=i,{...e.session,state:a}}function resolveApprovalOutcome(e){return e===void 0?{approved:!1,reason:`Ignored because the user continued without responding.`,status:`ignored`}:e.optionId===`approve`?{approved:!0,reason:void 0,status:`approved`}:e.optionId===`deny`?{approved:!1,reason:TOOL_EXECUTION_DENIED_MESSAGE,status:`denied`}:{approved:!1,reason:`Invalid approval response.`,status:`invalid`}}function buildRejectedActionBatch(e,t){if(e.event===void 0)return;let n=new Map(t.map(e=>[e.requestId,e])),r=[];for(let t of e.requests){if(!isApprovalRequest(t))continue;let{approved:e,reason:i,status:a}=resolveApprovalOutcome(n.get(t.requestId));e||r.push({callId:t.action.callId,isError:!0,kind:`tool-result`,output:{approval:{requestId:t.requestId,status:a},code:`TOOL_EXECUTION_DENIED`,message:i??TOOL_EXECUTION_DENIED_MESSAGE,tool:{result:`not_run`}},toolName:t.action.toolName})}return r.length>0?{event:e.event,results:r}:void 0}function buildToolResponseParts(e,t){let n=new Map(t.map(e=>[e.requestId,e])),r=[];for(let t of e.requests)r.push(...buildToolResponsePartsForRequest(t,n.get(t.requestId)));return r}function buildToolResponsePartsForRequest(e,t){if(isSessionLimitContinuationRequest(e))return[];if(isApprovalRequest(e)){let{approved:n,reason:r}=resolveApprovalOutcome(t),i=[{approvalId:e.requestId,approved:n,reason:r,type:`tool-approval-response`}];return n||i.push({output:{type:`execution-denied`,reason:r},toolCallId:e.action.callId,toolName:e.action.toolName,type:`tool-result`}),i}return[{output:{type:`json`,value:t===void 0?{status:`ignored`}:{optionId:t.optionId,text:t.text,status:`answered`}},toolCallId:e.action.callId,toolName:e.action.toolName,type:`tool-result`}]}function isApprovalRequest(e){return e.options?.length===2&&e.options[0]?.id===`approve`&&e.options[1]?.id===`deny`}function createRuntimeToolCallActionFromToolCall(e){return{callId:e.toolCall.toolCallId,input:resolveToolCallInputObject(e.toolCall.input,{callId:e.toolCall.toolCallId,toolName:e.toolCall.toolName}),kind:`tool-call`,toolName:e.toolCall.toolName}}export{consumeDeferredStepInput,createRuntimeToolCallActionFromToolCall,getApprovedTools,getPendingInputRequestIds,hasDeferredStepInput,hasPendingInputBatch,hasStepInput,isApprovalRequest,resolvePendingInput,setPendingInputBatch};
|
|
@@ -94,6 +94,10 @@ export declare function createRuntimeActionRequestFromToolCall(input: {
|
|
|
94
94
|
* Coerces an AI SDK tool-call `input` into the runtime-action `JsonObject`
|
|
95
95
|
* contract, throwing a `TypeError` (with the original as `cause`) that names
|
|
96
96
|
* the offending tool when the payload is not a JSON object.
|
|
97
|
+
*
|
|
98
|
+
* String inputs are parsed as JSON first: the model protocol carries tool
|
|
99
|
+
* arguments as text, and provider-executed tool calls can surface that raw
|
|
100
|
+
* string — or an empty string when the model sends no arguments.
|
|
97
101
|
*/
|
|
98
102
|
export declare function resolveToolCallInputObject(value: unknown, context: {
|
|
99
103
|
readonly callId: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createActionResultEvent}from"#protocol/message.js";import{parseJsonObject}from"#shared/json.js";import{clearProxyInputRequestsForChild}from"#harness/proxy-input-requests.js";import{accumulateSessionUsage,getTurnUsageState,setTurnUsageState}from"#harness/turn-tag-state.js";import{getRuntimeActionRequestKey,getRuntimeActionResultKey}from"#runtime/actions/keys.js";const PENDING_RUNTIME_ACTION_BATCH_KEY=`eve.runtime.pendingActionBatch`;function getPendingRuntimeActionBatch(e){let t=e?.[PENDING_RUNTIME_ACTION_BATCH_KEY];if(typeof t!=`object`||!t)return;let n=t;if(!(!Array.isArray(n.actions)||!Array.isArray(n.responseMessages)||typeof n.event!=`object`||n.event===null))return n}function hasPendingRuntimeActionBatch(e){return getPendingRuntimeActionBatch(e)!==void 0}function clearPendingRuntimeActionBatch(e){if(e.state?.[PENDING_RUNTIME_ACTION_BATCH_KEY]===void 0)return e;let t={...e.state};return delete t[PENDING_RUNTIME_ACTION_BATCH_KEY],{...e,state:Object.keys(t).length>0?t:void 0}}function setPendingRuntimeActionBatch(e){let t={...e.session.state};return t[PENDING_RUNTIME_ACTION_BATCH_KEY]={actions:[...e.actions],event:e.event,responseMessages:[...e.responseMessages]},{...e.session,state:t}}function recordPendingSubagentChild(e){let t=getPendingRuntimeActionBatch(e.session.state);if(t===void 0)return e.session;let n={...e.session.state};return n[PENDING_RUNTIME_ACTION_BATCH_KEY]={...t,...e.child.kind===`local`?{childContinuationTokens:{...t.childContinuationTokens,[e.callId]:e.child.continuationToken}}:{},childSessionIds:{...t.childSessionIds,[e.callId]:e.child.sessionId}},{...e.session,state:n}}function resolveReadyRuntimeActionResults(e){let t=getPendingRuntimeActionBatch(e.session.state);if(t!==void 0)return resolveRuntimeActionResultsForBatch({batch:t,results:e.results})}function resolveRuntimeActionResultsForBatch(e){return resolveRuntimeActionResultsForKeys({pendingKeys:e.batch.actions.map(e=>getRuntimeActionRequestKey(e)),results:e.results})}function resolveRuntimeActionResultsForKeys(e){let t=new Set(e.pendingKeys),n=new Map;for(let r of e.results){let e=getRuntimeActionResultKey(r);t.has(e)&&n.set(e,r)}let r=[];for(let t of e.pendingKeys){let e=n.get(t);if(e===void 0)return;r.push(e)}return r}async function resolvePendingRuntimeActions(t){let i=getPendingRuntimeActionBatch(t.session.state);if(i===void 0)return{messages:[...t.session.history],outcome:`continue`,session:t.session};let a=resolveReadyRuntimeActionResults({results:t.stepInput?.runtimeActionResults??[],session:t.session});if(a===void 0)return{messages:[...t.session.history],outcome:`unresolved`,session:t.session};if(t.emit!==void 0)for(let n of a)n.kind===`subagent-result`&&n.isError!==!0&&await t.emit({data:{callId:n.callId,output:typeof n.output==`string`?n.output:JSON.stringify(n.output),subagentName:n.subagentName},type:`subagent.completed`}),await t.emit(createActionResultEvent({result:n,sequence:i.event.sequence,stepIndex:i.event.stepIndex,turnId:i.event.turnId}));let o={...t.session.state};delete o[PENDING_RUNTIME_ACTION_BATCH_KEY];let s={...t.session,state:Object.keys(o).length>0?o:void 0},c=i.childContinuationTokens;if(c!==void 0)for(let e of a){if(e.kind!==`subagent-result`)continue;let t=c[e.callId];t!==void 0&&(s=clearProxyInputRequestsForChild(s,t))}for(let e of a)e.kind!==`subagent-result`||e.usage===void 0||(s=setTurnUsageState(s,accumulateSessionUsage({previous:getTurnUsageState(s.state),usage:e.usage})));let l=a.map(e=>{switch(e.kind){case`load-skill-result`:return{output:toToolResultOutput(e),toolCallId:e.callId,toolName:`load_skill`,type:`tool-result`};case`subagent-result`:return{output:toToolResultOutput(e),toolCallId:e.callId,toolName:e.subagentName,type:`tool-result`};case`tool-result`:return{output:toToolResultOutput(e),toolCallId:e.callId,toolName:e.toolName,type:`tool-result`}}throw Error(`Unsupported runtime action result kind "${String(e)}".`)}),u=[...s.history,...i.responseMessages];return l.length>0&&u.push({content:l,role:`tool`}),{messages:u,outcome:`resolved`,session:s}}function createRuntimeActionRequestFromToolCall(e){let t=e.tools.get(e.toolCall.toolName);return t?.runtimeAction?.kind===`subagent-call`?{callId:e.toolCall.toolCallId,description:t.description,input:resolveToolCallInputObject(e.toolCall.input,{callId:e.toolCall.toolCallId,toolName:e.toolCall.toolName}),kind:`subagent-call`,name:t.name,nodeId:t.runtimeAction.nodeId,subagentName:t.runtimeAction.subagentName}:t?.runtimeAction?.kind===`remote-agent-call`?{callId:e.toolCall.toolCallId,description:t.description,input:resolveToolCallInputObject(e.toolCall.input,{callId:e.toolCall.toolCallId,toolName:e.toolCall.toolName}),kind:`remote-agent-call`,name:t.name,nodeId:t.runtimeAction.nodeId,remoteAgentName:t.runtimeAction.remoteAgentName??t.name}:{callId:e.toolCall.toolCallId,input:resolveToolCallInputObject(e.toolCall.input,{callId:e.toolCall.toolCallId,toolName:e.toolCall.toolName}),kind:`tool-call`,toolName:e.toolCall.toolName}}function resolveToolCallInputObject(e,n){if(e==null)return{};try{return parseJsonObject(e)}catch(e){let t=e instanceof Error?e.message:String(e);throw TypeError(`Failed to parse tool-call arguments for "${n.toolName}" (${n.callId}): ${t}`,{cause:e})}}function toToolResultOutput(e){return typeof e.output==`string`?e.isError===!0?{type:`error-text`,value:e.output}:{type:`text`,value:e.output}:e.isError===!0?{type:`error-json`,value:toMutableJsonValue(e.output)}:{type:`json`,value:toMutableJsonValue(e.output)}}function toMutableJsonValue(e){if(e===null||typeof e==`string`||typeof e==`number`||typeof e==`boolean`)return e;if(Array.isArray(e))return e.map(e=>toMutableJsonValue(e));let t={};for(let[n,r]of Object.entries(e))t[n]=toMutableJsonValue(r);return t}export{clearPendingRuntimeActionBatch,createRuntimeActionRequestFromToolCall,getPendingRuntimeActionBatch,hasPendingRuntimeActionBatch,recordPendingSubagentChild,resolvePendingRuntimeActions,resolveRuntimeActionResultsForKeys,resolveToolCallInputObject,setPendingRuntimeActionBatch};
|
|
1
|
+
import{createActionResultEvent}from"#protocol/message.js";import{parseJsonObject}from"#shared/json.js";import{clearProxyInputRequestsForChild}from"#harness/proxy-input-requests.js";import{accumulateSessionUsage,getTurnUsageState,setTurnUsageState}from"#harness/turn-tag-state.js";import{getRuntimeActionRequestKey,getRuntimeActionResultKey}from"#runtime/actions/keys.js";const PENDING_RUNTIME_ACTION_BATCH_KEY=`eve.runtime.pendingActionBatch`;function getPendingRuntimeActionBatch(e){let t=e?.[PENDING_RUNTIME_ACTION_BATCH_KEY];if(typeof t!=`object`||!t)return;let n=t;if(!(!Array.isArray(n.actions)||!Array.isArray(n.responseMessages)||typeof n.event!=`object`||n.event===null))return n}function hasPendingRuntimeActionBatch(e){return getPendingRuntimeActionBatch(e)!==void 0}function clearPendingRuntimeActionBatch(e){if(e.state?.[PENDING_RUNTIME_ACTION_BATCH_KEY]===void 0)return e;let t={...e.state};return delete t[PENDING_RUNTIME_ACTION_BATCH_KEY],{...e,state:Object.keys(t).length>0?t:void 0}}function setPendingRuntimeActionBatch(e){let t={...e.session.state};return t[PENDING_RUNTIME_ACTION_BATCH_KEY]={actions:[...e.actions],event:e.event,responseMessages:[...e.responseMessages]},{...e.session,state:t}}function recordPendingSubagentChild(e){let t=getPendingRuntimeActionBatch(e.session.state);if(t===void 0)return e.session;let n={...e.session.state};return n[PENDING_RUNTIME_ACTION_BATCH_KEY]={...t,...e.child.kind===`local`?{childContinuationTokens:{...t.childContinuationTokens,[e.callId]:e.child.continuationToken}}:{},childSessionIds:{...t.childSessionIds,[e.callId]:e.child.sessionId}},{...e.session,state:n}}function resolveReadyRuntimeActionResults(e){let t=getPendingRuntimeActionBatch(e.session.state);if(t!==void 0)return resolveRuntimeActionResultsForBatch({batch:t,results:e.results})}function resolveRuntimeActionResultsForBatch(e){return resolveRuntimeActionResultsForKeys({pendingKeys:e.batch.actions.map(e=>getRuntimeActionRequestKey(e)),results:e.results})}function resolveRuntimeActionResultsForKeys(e){let t=new Set(e.pendingKeys),n=new Map;for(let r of e.results){let e=getRuntimeActionResultKey(r);t.has(e)&&n.set(e,r)}let r=[];for(let t of e.pendingKeys){let e=n.get(t);if(e===void 0)return;r.push(e)}return r}async function resolvePendingRuntimeActions(t){let i=getPendingRuntimeActionBatch(t.session.state);if(i===void 0)return{messages:[...t.session.history],outcome:`continue`,session:t.session};let a=resolveReadyRuntimeActionResults({results:t.stepInput?.runtimeActionResults??[],session:t.session});if(a===void 0)return{messages:[...t.session.history],outcome:`unresolved`,session:t.session};if(t.emit!==void 0)for(let n of a)n.kind===`subagent-result`&&n.isError!==!0&&await t.emit({data:{callId:n.callId,output:typeof n.output==`string`?n.output:JSON.stringify(n.output),subagentName:n.subagentName},type:`subagent.completed`}),await t.emit(createActionResultEvent({result:n,sequence:i.event.sequence,stepIndex:i.event.stepIndex,turnId:i.event.turnId}));let o={...t.session.state};delete o[PENDING_RUNTIME_ACTION_BATCH_KEY];let s={...t.session,state:Object.keys(o).length>0?o:void 0},c=i.childContinuationTokens;if(c!==void 0)for(let e of a){if(e.kind!==`subagent-result`)continue;let t=c[e.callId];t!==void 0&&(s=clearProxyInputRequestsForChild(s,t))}for(let e of a)e.kind!==`subagent-result`||e.usage===void 0||(s=setTurnUsageState(s,accumulateSessionUsage({previous:getTurnUsageState(s.state),usage:e.usage})));let l=a.map(e=>{switch(e.kind){case`load-skill-result`:return{output:toToolResultOutput(e),toolCallId:e.callId,toolName:`load_skill`,type:`tool-result`};case`subagent-result`:return{output:toToolResultOutput(e),toolCallId:e.callId,toolName:e.subagentName,type:`tool-result`};case`tool-result`:return{output:toToolResultOutput(e),toolCallId:e.callId,toolName:e.toolName,type:`tool-result`}}throw Error(`Unsupported runtime action result kind "${String(e)}".`)}),u=[...s.history,...i.responseMessages];return l.length>0&&u.push({content:l,role:`tool`}),{messages:u,outcome:`resolved`,session:s}}function createRuntimeActionRequestFromToolCall(e){let t=e.tools.get(e.toolCall.toolName);return t?.runtimeAction?.kind===`subagent-call`?{callId:e.toolCall.toolCallId,description:t.description,input:resolveToolCallInputObject(e.toolCall.input,{callId:e.toolCall.toolCallId,toolName:e.toolCall.toolName}),kind:`subagent-call`,name:t.name,nodeId:t.runtimeAction.nodeId,subagentName:t.runtimeAction.subagentName}:t?.runtimeAction?.kind===`remote-agent-call`?{callId:e.toolCall.toolCallId,description:t.description,input:resolveToolCallInputObject(e.toolCall.input,{callId:e.toolCall.toolCallId,toolName:e.toolCall.toolName}),kind:`remote-agent-call`,name:t.name,nodeId:t.runtimeAction.nodeId,remoteAgentName:t.runtimeAction.remoteAgentName??t.name}:{callId:e.toolCall.toolCallId,input:resolveToolCallInputObject(e.toolCall.input,{callId:e.toolCall.toolCallId,toolName:e.toolCall.toolName}),kind:`tool-call`,toolName:e.toolCall.toolName}}function resolveToolCallInputObject(e,n){if(e==null||typeof e==`string`&&e.trim()===``)return{};try{return parseJsonObject(typeof e==`string`?parseJsonStringInput(e):e)}catch(e){let t=e instanceof Error?e.message:String(e);throw TypeError(`Failed to parse tool-call arguments for "${n.toolName}" (${n.callId}): ${t}`,{cause:e})}}function parseJsonStringInput(e){try{return JSON.parse(e)}catch{return e}}function toToolResultOutput(e){return typeof e.output==`string`?e.isError===!0?{type:`error-text`,value:e.output}:{type:`text`,value:e.output}:e.isError===!0?{type:`error-json`,value:toMutableJsonValue(e.output)}:{type:`json`,value:toMutableJsonValue(e.output)}}function toMutableJsonValue(e){if(e===null||typeof e==`string`||typeof e==`number`||typeof e==`boolean`)return e;if(Array.isArray(e))return e.map(e=>toMutableJsonValue(e));let t={};for(let[n,r]of Object.entries(e))t[n]=toMutableJsonValue(r);return t}export{clearPendingRuntimeActionBatch,createRuntimeActionRequestFromToolCall,getPendingRuntimeActionBatch,hasPendingRuntimeActionBatch,recordPendingSubagentChild,resolvePendingRuntimeActions,resolveRuntimeActionResultsForKeys,resolveToolCallInputObject,setPendingRuntimeActionBatch};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { ToolSet, TypedToolCall, TypedToolError } from "ai";
|
|
2
|
+
import type { RuntimeToolCallActionRequest } from "#runtime/actions/types.js";
|
|
2
3
|
/**
|
|
3
4
|
* Returns true when the AI SDK marked the tool call `invalid` (typically
|
|
4
5
|
* because the model emitted unparsable JSON or targeted an unknown tool).
|
|
@@ -14,6 +15,25 @@ export declare function createInvalidToolCallInputError(input: {
|
|
|
14
15
|
readonly error: unknown;
|
|
15
16
|
readonly toolCall: TypedToolCall<ToolSet>;
|
|
16
17
|
}): TypedToolError<ToolSet>;
|
|
18
|
+
/**
|
|
19
|
+
* Resolves a provider-executed tool call into an observable runtime-action
|
|
20
|
+
* request, or the synthesized tool error when the model emitted arguments
|
|
21
|
+
* that cannot satisfy the JSON-object contract.
|
|
22
|
+
*
|
|
23
|
+
* Provider-executed calls skip the AI SDK's input validation, so malformed
|
|
24
|
+
* JSON argument text reaches the harness only here.
|
|
25
|
+
*/
|
|
26
|
+
export declare function resolveProviderToolCallRequest(toolCall: {
|
|
27
|
+
readonly input?: unknown;
|
|
28
|
+
readonly toolCallId: string;
|
|
29
|
+
readonly toolName: string;
|
|
30
|
+
}): {
|
|
31
|
+
readonly request: RuntimeToolCallActionRequest;
|
|
32
|
+
readonly toolError?: undefined;
|
|
33
|
+
} | {
|
|
34
|
+
readonly request?: undefined;
|
|
35
|
+
readonly toolError: TypedToolError<ToolSet>;
|
|
36
|
+
};
|
|
17
37
|
export declare function getInvalidToolCallInputError(input: {
|
|
18
38
|
readonly toolCall: TypedToolCall<ToolSet>;
|
|
19
39
|
}): TypedToolError<ToolSet> | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{resolveToolCallInputObject}from"#harness/runtime-actions.js";function isInvalidToolCall(e){return e.invalid===!0}function createInvalidToolCallInputError(e){let{toolCall:t}=e,n={type:`tool-error`,toolCallId:t.toolCallId,toolName:t.toolName,input:t.input,error:e.error};return t.dynamic===!0&&(n.dynamic=!0),t.providerExecuted===!0&&(n.providerExecuted=!0),t.providerMetadata!==void 0&&(n.providerMetadata=t.providerMetadata),t.toolMetadata!==void 0&&(n.toolMetadata=t.toolMetadata),n}function getInvalidToolCallInputError(t){let{toolCall:n}=t;if(!isInvalidToolCall(n))try{resolveToolCallInputObject(n.input,{callId:n.toolCallId,toolName:n.toolName});return}catch(e){if(e instanceof TypeError)return createInvalidToolCallInputError({error:e,toolCall:n});throw e}}export{createInvalidToolCallInputError,getInvalidToolCallInputError,isInvalidToolCall};
|
|
1
|
+
import{resolveToolCallInputObject}from"#harness/runtime-actions.js";function isInvalidToolCall(e){return e.invalid===!0}function createInvalidToolCallInputError(e){let{toolCall:t}=e,n={type:`tool-error`,toolCallId:t.toolCallId,toolName:t.toolName,input:t.input,error:e.error};return t.dynamic===!0&&(n.dynamic=!0),t.providerExecuted===!0&&(n.providerExecuted=!0),t.providerMetadata!==void 0&&(n.providerMetadata=t.providerMetadata),t.toolMetadata!==void 0&&(n.toolMetadata=t.toolMetadata),n}function resolveProviderToolCallRequest(t){try{return{request:{callId:t.toolCallId,input:resolveToolCallInputObject(t.input,{callId:t.toolCallId,toolName:t.toolName}),kind:`tool-call`,toolName:t.toolName}}}catch(e){if(!(e instanceof TypeError))throw e;return{toolError:createInvalidToolCallInputError({error:e,toolCall:{input:t.input,providerExecuted:!0,toolCallId:t.toolCallId,toolName:t.toolName,type:`tool-call`}})}}}function getInvalidToolCallInputError(t){let{toolCall:n}=t;if(!isInvalidToolCall(n))try{resolveToolCallInputObject(n.input,{callId:n.toolCallId,toolName:n.toolName});return}catch(e){if(e instanceof TypeError)return createInvalidToolCallInputError({error:e,toolCall:n});throw e}}export{createInvalidToolCallInputError,getInvalidToolCallInputError,isInvalidToolCall,resolveProviderToolCallRequest};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{join,resolve}from"node:path";import{mkdir,rm}from"node:fs/promises";import{resolveOutputDirectory}from"#internal/application/paths.js";import{randomUUID}from"node:crypto";import{VERCEL_EVE_AGENT_SUMMARY_OUTPUT_PATH}from"#internal/vercel-agent-summary.js";async function createApplicationBuildWorkspace(t,n){let r=resolve(t),i=join(r,`.eve`,`builds`,`${Date.now().toString(36)}-${randomUUID()}`),a=join(i,`compiler`),o={appRoot:r,compiler:{artifactsDir:join(a,`.eve`),rootDir:a},host:{artifactsDir:join(i,`host`)},nitro:{buildDir:join(i,`nitro`)
|
|
1
|
+
import{join,resolve}from"node:path";import{mkdir,rm}from"node:fs/promises";import{resolveOutputDirectory}from"#internal/application/paths.js";import{randomUUID}from"node:crypto";import{VERCEL_EVE_AGENT_SUMMARY_OUTPUT_PATH}from"#internal/vercel-agent-summary.js";async function createApplicationBuildWorkspace(t,n){let r=resolve(t),i=join(r,`.eve`,`builds`,`${Date.now().toString(36)}-${randomUUID()}`),a=join(i,`compiler`),o={appRoot:r,compiler:{artifactsDir:join(a,`.eve`),rootDir:a},host:{artifactsDir:join(i,`host`)},nitro:{buildDir:join(i,`nitro`)},publication:{output:{finalDir:n??resolveOutputDirectory(r),stagedDir:join(i,`output`)},summary:{finalPath:join(r,VERCEL_EVE_AGENT_SUMMARY_OUTPUT_PATH),stagedPath:join(i,`agent-summary.json`)}},rootDir:i,workflow:{buildDir:join(i,`workflow`)}};return await mkdir(i,{recursive:!0}),o}async function removeApplicationBuildWorkspace(e){await rm(e.rootDir,{force:!0,recursive:!0})}export{createApplicationBuildWorkspace,removeApplicationBuildWorkspace};
|