eve 0.30.8 → 0.31.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +29 -0
- package/README.md +5 -6
- package/dist/src/acp/adapter.d.ts +10 -4
- package/dist/src/acp/adapter.js +1 -1
- package/dist/src/channel/adapter-context.d.ts +1 -1
- package/dist/src/channel/adapter.d.ts +2 -4
- package/dist/src/channel/adapter.js +1 -1
- package/dist/src/channel/channel-address.d.ts +58 -0
- package/dist/src/channel/channel-address.js +1 -0
- package/dist/src/channel/channel-operations.d.ts +72 -0
- package/dist/src/channel/channel-operations.js +1 -0
- package/dist/src/channel/compiled-channel.d.ts +10 -6
- package/dist/src/channel/cross-channel-receive.d.ts +13 -25
- package/dist/src/channel/cross-channel-receive.js +2 -2
- package/dist/src/channel/receive-target.d.ts +1 -2
- package/dist/src/channel/routes.d.ts +21 -149
- package/dist/src/channel/schedule.d.ts +1 -1
- package/dist/src/channel/schedule.js +1 -1
- package/dist/src/channel/send-input.d.ts +6 -0
- package/dist/src/channel/send-input.js +1 -0
- package/dist/src/channel/session.d.ts +44 -30
- package/dist/src/channel/session.js +1 -1
- package/dist/src/channel/types.d.ts +8 -35
- package/dist/src/chunks/{use-eve-agent-DDoDDmJ2.js → use-eve-agent-CF5D6jSV.js} +339 -367
- package/dist/src/chunks/{use-eve-agent-Bx-ONuyb.js → use-eve-agent-DbYZLG0h.js} +342 -368
- package/dist/src/cli/commands/agent-prompt/build-and-verify.md +1 -2
- package/dist/src/cli/commands/channel-add-conflicts.js +1 -1
- package/dist/src/cli/commands/info.d.ts +1 -1
- package/dist/src/cli/commands/info.js +1 -1
- package/dist/src/cli/dev/tui/runner.d.ts +1 -1
- package/dist/src/cli/dev/tui/runner.js +1 -1
- package/dist/src/cli/dev/tui/subagent-pump.js +1 -1
- package/dist/src/cli/dev/tui/tui.js +1 -1
- package/dist/src/cli/invoke/invoke.d.ts +1 -1
- package/dist/src/cli/invoke/invoke.js +1 -1
- package/dist/src/cli/invoke/result.d.ts +0 -11
- package/dist/src/cli/invoke/result.js +1 -1
- package/dist/src/client/client-error.d.ts +2 -0
- package/dist/src/client/client-error.js +1 -1
- package/dist/src/client/client.d.ts +7 -14
- package/dist/src/client/client.js +1 -1
- package/dist/src/client/eve-agent-store.d.ts +4 -4
- package/dist/src/client/eve-agent-store.js +1 -1
- package/dist/src/client/index.d.ts +2 -1
- package/dist/src/client/index.js +1 -1
- package/dist/src/client/message-response.d.ts +2 -7
- package/dist/src/client/message-response.js +1 -1
- package/dist/src/client/open-stream.js +1 -1
- package/dist/src/client/session-controls.d.ts +29 -0
- package/dist/src/client/session-controls.js +1 -0
- package/dist/src/client/session-utils.d.ts +0 -20
- package/dist/src/client/session-utils.js +1 -1
- package/dist/src/client/session.d.ts +26 -90
- package/dist/src/client/session.js +1 -1
- package/dist/src/client/sessions.d.ts +20 -0
- package/dist/src/client/sessions.js +1 -0
- package/dist/src/client/types.d.ts +26 -47
- package/dist/src/compiler/normalize-subagent.js +1 -1
- package/dist/src/evals/cli/eval-client.js +1 -1
- package/dist/src/evals/context.js +1 -1
- package/dist/src/evals/session.d.ts +7 -6
- package/dist/src/evals/session.js +1 -1
- package/dist/src/evals/types.d.ts +9 -9
- package/dist/src/execution/agent-handle-dispatch.js +1 -1
- package/dist/src/execution/cancel-descendant-turns-step.js +1 -1
- package/dist/src/execution/dispatch-runtime-actions-step.js +1 -1
- package/dist/src/execution/remote-agent-dispatch.d.ts +1 -3
- package/dist/src/execution/remote-agent-dispatch.js +1 -1
- package/dist/src/execution/runtime-context.js +1 -1
- package/dist/src/execution/runtime-errors.d.ts +1 -1
- package/dist/src/execution/session-command-token.d.ts +2 -0
- package/dist/src/execution/session-command-token.js +1 -1
- package/dist/src/execution/settle-cancelled-turn-step.js +1 -1
- package/dist/src/execution/subagent-hitl-proxy.js +1 -1
- package/dist/src/execution/turn-control-receiver.d.ts +2 -2
- package/dist/src/execution/turn-workflow.js +1 -1
- package/dist/src/execution/workflow-entry.js +1 -1
- package/dist/src/execution/workflow-runtime.js +1 -1
- package/dist/src/harness/cancelled-turn-emission.d.ts +1 -1
- package/dist/src/harness/cancelled-turn-emission.js +1 -1
- package/dist/src/harness/emission.d.ts +1 -1
- package/dist/src/harness/emission.js +1 -1
- package/dist/src/harness/handles/prompt.d.ts +22 -3
- package/dist/src/harness/handles/prompt.js +1 -1
- package/dist/src/harness/handles/store.d.ts +0 -5
- package/dist/src/harness/handles/store.js +1 -1
- package/dist/src/harness/runtime-actions.js +1 -1
- package/dist/src/harness/session-limit-enforcement.js +1 -1
- package/dist/src/harness/tool-loop.js +1 -1
- package/dist/src/internal/application/package.js +1 -1
- package/dist/src/internal/nitro/dev-runtime-artifacts.js +1 -1
- package/dist/src/internal/nitro/dev-runtime-source-snapshot-copy.js +1 -1
- package/dist/src/internal/nitro/dev-runtime-source-snapshot-local-roots.d.ts +15 -0
- package/dist/src/internal/nitro/dev-runtime-source-snapshot-local-roots.js +1 -0
- package/dist/src/internal/nitro/dev-runtime-source-snapshot.d.ts +14 -2
- package/dist/src/internal/nitro/dev-runtime-source-snapshot.js +1 -1
- package/dist/src/internal/nitro/host/dev-server-http.js +1 -1
- package/dist/src/internal/nitro/routes/channel-dispatch.d.ts +2 -5
- package/dist/src/internal/nitro/routes/channel-dispatch.js +1 -1
- package/dist/src/internal/nitro/routes/channel-route-context.d.ts +4 -3
- package/dist/src/internal/nitro/routes/channel-route-context.js +1 -1
- package/dist/src/packages/eve-catalog/src/index.js +1 -1
- package/dist/src/protocol/cancel-turn.d.ts +9 -4
- package/dist/src/protocol/cancel-turn.js +1 -1
- package/dist/src/protocol/message.d.ts +4 -14
- package/dist/src/protocol/message.js +2 -2
- package/dist/src/protocol/reset-session.d.ts +1 -1
- package/dist/src/protocol/routes.d.ts +27 -47
- package/dist/src/protocol/routes.js +1 -1
- package/dist/src/public/channels/chat-sdk/chatSdkChannel.d.ts +19 -21
- package/dist/src/public/channels/chat-sdk/chatSdkChannel.js +2 -2
- package/dist/src/public/channels/discord/discordChannel.d.ts +4 -4
- package/dist/src/public/channels/discord/discordChannel.js +1 -1
- package/dist/src/public/channels/eve.d.ts +11 -10
- package/dist/src/public/channels/eve.js +1 -1
- package/dist/src/public/channels/github/dispatch.d.ts +8 -8
- package/dist/src/public/channels/github/dispatch.js +1 -1
- package/dist/src/public/channels/github/githubChannel.d.ts +3 -3
- package/dist/src/public/channels/github/githubChannel.js +1 -1
- package/dist/src/public/channels/github/pr-context.d.ts +1 -1
- package/dist/src/public/channels/index.d.ts +1 -1
- package/dist/src/public/channels/linear/linearChannel.d.ts +3 -3
- package/dist/src/public/channels/linear/linearChannel.js +1 -1
- package/dist/src/public/channels/slack/index.d.ts +1 -1
- package/dist/src/public/channels/slack/interactions.d.ts +3 -4
- package/dist/src/public/channels/slack/interactions.js +1 -1
- package/dist/src/public/channels/slack/session-operations.d.ts +37 -0
- package/dist/src/public/channels/slack/session-operations.js +1 -0
- package/dist/src/public/channels/slack/slackChannel.d.ts +55 -74
- package/dist/src/public/channels/slack/slackChannel.js +1 -1
- package/dist/src/public/channels/teams/teamsChannel.d.ts +3 -3
- package/dist/src/public/channels/teams/teamsChannel.js +1 -1
- package/dist/src/public/channels/telegram/telegramChannel.d.ts +4 -4
- package/dist/src/public/channels/telegram/telegramChannel.js +1 -1
- package/dist/src/public/channels/twilio/twilioChannel.d.ts +3 -3
- package/dist/src/public/channels/twilio/twilioChannel.js +1 -1
- package/dist/src/public/definitions/callback-context.d.ts +1 -2
- package/dist/src/public/definitions/channel.d.ts +21 -86
- package/dist/src/public/definitions/channel.js +1 -1
- package/dist/src/public/definitions/remote-agent.js +1 -1
- package/dist/src/public/definitions/schedule.d.ts +16 -16
- package/dist/src/public/schedules/index.d.ts +1 -1
- package/dist/src/react/use-eve-agent.d.ts +7 -4
- package/dist/src/react/use-eve-agent.js +1 -1
- package/dist/src/runtime/agent/bootstrap-model-utils.d.ts +11 -0
- package/dist/src/runtime/agent/bootstrap-model-utils.js +1 -1
- package/dist/src/runtime/agent/mock-model-adapter.js +1 -1
- package/dist/src/runtime/agent/mock-model-fixtures.js +2 -2
- package/dist/src/runtime/prompt/compose.js +1 -1
- package/dist/src/runtime/subagents/dynamic-remote-agent-config.js +1 -1
- package/dist/src/runtime/types.d.ts +2 -2
- package/dist/src/services/inspect-application.d.ts +1 -1
- package/dist/src/services/inspect-application.js +1 -1
- package/dist/src/setup/channel-add-conflicts.js +1 -1
- package/dist/src/setup/scaffold/create/project.js +1 -1
- package/dist/src/setup/scaffold/create/web-template.d.ts +1 -1
- package/dist/src/setup/scaffold/create/web-template.js +29 -17
- package/dist/src/shared/channel-definition.d.ts +7 -7
- package/dist/src/shared/schedule-definition.d.ts +2 -2
- package/dist/src/svelte/index.js +1 -1
- package/dist/src/svelte/use-eve-agent.d.ts +8 -5
- package/dist/src/svelte/use-eve-agent.js +1 -1
- package/dist/src/vue/index.js +1 -1
- package/dist/src/vue/use-eve-agent.d.ts +8 -5
- package/dist/src/vue/use-eve-agent.js +1 -1
- package/docs/README.md +6 -6
- package/docs/channels/chat-sdk.mdx +5 -6
- package/docs/channels/custom.mdx +116 -144
- package/docs/channels/discord.mdx +1 -1
- package/docs/channels/eve.mdx +76 -30
- package/docs/channels/github.mdx +1 -1
- package/docs/channels/linear.mdx +6 -8
- package/docs/channels/overview.mdx +2 -2
- package/docs/channels/slack.mdx +46 -15
- package/docs/channels/telegram.mdx +1 -1
- package/docs/channels/twilio.mdx +1 -1
- package/docs/concepts/default-harness.md +11 -3
- package/docs/concepts/execution-model-and-durability.mdx +17 -5
- package/docs/concepts/sessions-runs-and-streaming.md +42 -16
- package/docs/evals/cases.mdx +3 -3
- package/docs/evals/targets.mdx +1 -1
- package/docs/guides/auth-and-route-protection.md +2 -1
- package/docs/guides/client/continuations.mdx +50 -77
- package/docs/guides/client/messages.mdx +29 -33
- package/docs/guides/client/output-schema.mdx +7 -14
- package/docs/guides/client/overview.mdx +40 -11
- package/docs/guides/client/streaming.mdx +17 -23
- package/docs/guides/frontend/nuxt.mdx +1 -1
- package/docs/guides/frontend/overview.mdx +40 -36
- package/docs/guides/frontend/sveltekit.mdx +1 -1
- package/docs/guides/frontend/use-eve-agent-svelte.mdx +19 -23
- package/docs/guides/frontend/use-eve-agent-vue.mdx +21 -25
- package/docs/guides/instrumentation.md +1 -1
- package/docs/patterns/dynamic-scheduling.md +16 -15
- package/docs/schedules.mdx +10 -11
- package/docs/subagents.mdx +1 -1
- package/docs/tools/human-in-the-loop.md +1 -1
- package/docs/tutorial/ship-it.mdx +1 -1
- package/package.json +1 -1
- package/dist/src/channel/cancel.d.ts +0 -6
- package/dist/src/channel/cancel.js +0 -1
- package/dist/src/channel/clear-session.d.ts +0 -4
- package/dist/src/channel/clear-session.js +0 -1
- package/dist/src/channel/compact-session.d.ts +0 -4
- package/dist/src/channel/compact-session.js +0 -1
- package/dist/src/channel/reset-session.d.ts +0 -6
- package/dist/src/channel/reset-session.js +0 -1
- package/dist/src/channel/resolve-active-session.d.ts +0 -4
- package/dist/src/channel/resolve-active-session.js +0 -1
- package/dist/src/channel/send.d.ts +0 -6
- package/dist/src/channel/send.js +0 -1
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { CancelSessionResult, ClearResult, ClientRedirectPolicy, CompactResult, ResetResult } from "#client/types.js";
|
|
2
|
+
interface SessionControlContext {
|
|
3
|
+
readonly host: string;
|
|
4
|
+
readonly redirect?: ClientRedirectPolicy;
|
|
5
|
+
resolveHeaders(): Promise<Headers>;
|
|
6
|
+
}
|
|
7
|
+
export declare function cancelClientSession(input: {
|
|
8
|
+
readonly context: SessionControlContext;
|
|
9
|
+
readonly options?: {
|
|
10
|
+
readonly turnId?: string;
|
|
11
|
+
};
|
|
12
|
+
readonly sessionId: string;
|
|
13
|
+
}): Promise<CancelSessionResult>;
|
|
14
|
+
export declare function clearClientSession(input: {
|
|
15
|
+
readonly context: SessionControlContext;
|
|
16
|
+
readonly sessionId: string;
|
|
17
|
+
}): Promise<ClearResult>;
|
|
18
|
+
export declare function compactClientSession(input: {
|
|
19
|
+
readonly context: SessionControlContext;
|
|
20
|
+
readonly sessionId: string;
|
|
21
|
+
}): Promise<CompactResult>;
|
|
22
|
+
export declare function resetClientSession(input: {
|
|
23
|
+
readonly context: SessionControlContext;
|
|
24
|
+
readonly options?: {
|
|
25
|
+
readonly reason?: string;
|
|
26
|
+
};
|
|
27
|
+
readonly sessionId: string;
|
|
28
|
+
}): Promise<ResetResult>;
|
|
29
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{createEveSessionCancelRoutePath,createEveSessionClearRoutePath,createEveSessionCompactRoutePath,createEveSessionResetRoutePath}from"#protocol/routes.js";import{ClientError}from"#client/client-error.js";import{createClientUrl}from"#client/url.js";import{CancelTurnResponseSchema}from"#protocol/cancel-turn.js";import{ClearResponseSchema}from"#protocol/clear-session.js";import{CompactResponseSchema}from"#protocol/compact-session.js";import{ResetResponseSchema}from"#protocol/reset-session.js";async function cancelClientSession(t){let{payload:n,response:r}=await postJson({body:t.options,context:t.context,operation:`Cancel`,path:createEveSessionCancelRoutePath(t.sessionId)}),i=CancelTurnResponseSchema.safeParse(n);if(!i.success||i.data.status===`accepted`&&i.data.sessionId!==t.sessionId)throw Error(`Cancel route returned an invalid response (${r.status}).`);return i.data.status===`accepted`?{sessionId:i.data.sessionId,status:`accepted`}:{status:`no_active_turn`}}async function clearClientSession(e){let{payload:n}=await postJson({context:e.context,operation:`Clear`,path:createEveSessionClearRoutePath(e.sessionId)}),r=ClearResponseSchema.safeParse(n);if(!r.success||r.data.status===`accepted`&&r.data.sessionId!==e.sessionId)throw Error(`Clear route returned an invalid response.`);return r.data.status===`accepted`?{sessionId:r.data.sessionId,status:`accepted`}:{status:`no_active_session`}}async function compactClientSession(e){let{payload:t}=await postJson({context:e.context,operation:`Compact`,path:createEveSessionCompactRoutePath(e.sessionId)}),r=CompactResponseSchema.safeParse(t);if(!r.success||r.data.status===`accepted`&&r.data.sessionId!==e.sessionId)throw Error(`Compact route returned an invalid response.`);return r.data.status===`accepted`?{sessionId:r.data.sessionId,status:`accepted`}:{status:`no_active_session`}}async function resetClientSession(e){let{payload:t}=await postJson({body:e.options,context:e.context,operation:`Reset`,path:createEveSessionResetRoutePath(e.sessionId)}),n=ResetResponseSchema.safeParse(t);if(!n.success||n.data.status===`reset`&&n.data.previousSessionId!==e.sessionId)throw Error(`Reset route returned an invalid response.`);return n.data.status===`reset`?{previousSessionId:n.data.previousSessionId,status:`reset`}:{status:`no_active_session`}}async function postJson(e){let t=await e.context.resolveHeaders();t.set(`content-type`,`application/json`);let n=await fetch(createClientUrl(e.context.host,e.path),withRedirectPolicy({body:e.body===void 0?void 0:JSON.stringify(e.body),headers:t,method:`POST`},e.context.redirect)),r=await n.text();if(!n.ok)throw new ClientError(n.status,r,n.headers);try{return{payload:JSON.parse(r),response:n}}catch{throw Error(`${e.operation} route returned invalid JSON (${n.status}).`)}}function withRedirectPolicy(e,t){return t===void 0?e:{...e,redirect:t}}export{cancelClientSession,clearClientSession,compactClientSession,resetClientSession};
|
|
@@ -1,25 +1,5 @@
|
|
|
1
1
|
import type { AuthorizationRequiredStreamEvent, TurnFailureStreamEvent, UnstampedMessageStreamEvent } from "#protocol/message.js";
|
|
2
|
-
import type { SessionState } from "#client/types.js";
|
|
3
2
|
import type { InputRequest } from "#runtime/input/types.js";
|
|
4
|
-
/**
|
|
5
|
-
* Returns a fresh session state with no active run.
|
|
6
|
-
*/
|
|
7
|
-
export declare function createInitialSessionState(): SessionState;
|
|
8
|
-
/**
|
|
9
|
-
* Advances the session cursor after one streamed turn completes.
|
|
10
|
-
*
|
|
11
|
-
* When the boundary event is `session.waiting`, the session is preserved for
|
|
12
|
-
* the next message. For `session.completed` and `session.failed`, the session
|
|
13
|
-
* resets so the next call starts a new conversation. Without a boundary, the
|
|
14
|
-
* session stays resumable from its advanced cursor.
|
|
15
|
-
*/
|
|
16
|
-
export declare function advanceSession(input: {
|
|
17
|
-
readonly continuationToken?: string;
|
|
18
|
-
readonly events: readonly UnstampedMessageStreamEvent[];
|
|
19
|
-
readonly preserveCompletedSessions?: boolean;
|
|
20
|
-
readonly sessionId: string;
|
|
21
|
-
readonly session: SessionState;
|
|
22
|
-
}): SessionState;
|
|
23
3
|
/** A connection authorization challenge that remains unresolved at a turn boundary. */
|
|
24
4
|
export interface PendingAuthorization {
|
|
25
5
|
readonly authorization?: AuthorizationRequiredStreamEvent["data"]["authorization"];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{isCurrentTurnBoundaryEvent,isTurnFailureEvent}from"#protocol/message.js";function
|
|
1
|
+
import{isCurrentTurnBoundaryEvent,isTurnFailureEvent}from"#protocol/message.js";function summarizeTurnEvents(n){let r,i,a,o=[],s=new Map;for(let c of n)isCurrentTurnBoundaryEvent(c)&&(r=c),isTurnFailureEvent(c)&&(i=c),isFinalMessageCompleted(c)&&(a=c.data.message??void 0),c.type===`input.requested`&&o.push(...c.data.requests),c.type===`authorization.required`&&s.set(c.data.name,c.data),c.type===`authorization.completed`&&s.delete(c.data.name);return{boundary:r,failure:i,inputRequests:o,message:a,pendingAuthorizations:[...s.values()],status:r?.type===`session.waiting`?`waiting`:r?.type===`session.failed`?`failed`:`completed`}}async function collectTurnEvents(t){let n=[];for await(let r of t)if(n.push(r),isCurrentTurnBoundaryEvent(r))break;return n}function isFinalMessageCompleted(e){return e.type===`message.completed`&&e.data.finishReason!==`tool-calls`}export{collectTurnEvents,summarizeTurnEvents};
|
|
@@ -1,112 +1,48 @@
|
|
|
1
1
|
import type { MessageStreamEvent } from "#protocol/message.js";
|
|
2
2
|
import { MessageResponse } from "#client/message-response.js";
|
|
3
|
-
import type {
|
|
3
|
+
import type { InputResponse } from "#runtime/input/types.js";
|
|
4
|
+
import type { CancelSessionResult, ClearResult, ClientSessionState, CompactResult, ClientRedirectPolicy, RespondTurnOptions, ResetResult, SendTurnInput, SendTurnOptions, SessionSnapshot, StreamOptions } from "#client/types.js";
|
|
4
5
|
/**
|
|
5
6
|
* Internal interface that a {@link ClientSession} uses to access client-level
|
|
6
7
|
* configuration without depending on the full {@link Client} class.
|
|
7
8
|
*/
|
|
8
|
-
interface
|
|
9
|
+
export interface ClientSessionContext {
|
|
9
10
|
readonly host: string;
|
|
10
|
-
readonly preserveCompletedSessions: boolean;
|
|
11
11
|
readonly redirect?: ClientRedirectPolicy;
|
|
12
12
|
resolveHeaders(perRequest?: Readonly<Record<string, string>>): Promise<Headers>;
|
|
13
13
|
}
|
|
14
|
-
/**
|
|
15
|
-
* One conversation with an eve agent.
|
|
16
|
-
*
|
|
17
|
-
* A session tracks conversation state (continuation token, session ID, stream
|
|
18
|
-
* cursor) automatically across {@link send} calls. Read the state from
|
|
19
|
-
* the {@link state} getter and serialize it to persist a session.
|
|
20
|
-
*/
|
|
14
|
+
/** One fixed, ID-addressed conversation with an eve agent. */
|
|
21
15
|
export declare class ClientSession {
|
|
22
16
|
#private;
|
|
23
17
|
/** @internal */
|
|
24
|
-
constructor(context:
|
|
25
|
-
/**
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
*
|
|
34
|
-
* The read starts at the beginning of the session and stops at the durable
|
|
35
|
-
* tail observed when it opens. The returned cursor points exactly after the
|
|
36
|
-
* returned events, so it can hydrate a UI and resume without a gap.
|
|
37
|
-
* Reading a snapshot does not advance or reset this handle's state.
|
|
38
|
-
*
|
|
39
|
-
* @throws {Error} If the session has no session ID (no message has been sent
|
|
40
|
-
* yet).
|
|
41
|
-
*/
|
|
18
|
+
constructor(context: ClientSessionContext, state: ClientSessionState);
|
|
19
|
+
/** @internal */
|
|
20
|
+
static create<TOutput = unknown>(context: ClientSessionContext, input: SendTurnInput<TOutput>): Promise<{
|
|
21
|
+
readonly response: MessageResponse<TOutput>;
|
|
22
|
+
readonly session: ClientSession;
|
|
23
|
+
}>;
|
|
24
|
+
/** Current fixed session identity and durable stream cursor. */
|
|
25
|
+
get state(): ClientSessionState;
|
|
26
|
+
/** Reads a finite prefix through the durable tail without advancing this handle. */
|
|
42
27
|
snapshot(options?: {
|
|
43
28
|
readonly signal?: AbortSignal;
|
|
44
29
|
}): Promise<SessionSnapshot>;
|
|
45
|
-
/**
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
* headers in a single request.
|
|
51
|
-
*/
|
|
52
|
-
send<TOutput = unknown>(input: SendTurnInput<TOutput>): Promise<MessageResponse<TOutput>>;
|
|
53
|
-
/**
|
|
54
|
-
* Requests cooperative cancellation of this session's active turn.
|
|
55
|
-
*
|
|
56
|
-
* Both `accepted` and `no_active_turn` are successful outcomes. The latter
|
|
57
|
-
* means the active turn settled before the request arrived or the session is
|
|
58
|
-
* already parked. `turnId` limits the request to the turn the caller
|
|
59
|
-
* observed; a stale guard is consumed as a benign no-op. Credentials are
|
|
60
|
-
* resolved immediately before the request.
|
|
61
|
-
*
|
|
62
|
-
* @throws {Error} If this handle has not started or attached to a session.
|
|
63
|
-
* @throws {ClientError} If the cancel route returns a non-successful status.
|
|
64
|
-
*/
|
|
30
|
+
/** Sends a message to this exact session ID. */
|
|
31
|
+
send<TOutput = unknown>(message: SendTurnInput<TOutput>["message"], options?: SendTurnOptions<TOutput>): Promise<MessageResponse<TOutput>>;
|
|
32
|
+
/** Answers pending input requests on this exact session ID. */
|
|
33
|
+
respond<TOutput = unknown>(inputResponses: readonly InputResponse[], options?: RespondTurnOptions<TOutput>): Promise<MessageResponse<TOutput>>;
|
|
34
|
+
/** Requests cooperative cancellation of this session's active turn. */
|
|
65
35
|
cancel(options?: {
|
|
66
|
-
turnId?: string;
|
|
36
|
+
readonly turnId?: string;
|
|
67
37
|
}): Promise<CancelSessionResult>;
|
|
68
|
-
/**
|
|
69
|
-
* Queues removal of this session's durable model-message history. The
|
|
70
|
-
* session identity, agent configuration, state, limits, and sandbox remain.
|
|
71
|
-
* Consume the durable stream through `context.cleared` and its following
|
|
72
|
-
* `session.waiting` boundary before sending another turn.
|
|
73
|
-
*/
|
|
38
|
+
/** Queues removal of this session's durable model-message history. */
|
|
74
39
|
clear(): Promise<ClearResult>;
|
|
75
|
-
/**
|
|
76
|
-
* Queues context compaction without sending model input. The request is
|
|
77
|
-
* asynchronous; consume the durable event stream through its next session
|
|
78
|
-
* boundary before sending another turn. `compaction.completed` confirms that
|
|
79
|
-
* summarization succeeded. A never-started handle is a successful no-op.
|
|
80
|
-
*/
|
|
40
|
+
/** Queues context compaction without sending model input. */
|
|
81
41
|
compact(): Promise<CompactResult>;
|
|
82
|
-
/**
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
* fresh conversation and initializes a new session-scoped sandbox on first
|
|
88
|
-
* sandbox use. Resetting a never-started handle is a successful no-op. After
|
|
89
|
-
* a successful reset, this handle has no session state.
|
|
90
|
-
*
|
|
91
|
-
* @throws {ClientError} If the reset route returns a non-successful status.
|
|
92
|
-
*/
|
|
93
|
-
reset(): Promise<ResetResult>;
|
|
94
|
-
/**
|
|
95
|
-
* Opens this session's event stream for the current session ID.
|
|
96
|
-
*
|
|
97
|
-
* Resumes from the session's stored stream cursor unless `options.startIndex`
|
|
98
|
-
* overrides it. By default, the stream reconnects from its cursor when the
|
|
99
|
-
* connection ends; pass `streamReconnectPolicy: { reconnect: false }` to use
|
|
100
|
-
* one connection. Negative indices read relative to the current tail on one connection
|
|
101
|
-
* and do not advance the stored absolute cursor.
|
|
102
|
-
*
|
|
103
|
-
* Pass `follow: false` for a bounded read: yields events up to the durable
|
|
104
|
-
* tail observed when the stream opens, then returns instead of following.
|
|
105
|
-
* The stored cursor still advances past the consumed events.
|
|
106
|
-
*
|
|
107
|
-
* @throws {Error} If the session has no session ID (no message has been sent
|
|
108
|
-
* yet), or if `follow: false` is combined with a negative `startIndex`.
|
|
109
|
-
*/
|
|
42
|
+
/** Terminally retires this exact session ID. The handle remains pinned to it. */
|
|
43
|
+
reset(options?: {
|
|
44
|
+
readonly reason?: string;
|
|
45
|
+
}): Promise<ResetResult>;
|
|
46
|
+
/** Opens this session's durable event stream from its stored cursor. */
|
|
110
47
|
stream(options?: StreamOptions): AsyncIterable<MessageStreamEvent>;
|
|
111
48
|
}
|
|
112
|
-
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{EVE_SESSION_ROUTE_PATH,createEveSessionRoutePath}from"#protocol/routes.js";import{EVE_SESSION_ID_HEADER,isCurrentTurnBoundaryEvent}from"#protocol/message.js";import{ClientError}from"#client/client-error.js";import{createClientUrl}from"#client/url.js";import{MessageResponse}from"#client/message-response.js";import{followStreamIterable}from"#client/open-stream.js";import{cancelClientSession,clearClientSession,compactClientSession,resetClientSession}from"#client/session-controls.js";import{serializeOutputSchema}from"#shared/tool-schema.js";var ClientSession=class ClientSession{#e;#t;constructor(e,t){this.#e=e,this.#t=t}static async create(t,n){let r=await postTurn(t,EVE_SESSION_ROUTE_PATH,n,!0),i=await readSessionId(r),a=new ClientSession(t,{sessionId:i,streamIndex:0});return{response:a.#r(r,n,0),session:a}}get state(){return this.#t}async snapshot(e){e?.signal?.throwIfAborted();let t=[];for await(let n of this.#o({follow:!1,signal:e?.signal,startIndex:0}))t.push(n);return e?.signal?.throwIfAborted(),{events:t,session:{sessionId:this.#t.sessionId,streamIndex:t.length}}}async send(e,t={}){return await this.#n({...t,message:e})}async respond(e,t={}){if(e.length===0)throw Error(`ClientSession.respond() requires at least one input response.`);return await this.#n({...t,inputResponses:e})}async#n(e){let n=this.#t.streamIndex,r=await postTurn(this.#e,createEveSessionRoutePath(this.#t.sessionId),e,!1);if(await readSessionId(r,this.#t.sessionId)!==this.#t.sessionId)throw Error(`Message route returned a different session id.`);return this.#r(r,e,n)}async cancel(e){return await cancelClientSession({context:this.#e,options:e,sessionId:this.#t.sessionId})}async clear(){return await clearClientSession({context:this.#e,sessionId:this.#t.sessionId})}async compact(){return await compactClientSession({context:this.#e,sessionId:this.#t.sessionId})}async reset(e){return await resetClientSession({context:this.#e,options:e,sessionId:this.#t.sessionId})}stream(e){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.#a(e)}#r(e,t,n){return e.body?.cancel().catch(()=>{}),new MessageResponse({createStream:()=>this.#i(n,t),sessionId:this.#t.sessionId})}async*#i(e,t){let n=0;try{for await(let i of this.#o({headers:t.headers,signal:t.signal,startIndex:e,streamReconnectPolicy:t.streamReconnectPolicy}))if(n+=1,yield i,isCurrentTurnBoundaryEvent(i))break}finally{this.#t={sessionId:this.#t.sessionId,streamIndex:e+n}}}async*#a(e){let t=e?.startIndex??this.#t.streamIndex,n=0;try{for await(let r of this.#o({follow:e?.follow,signal:e?.signal,startIndex:t,streamReconnectPolicy:e?.streamReconnectPolicy}))n+=1,yield r}finally{t>=0&&(this.#t={sessionId:this.#t.sessionId,streamIndex:t+n})}}#o(e){return followStreamIterable({follow:e.follow,host:this.#e.host,resolveHeaders:()=>this.#e.resolveHeaders(e.headers),redirect:this.#e.redirect,sessionId:this.#t.sessionId,signal:e.signal,startIndex:e.startIndex,streamReconnectPolicy:e.streamReconnectPolicy})}};async function postTurn(e,t,n,r){let o=createMessageBody(n,r);if(o===null)throw Error(r?`Creating a session requires a non-empty message.`:`A session turn requires a non-empty message or inputResponses.`);let s=await e.resolveHeaders(n.headers);s.set(`content-type`,`application/json`);let c=await fetch(createClientUrl(e.host,t),{body:JSON.stringify(o),headers:s,method:`POST`,redirect:e.redirect,signal:n.signal??null});if(!c.ok){let e=await c.text();throw new ClientError(c.status,e,c.headers)}return c}async function readSessionId(e,t){let r=await e.json(),i=(typeof r.sessionId==`string`?r.sessionId:void 0)??e.headers.get(EVE_SESSION_ID_HEADER)?.trim()??t;if(!i)throw Error(`Message route did not return a session id.`);return i}function createMessageBody(e,t){let n={};e.message!==void 0&&(n.message=e.message),e.inputResponses!==void 0&&e.inputResponses.length>0&&(n.inputResponses=e.inputResponses),e.clientContext!==void 0&&(n.clientContext=e.clientContext);let r=serializeOutputSchema(e.outputSchema);return r!==void 0&&(n.outputSchema=r),t&&n.message===void 0||n.message===void 0&&n.inputResponses===void 0?null:n}export{ClientSession};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { ClientSession, type ClientSessionContext } from "#client/session.js";
|
|
2
|
+
import type { MessageResponse } from "#client/message-response.js";
|
|
3
|
+
import type { SendTurnInput } from "#client/types.js";
|
|
4
|
+
/** Result of explicitly creating an ID-addressed client session. */
|
|
5
|
+
export interface CreatedClientSession<TOutput = unknown> {
|
|
6
|
+
readonly response: MessageResponse<TOutput>;
|
|
7
|
+
readonly session: ClientSession;
|
|
8
|
+
}
|
|
9
|
+
/** Collection surface for explicitly creating or attaching ID-addressed sessions. */
|
|
10
|
+
export declare class ClientSessions {
|
|
11
|
+
#private;
|
|
12
|
+
/** @internal */
|
|
13
|
+
constructor(context: ClientSessionContext);
|
|
14
|
+
/** Creates a session immediately and returns its fixed handle plus first-turn response. */
|
|
15
|
+
create<TOutput = unknown>(input: SendTurnInput<TOutput>): Promise<CreatedClientSession<TOutput>>;
|
|
16
|
+
/** Attaches a fixed handle to a known session ID without performing I/O. */
|
|
17
|
+
attach(sessionId: string, options?: {
|
|
18
|
+
readonly streamIndex?: number;
|
|
19
|
+
}): ClientSession;
|
|
20
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{ClientSession}from"#client/session.js";var ClientSessions=class{#e;constructor(e){this.#e=e}async create(t){return await ClientSession.create(this.#e,t)}attach(t,n){if(t.length===0)throw Error(`sessionId must be a non-empty string.`);return new ClientSession(this.#e,{sessionId:t,streamIndex:n?.streamIndex??0})}};export{ClientSessions};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { UserContent } from "ai";
|
|
2
2
|
import type { StandardJSONSchemaV1 } from "#compiled/@standard-schema/spec/index.js";
|
|
3
3
|
import type { MessageStreamEvent } from "#protocol/message.js";
|
|
4
|
-
import type {
|
|
4
|
+
import type { CancelTurnResult } from "#protocol/cancel-turn.js";
|
|
5
5
|
import type { ClearStatus } from "#protocol/clear-session.js";
|
|
6
6
|
import type { CompactStatus } from "#protocol/compact-session.js";
|
|
7
7
|
import type { ResetStatus } from "#protocol/reset-session.js";
|
|
@@ -70,31 +70,15 @@ export interface ClientOptions {
|
|
|
70
70
|
* redirect.
|
|
71
71
|
*/
|
|
72
72
|
readonly redirect?: ClientRedirectPolicy;
|
|
73
|
-
/**
|
|
74
|
-
* Keep a session's continuation token after a normal `session.completed`
|
|
75
|
-
* boundary.
|
|
76
|
-
*
|
|
77
|
-
* By default, completed turns reset the client-side session so the next
|
|
78
|
-
* `send()` starts a fresh server-side conversation. Interactive clients can
|
|
79
|
-
* set this to preserve durable session state, including framework-managed
|
|
80
|
-
* sandbox state, across follow-up prompts until they explicitly create a new
|
|
81
|
-
* session.
|
|
82
|
-
*
|
|
83
|
-
* @default false
|
|
84
|
-
*/
|
|
85
|
-
readonly preserveCompletedSessions?: boolean;
|
|
86
73
|
}
|
|
87
74
|
/**
|
|
88
|
-
* Input
|
|
89
|
-
* `{ message: string }`, or pass an object to include a message, HITL input
|
|
90
|
-
* responses, one-turn client context, structured-output schema, abort signal,
|
|
91
|
-
* and per-turn headers.
|
|
75
|
+
* Input object for creating a client session. The first message is required.
|
|
92
76
|
*/
|
|
93
|
-
export
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
*/
|
|
97
|
-
export interface
|
|
77
|
+
export interface SendTurnInput<TOutput = unknown> extends SendTurnOptions<TOutput> {
|
|
78
|
+
readonly message: string | UserContent;
|
|
79
|
+
}
|
|
80
|
+
/** Options shared by message sends and HITL responses on a client session. */
|
|
81
|
+
export interface SendTurnOptions<TOutput = unknown> {
|
|
98
82
|
/**
|
|
99
83
|
* Ephemeral client/page context for the next model call only.
|
|
100
84
|
*
|
|
@@ -104,14 +88,6 @@ export interface SendTurnPayload<TOutput = unknown> {
|
|
|
104
88
|
* itself and is never persisted to durable session history.
|
|
105
89
|
*/
|
|
106
90
|
readonly clientContext?: string | readonly string[] | JsonObject;
|
|
107
|
-
/**
|
|
108
|
-
* HITL responses resolving pending approvals or questions.
|
|
109
|
-
*/
|
|
110
|
-
readonly inputResponses?: readonly InputResponse[];
|
|
111
|
-
/**
|
|
112
|
-
* Optional follow-up user message for the same turn.
|
|
113
|
-
*/
|
|
114
|
-
readonly message?: string | UserContent;
|
|
115
91
|
/**
|
|
116
92
|
* Optional schema the harness must satisfy before this turn terminates.
|
|
117
93
|
*
|
|
@@ -136,6 +112,16 @@ export interface SendTurnPayload<TOutput = unknown> {
|
|
|
136
112
|
*/
|
|
137
113
|
readonly headers?: Readonly<Record<string, string>>;
|
|
138
114
|
}
|
|
115
|
+
/** Options for answering pending HITL input requests on a client session. */
|
|
116
|
+
export type RespondTurnOptions<TOutput = unknown> = SendTurnOptions<TOutput>;
|
|
117
|
+
/** @internal Transport envelope used by stores and command adapters. */
|
|
118
|
+
export type SendTurnPayload<TOutput = unknown> = (SendTurnOptions<TOutput> & {
|
|
119
|
+
readonly inputResponses?: never;
|
|
120
|
+
readonly message: string | UserContent;
|
|
121
|
+
}) | (RespondTurnOptions<TOutput> & {
|
|
122
|
+
readonly inputResponses: readonly InputResponse[];
|
|
123
|
+
readonly message?: never;
|
|
124
|
+
});
|
|
139
125
|
/** Retry and backoff settings for one kind of stream reconnection. */
|
|
140
126
|
export interface StreamReconnectRetryPolicy {
|
|
141
127
|
/** Initial delay before retrying, in milliseconds. */
|
|
@@ -186,19 +172,14 @@ export interface StreamOptions {
|
|
|
186
172
|
readonly signal?: AbortSignal;
|
|
187
173
|
}
|
|
188
174
|
/** Result of requesting cancellation for a client session's active turn. */
|
|
189
|
-
export
|
|
190
|
-
/** Session whose active turn was targeted. */
|
|
191
|
-
readonly sessionId: string;
|
|
192
|
-
/** Both outcomes are successful; `no_active_turn` means there was nothing left to cancel. */
|
|
193
|
-
readonly status: CancelTurnStatus;
|
|
194
|
-
}
|
|
175
|
+
export type CancelSessionResult = CancelTurnResult;
|
|
195
176
|
/** Result of requesting a context clear for a client session. */
|
|
196
177
|
export type ClearResult = {
|
|
197
178
|
/** Session whose clear request was queued. */
|
|
198
179
|
readonly sessionId: string;
|
|
199
180
|
readonly status: Extract<ClearStatus, "accepted">;
|
|
200
181
|
} | {
|
|
201
|
-
/** The
|
|
182
|
+
/** The fixed session ID was unknown or no longer active. */
|
|
202
183
|
readonly status: Extract<ClearStatus, "no_active_session">;
|
|
203
184
|
};
|
|
204
185
|
/** Result of requesting context compaction for a client session. */
|
|
@@ -207,16 +188,16 @@ export type CompactResult = {
|
|
|
207
188
|
readonly sessionId: string;
|
|
208
189
|
readonly status: Extract<CompactStatus, "accepted">;
|
|
209
190
|
} | {
|
|
210
|
-
/** The
|
|
191
|
+
/** The fixed session ID was unknown or no longer active. */
|
|
211
192
|
readonly status: Extract<CompactStatus, "no_active_session">;
|
|
212
193
|
};
|
|
213
194
|
/** Result of terminally resetting a client session. */
|
|
214
195
|
export type ResetResult = {
|
|
215
|
-
/** The prior session was retired
|
|
196
|
+
/** The prior session was terminally retired. */
|
|
216
197
|
readonly previousSessionId: string;
|
|
217
198
|
readonly status: Extract<ResetStatus, "reset">;
|
|
218
199
|
} | {
|
|
219
|
-
/** The
|
|
200
|
+
/** The fixed session ID was unknown or no longer active. */
|
|
220
201
|
readonly status: Extract<ResetStatus, "no_active_session">;
|
|
221
202
|
};
|
|
222
203
|
/**
|
|
@@ -266,12 +247,10 @@ export interface HealthResult {
|
|
|
266
247
|
readonly workflowId: string;
|
|
267
248
|
}
|
|
268
249
|
/**
|
|
269
|
-
* Serializable
|
|
270
|
-
* {@link Client.session} to resume a conversation later.
|
|
250
|
+
* Serializable cursor for one fixed, ID-addressed client session.
|
|
271
251
|
*/
|
|
272
|
-
export interface
|
|
273
|
-
readonly
|
|
274
|
-
readonly sessionId?: string;
|
|
252
|
+
export interface ClientSessionState {
|
|
253
|
+
readonly sessionId: string;
|
|
275
254
|
readonly streamIndex: number;
|
|
276
255
|
}
|
|
277
256
|
/**
|
|
@@ -281,5 +260,5 @@ export interface SessionSnapshot {
|
|
|
281
260
|
/** Events from the start of the session through the durable tail observed when the read opened. */
|
|
282
261
|
readonly events: readonly MessageStreamEvent[];
|
|
283
262
|
/** Session cursor advanced exactly past {@link events}. */
|
|
284
|
-
readonly session:
|
|
263
|
+
readonly session: ClientSessionState;
|
|
285
264
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{expectBoolean,expectFunction,expectObjectRecord,expectOnlyKnownKeys,expectString}from"#internal/authored-module.js";import{
|
|
1
|
+
import{expectBoolean,expectFunction,expectObjectRecord,expectOnlyKnownKeys,expectString}from"#internal/authored-module.js";import{EVE_SESSION_ROUTE_PATH}from"#protocol/routes.js";import{DEFAULT_AGENT_MODEL_ID}from"#shared/default-agent-model.js";import{serializeOutputSchema}from"#shared/tool-schema.js";import{createCompiledSubagentNodeId}from"#compiler/manifest.js";import{normalizeAgentDefinition}from"#internal/authored-definition/core.js";import{loadModuleBackedDefinition}from"#compiler/normalize-helpers.js";import{isDynamicSentinel}from"#shared/dynamic-tool-definition.js";import{createPathDerivedSourceId}from"#discover/manifest.js";const ALLOWED_DYNAMIC_SUBAGENT_EVENTS=new Set([`session.started`,`turn.started`]);async function compileSubagentGraph(e){let t=[],n=[],r=[];for(let i of e.subagents){let a=await compileSubagentDefinition({appRoot:e.appRoot,compileAgentNodeManifest:e.compileAgentNodeManifest,context:e.context,externalDependencies:e.externalDependencies,parentNodeId:e.parentNodeId,source:i});if(a.kind===`remote`){r.push(a.node);continue}t.push(a.node,...a.descendants.nodes),n.push({childNodeId:a.node.nodeId,parentNodeId:e.parentNodeId},...a.descendants.edges)}return{edges:n,nodes:t,remoteAgents:r}}async function compileSubagentDefinition(e){let t=e.source.manifest.configModule;if(t===void 0)throw Error(`Subagent "${e.source.logicalPath}" is missing an agent config module.`);let n=createSubagentConfigModuleSourceRef(e.source,t),r=await loadModuleBackedDefinition({agentRoot:e.source.manifest.agentRoot,displayPath:n.logicalPath,externalDependencies:e.externalDependencies,kind:`subagent config`,source:t}),i=normalizeDynamicSubagentDefinition(r,`Expected the dynamic subagent config export "${t.exportName??`default`}" from "${n.logicalPath}" to match the public eve shape.`);if(i===void 0&&readAgentDefinitionKind(r)===`remote`)return{kind:`remote`,node:compileRemoteAgent({source:e.source,value:r})};let a=r;if(i!==void 0){let e={model:DEFAULT_AGENT_MODEL_ID};i.build!==void 0&&(e.build=i.build),a=e}return{kind:`local`,...await compileLocalSubagent({...e,agentConfigDefinition:a,dynamic:i?.definition})}}async function compileSubagent(e){let t=createCompiledSubagentNodeId(e.parentNodeId,e.source.sourceId),n=e.source.subagentId,r=await e.compileAgentNodeManifest({...e.source.manifest,appRoot:e.appRoot},e.context,{agentConfigDefinition:e.agentConfigDefinition,allowWorkflowConfig:!1,externalDependencies:e.externalDependencies}),i=r.config.description,a;if(e.dynamic!==void 0)a={dynamic:e.dynamic};else{if(!i)throw Error(`Local subagent "${e.source.logicalPath}" is missing a "description" field on its agent config. Add \`description\` to \`defineAgent({ ... })\` so the parent agent can decide when to delegate to this subagent.`);a={description:i}}let o=await compileSubagentGraph({appRoot:e.appRoot,compileAgentNodeManifest:e.compileAgentNodeManifest,context:e.context,externalDependencies:r.config.build?.externalDependencies,parentNodeId:t,subagents:e.source.manifest.subagents});return{descendants:o,node:{agent:{...r,remoteAgents:[...o.remoteAgents]},...a,entryPath:e.source.entryPath,logicalPath:e.source.logicalPath,name:n,nodeId:t,rootPath:e.source.rootPath,sourceId:e.source.sourceId,sourceKind:`module`}}}const compileLocalSubagent=compileSubagent;function compileRemoteAgent(e){let t=e.source.manifest.configModule;if(t===void 0)throw Error(`Remote agent "${e.source.logicalPath}" is missing a config module.`);assertRemoteAgentDefinitionHasNoLocalPackageEntries(e.source);let n=createSubagentConfigModuleSourceRef(e.source,t),r=normalizeRemoteAgentDefinition(e.value,`Expected the remote agent config export "${t.exportName??`default`}" from "${n.logicalPath}" to match the public eve shape.`),i={...n,description:r.description,entryPath:e.source.entryPath,name:e.source.subagentId,nodeId:e.source.sourceId,outputSchema:r.outputSchema,path:r.path,rootPath:e.source.rootPath};return r.url===void 0?i:{...i,url:r.url}}function normalizeDynamicSubagentDefinition(e,i){if(!isDynamicSentinel(e))return;let a=expectObjectRecord(e,i);if(Object.hasOwn(a,`fallback`))throw Error(`${i} Dynamic subagent definitions do not support "fallback". Return defineAgent(...) or defineRemoteAgent(...) from an event handler instead.`);expectOnlyKnownKeys(a,[`build`,`events`,`kind`],i);let s=a.build===void 0?void 0:normalizeAgentDefinition({build:a.build,model:DEFAULT_AGENT_MODEL_ID},i).build,c=expectObjectRecord(a.events,i),l=[];for(let[e,n]of Object.entries(c)){if(!ALLOWED_DYNAMIC_SUBAGENT_EVENTS.has(e))throw Error(`${i} Dynamic subagents support only "session.started" and "turn.started" handlers.`);expectFunction(n,i),l.push(e)}let u={definition:{eventNames:l}};return s!==void 0&&(u.build=s),u}function createSubagentConfigModuleSourceRef(e,t){let n=e.logicalPath===t.logicalPath?t.logicalPath:`${e.logicalPath}/${t.logicalPath}`,r={logicalPath:n,sourceId:createPathDerivedSourceId(n),sourceKind:`module`};return t.exportName!==void 0&&(r.exportName=t.exportName),r}function readAgentDefinitionKind(e){return typeof e!=`object`||!e?`local`:e.kind===`remote`?`remote`:`local`}function normalizeRemoteAgentDefinition(t,o){let c=expectObjectRecord(t,o);if(expectOnlyKnownKeys(c,[`auth`,`description`,`forwardPrincipal`,`headers`,`kind`,`outputSchema`,`path`,`url`],o),c.kind!==`remote`)throw Error(`${o} Expected "kind" to be "remote".`);return c.forwardPrincipal!==void 0&&expectBoolean(c.forwardPrincipal,`${o} Expected "forwardPrincipal" to be a boolean.`),{description:expectString(c.description,o),outputSchema:serializeOutputSchema(c.outputSchema),path:c.path===void 0?EVE_SESSION_ROUTE_PATH:expectString(c.path,o),url:typeof c.url==`function`?void 0:expectString(c.url,o)}}function assertRemoteAgentDefinitionHasNoLocalPackageEntries(e){let t=e.manifest,n=[t.connections.length>0?`connections/`:void 0,t.hooks.length>0?`hooks/`:void 0,t.instructions.length>0?`instructions`:void 0,t.lib.length>0?`lib/`:void 0,t.sandbox===null?void 0:`sandbox/`,t.sandboxWorkspaces.length>0?`sandbox/workspace/`:void 0,t.schedules.length>0?`schedules/`:void 0,t.skills.length>0?`skills/`:void 0,t.subagents.length>0?`subagents/`:void 0,t.tools.length>0?`tools/`:void 0].filter(e=>e!==void 0);if(n.length!==0)throw Error(`Remote subagent definition "${e.logicalPath}" cannot include local package entries. Remove unsupported entries: ${n.join(`, `)}.`)}export{compileSubagentGraph};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{resolveDevelopmentClientOptions}from"#services/dev-client/client-options.js";import{resolveVerifiedRemoteDevelopmentClient}from"#setup/verified-remote-client.js";import{Client}from"#client/client.js";function resolveEvalClientOptions(t){if(t.kind===`local`)return{host:t.url};let n=
|
|
1
|
+
import{resolveDevelopmentClientOptions}from"#services/dev-client/client-options.js";import{resolveVerifiedRemoteDevelopmentClient}from"#setup/verified-remote-client.js";import{Client}from"#client/client.js";function resolveEvalClientOptions(t){if(t.kind===`local`)return{host:t.url};let n=resolveDevelopmentClientOptions(t.url),r=process.env.EVE_EVAL_AUTH_TOKEN?.trim();return r?{...n,auth:{bearer:r},redirect:`manual`}:n}async function createEvalClient(e,r={}){let i=resolveEvalClientOptions(e);if(e.kind===`local`||i.auth!==void 0||r.workspaceRoot===void 0)return new Client(i);let{options:a}=await resolveVerifiedRemoteDevelopmentClient({serverUrl:e.url,workspaceRoot:r.workspaceRoot,deps:r.deps});return new Client({...i,...a})}export{createEvalClient,resolveEvalClientOptions};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import"#evals/assertions/collector.js";import"#evals/session.js";import{createScopedAssertions}from"#evals/assertions/scoped.js";import{buildJudgeContext}from"#evals/judge.js";import{EvalRequirementFailed,EvalSkipped}from"#evals/control-flow.js";function createEvalContext(n){let i=n.collector,a=``,primary=()=>n.manager.primary,replyMessage=()=>n.manager.lastTurnSession()?.lastTurn?.message??null,o=buildJudgeContext({collector:i,getReply:replyMessage,getInput:()=>a,judge:n.judge});return{context:{get events(){return primary().events},get pendingInputRequests(){return primary().pendingInputRequests},get state(){return primary().state},get sessionId(){return primary().sessionId},cancel:()=>primary().cancel(),requireInputRequest:e=>primary().requireInputRequest(e),respond:(
|
|
1
|
+
import"#evals/assertions/collector.js";import"#evals/session.js";import{createScopedAssertions}from"#evals/assertions/scoped.js";import{buildJudgeContext}from"#evals/judge.js";import{EvalRequirementFailed,EvalSkipped}from"#evals/control-flow.js";function createEvalContext(n){let i=n.collector,a=``,primary=()=>n.manager.primary,replyMessage=()=>n.manager.lastTurnSession()?.lastTurn?.message??null,o=buildJudgeContext({collector:i,getReply:replyMessage,getInput:()=>a,judge:n.judge});return{context:{get events(){return primary().events},get pendingInputRequests(){return primary().pendingInputRequests},get state(){return primary().state},get sessionId(){return primary().sessionId},cancel:()=>primary().cancel(),requireInputRequest:e=>primary().requireInputRequest(e),respond:(e,t)=>primary().respond(e,t),respondAll:e=>primary().respondAll(e),send:(e,t)=>(a=typeof e==`string`?e:``,primary().send(e,t)),start:(e,t)=>(a=e,primary().start(e,t)),sendFile:(e,t,n)=>(a=e,primary().sendFile(e,t,n)),signal:n.signal,target:n.target,get reply(){return replyMessage()},log:n.log,sleep:e=>sleep(e,n.signal),newSession:()=>n.manager.newSession(),...createScopedAssertions(i,{timing:`final`,select:e=>e}),check:(e,t)=>recordCheck(i,e,t),require:(e,t)=>requireCheck(i,e,t),skip:e=>{throw e.trim().length===0?Error(`skip() requires a non-empty reason.`):i.hasEntries||n.manager.hasActivity()?Error(`skip() must be called before sending messages or recording assertions.`):new EvalSkipped(e)},judge:o},collector:i}}async function requireCheck(e,t,r){let i=r.gate(r.threshold);if(!await e.recordRequirement({name:i.name,threshold:i.threshold,score:()=>evaluateAssertion(i,t)}))throw new EvalRequirementFailed;return t}function recordCheck(e,t,n){return e.recordValue({name:n.name,severity:n.severity,threshold:n.threshold,score:()=>evaluateAssertion(n,t)})}async function evaluateAssertion(e,t){return e.evaluate===void 0?{score:await e.score(t)}:await e.evaluate(t)}function sleep(e=1e3,t){if(!Number.isFinite(e)||e<0)throw Error(`sleep() duration must be a non-negative finite number.`);return t?.aborted?Promise.reject(t.reason):new Promise((n,r)=>{let i=setTimeout(n,e);t?.addEventListener(`abort`,()=>{clearTimeout(i),r(t.reason)},{once:!0})})}export{createEvalContext};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Client } from "#client/client.js";
|
|
2
2
|
import type { ClientSession } from "#client/session.js";
|
|
3
|
-
import type { CancelSessionResult, SendTurnInput,
|
|
3
|
+
import type { CancelSessionResult, ClientSessionState, SendTurnInput, SendTurnOptions } from "#client/types.js";
|
|
4
4
|
import type { MessageStreamEvent, TurnFailureStreamEvent } from "#protocol/message.js";
|
|
5
5
|
import type { InputRequest, InputResponse } from "#runtime/input/types.js";
|
|
6
6
|
import { AssertionCollector } from "#evals/assertions/collector.js";
|
|
@@ -19,21 +19,22 @@ export interface EvalSessionDriver extends EveEvalAssertions, EveEvalOutputAsser
|
|
|
19
19
|
export declare class EvalSessionDriver implements EveEvalSession {
|
|
20
20
|
#private;
|
|
21
21
|
constructor(input: {
|
|
22
|
+
readonly client: Client;
|
|
22
23
|
readonly collector: AssertionCollector;
|
|
23
|
-
readonly session
|
|
24
|
+
readonly session?: ClientSession;
|
|
24
25
|
readonly signal?: AbortSignal;
|
|
25
26
|
});
|
|
26
27
|
get events(): readonly MessageStreamEvent[];
|
|
27
28
|
get lastTurn(): EveEvalTurn | undefined;
|
|
28
29
|
get pendingInputRequests(): readonly InputRequest[];
|
|
29
30
|
get sessionId(): string | undefined;
|
|
30
|
-
get state():
|
|
31
|
+
get state(): ClientSessionState | undefined;
|
|
31
32
|
cancel(): Promise<CancelSessionResult>;
|
|
32
33
|
requireInputRequest(filter?: EveEvalInputRequestMatchOptions): InputRequest;
|
|
33
|
-
respond(
|
|
34
|
+
respond(responses: readonly InputResponse[], options?: SendTurnOptions): Promise<EveEvalTurn>;
|
|
34
35
|
respondAll(optionId: string): Promise<EveEvalTurn>;
|
|
35
|
-
send(
|
|
36
|
-
start(
|
|
36
|
+
send(message: SendTurnInput["message"], options?: SendTurnOptions): Promise<EveEvalTurn>;
|
|
37
|
+
start(message: string, options?: SendTurnOptions): Promise<EveEvalLiveTurn>;
|
|
37
38
|
sendFile(text: string, filePath: string, mediaType?: string): Promise<EveEvalTurn>;
|
|
38
39
|
readTurn(options?: {
|
|
39
40
|
readonly startIndex?: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{readFile}from"node:fs/promises";import{basename,extname}from"node:path";import{isCurrentTurnBoundaryEvent,isTurnFailureEvent}from"#protocol/message.js";import{summarizeTurnEvents}from"#client/session-utils.js";import{createTextWithFileContent}from"#client/file-parts.js";import{extractCompletedResult}from"#client/output-schema.js";import{inputRequestMatches,matchesValue,toolCallMatches}from"#evals/match.js";import{AssertionCollector}from"#evals/assertions/collector.js";import{createOutputAssertions,createScopedAssertions}from"#evals/assertions/scoped.js";import{EvalRequirementFailed}from"#evals/control-flow.js";import{deriveRunFacts}from"#evals/runner/derive-run-facts.js";var EveEvalTurnFailedError=class extends Error{event;turn;constructor(e){let t=e.events.find(isTurnFailureEvent),n=t===void 0?`turn ended with status "${e.status}"`:`${t.type}: ${t.data.code} ${t.data.message}`.trim();super(`Eval turn failed: ${n}`),this.name=`EveEvalTurnFailedError`,this.event=t,this.turn=e}},EvalSessionDriver=class{#e;#t;#n;#r=[];#
|
|
1
|
+
import{readFile}from"node:fs/promises";import{basename,extname}from"node:path";import{isCurrentTurnBoundaryEvent,isTurnFailureEvent}from"#protocol/message.js";import{summarizeTurnEvents}from"#client/session-utils.js";import{createTextWithFileContent}from"#client/file-parts.js";import{extractCompletedResult}from"#client/output-schema.js";import{inputRequestMatches,matchesValue,toolCallMatches}from"#evals/match.js";import{AssertionCollector}from"#evals/assertions/collector.js";import{createOutputAssertions,createScopedAssertions}from"#evals/assertions/scoped.js";import{EvalRequirementFailed}from"#evals/control-flow.js";import{deriveRunFacts}from"#evals/runner/derive-run-facts.js";var EveEvalTurnFailedError=class extends Error{event;turn;constructor(e){let t=e.events.find(isTurnFailureEvent),n=t===void 0?`turn ended with status "${e.status}"`:`${t.type}: ${t.data.code} ${t.data.message}`.trim();super(`Eval turn failed: ${n}`),this.name=`EveEvalTurnFailedError`,this.event=t,this.turn=e}},EvalSessionDriver=class{#e;#t;#n;#r;#i=[];#a;#o=[];constructor(e){this.#e=e.client,this.#r=e.collector,this.#t=e.session,this.#n=e.signal,Object.assign(this,createScopedAssertions(this.#r,{timing:`snapshot`,select:()=>this.#u()}),createOutputAssertions(this.#r,{timing:`snapshot`,select:()=>this.#u()}))}get events(){return this.#i}get lastTurn(){return this.#a}get pendingInputRequests(){return this.#o}get sessionId(){return this.#t?.state.sessionId??this.#a?.sessionId}get state(){return this.#t?.state}async cancel(){if(this.#t===void 0)throw Error(`Eval session has not started.`);return await this.#t.cancel()}requireInputRequest(e={}){this.#o.length===0&&this.#d(`requireInputRequest`,`expected one pending input request, but the last turn did not park`);let t=this.#o.filter(t=>inputRequestMatches(t,e));return(this.#o.length!==1||t.length!==1)&&this.#d(`requireInputRequest`,`expected exactly one pending input request matching ${formatInputRequestFilter(e)}, found ${t.length} match(es) across ${this.#o.length} pending request(s)`),this.#r.recordOutcome({name:`requireInputRequest`,outcome:{score:1}}),t[0]}async respond(e,t={}){if(e.length===0)throw Error(`respond() requires at least one input response.`);return await(await this.#s({...t,inputResponses:e})).result()}async respondAll(e){let t=this.#o;if(t.length===0)throw Error(`respondAll() requires at least one pending input request.`);for(let n of t)assertRequestHasOption(n,e);return await this.respond(t.map(t=>({optionId:e,requestId:t.requestId})))}async send(e,t={}){return await(await this.#s({...t,message:e})).result()}async start(e,t={}){return await this.#s({...t,message:e})}async#s(e){let t=attachSignal(e,this.#n),n;if(this.#t===void 0){if(t.message===void 0)throw Error(`Eval session has not started.`);let e=await this.#e.sessions.create({...t,message:t.message});this.#t=e.session,n=e.response}else{let{inputResponses:e,message:r,...i}=t;n=e===void 0?await this.#t.send(r,i):await this.#t.respond(e,i)}return new EvalLiveTurn({events:n,record:e=>this.#l(n.sessionId,e),session:this,sessionId:n.sessionId})}async sendFile(n,r,i){let a=createTextWithFileContent({bytes:await readFile(r),filename:basename(r),mediaType:i??inferMediaType(r),text:n});return await this.send(a)}async readTurn(e){let t=this.sessionId;return await this.watchTurn(e,requireSessionId(t)).result()}watchTurn(e,t=requireSessionId(this.sessionId)){if(this.#t===void 0)throw Error(`Eval session has not started.`);return new EvalLiveTurn({events:this.#t.stream({signal:this.#n,startIndex:e?.startIndex}),record:e=>this.#l(t,e),session:this,sessionId:t})}snapshot(e){let t=this.sessionId;return{derived:deriveRunFacts(this.#i,{sessionId:t}),events:[...this.#i],primary:e,sessionId:t,state:this.#t?.state}}#c(e){this.#i.push(...e.events),this.#o=e.status===`waiting`?e.inputRequests:[];let t=deriveRunFacts(e.events,{sessionId:e.sessionId}),n=new EvalTurn({collector:this.#r,data:e.data,derived:t,events:e.events,inputRequests:e.inputRequests,message:e.message,sessionId:e.sessionId,status:e.status,toolCalls:t.toolCalls});return this.#a=n,n}#l(e,t){let n=summarizeTurnEvents(t);return this.#c({data:extractCompletedResult(t),events:t,inputRequests:n.inputRequests,message:n.message,sessionId:e,status:n.status})}#u(){let e=this.sessionId;return{derived:deriveRunFacts(this.#i,{sessionId:e}),events:[...this.#i],output:outputOf(this.#a),status:this.#a?.status??`completed`}}#d(e,t){throw this.#r.recordOutcome({name:e,outcome:{score:0,message:t}}),new EvalRequirementFailed}},EvalLiveTurn=class{session;sessionId;#e;#t=[];#n=new Set;#r;constructor(e){this.session=e.session,this.sessionId=e.sessionId,this.#e=this.#i(e.events,e.record),this.#e.catch(()=>{})}get events(){return this.#t}async cancel(){return await this.session.cancel()}async result(){return await this.#e}async waitForEvent(e,t){let matches=n=>n.type===e&&(t?.data===void 0||matchesValue(t.data,`data`in n?n.data:void 0)),n=this.#t.find(matches);if(n!==void 0)return n;if(this.#r!==void 0)throw this.#r;return await new Promise((e,t)=>{let n={matches,reject:t,resolve:t=>e(t)};this.#n.add(n)})}async#i(e,t){try{let n=!1;for await(let t of e)if(this.#t.push(t),this.#a(t),isTurnFailureEvent(t)&&this.#o(Error(`Session ${this.sessionId} failed before the expected event (${t.type}).`)),isCurrentTurnBoundaryEvent(t)){n=!0,this.#o(Error(`Session ${this.sessionId} reached ${t.type} before the expected event.`));break}if(!n)throw Error(`Stream for session "${this.sessionId}" closed before a turn boundary.`);return t(this.#t)}catch(e){let t=e instanceof Error?e:Error(String(e));throw this.#o(t),e}}#a(e){for(let t of this.#n)t.matches(e)&&(this.#n.delete(t),t.resolve(e))}#o(e){if(this.#r===void 0){this.#r=e;for(let t of this.#n)t.reject(e);this.#n.clear()}}},EvalTurn=class{data;events;inputRequests;message;sessionId;status;toolCalls;#e;#t;constructor(e){this.data=e.data,this.events=e.events,this.inputRequests=e.inputRequests,this.message=e.message,this.sessionId=e.sessionId,this.status=e.status,this.toolCalls=e.toolCalls,this.#e=e.collector,this.#t=e.derived,Object.assign(this,createScopedAssertions(e.collector,{timing:`snapshot`,select:()=>this.#n()}),createOutputAssertions(e.collector,{timing:`snapshot`,select:()=>this.#n()}))}expectOk(){if(this.status!==`failed`)return this;throw new EveEvalTurnFailedError(this)}requireToolCall(e,t={}){let n=this.toolCalls.filter(n=>n.name===e&&toolCallMatches(n,t));return n.length!==1&&inputRequirementFailed(this.#e,`requireToolCall`,`expected exactly one matching "${e}" tool call in this turn, found ${n.length}; observed [${this.toolCalls.map(e=>e.name).join(`, `)}]`),this.#e.recordOutcome({name:`requireToolCall`,outcome:{score:1}}),n[0]}#n(){return{derived:this.#t,events:this.events,output:outputOf(this),status:this.status}}},EvalSessionManager=class{#e;#t;#n;#r=[];#i;constructor(e){this.#e=e.client,this.#n=e.collector??new AssertionCollector,this.#t=e.signal}get primary(){return this.#i??=this.#a(),this.#i}newSession(){return this.#a()}async attachSession(e,t){let n=this.#o(e,t);return await n.readTurn(t),n}watchTurn(e,t){return this.#o(e,t).watchTurn(t,e)}snapshots(){return this.#r.map(e=>e.snapshot(e===this.#i))}lastTurnSession(){return this.#i?.lastTurn===void 0?this.#r.find(e=>e.lastTurn!==void 0):this.#i}hasActivity(){return this.#r.length>0}#a(){let e=new EvalSessionDriver({client:this.#e,collector:this.#n,signal:this.#t});return this.#r.push(e),e}#o(e,t){let n=new EvalSessionDriver({client:this.#e,collector:this.#n,session:this.#e.sessions.attach(e,{streamIndex:t?.startIndex??0}),signal:this.#t});return this.#r.push(n),n}};function attachSignal(e,t){return t===void 0?e:e.signal===void 0?{...e,signal:t}:e}function formatInputRequestFilter(e){return JSON.stringify(e)}function inputRequirementFailed(e,t,n){throw e.recordOutcome({name:t,outcome:{score:0,message:n}}),new EvalRequirementFailed}function outputOf(e){return e===void 0?null:e.data===void 0?e.message??null:e.data}function requireSessionId(e){if(e===void 0)throw Error(`Eval session produced a turn without a session id.`);return e}function assertRequestHasOption(e,t){if(e.options===void 0||e.options.length===0)throw Error(`Input request "${e.requestId}" has no selectable options.`);if(!e.options.some(e=>e.id===t))throw Error(`Input request "${e.requestId}" does not offer option "${t}".`)}function inferMediaType(e){switch(extname(e).toLowerCase()){case`.gif`:return`image/gif`;case`.jpg`:case`.jpeg`:return`image/jpeg`;case`.png`:return`image/png`;case`.webp`:return`image/webp`;default:return`application/octet-stream`}}export{EvalSessionDriver,EvalSessionManager,EveEvalTurnFailedError};
|