@finalai/agents 0.16.2 → 0.17.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/README.md CHANGED
@@ -100,6 +100,32 @@ sandbox created first can be owned by the session or conversation it is for
100
100
  (`project.sandboxes.create(environment, { setup, ownedBy, idempotencyKey })`).
101
101
  `conversations.findDirect({ agent })` looks up without creating.
102
102
 
103
+ ## Structured results
104
+
105
+ `sessions.create({ message, output })` and `handle.send(content, { output })`
106
+ ask that the turn end with a result matching `output`: a zod 4 schema (or any
107
+ schema with Standard JSON Schema support) or a JSON Schema, whose root is an
108
+ object. The agent returns the result by calling the `submit_result` tool, whose
109
+ input schema is `output`. A turn that ends without a valid result is asked once
110
+ more, then ends with the stop reason `output_missing`. A turn with `output`
111
+ waits for a running turn to end instead of steering into it.
112
+
113
+ ```ts
114
+ const { response } = await project.sessions.create({
115
+ agent,
116
+ provide,
117
+ message: 'Classify this support email: ...',
118
+ output: z.object({ severity: z.enum(['low', 'high']), summary: z.string() }),
119
+ });
120
+ const { output, stopReason } = await response!.result();
121
+ // output: { severity: 'low' | 'high'; summary: string } | null
122
+ ```
123
+
124
+ A library schema also parses the result in `result()`, so `output` has its
125
+ type. The turn record (`handle.turn(turnId)`) and the `turn.ended` event carry
126
+ the result as JSON; the event carries it only for the API key or app that
127
+ created the session, and sets `outputTruncated` instead when it is too large.
128
+
103
129
  ## Where things run
104
130
 
105
131
  - **The model's files and shell** run on whatever sandbox is provided
@@ -187,6 +213,15 @@ resume, park, close, health }) })`, self-contained like a serverless tool. `@fin
187
213
  `platformIdentity`) and `finalGateway({ url })`. A person's own sign-in is never a
188
214
  requirement: the platform asks them on first use.
189
215
 
216
+ An API key or an app can call an integration's tools without a session:
217
+ `project.integrations.listTools(integrationId)` and
218
+ `project.integrations.callTool(integrationId, { name, arguments, callKey, requirement?,
219
+ conversationId?, decisionId?, dryRun? })`. A call returns `completed` (the MCP result),
220
+ `failed` (a code and message), or `decision_required` (an approval, a sign-in or a question
221
+ the tool asks, raised in `conversationId`): once the decision resolves, call again with the
222
+ same `callKey` and its `decisionId`. A key that completed returns its outcome again and never
223
+ runs the tool twice. An app's token acting for a person calls as that person.
224
+
190
225
  ## Publishing
191
226
 
192
227
  ```sh
@@ -18,7 +18,7 @@ export { EVENTS_POLL_INTERVAL_MS, type EventsApiIface, type EventSubscriptionsAp
18
18
  export { defaultStreamTiming, type StreamTimingIface } from "./frame-stream.mjs";
19
19
  export type { AgentClientAuth, FetchIface, HeadersOption } from "./http.mjs";
20
20
  export type { AcpAdaptersApiIface, DefinitionSelectorIface, HarnessesApiIface, SubscriptionAllowancesApiIface, } from "./harnesses.mjs";
21
- export type { IntegrationsApiIface } from "./integrations.mjs";
21
+ export type { CallIntegrationToolArgsIface, IntegrationsApiIface } from "./integrations.mjs";
22
22
  export { SessionLiveEventKind, type SessionLiveEvent } from "./live-stream.mjs";
23
23
  export type { LocalComputeIface } from "./local-host.mjs";
24
24
  export type { OAuthClientsApiIface, SignInReturnOriginsApiIface } from "./oauth-clients.mjs";
@@ -33,3 +33,4 @@ export type { SandboxProvidersApiIface } from "./sandbox-providers.mjs";
33
33
  export type { CreateSandboxOptionsIface, SandboxEnvironmentValueIface, SandboxHandleIface, SandboxOwnerIface, SandboxSetupRefIface, SandboxSetupsApiIface, SandboxesApiIface, } from "./sandboxes.mjs";
34
34
  export type { ProjectSchedulesApiIface } from "./schedules.mjs";
35
35
  export type { CreateSessionArgsIface, CreatedSessionIface, ForkSessionOptionsIface, ProjectSessionsApiIface, RespondArgs, SendOptionsIface, SessionHandleIface, SessionsApiIface, StreamOptionsIface, TurnHandleIface, TurnResultIface, } from "./sessions.mjs";
36
+ export type { TurnOutputOf, TurnOutputSchema, TurnOutputStandardSchemaIface } from "./turn-output.mjs";
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/agent-client/api.ts"],
4
- "sourcesContent": ["// Everything `@finalai/agents/client` exports in every runtime except\n// `createClient`, which each runtime's entry binds to its own defaults.\n// Wire types come from `@finalai/agent-protocol/agent-platform`, re-exported\n// here so consumers need one import.\n\nexport * from '@finalai/agent-protocol/agent-platform';\nexport {\n Capability,\n FilesAccess,\n ScreenAccess,\n ShellAccess,\n type CapabilityAccess,\n} from '@finalai/agent-protocol';\nexport { AcpAuthMode, type AcpApiIface, type AcpConnectArgsIface } from \"./acp.mjs\";\nexport {\n createTextCollector,\n isUserMessageFor,\n sessionUpdateOf,\n textOf,\n turnEndOf,\n type AcpSessionUpdateIface,\n type TurnEndIface,\n} from \"./acp-frames.mjs\";\nexport type { AgentInput, AgentValue, AgentValueCodecIface } from \"./agent-input.mjs\";\nexport type {\n ActorOptionIface,\n ChannelAppsApiIface,\n ChannelBindingsApiIface,\n ChannelSourceIface,\n ChannelSourceOf,\n ChannelTicketsApiIface,\n IdentityLinksApiIface,\n InstallChannelArgsIface,\n ProjectChannelsApiIface,\n PublishChannelArgsIface,\n UpdateChannelBindingArgsIface,\n} from \"./channels.mjs\";\nexport {\n DEFAULT_AGENTS_HOST,\n type AgentClientIface,\n type AgentsApiIface,\n type AppApiIface,\n type CreateClientOptionsIface,\n type DecisionsApiIface,\n type InferenceApiIface,\n type PeopleApiIface,\n type PlatformIdentityApiIface,\n type RealtimeApiIface,\n} from \"./client.mjs\";\nexport {\n CollectionEventKind,\n CollectionResyncReason,\n type CollectionEvent,\n type CollectionEventsOptionsIface,\n type CollectionResyncEventIface,\n} from \"./collection-events.mjs\";\nexport {\n ConfigOptionCategory,\n configSelectFor,\n configSelectsOf,\n type ConfigSelectChoiceIface,\n type ConfigSelectIface,\n type SessionConfigOptionIface,\n} from \"./config-options.mjs\";\nexport type { EnumInput, SignalOptionsIface } from \"./context.mjs\";\nexport type {\n AllowedEndpointsApiIface,\n BudgetsApiIface,\n ModelCredentialGrantsApiIface,\n ModelCredentialsApiIface,\n OrganizationApiIface,\n OrganizationPolicyApiIface,\n SpendingRestrictionsApiIface,\n} from \"./organization.mjs\";\nexport type { ParticipantConfigurationApiIface } from \"./participant-configuration.mjs\";\nexport type {\n ConversationChannelRoutesApiIface,\n ConversationContextApiIface,\n ConversationContextEntryInputIface,\n ConversationDecisionsApiIface,\n ConversationInputsApiIface,\n ConversationLabelsApiIface,\n ConversationReadGrantsApiIface,\n ConversationResourcesIface,\n ResourceSubscriptionsApiIface,\n SendInputArgsIface,\n} from \"./conversation-resources.mjs\";\nexport {\n TURN_OPEN_SESSION_STATES,\n isNewerMessageVersion,\n messageVersionOf,\n type MessageVersionIface,\n} from \"./conversations.mjs\";\nexport type {\n ConversationAgentTurnIface,\n ConversationEvent,\n ConversationEventMetaIface,\n ConversationEventsOptionsIface,\n ConversationHandleIface,\n ConversationsApiIface,\n CreateConversationArgsIface,\n ListMessagesOptionsIface,\n OpenedConversationIface,\n ParticipantCreateInput,\n ParticipantsApiIface,\n ProjectConversationsApiIface,\n SandboxFileContentArgsIface,\n SandboxFileContentRequestIface,\n SendMessageOptionsIface,\n SentMessageIface,\n UploadAttachmentArgsIface,\n} from \"./conversations.mjs\";\nexport {\n AgentClientErrorName,\n ClientErrorCode,\n DecisionErrorReason,\n clientError,\n decisionError,\n isClientError,\n isDecisionError,\n isRealtimeSubscriptionError,\n isRequirementsUnmetError,\n isTerminalRealtimeError,\n isTurnRejectedError,\n realtimeSubscriptionError,\n requirementsUnmetError,\n turnRejectedError,\n type AgentClientError,\n type ClientErrorIface,\n type DecisionErrorIface,\n type RealtimeSubscriptionErrorIface,\n type RequirementsUnmetErrorIface,\n type TurnRejectedErrorIface,\n} from \"./errors.mjs\";\nexport {\n EVENTS_POLL_INTERVAL_MS,\n type EventsApiIface,\n type EventSubscriptionsApiIface,\n type ListEventsOptionsIface,\n type StreamEventsOptionsIface,\n} from \"./events.mjs\";\nexport { defaultStreamTiming, type StreamTimingIface } from \"./frame-stream.mjs\";\nexport type { AgentClientAuth, FetchIface, HeadersOption } from \"./http.mjs\";\nexport type {\n AcpAdaptersApiIface,\n DefinitionSelectorIface,\n HarnessesApiIface,\n SubscriptionAllowancesApiIface,\n} from \"./harnesses.mjs\";\nexport type { IntegrationsApiIface } from \"./integrations.mjs\";\nexport { SessionLiveEventKind, type SessionLiveEvent } from \"./live-stream.mjs\";\nexport type { LocalComputeIface } from \"./local-host.mjs\";\nexport type { OAuthClientsApiIface, SignInReturnOriginsApiIface } from \"./oauth-clients.mjs\";\nexport type { ProjectClientIface } from \"./project.mjs\";\nexport type { AgentSelectorIface, ProjectAgentsApiIface } from \"./project-agents.mjs\";\nexport type {\n ProjectApiKeysApiIface,\n ProjectMembersApiIface,\n ProjectResourceApiIface,\n ProjectsApiIface,\n} from \"./projects.mjs\";\nexport type {\n ProjectPublisherApiIface,\n PublicNamesApiIface,\n PublisherHandleIface,\n PublishersApiIface,\n} from \"./publishers.mjs\";\nexport {\n provideDocumentOf,\n resourceIdOf,\n type ProvideIface,\n type ProvidePatchIface,\n type ResourceRef,\n type ResourceRefIface,\n} from \"./provide.mjs\";\nexport {\n createGatewayRealtimeTransport,\n type GatewayConnect,\n type GatewayConnectionIface,\n type GatewayRealtimeTransportOptionsIface,\n type RealtimeSubscribeOptionsIface,\n type RealtimeTransportFrameIface,\n type RealtimeTransportIface,\n} from \"./realtime.mjs\";\nexport {\n SANDBOX_FILE_URI_SCHEME,\n createSandboxFileUri,\n parseSandboxFileUri,\n type SandboxFileTargetIface,\n} from \"./sandbox-uri.mjs\";\nexport type { SandboxProvidersApiIface } from \"./sandbox-providers.mjs\";\nexport type {\n CreateSandboxOptionsIface,\n SandboxEnvironmentValueIface,\n SandboxHandleIface,\n SandboxOwnerIface,\n SandboxSetupRefIface,\n SandboxSetupsApiIface,\n SandboxesApiIface,\n} from \"./sandboxes.mjs\";\nexport type { ProjectSchedulesApiIface } from \"./schedules.mjs\";\nexport type {\n CreateSessionArgsIface,\n CreatedSessionIface,\n ForkSessionOptionsIface,\n ProjectSessionsApiIface,\n RespondArgs,\n SendOptionsIface,\n SessionHandleIface,\n SessionsApiIface,\n StreamOptionsIface,\n TurnHandleIface,\n TurnResultIface,\n} from \"./sessions.mjs\";\n"],
4
+ "sourcesContent": ["// Everything `@finalai/agents/client` exports in every runtime except\n// `createClient`, which each runtime's entry binds to its own defaults.\n// Wire types come from `@finalai/agent-protocol/agent-platform`, re-exported\n// here so consumers need one import.\n\nexport * from '@finalai/agent-protocol/agent-platform';\nexport {\n Capability,\n FilesAccess,\n ScreenAccess,\n ShellAccess,\n type CapabilityAccess,\n} from '@finalai/agent-protocol';\nexport { AcpAuthMode, type AcpApiIface, type AcpConnectArgsIface } from \"./acp.mjs\";\nexport {\n createTextCollector,\n isUserMessageFor,\n sessionUpdateOf,\n textOf,\n turnEndOf,\n type AcpSessionUpdateIface,\n type TurnEndIface,\n} from \"./acp-frames.mjs\";\nexport type { AgentInput, AgentValue, AgentValueCodecIface } from \"./agent-input.mjs\";\nexport type {\n ActorOptionIface,\n ChannelAppsApiIface,\n ChannelBindingsApiIface,\n ChannelSourceIface,\n ChannelSourceOf,\n ChannelTicketsApiIface,\n IdentityLinksApiIface,\n InstallChannelArgsIface,\n ProjectChannelsApiIface,\n PublishChannelArgsIface,\n UpdateChannelBindingArgsIface,\n} from \"./channels.mjs\";\nexport {\n DEFAULT_AGENTS_HOST,\n type AgentClientIface,\n type AgentsApiIface,\n type AppApiIface,\n type CreateClientOptionsIface,\n type DecisionsApiIface,\n type InferenceApiIface,\n type PeopleApiIface,\n type PlatformIdentityApiIface,\n type RealtimeApiIface,\n} from \"./client.mjs\";\nexport {\n CollectionEventKind,\n CollectionResyncReason,\n type CollectionEvent,\n type CollectionEventsOptionsIface,\n type CollectionResyncEventIface,\n} from \"./collection-events.mjs\";\nexport {\n ConfigOptionCategory,\n configSelectFor,\n configSelectsOf,\n type ConfigSelectChoiceIface,\n type ConfigSelectIface,\n type SessionConfigOptionIface,\n} from \"./config-options.mjs\";\nexport type { EnumInput, SignalOptionsIface } from \"./context.mjs\";\nexport type {\n AllowedEndpointsApiIface,\n BudgetsApiIface,\n ModelCredentialGrantsApiIface,\n ModelCredentialsApiIface,\n OrganizationApiIface,\n OrganizationPolicyApiIface,\n SpendingRestrictionsApiIface,\n} from \"./organization.mjs\";\nexport type { ParticipantConfigurationApiIface } from \"./participant-configuration.mjs\";\nexport type {\n ConversationChannelRoutesApiIface,\n ConversationContextApiIface,\n ConversationContextEntryInputIface,\n ConversationDecisionsApiIface,\n ConversationInputsApiIface,\n ConversationLabelsApiIface,\n ConversationReadGrantsApiIface,\n ConversationResourcesIface,\n ResourceSubscriptionsApiIface,\n SendInputArgsIface,\n} from \"./conversation-resources.mjs\";\nexport {\n TURN_OPEN_SESSION_STATES,\n isNewerMessageVersion,\n messageVersionOf,\n type MessageVersionIface,\n} from \"./conversations.mjs\";\nexport type {\n ConversationAgentTurnIface,\n ConversationEvent,\n ConversationEventMetaIface,\n ConversationEventsOptionsIface,\n ConversationHandleIface,\n ConversationsApiIface,\n CreateConversationArgsIface,\n ListMessagesOptionsIface,\n OpenedConversationIface,\n ParticipantCreateInput,\n ParticipantsApiIface,\n ProjectConversationsApiIface,\n SandboxFileContentArgsIface,\n SandboxFileContentRequestIface,\n SendMessageOptionsIface,\n SentMessageIface,\n UploadAttachmentArgsIface,\n} from \"./conversations.mjs\";\nexport {\n AgentClientErrorName,\n ClientErrorCode,\n DecisionErrorReason,\n clientError,\n decisionError,\n isClientError,\n isDecisionError,\n isRealtimeSubscriptionError,\n isRequirementsUnmetError,\n isTerminalRealtimeError,\n isTurnRejectedError,\n realtimeSubscriptionError,\n requirementsUnmetError,\n turnRejectedError,\n type AgentClientError,\n type ClientErrorIface,\n type DecisionErrorIface,\n type RealtimeSubscriptionErrorIface,\n type RequirementsUnmetErrorIface,\n type TurnRejectedErrorIface,\n} from \"./errors.mjs\";\nexport {\n EVENTS_POLL_INTERVAL_MS,\n type EventsApiIface,\n type EventSubscriptionsApiIface,\n type ListEventsOptionsIface,\n type StreamEventsOptionsIface,\n} from \"./events.mjs\";\nexport { defaultStreamTiming, type StreamTimingIface } from \"./frame-stream.mjs\";\nexport type { AgentClientAuth, FetchIface, HeadersOption } from \"./http.mjs\";\nexport type {\n AcpAdaptersApiIface,\n DefinitionSelectorIface,\n HarnessesApiIface,\n SubscriptionAllowancesApiIface,\n} from \"./harnesses.mjs\";\nexport type { CallIntegrationToolArgsIface, IntegrationsApiIface } from \"./integrations.mjs\";\nexport { SessionLiveEventKind, type SessionLiveEvent } from \"./live-stream.mjs\";\nexport type { LocalComputeIface } from \"./local-host.mjs\";\nexport type { OAuthClientsApiIface, SignInReturnOriginsApiIface } from \"./oauth-clients.mjs\";\nexport type { ProjectClientIface } from \"./project.mjs\";\nexport type { AgentSelectorIface, ProjectAgentsApiIface } from \"./project-agents.mjs\";\nexport type {\n ProjectApiKeysApiIface,\n ProjectMembersApiIface,\n ProjectResourceApiIface,\n ProjectsApiIface,\n} from \"./projects.mjs\";\nexport type {\n ProjectPublisherApiIface,\n PublicNamesApiIface,\n PublisherHandleIface,\n PublishersApiIface,\n} from \"./publishers.mjs\";\nexport {\n provideDocumentOf,\n resourceIdOf,\n type ProvideIface,\n type ProvidePatchIface,\n type ResourceRef,\n type ResourceRefIface,\n} from \"./provide.mjs\";\nexport {\n createGatewayRealtimeTransport,\n type GatewayConnect,\n type GatewayConnectionIface,\n type GatewayRealtimeTransportOptionsIface,\n type RealtimeSubscribeOptionsIface,\n type RealtimeTransportFrameIface,\n type RealtimeTransportIface,\n} from \"./realtime.mjs\";\nexport {\n SANDBOX_FILE_URI_SCHEME,\n createSandboxFileUri,\n parseSandboxFileUri,\n type SandboxFileTargetIface,\n} from \"./sandbox-uri.mjs\";\nexport type { SandboxProvidersApiIface } from \"./sandbox-providers.mjs\";\nexport type {\n CreateSandboxOptionsIface,\n SandboxEnvironmentValueIface,\n SandboxHandleIface,\n SandboxOwnerIface,\n SandboxSetupRefIface,\n SandboxSetupsApiIface,\n SandboxesApiIface,\n} from \"./sandboxes.mjs\";\nexport type { ProjectSchedulesApiIface } from \"./schedules.mjs\";\nexport type {\n CreateSessionArgsIface,\n CreatedSessionIface,\n ForkSessionOptionsIface,\n ProjectSessionsApiIface,\n RespondArgs,\n SendOptionsIface,\n SessionHandleIface,\n SessionsApiIface,\n StreamOptionsIface,\n TurnHandleIface,\n TurnResultIface,\n} from \"./sessions.mjs\";\nexport type { TurnOutputOf, TurnOutputSchema, TurnOutputStandardSchemaIface } from \"./turn-output.mjs\";\n"],
5
5
  "mappings": "AAKA,cAAc;AACd;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAEK;AACP,SAAS,mBAA+D;AACxE;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAGK;AAeP;AAAA,EACE;AAAA,OAUK;AACP;AAAA,EACE;AAAA,EACA;AAAA,OAIK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OAIK;AAwBP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OAEK;AAoBP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAOK;AACP;AAAA,EACE;AAAA,OAKK;AACP,SAAS,2BAAmD;AAS5D,SAAS,4BAAmD;AAiB5D;AAAA,EACE;AAAA,EACA;AAAA,OAKK;AACP;AAAA,EACE;AAAA,OAOK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OAEK;",
6
6
  "names": []
7
7
  }
@@ -1,4 +1,6 @@
1
- import { type CompleteSignInResponseIface, type CreateIntegrationRequestIface, type IntegrationIface, type IntegrationListIface, type StartSignInResponseIface, type UpdateIntegrationRequestIface } from '@finalai/agent-protocol/agent-platform';
1
+ import { type JsonObjectIface } from '@finalai/agent-protocol';
2
+ import type { IntegrationRequirementInputIface } from '@finalai/agent-definition';
3
+ import { type CompleteSignInResponseIface, type CreateIntegrationRequestIface, type IntegrationIface, type IntegrationListIface, type IntegrationToolCallOutcomeType, type IntegrationToolIface, type StartSignInResponseIface, type UpdateIntegrationRequestIface } from '@finalai/agent-protocol/agent-platform';
2
4
  import { type ClientContextIface, type SignalOptionsIface } from "./context.mjs";
3
5
  export interface IntegrationsApiIface {
4
6
  /** Names are unique in a project. Returns the integration; pass it in `provide.integrations`. */
@@ -37,6 +39,28 @@ export interface IntegrationsApiIface {
37
39
  signOut: (args: {
38
40
  id: string;
39
41
  } & SignalOptionsIface) => Promise<void>;
42
+ /** The integration's tools (`integrations:read`), for an API key or an app. */
43
+ listTools: (integrationId: string, options?: SignalOptionsIface) => Promise<IntegrationToolIface[]>;
44
+ /**
45
+ * Calls one of its tools without a session (`integrations:call`), for an API key or an app
46
+ * (acting for the person its token names). On `decision_required`, call again with the same
47
+ * `callKey` and the decision's id once it resolves; a completed key returns its outcome again.
48
+ */
49
+ callTool: (integrationId: string, call: CallIntegrationToolArgsIface, options?: SignalOptionsIface) => Promise<IntegrationToolCallOutcomeType>;
50
+ }
51
+ export interface CallIntegrationToolArgsIface {
52
+ name: string;
53
+ arguments?: JsonObjectIface;
54
+ /** Unique per logical call: repeating it never runs the tool twice. */
55
+ callKey: string;
56
+ /** An agent requirement for the integration: tool allow/deny and approvals. */
57
+ requirement?: IntegrationRequirementInputIface;
58
+ /** Where an approval or a question is raised; required when one is needed. */
59
+ conversationId?: string;
60
+ /** The resolved decision this repeated call relies on. */
61
+ decisionId?: string;
62
+ /** Checks the call without running the tool. */
63
+ dryRun?: boolean;
40
64
  }
41
65
  export declare const createIntegrationsApi: (args: {
42
66
  context: ClientContextIface;
@@ -1,9 +1,13 @@
1
+ import { jsonObjectSchema } from "@finalai/agent-protocol";
1
2
  import {
3
+ callIntegrationToolRequestSchema,
2
4
  completeSignInRequestSchema,
3
5
  completeSignInResponseSchema,
4
6
  createIntegrationRequestSchema,
5
7
  integrationListSchema,
6
8
  integrationSchema,
9
+ integrationToolCallOutcomeSchema,
10
+ integrationToolListSchema,
7
11
  okResponseSchema,
8
12
  startSignInRequestSchema,
9
13
  startSignInResponseSchema,
@@ -91,7 +95,26 @@ const createIntegrationsApi = (args) => {
91
95
  response: okResponseSchema,
92
96
  signal
93
97
  });
94
- }
98
+ },
99
+ listTools: async (integrationId, options) => (await http.request({
100
+ method: HttpMethod.Get,
101
+ path: integrationPath(integrationId, "/tools"),
102
+ response: integrationToolListSchema,
103
+ signal: options?.signal
104
+ })).tools,
105
+ callTool: (integrationId, call, options) => http.request({
106
+ method: HttpMethod.Post,
107
+ path: integrationPath(integrationId, "/tools/call"),
108
+ body: {
109
+ schema: callIntegrationToolRequestSchema,
110
+ value: {
111
+ ...call,
112
+ requirement: call.requirement == null ? void 0 : jsonObjectSchema.parse(JSON.parse(JSON.stringify(call.requirement)))
113
+ }
114
+ },
115
+ response: integrationToolCallOutcomeSchema,
116
+ signal: options?.signal
117
+ })
95
118
  };
96
119
  };
97
120
  export {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/agent-client/integrations.ts"],
4
- "sourcesContent": ["import {\n completeSignInRequestSchema,\n completeSignInResponseSchema,\n createIntegrationRequestSchema,\n integrationListSchema,\n integrationSchema,\n okResponseSchema,\n startSignInRequestSchema,\n startSignInResponseSchema,\n updateIntegrationRequestSchema,\n type CompleteSignInResponseIface,\n type CreateIntegrationRequestIface,\n type IntegrationIface,\n type IntegrationListIface,\n type StartSignInResponseIface,\n type UpdateIntegrationRequestIface,\n} from '@finalai/agent-protocol/agent-platform';\nimport { encodePath, type ClientContextIface, type SignalOptionsIface } from \"./context.mjs\";\nimport { clientError, ClientErrorCode } from \"./errors.mjs\";\nimport { HttpMethod } from \"./http.mjs\";\n\n// Integrations (sources of tools: MCP servers, Final's gateway among them),\n// scoped to one project.\n\nexport interface IntegrationsApiIface {\n /** Names are unique in a project. Returns the integration; pass it in `provide.integrations`. */\n create: (args: CreateIntegrationRequestIface & SignalOptionsIface) => Promise<IntegrationIface>;\n get: (\n selector: ({ name: string } | { id: string }) & SignalOptionsIface,\n ) => Promise<IntegrationIface>;\n list: (\n options?: SignalOptionsIface & { cursor?: string; limit?: number },\n ) => Promise<IntegrationListIface>;\n /** Changes it in place: the id, and so every `provide` naming it, stays. */\n update: (\n args: { id: string } & UpdateIntegrationRequestIface & SignalOptionsIface,\n ) => Promise<IntegrationIface>;\n delete: (args: { id: string } & SignalOptionsIface) => Promise<void>;\n /**\n * Starts the caller's own sign-in: an authorization URL to open. Pass the\n * sign-in decision's id to resolve it when the sign-in completes.\n */\n signIn: (\n args: { id: string; returnUrl?: string; decisionId?: string } & SignalOptionsIface,\n ) => Promise<StartSignInResponseIface>;\n /** Activates a sign-in with the `state` and `code` the provider redirected with. */\n completeSignIn: (\n args: { state: string; code: string } & SignalOptionsIface,\n ) => Promise<CompleteSignInResponseIface>;\n /** Forgets the caller's own sign-in. */\n signOut: (args: { id: string } & SignalOptionsIface) => Promise<void>;\n}\n\nconst projectPath = (projectId: string, suffix: string): string =>\n `/v1/projects/${encodePath(projectId)}${suffix}`;\n\nexport const createIntegrationsApi = (args: {\n context: ClientContextIface;\n projectId: string;\n}): IntegrationsApiIface => {\n const { http } = args.context;\n const integrationPath = (id: string, suffix = '') =>\n projectPath(args.projectId, `/integrations/${encodePath(id)}${suffix}`);\n return {\n create: ({ signal, ...value }) =>\n http.request({\n method: HttpMethod.Post,\n path: projectPath(args.projectId, '/integrations'),\n body: { schema: createIntegrationRequestSchema, value },\n response: integrationSchema,\n signal,\n }),\n get: async ({ signal, ...selector }) => {\n if ('id' in selector)\n return http.request({\n method: HttpMethod.Get,\n path: integrationPath(selector.id),\n response: integrationSchema,\n signal,\n });\n const { integrations } = await http.request({\n method: HttpMethod.Get,\n path: projectPath(args.projectId, '/integrations'),\n query: { name: selector.name },\n response: integrationListSchema,\n signal,\n });\n const found = integrations.find((integration) => integration.name === selector.name);\n if (found == null)\n throw clientError({\n message: `No integration named ${selector.name} in this project`,\n status: 404,\n code: ClientErrorCode.NotFound,\n });\n return found;\n },\n list: (options) =>\n http.request({\n method: HttpMethod.Get,\n path: projectPath(args.projectId, '/integrations'),\n query: { cursor: options?.cursor, limit: options?.limit },\n response: integrationListSchema,\n signal: options?.signal,\n }),\n update: ({ id, signal, ...value }) =>\n http.request({\n method: HttpMethod.Patch,\n path: integrationPath(id),\n body: { schema: updateIntegrationRequestSchema, value },\n response: integrationSchema,\n signal,\n }),\n delete: async ({ id, signal }) => {\n await http.request({\n method: HttpMethod.Delete,\n path: integrationPath(id),\n response: okResponseSchema,\n signal,\n });\n },\n signIn: ({ id, signal, ...value }) =>\n http.request({\n method: HttpMethod.Post,\n path: integrationPath(id, '/sign-in'),\n body: { schema: startSignInRequestSchema, value },\n response: startSignInResponseSchema,\n signal,\n }),\n completeSignIn: ({ signal, ...value }) =>\n http.request({\n method: HttpMethod.Post,\n path: '/v1/sign-ins/complete',\n body: { schema: completeSignInRequestSchema, value },\n response: completeSignInResponseSchema,\n signal,\n }),\n signOut: async ({ id, signal }) => {\n await http.request({\n method: HttpMethod.Delete,\n path: integrationPath(id, '/sign-in'),\n response: okResponseSchema,\n signal,\n });\n },\n };\n};\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { jsonObjectSchema, type JsonObjectIface } from '@finalai/agent-protocol';\nimport type { IntegrationRequirementInputIface } from '@finalai/agent-definition';\nimport {\n callIntegrationToolRequestSchema,\n completeSignInRequestSchema,\n completeSignInResponseSchema,\n createIntegrationRequestSchema,\n integrationListSchema,\n integrationSchema,\n integrationToolCallOutcomeSchema,\n integrationToolListSchema,\n okResponseSchema,\n startSignInRequestSchema,\n startSignInResponseSchema,\n updateIntegrationRequestSchema,\n type CompleteSignInResponseIface,\n type CreateIntegrationRequestIface,\n type IntegrationIface,\n type IntegrationListIface,\n type IntegrationToolCallOutcomeType,\n type IntegrationToolIface,\n type StartSignInResponseIface,\n type UpdateIntegrationRequestIface,\n} from '@finalai/agent-protocol/agent-platform';\nimport { encodePath, type ClientContextIface, type SignalOptionsIface } from \"./context.mjs\";\nimport { clientError, ClientErrorCode } from \"./errors.mjs\";\nimport { HttpMethod } from \"./http.mjs\";\n\n// Integrations (sources of tools: MCP servers, Final's gateway among them),\n// scoped to one project.\n\nexport interface IntegrationsApiIface {\n /** Names are unique in a project. Returns the integration; pass it in `provide.integrations`. */\n create: (args: CreateIntegrationRequestIface & SignalOptionsIface) => Promise<IntegrationIface>;\n get: (\n selector: ({ name: string } | { id: string }) & SignalOptionsIface,\n ) => Promise<IntegrationIface>;\n list: (\n options?: SignalOptionsIface & { cursor?: string; limit?: number },\n ) => Promise<IntegrationListIface>;\n /** Changes it in place: the id, and so every `provide` naming it, stays. */\n update: (\n args: { id: string } & UpdateIntegrationRequestIface & SignalOptionsIface,\n ) => Promise<IntegrationIface>;\n delete: (args: { id: string } & SignalOptionsIface) => Promise<void>;\n /**\n * Starts the caller's own sign-in: an authorization URL to open. Pass the\n * sign-in decision's id to resolve it when the sign-in completes.\n */\n signIn: (\n args: { id: string; returnUrl?: string; decisionId?: string } & SignalOptionsIface,\n ) => Promise<StartSignInResponseIface>;\n /** Activates a sign-in with the `state` and `code` the provider redirected with. */\n completeSignIn: (\n args: { state: string; code: string } & SignalOptionsIface,\n ) => Promise<CompleteSignInResponseIface>;\n /** Forgets the caller's own sign-in. */\n signOut: (args: { id: string } & SignalOptionsIface) => Promise<void>;\n /** The integration's tools (`integrations:read`), for an API key or an app. */\n listTools: (\n integrationId: string,\n options?: SignalOptionsIface,\n ) => Promise<IntegrationToolIface[]>;\n /**\n * Calls one of its tools without a session (`integrations:call`), for an API key or an app\n * (acting for the person its token names). On `decision_required`, call again with the same\n * `callKey` and the decision's id once it resolves; a completed key returns its outcome again.\n */\n callTool: (\n integrationId: string,\n call: CallIntegrationToolArgsIface,\n options?: SignalOptionsIface,\n ) => Promise<IntegrationToolCallOutcomeType>;\n}\n\nexport interface CallIntegrationToolArgsIface {\n name: string;\n arguments?: JsonObjectIface;\n /** Unique per logical call: repeating it never runs the tool twice. */\n callKey: string;\n /** An agent requirement for the integration: tool allow/deny and approvals. */\n requirement?: IntegrationRequirementInputIface;\n /** Where an approval or a question is raised; required when one is needed. */\n conversationId?: string;\n /** The resolved decision this repeated call relies on. */\n decisionId?: string;\n /** Checks the call without running the tool. */\n dryRun?: boolean;\n}\n\nconst projectPath = (projectId: string, suffix: string): string =>\n `/v1/projects/${encodePath(projectId)}${suffix}`;\n\nexport const createIntegrationsApi = (args: {\n context: ClientContextIface;\n projectId: string;\n}): IntegrationsApiIface => {\n const { http } = args.context;\n const integrationPath = (id: string, suffix = '') =>\n projectPath(args.projectId, `/integrations/${encodePath(id)}${suffix}`);\n return {\n create: ({ signal, ...value }) =>\n http.request({\n method: HttpMethod.Post,\n path: projectPath(args.projectId, '/integrations'),\n body: { schema: createIntegrationRequestSchema, value },\n response: integrationSchema,\n signal,\n }),\n get: async ({ signal, ...selector }) => {\n if ('id' in selector)\n return http.request({\n method: HttpMethod.Get,\n path: integrationPath(selector.id),\n response: integrationSchema,\n signal,\n });\n const { integrations } = await http.request({\n method: HttpMethod.Get,\n path: projectPath(args.projectId, '/integrations'),\n query: { name: selector.name },\n response: integrationListSchema,\n signal,\n });\n const found = integrations.find((integration) => integration.name === selector.name);\n if (found == null)\n throw clientError({\n message: `No integration named ${selector.name} in this project`,\n status: 404,\n code: ClientErrorCode.NotFound,\n });\n return found;\n },\n list: (options) =>\n http.request({\n method: HttpMethod.Get,\n path: projectPath(args.projectId, '/integrations'),\n query: { cursor: options?.cursor, limit: options?.limit },\n response: integrationListSchema,\n signal: options?.signal,\n }),\n update: ({ id, signal, ...value }) =>\n http.request({\n method: HttpMethod.Patch,\n path: integrationPath(id),\n body: { schema: updateIntegrationRequestSchema, value },\n response: integrationSchema,\n signal,\n }),\n delete: async ({ id, signal }) => {\n await http.request({\n method: HttpMethod.Delete,\n path: integrationPath(id),\n response: okResponseSchema,\n signal,\n });\n },\n signIn: ({ id, signal, ...value }) =>\n http.request({\n method: HttpMethod.Post,\n path: integrationPath(id, '/sign-in'),\n body: { schema: startSignInRequestSchema, value },\n response: startSignInResponseSchema,\n signal,\n }),\n completeSignIn: ({ signal, ...value }) =>\n http.request({\n method: HttpMethod.Post,\n path: '/v1/sign-ins/complete',\n body: { schema: completeSignInRequestSchema, value },\n response: completeSignInResponseSchema,\n signal,\n }),\n signOut: async ({ id, signal }) => {\n await http.request({\n method: HttpMethod.Delete,\n path: integrationPath(id, '/sign-in'),\n response: okResponseSchema,\n signal,\n });\n },\n listTools: async (integrationId, options) =>\n (\n await http.request({\n method: HttpMethod.Get,\n path: integrationPath(integrationId, '/tools'),\n response: integrationToolListSchema,\n signal: options?.signal,\n })\n ).tools,\n callTool: (integrationId, call, options) =>\n http.request({\n method: HttpMethod.Post,\n path: integrationPath(integrationId, '/tools/call'),\n body: {\n schema: callIntegrationToolRequestSchema,\n value: {\n ...call,\n requirement:\n call.requirement == null\n ? undefined\n : jsonObjectSchema.parse(JSON.parse(JSON.stringify(call.requirement))),\n },\n },\n response: integrationToolCallOutcomeSchema,\n signal: options?.signal,\n }),\n };\n};\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -5,6 +5,7 @@ import { type ClientContextIface, type EnumInput, type SignalOptionsIface } from
5
5
  import { type SessionLiveEvent } from "./live-stream.mjs";
6
6
  import type { ProvideIface } from "./provide.mjs";
7
7
  import { type AgentStartDepsIface } from "./start.mjs";
8
+ import { type TurnOutputOf, type TurnOutputSchema } from "./turn-output.mjs";
8
9
  /** Answer a decision by option id (permission) or with a full ACP outcome. */
9
10
  export type RespondArgs = {
10
11
  decisionId: string;
@@ -19,7 +20,7 @@ export interface StreamOptionsIface extends SignalOptionsIface {
19
20
  /** Keep streaming live frames after replay catches up; defaults to true. */
20
21
  follow?: boolean;
21
22
  }
22
- export interface TurnResultIface<MessageId extends string | null = string> {
23
+ export interface TurnResultIface<MessageId extends string | null = string, Output = JsonValue> {
23
24
  messageId: MessageId;
24
25
  turnId: string;
25
26
  stopReason: string | null;
@@ -27,23 +28,36 @@ export interface TurnResultIface<MessageId extends string | null = string> {
27
28
  text: string;
28
29
  /** Seq of the frame that ended the turn. */
29
30
  toSeq: number;
31
+ /**
32
+ * The result the turn was asked for (`output`), parsed by its schema; null
33
+ * when none was asked for, or the turn ended without one (stop reason
34
+ * `output_missing`, or a cancelled or failed turn).
35
+ */
36
+ output: Output | null;
30
37
  }
31
38
  /** An accepted prompt. `stream()` yields this turn's frames; `result()` waits for its end. */
32
- export interface TurnHandleIface<MessageId extends string | null = string> extends Omit<PromptAcceptedIface, 'messageId'> {
39
+ export interface TurnHandleIface<MessageId extends string | null = string, Output = JsonValue> extends Omit<PromptAcceptedIface, 'messageId'> {
33
40
  messageId: MessageId;
34
41
  sessionId: string;
35
42
  get: (options?: SignalOptionsIface) => Promise<AgentTurnIface>;
36
43
  stream: (options?: SignalOptionsIface) => AsyncIterableIterator<AcpFrameEventIface>;
37
- result: (options?: SignalOptionsIface) => Promise<TurnResultIface<MessageId>>;
44
+ result: (options?: SignalOptionsIface) => Promise<TurnResultIface<MessageId, Output>>;
38
45
  /** The turn's visible agent text, once it ends. */
39
46
  text: (options?: SignalOptionsIface) => Promise<string>;
40
47
  }
41
- export interface SendOptionsIface extends SignalOptionsIface {
48
+ export interface SendOptionsIface<Schema extends TurnOutputSchema | undefined = undefined> extends SignalOptionsIface {
42
49
  turnPolicy?: EnumInput<AgentTurnPolicy>;
43
50
  idempotencyKey?: string;
44
51
  meta?: JsonObjectIface;
45
52
  /** When the person submitted, for the prompt-to-inference trace; defaults to now. */
46
53
  clientSubmittedAtMs?: number;
54
+ /**
55
+ * The result the turn must end with: a zod 4 schema (or another with Standard
56
+ * JSON Schema support) or a JSON Schema, whose root is an object. The turn
57
+ * waits for a running one to end instead of steering into it, and `result()`
58
+ * returns the result as `output`.
59
+ */
60
+ output?: Schema;
47
61
  }
48
62
  export interface ForkSessionOptionsIface extends SignalOptionsIface {
49
63
  /** Retain this key when retrying an interrupted fork. Defaults to a new key. */
@@ -58,7 +72,7 @@ export interface SessionHandleIface {
58
72
  get: (options?: SignalOptionsIface) => Promise<AgentSessionIface>;
59
73
  /** Resolves a `final-attachment:` resource link from this session's frames. */
60
74
  attachment: (attachmentId: string, options?: SignalOptionsIface) => Promise<AttachmentDownloadIface>;
61
- send: (content: ContentInput, options?: SendOptionsIface) => Promise<TurnHandleIface>;
75
+ send: <Schema extends TurnOutputSchema | undefined = undefined>(content: ContentInput, options?: SendOptionsIface<Schema>) => Promise<TurnHandleIface<string, TurnOutputOf<Schema>>>;
62
76
  /** Adds content to history without a model call (`_final/session/observe`). */
63
77
  observe: (content: ContentInput, options?: SignalOptionsIface & {
64
78
  idempotencyKey?: string;
@@ -117,7 +131,7 @@ export interface SessionHandleIface {
117
131
  */
118
132
  plan: (options?: SignalOptionsIface) => Promise<SessionPlanIface | null>;
119
133
  }
120
- export interface CreateSessionArgsIface extends SignalOptionsIface {
134
+ export interface CreateSessionArgsIface<Schema extends TurnOutputSchema | undefined = undefined> extends SignalOptionsIface {
121
135
  /**
122
136
  * A session id you chose, so whatever you create for it first (a sandbox it
123
137
  * owns) can name it. Creating with an id that exists returns that session.
@@ -135,6 +149,8 @@ export interface CreateSessionArgsIface extends SignalOptionsIface {
135
149
  displayName?: string;
136
150
  };
137
151
  message?: ContentInput;
152
+ /** The result the first turn must end with (see `SendOptionsIface.output`); requires `message`. */
153
+ output?: Schema;
138
154
  turnPolicy?: EnumInput<AgentTurnPolicy>;
139
155
  idempotencyKey?: string;
140
156
  title?: string;
@@ -142,11 +158,11 @@ export interface CreateSessionArgsIface extends SignalOptionsIface {
142
158
  /** When the person submitted `message`; defaults to now. */
143
159
  clientSubmittedAtMs?: number;
144
160
  }
145
- export interface CreatedSessionIface {
161
+ export interface CreatedSessionIface<Output = JsonValue> {
146
162
  session: AgentSessionIface;
147
163
  handle: SessionHandleIface;
148
164
  /** The first turn when `message` was given. */
149
- response: TurnHandleIface | null;
165
+ response: TurnHandleIface<string, Output> | null;
150
166
  }
151
167
  export interface SessionsApiIface {
152
168
  fork: (sessionId: string, options?: ForkSessionOptionsIface) => Promise<CreatedSessionIface>;
@@ -161,7 +177,7 @@ export interface ProjectSessionsApiIface extends SessionsApiIface {
161
177
  * Starts a session. Fails with `requirements_unmet`, creating nothing, unless
162
178
  * every requirement the agent does not mark optional is provided.
163
179
  */
164
- create: (args: CreateSessionArgsIface) => Promise<CreatedSessionIface>;
180
+ create: <Schema extends TurnOutputSchema | undefined = undefined>(args: CreateSessionArgsIface<Schema>) => Promise<CreatedSessionIface<TurnOutputOf<Schema>>>;
165
181
  }
166
182
  export declare const createProjectSessionsApi: (args: {
167
183
  context: ClientContextIface;
@@ -41,8 +41,13 @@ import { HttpMethod } from "./http.mjs";
41
41
  import { streamSessionLiveEvents } from "./live-stream.mjs";
42
42
  import { LocalHostOwnerKind } from "./local-host-protocol.mjs";
43
43
  import { serveCodeFor, startAgent } from "./start.mjs";
44
+ import {
45
+ outputJsonSchemaOf,
46
+ turnOutputParser
47
+ } from "./turn-output.mjs";
44
48
  const outcomeOf = (args) => "optionId" in args ? { outcome: "selected", optionId: args.optionId } : args.outcome;
45
49
  const sessionPath = (sessionId, suffix = "") => `/v1/sessions/${encodePath(sessionId)}${suffix}`;
50
+ const storedOutput = async (stored) => stored;
46
51
  const turnHandle = (args) => {
47
52
  const { context, sessionId, accepted } = args;
48
53
  const get = (options) => getTurn({ context, sessionId, turnId: accepted.turnId, signal: options?.signal });
@@ -84,6 +89,21 @@ const turnHandle = (args) => {
84
89
  };
85
90
  return iterator;
86
91
  };
92
+ const streamOn = (fromSeq, options) => streamSessionFrames({
93
+ sessionId,
94
+ fromSeq,
95
+ follow: true,
96
+ ...frameSources({ context, sessionId }),
97
+ transport: context.realtime(),
98
+ timing: context.timing,
99
+ signal: options?.signal,
100
+ closeSignal: context.closeSignal,
101
+ terminal: async (signal) => {
102
+ const receipt = await get({ signal });
103
+ return receipt.endedAt == null ? null : { throughSeq: receipt.toSeq ?? 0 };
104
+ },
105
+ until: (event) => turnEndOf(event) != null
106
+ });
87
107
  const result = async (options) => {
88
108
  const text = createTextCollector();
89
109
  let last = null;
@@ -91,14 +111,22 @@ const turnHandle = (args) => {
91
111
  text.add(event);
92
112
  last = event;
93
113
  }
114
+ let receipt = await get(options);
115
+ while (args.outputRequested && receipt.endedAt == null) {
116
+ for await (const event of streamOn((last?.seq ?? accepted.fromSeq ?? 0) + 1, options)) {
117
+ text.add(event);
118
+ last = event;
119
+ }
120
+ receipt = await get(options);
121
+ }
94
122
  const end = last == null ? null : turnEndOf(last);
95
- const receipt = await get(options);
96
123
  return {
97
124
  messageId: accepted.messageId,
98
125
  turnId: accepted.turnId,
99
126
  stopReason: receipt.stopReason ?? end?.stopReason ?? null,
100
127
  text: text.text(),
101
- toSeq: receipt.toSeq ?? last?.seq ?? accepted.fromSeq ?? 0
128
+ toSeq: receipt.toSeq ?? last?.seq ?? accepted.fromSeq ?? 0,
129
+ output: await args.output(receipt.output)
102
130
  };
103
131
  };
104
132
  return {
@@ -263,6 +291,7 @@ const createSessionHandle = (context, sessionId) => {
263
291
  signal: options?.signal
264
292
  })).provide,
265
293
  send: async (content, options) => {
294
+ const schema = options?.output;
266
295
  const accepted = await http.request({
267
296
  method: HttpMethod.Post,
268
297
  path: sessionPath(sessionId, "/prompt"),
@@ -270,6 +299,7 @@ const createSessionHandle = (context, sessionId) => {
270
299
  schema: promptSessionRequestSchema,
271
300
  value: {
272
301
  content,
302
+ output: schema == null ? void 0 : outputJsonSchemaOf(schema),
273
303
  turnPolicy: options?.turnPolicy,
274
304
  idempotencyKey: options?.idempotencyKey ?? context.newKey(),
275
305
  meta: options?.meta,
@@ -280,7 +310,13 @@ const createSessionHandle = (context, sessionId) => {
280
310
  signal: options?.signal,
281
311
  context: { sessionId }
282
312
  });
283
- return turnHandle({ context, sessionId, accepted });
313
+ return turnHandle({
314
+ context,
315
+ sessionId,
316
+ accepted,
317
+ output: turnOutputParser(schema),
318
+ outputRequested: schema != null
319
+ });
284
320
  },
285
321
  observe: (content, options) => post({
286
322
  suffix: "/observe",
@@ -325,7 +361,9 @@ const createSessionHandle = (context, sessionId) => {
325
361
  turnId: receipt.id,
326
362
  messageId: receipt.promptMessageId,
327
363
  fromSeq: receipt.fromSeq
328
- }
364
+ },
365
+ output: storedOutput,
366
+ outputRequested: false
329
367
  });
330
368
  },
331
369
  respond: (args, options) => http.request({
@@ -388,6 +426,7 @@ const createProjectSessionsApi = (args) => {
388
426
  provide: started.provide,
389
427
  actor: create.actor,
390
428
  message: create.message,
429
+ output: create.output == null ? void 0 : outputJsonSchemaOf(create.output),
391
430
  turnPolicy: create.turnPolicy,
392
431
  idempotencyKey: create.idempotencyKey ?? (create.message == null ? void 0 : context.newKey()),
393
432
  title: create.title,
@@ -413,7 +452,13 @@ const createProjectSessionsApi = (args) => {
413
452
  return {
414
453
  session: created.session,
415
454
  handle,
416
- response: created.turn == null ? null : turnHandle({ context, sessionId: created.session.id, accepted: created.turn })
455
+ response: created.turn == null ? null : turnHandle({
456
+ context,
457
+ sessionId: created.session.id,
458
+ accepted: created.turn,
459
+ output: turnOutputParser(create.output),
460
+ outputRequested: create.output != null
461
+ })
417
462
  };
418
463
  } catch (cause) {
419
464
  started.abandon();
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/agent-client/sessions.ts"],
4
- "sourcesContent": ["import type { JsonObjectIface, JsonValue } from '@finalai/agent-protocol';\nimport {\n acpFrameEventSchema,\n acpLiveTextEventSchema,\n acpPreviewEventSchema,\n agentRealtimeFrameSchema,\n AgentRealtimeFrameType,\n AgentRealtimeKind,\n agentRealtimeTopics,\n attachmentDownloadSchema,\n cancelRequestSchema,\n createSessionRequestSchema,\n createSessionResponseSchema,\n FIRST_ACP_FRAME_SEQ,\n forkSessionRequestSchema,\n observeSessionRequestSchema,\n decisionRecordListSchema,\n okResponseSchema,\n promptAcceptedSchema,\n promptSessionRequestSchema,\n respondDecisionResponseSchema,\n respondDecisionSchema,\n sessionFramesPageSchema,\n sessionLiveTextSchema,\n SessionRealtimeKind,\n sessionManifestSchema,\n sessionPlanResponseSchema,\n sessionRequirementsSchema,\n sessionSchema,\n setConfigOptionRequestSchema,\n turnSchema,\n type AcpFrameEventIface,\n type AcpLiveTextEventIface,\n type AcpPreviewEventIface,\n type ActorIface,\n type AgentSessionIface,\n type AgentTurnIface,\n type AgentTurnPolicy,\n type AttachmentDownloadIface,\n type ContentInput,\n type DecisionOutcomeInput,\n type DecisionRecordIface,\n type PromptAcceptedIface,\n type ProvideDocumentViewIface,\n type RequirementStatusIface,\n type RespondDecisionResponseIface,\n type SessionFramesPageIface,\n type SessionLiveTextIface,\n type SessionManifestIface,\n type SessionPlanIface,\n} from '@finalai/agent-protocol/agent-platform';\nimport { createTextCollector, isUserMessageFor, turnEndOf } from \"./acp-frames.mjs\";\nimport type { AgentInput } from \"./agent-input.mjs\";\nimport { createAsyncQueue, failOnAbort } from \"./async-queue.mjs\";\nimport {\n encodePath,\n type ClientContextIface,\n type EnumInput,\n type SignalOptionsIface,\n} from \"./context.mjs\";\nimport { isTerminalRealtimeError, realtimeSubscriptionError } from \"./errors.mjs\";\nimport { streamServerSentEvents } from \"./event-stream.mjs\";\nimport { streamSessionFrames } from \"./frame-stream.mjs\";\nimport { HttpMethod, type HttpBodyIface } from \"./http.mjs\";\nimport { streamSessionLiveEvents, type SessionLiveEvent } from \"./live-stream.mjs\";\nimport { LocalHostOwnerKind } from \"./local-host-protocol.mjs\";\nimport type { ProvideIface } from \"./provide.mjs\";\nimport type { RealtimeTransportFrameIface } from \"./realtime.mjs\";\nimport { serveCodeFor, startAgent, type AgentStartDepsIface } from \"./start.mjs\";\n\n/** Answer a decision by option id (permission) or with a full ACP outcome. */\nexport type RespondArgs =\n | { decisionId: string; optionId: string }\n | { decisionId: string; outcome: DecisionOutcomeInput };\n\nexport interface StreamOptionsIface extends SignalOptionsIface {\n /** Inclusive; defaults to `FIRST_ACP_FRAME_SEQ` (the whole log). Earlier values are clamped. */\n fromSeq?: number;\n /** Keep streaming live frames after replay catches up; defaults to true. */\n follow?: boolean;\n}\n\nexport interface TurnResultIface<MessageId extends string | null = string> {\n messageId: MessageId;\n turnId: string;\n stopReason: string | null;\n /** Visible agent text of the turn. */\n text: string;\n /** Seq of the frame that ended the turn. */\n toSeq: number;\n}\n\n/** An accepted prompt. `stream()` yields this turn's frames; `result()` waits for its end. */\nexport interface TurnHandleIface<MessageId extends string | null = string> extends Omit<\n PromptAcceptedIface,\n 'messageId'\n> {\n messageId: MessageId;\n sessionId: string;\n get: (options?: SignalOptionsIface) => Promise<AgentTurnIface>;\n stream: (options?: SignalOptionsIface) => AsyncIterableIterator<AcpFrameEventIface>;\n result: (options?: SignalOptionsIface) => Promise<TurnResultIface<MessageId>>;\n /** The turn's visible agent text, once it ends. */\n text: (options?: SignalOptionsIface) => Promise<string>;\n}\n\nexport interface SendOptionsIface extends SignalOptionsIface {\n turnPolicy?: EnumInput<AgentTurnPolicy>;\n idempotencyKey?: string;\n meta?: JsonObjectIface;\n /** When the person submitted, for the prompt-to-inference trace; defaults to now. */\n clientSubmittedAtMs?: number;\n}\n\nexport interface ForkSessionOptionsIface extends SignalOptionsIface {\n /** Retain this key when retrying an interrupted fork. Defaults to a new key. */\n idempotencyKey?: string;\n title?: string;\n}\n\n/** An I/O-free handle on one session; every method is one HTTP call or one stream. */\nexport interface SessionHandleIface {\n id: string;\n /** Native fork of an idle source on its pinned agent hash; the standalone child has fresh scopes. */\n fork: (options?: ForkSessionOptionsIface) => Promise<CreatedSessionIface>;\n get: (options?: SignalOptionsIface) => Promise<AgentSessionIface>;\n /** Resolves a `final-attachment:` resource link from this session's frames. */\n attachment: (\n attachmentId: string,\n options?: SignalOptionsIface,\n ) => Promise<AttachmentDownloadIface>;\n send: (content: ContentInput, options?: SendOptionsIface) => Promise<TurnHandleIface>;\n /** Adds content to history without a model call (`_final/session/observe`). */\n observe: (\n content: ContentInput,\n options?: SignalOptionsIface & { idempotencyKey?: string; meta?: JsonObjectIface },\n ) => Promise<void>;\n stream: (options?: StreamOptionsIface) => AsyncIterableIterator<AcpFrameEventIface>;\n /** Full provisional frames and reset notices; never a durable replay cursor or receipt. */\n liveEvents: (options?: SignalOptionsIface) => AsyncIterableIterator<SessionLiveEvent>;\n /**\n * `acp.preview` events: the text of message and thought chunks as the session\n * publishes them, live only (never replayed), for surfaces that render text\n * ahead of the durable frames and the conversation's projected messages.\n */\n previews: (options?: SignalOptionsIface) => AsyncIterableIterator<AcpPreviewEventIface>;\n /**\n * The agent's text as it streams, in arrival order: the saved chunks (`acp.preview`) and the\n * model's live text ahead of them (`acp.live_text`). Live only; start from `liveText()`.\n */\n textEvents: (\n options?: SignalOptionsIface,\n ) => AsyncIterableIterator<AcpPreviewEventIface | AcpLiveTextEventIface>;\n /** What each agent message of the session's open turns has streamed so far. */\n liveText: (options?: SignalOptionsIface) => Promise<SessionLiveTextIface>;\n /** One replay page (`GET /sessions/:id/frames`). */\n frames: (\n options: SignalOptionsIface & { fromSeq: number; limit?: number },\n ) => Promise<SessionFramesPageIface>;\n /** The session's open decisions (`GET /sessions/:id/decisions`). */\n decisions: (options?: SignalOptionsIface) => Promise<DecisionRecordIface[]>;\n turn: (turnId: string, options?: SignalOptionsIface) => Promise<AgentTurnIface>;\n /** Reconstruct an accepted response from its durable turn id, without resending its prompt. */\n response: (\n turnId: string,\n options?: SignalOptionsIface,\n ) => Promise<TurnHandleIface<string | null>>;\n respond: (\n args: RespondArgs,\n options?: SignalOptionsIface,\n ) => Promise<RespondDecisionResponseIface>;\n cancel: (options?: SignalOptionsIface & { reason?: string }) => Promise<void>;\n /**\n * ACP `session/set_config_option` (model, reasoning, mode, ...): `configId` and a value\n * from the options the harness advertises (`get().configOptions`, `configSelectsOf`).\n * Changing them takes the session's owner, or a conversation owner or admin.\n */\n setConfigOption: (\n args: { configId: string; value: JsonValue },\n options?: SignalOptionsIface,\n ) => Promise<void>;\n close: (options?: SignalOptionsIface) => Promise<void>;\n /** The agent document the session pins and the provide document it was resolved with. */\n manifest: (options?: SignalOptionsIface) => Promise<SessionManifestIface>;\n /** Each of the agent's requirements and what provides it now. */\n requirements: (options?: SignalOptionsIface) => Promise<RequirementStatusIface[]>;\n /** What the session was provided; null before its first open. */\n provide: (options?: SignalOptionsIface) => Promise<ProvideDocumentViewIface | null>;\n /**\n * The latest plan the agent reported, with its history (`GET \u2026/plan`); null\n * until it reports one. Each update raises `revision` and emits a\n * `session.plan_updated` event.\n */\n plan: (options?: SignalOptionsIface) => Promise<SessionPlanIface | null>;\n}\n\nexport interface CreateSessionArgsIface extends SignalOptionsIface {\n /**\n * A session id you chose, so whatever you create for it first (a sandbox it\n * owns) can name it. Creating with an id that exists returns that session.\n */\n id?: string;\n /** The agent you defined, or one fetched with `project.agents.get`; never a string. */\n agent: AgentInput;\n /**\n * What the agent requires. Files and shell left out run in this process\n * unless the client was created with `localCompute: false`.\n */\n provide: ProvideIface;\n /** Your app's end user the first turn acts for. */\n actor?: Omit<ActorIface, 'displayName'> & { displayName?: string };\n message?: ContentInput;\n turnPolicy?: EnumInput<AgentTurnPolicy>;\n idempotencyKey?: string;\n title?: string;\n meta?: JsonObjectIface;\n /** When the person submitted `message`; defaults to now. */\n clientSubmittedAtMs?: number;\n}\n\nexport interface CreatedSessionIface {\n session: AgentSessionIface;\n handle: SessionHandleIface;\n /** The first turn when `message` was given. */\n response: TurnHandleIface | null;\n}\n\nexport interface SessionsApiIface {\n fork: (sessionId: string, options?: ForkSessionOptionsIface) => Promise<CreatedSessionIface>;\n get: (sessionId: string, options?: SignalOptionsIface) => Promise<AgentSessionIface>;\n attach: (sessionId: string) => SessionHandleIface;\n}\n\nexport const outcomeOf = (args: RespondArgs): DecisionOutcomeInput =>\n 'optionId' in args ? { outcome: 'selected', optionId: args.optionId } : args.outcome;\n\nconst sessionPath = (sessionId: string, suffix = ''): string =>\n `/v1/sessions/${encodePath(sessionId)}${suffix}`;\n\ninterface TurnHandleArgsIface<MessageId extends string | null> {\n context: ClientContextIface;\n sessionId: string;\n accepted: Omit<PromptAcceptedIface, 'messageId'> & { messageId: MessageId };\n}\n\nconst turnHandle = <MessageId extends string | null>(\n args: TurnHandleArgsIface<MessageId>,\n): TurnHandleIface<MessageId> => {\n const { context, sessionId, accepted } = args;\n const get = (options?: SignalOptionsIface) =>\n getTurn({ context, sessionId, turnId: accepted.turnId, signal: options?.signal });\n const stream = (options?: SignalOptionsIface): AsyncIterableIterator<AcpFrameEventIface> => {\n // Without the prompt's seq, scan from the start for ACP's user message with this id.\n // `until` runs as frames are queued and `next` as they are consumed, so each tracks its own start.\n let queuedStart = accepted.messageId == null && accepted.fromSeq != null;\n let started = queuedStart;\n const frames = streamSessionFrames({\n sessionId,\n fromSeq: accepted.fromSeq ?? FIRST_ACP_FRAME_SEQ,\n follow: true,\n ...frameSources({ context, sessionId }),\n transport: context.realtime(),\n timing: context.timing,\n signal: options?.signal,\n closeSignal: context.closeSignal,\n terminal: async (signal) => {\n const receipt = await get({ signal });\n return receipt.endedAt == null ? null : { throughSeq: receipt.toSeq ?? 0 };\n },\n until: (event) => {\n if (\n !queuedStart &&\n accepted.messageId != null &&\n isUserMessageFor(event, accepted.messageId)\n )\n queuedStart = true;\n return queuedStart && turnEndOf(event) != null;\n },\n });\n const iterator: AsyncIterableIterator<AcpFrameEventIface> = {\n next: async () => {\n for (;;) {\n const next = await frames.next();\n if (next.done === true || started) return next;\n if (accepted.messageId != null && isUserMessageFor(next.value, accepted.messageId)) {\n started = true;\n return next;\n }\n }\n },\n return: () => frames.return?.() ?? Promise.resolve({ done: true, value: undefined }),\n [Symbol.asyncIterator]: () => iterator,\n };\n return iterator;\n };\n\n const result = async (options?: SignalOptionsIface): Promise<TurnResultIface<MessageId>> => {\n const text = createTextCollector();\n let last: AcpFrameEventIface | null = null;\n for await (const event of stream(options)) {\n text.add(event);\n last = event;\n }\n const end = last == null ? null : turnEndOf(last);\n const receipt = await get(options);\n return {\n messageId: accepted.messageId,\n turnId: accepted.turnId,\n stopReason: receipt.stopReason ?? end?.stopReason ?? null,\n text: text.text(),\n toSeq: receipt.toSeq ?? last?.seq ?? accepted.fromSeq ?? 0,\n };\n };\n\n return {\n ...accepted,\n sessionId,\n get,\n stream,\n result,\n text: async (options) => (await result(options)).text,\n };\n};\n\nconst getTurn = (args: {\n context: ClientContextIface;\n sessionId: string;\n turnId: string;\n signal?: AbortSignal;\n}): Promise<AgentTurnIface> =>\n args.context.http.request({\n method: HttpMethod.Get,\n path: sessionPath(args.sessionId, `/turns/${encodePath(args.turnId)}`),\n response: turnSchema,\n signal: args.signal,\n });\n\ninterface ReplayArgsIface extends SignalOptionsIface {\n context: ClientContextIface;\n sessionId: string;\n fromSeq: number;\n limit?: number;\n}\n\nconst replay = (args: ReplayArgsIface): Promise<SessionFramesPageIface> =>\n args.context.http.request({\n method: HttpMethod.Get,\n path: sessionPath(args.sessionId, '/frames'),\n query: { fromSeq: args.fromSeq, limit: args.limit },\n response: sessionFramesPageSchema,\n signal: args.signal,\n });\n\nconst openDecisions = async (args: {\n context: ClientContextIface;\n sessionId: string;\n signal?: AbortSignal;\n}): Promise<DecisionRecordIface[]> =>\n (\n await args.context.http.request({\n method: HttpMethod.Get,\n path: sessionPath(args.sessionId, '/decisions'),\n response: decisionRecordListSchema,\n signal: args.signal,\n })\n ).decisions;\n\n/** The session's frames over Streamable HTTP (`GET /sessions/:id/frames/stream`), from `fromSeq`. */\nasync function* streamFramesOverHttp(args: {\n context: ClientContextIface;\n sessionId: string;\n fromSeq: number;\n signal: AbortSignal;\n}): AsyncGenerator<AcpFrameEventIface> {\n for await (const message of streamServerSentEvents({\n http: args.context.http,\n path: sessionPath(args.sessionId, '/frames/stream'),\n query: { fromSeq: args.fromSeq },\n signal: AbortSignal.any([args.signal, args.context.closeSignal]),\n })) {\n if (message.event !== AgentRealtimeKind.AcpFrame) continue;\n try {\n const event = acpFrameEventSchema.safeParse(JSON.parse(message.data));\n if (event.success) yield event.data;\n } catch {\n // A malformed event is skipped; replay fills any gap it leaves.\n }\n }\n}\n\n/** Live `acp.preview` events of the session topic. */\nconst streamSessionEvents = <Value>(args: {\n context: ClientContextIface;\n sessionId: string;\n signal?: AbortSignal;\n /** The event a frame's kind and payload carry, or null to skip the frame. */\n parse: (kind: string, payload: unknown) => Value | null;\n}): AsyncIterableIterator<Value> => {\n const topic = agentRealtimeTopics.session(args.sessionId);\n let unsubscribe: (() => void) | null = null;\n let detachAbort: () => void = () => {};\n let detachClose: () => void = () => {};\n const queue = createAsyncQueue<Value>(() => {\n unsubscribe?.();\n detachAbort();\n detachClose();\n });\n const onFrame = (raw: RealtimeTransportFrameIface): void => {\n const frame = agentRealtimeFrameSchema.safeParse(raw);\n if (!frame.success) return;\n if (frame.data.type === AgentRealtimeFrameType.Error && isTerminalRealtimeError(frame.data)) {\n queue.fail(\n realtimeSubscriptionError({\n topic: frame.data.topic ?? topic,\n code: frame.data.code ?? 'unknown',\n message: frame.data.message ?? 'Realtime subscription was refused',\n }),\n );\n return;\n }\n if (frame.data.type !== AgentRealtimeFrameType.Event) return;\n const value = args.parse(frame.data.kind, frame.data.payload);\n if (value != null) queue.push(value);\n };\n detachAbort = failOnAbort(queue, args.signal);\n detachClose = failOnAbort(queue, args.context.closeSignal);\n if (!queue.closed()) {\n const stop = args.context.realtime().subscribe(topic, onFrame);\n if (queue.closed()) stop();\n else unsubscribe = stop;\n }\n return queue.iterator;\n};\n\nconst parsePreview = (kind: string, payload: unknown): AcpPreviewEventIface | null => {\n if (kind !== AgentRealtimeKind.AcpPreview) return null;\n const preview = acpPreviewEventSchema.safeParse(payload);\n return preview.success ? preview.data : null;\n};\n\nconst parseTextEvent = (\n kind: string,\n payload: unknown,\n): AcpPreviewEventIface | AcpLiveTextEventIface | null => {\n if (kind !== SessionRealtimeKind.AcpLiveText) return parsePreview(kind, payload);\n const live = acpLiveTextEventSchema.safeParse(payload);\n return live.success ? live.data : null;\n};\n\n/** Replay, open decisions and the Streamable HTTP fallback of one session's frame stream. */\nconst frameSources = (args: { context: ClientContextIface; sessionId: string }) => ({\n replay: (page: { fromSeq: number; limit: number; signal?: AbortSignal }) =>\n replay({ context: args.context, sessionId: args.sessionId, ...page }),\n decisions: (signal?: AbortSignal) => openDecisions({ ...args, signal }),\n httpStream: (stream: { fromSeq: number; signal: AbortSignal }) =>\n streamFramesOverHttp({ ...args, ...stream }),\n});\n\nexport const createSessionHandle = (\n context: ClientContextIface,\n sessionId: string,\n): SessionHandleIface => {\n const { http } = context;\n const post = async (args: {\n suffix: string;\n body?: HttpBodyIface;\n signal?: AbortSignal;\n }): Promise<void> => {\n await http.request({\n method: HttpMethod.Post,\n path: sessionPath(sessionId, args.suffix),\n body: args.body,\n response: okResponseSchema,\n signal: args.signal,\n context: { sessionId },\n });\n };\n\n return {\n id: sessionId,\n fork: async (options) => {\n const created = await http.request({\n method: HttpMethod.Post,\n path: sessionPath(sessionId, '/fork'),\n body: {\n schema: forkSessionRequestSchema,\n value: {\n idempotencyKey: options?.idempotencyKey ?? context.newKey(),\n title: options?.title,\n },\n },\n response: createSessionResponseSchema,\n signal: options?.signal,\n context: { sessionId },\n });\n return {\n session: created.session,\n handle: createSessionHandle(context, created.session.id),\n response: null,\n };\n },\n attachment: (attachmentId, options) =>\n http.request({\n method: HttpMethod.Get,\n path: sessionPath(sessionId, `/attachments/${encodePath(attachmentId)}`),\n response: attachmentDownloadSchema,\n signal: options?.signal,\n }),\n get: (options) =>\n http.request({\n method: HttpMethod.Get,\n path: sessionPath(sessionId),\n response: sessionSchema,\n signal: options?.signal,\n }),\n manifest: (options) =>\n http.request({\n method: HttpMethod.Get,\n path: sessionPath(sessionId, '/manifest'),\n response: sessionManifestSchema,\n signal: options?.signal,\n }),\n requirements: async (options) =>\n (\n await http.request({\n method: HttpMethod.Get,\n path: sessionPath(sessionId, '/requirements'),\n response: sessionRequirementsSchema,\n signal: options?.signal,\n })\n ).requirements,\n provide: async (options) =>\n (\n await http.request({\n method: HttpMethod.Get,\n path: sessionPath(sessionId, '/manifest'),\n response: sessionManifestSchema,\n signal: options?.signal,\n })\n ).provide,\n send: async (content, options) => {\n const accepted = await http.request({\n method: HttpMethod.Post,\n path: sessionPath(sessionId, '/prompt'),\n body: {\n schema: promptSessionRequestSchema,\n value: {\n content,\n turnPolicy: options?.turnPolicy,\n idempotencyKey: options?.idempotencyKey ?? context.newKey(),\n meta: options?.meta,\n clientSubmittedAtMs: options?.clientSubmittedAtMs ?? context.now(),\n },\n },\n response: promptAcceptedSchema,\n signal: options?.signal,\n context: { sessionId },\n });\n return turnHandle({ context, sessionId, accepted });\n },\n observe: (content, options) =>\n post({\n suffix: '/observe',\n body: {\n schema: observeSessionRequestSchema,\n value: {\n content,\n idempotencyKey: options?.idempotencyKey ?? context.newKey(),\n meta: options?.meta,\n },\n },\n signal: options?.signal,\n }),\n stream: (options) =>\n streamSessionFrames({\n sessionId,\n fromSeq: options?.fromSeq ?? FIRST_ACP_FRAME_SEQ,\n follow: options?.follow ?? true,\n ...frameSources({ context, sessionId }),\n transport: context.realtime(),\n timing: context.timing,\n signal: options?.signal,\n closeSignal: context.closeSignal,\n }),\n liveEvents: (options) =>\n streamSessionLiveEvents({ context, sessionId, signal: options?.signal }),\n previews: (options) =>\n streamSessionEvents({ context, sessionId, signal: options?.signal, parse: parsePreview }),\n textEvents: (options) =>\n streamSessionEvents({ context, sessionId, signal: options?.signal, parse: parseTextEvent }),\n liveText: (options) =>\n http.request({\n method: HttpMethod.Get,\n path: sessionPath(sessionId, '/live-text'),\n response: sessionLiveTextSchema,\n signal: options?.signal,\n }),\n frames: (options) => replay({ context, sessionId, ...options }),\n decisions: (options) => openDecisions({ context, sessionId, signal: options?.signal }),\n turn: (turnId, options) => getTurn({ context, sessionId, turnId, signal: options?.signal }),\n response: async (turnId, options) => {\n const receipt = await getTurn({ context, sessionId, turnId, signal: options?.signal });\n return turnHandle({\n context,\n sessionId,\n accepted: {\n turnId: receipt.id,\n messageId: receipt.promptMessageId,\n fromSeq: receipt.fromSeq,\n },\n });\n },\n respond: (args, options) =>\n http.request({\n method: HttpMethod.Post,\n path: sessionPath(sessionId, '/respond'),\n body: {\n schema: respondDecisionSchema,\n value: { decisionId: args.decisionId, outcome: outcomeOf(args) },\n },\n response: respondDecisionResponseSchema,\n signal: options?.signal,\n context: { sessionId, decisionId: args.decisionId },\n }),\n cancel: (options) =>\n post({\n suffix: '/cancel',\n body: { schema: cancelRequestSchema, value: { reason: options?.reason } },\n signal: options?.signal,\n }),\n setConfigOption: (args, options) =>\n post({\n suffix: '/config-option',\n body: { schema: setConfigOptionRequestSchema, value: args },\n signal: options?.signal,\n }),\n close: (options) => post({ suffix: '/close', signal: options?.signal }),\n plan: async (options) =>\n (\n await http.request({\n method: HttpMethod.Get,\n path: sessionPath(sessionId, '/plan'),\n response: sessionPlanResponseSchema,\n signal: options?.signal,\n })\n ).plan,\n };\n};\n\nexport const createSessionsApi = (context: ClientContextIface): SessionsApiIface => ({\n fork: (sessionId, options) => createSessionHandle(context, sessionId).fork(options),\n get: (sessionId, options) => createSessionHandle(context, sessionId).get(options),\n attach: (sessionId) => createSessionHandle(context, sessionId),\n});\n\nexport interface ProjectSessionsApiIface extends SessionsApiIface {\n /**\n * Starts a session. Fails with `requirements_unmet`, creating nothing, unless\n * every requirement the agent does not mark optional is provided.\n */\n create: (args: CreateSessionArgsIface) => Promise<CreatedSessionIface>;\n}\n\nexport const createProjectSessionsApi = (args: {\n context: ClientContextIface;\n projectId: string;\n start: AgentStartDepsIface;\n}): ProjectSessionsApiIface => {\n const { context } = args;\n return {\n ...createSessionsApi(context),\n create: async (create) => {\n const started = await startAgent(args.start, {\n projectId: args.projectId,\n agent: create.agent,\n provide: create.provide,\n owner: { kind: LocalHostOwnerKind.Session, id: create.id },\n signal: create.signal,\n });\n try {\n const created = await context.http.request({\n method: HttpMethod.Post,\n path: '/v1/sessions',\n body: {\n schema: createSessionRequestSchema,\n value: {\n id: started.ownerId ?? create.id,\n projectId: args.projectId,\n agent: started.ref,\n provide: started.provide,\n actor: create.actor,\n message: create.message,\n turnPolicy: create.turnPolicy,\n idempotencyKey:\n create.idempotencyKey ?? (create.message == null ? undefined : context.newKey()),\n title: create.title,\n meta: create.meta,\n clientSubmittedAtMs:\n create.message == null ? undefined : (create.clientSubmittedAtMs ?? context.now()),\n },\n },\n response: createSessionResponseSchema,\n signal: create.signal,\n });\n const reserved = started.ownerId ?? create.id;\n if (reserved != null && created.session.id !== reserved) {\n // The idempotency key replayed an earlier creation: the session is that one, not\n // the id this call reserved, and what was started for that id serves nothing. Its\n // in-process code is served for it from here; its compute stays what that\n // creation named, which nothing can change now.\n started.abandon();\n if (started.host != null)\n await serveCodeFor(args.start, {\n projectId: args.projectId,\n agent: create.agent,\n owner: { kind: LocalHostOwnerKind.Session, id: created.session.id },\n signal: create.signal,\n });\n } else started.established();\n const handle = createSessionHandle(context, created.session.id);\n return {\n session: created.session,\n handle,\n response:\n created.turn == null\n ? null\n : turnHandle({ context, sessionId: created.session.id, accepted: created.turn }),\n };\n } catch (cause) {\n started.abandon();\n throw cause;\n }\n },\n };\n};\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import type { JsonObjectIface, JsonValue } from '@finalai/agent-protocol';\nimport {\n acpFrameEventSchema,\n acpLiveTextEventSchema,\n acpPreviewEventSchema,\n agentRealtimeFrameSchema,\n AgentRealtimeFrameType,\n AgentRealtimeKind,\n agentRealtimeTopics,\n attachmentDownloadSchema,\n cancelRequestSchema,\n createSessionRequestSchema,\n createSessionResponseSchema,\n FIRST_ACP_FRAME_SEQ,\n forkSessionRequestSchema,\n observeSessionRequestSchema,\n decisionRecordListSchema,\n okResponseSchema,\n promptAcceptedSchema,\n promptSessionRequestSchema,\n respondDecisionResponseSchema,\n respondDecisionSchema,\n sessionFramesPageSchema,\n sessionLiveTextSchema,\n SessionRealtimeKind,\n sessionManifestSchema,\n sessionPlanResponseSchema,\n sessionRequirementsSchema,\n sessionSchema,\n setConfigOptionRequestSchema,\n turnSchema,\n type AcpFrameEventIface,\n type AcpLiveTextEventIface,\n type AcpPreviewEventIface,\n type ActorIface,\n type AgentSessionIface,\n type AgentTurnIface,\n type AgentTurnPolicy,\n type AttachmentDownloadIface,\n type ContentInput,\n type DecisionOutcomeInput,\n type DecisionRecordIface,\n type PromptAcceptedIface,\n type ProvideDocumentViewIface,\n type RequirementStatusIface,\n type RespondDecisionResponseIface,\n type SessionFramesPageIface,\n type SessionLiveTextIface,\n type SessionManifestIface,\n type SessionPlanIface,\n} from '@finalai/agent-protocol/agent-platform';\nimport { createTextCollector, isUserMessageFor, turnEndOf } from \"./acp-frames.mjs\";\nimport type { AgentInput } from \"./agent-input.mjs\";\nimport { createAsyncQueue, failOnAbort } from \"./async-queue.mjs\";\nimport {\n encodePath,\n type ClientContextIface,\n type EnumInput,\n type SignalOptionsIface,\n} from \"./context.mjs\";\nimport { isTerminalRealtimeError, realtimeSubscriptionError } from \"./errors.mjs\";\nimport { streamServerSentEvents } from \"./event-stream.mjs\";\nimport { streamSessionFrames } from \"./frame-stream.mjs\";\nimport { HttpMethod, type HttpBodyIface } from \"./http.mjs\";\nimport { streamSessionLiveEvents, type SessionLiveEvent } from \"./live-stream.mjs\";\nimport { LocalHostOwnerKind } from \"./local-host-protocol.mjs\";\nimport type { ProvideIface } from \"./provide.mjs\";\nimport type { RealtimeTransportFrameIface } from \"./realtime.mjs\";\nimport { serveCodeFor, startAgent, type AgentStartDepsIface } from \"./start.mjs\";\nimport {\n outputJsonSchemaOf,\n turnOutputParser,\n type TurnOutputOf,\n type TurnOutputSchema,\n} from \"./turn-output.mjs\";\n\n/** Answer a decision by option id (permission) or with a full ACP outcome. */\nexport type RespondArgs =\n | { decisionId: string; optionId: string }\n | { decisionId: string; outcome: DecisionOutcomeInput };\n\nexport interface StreamOptionsIface extends SignalOptionsIface {\n /** Inclusive; defaults to `FIRST_ACP_FRAME_SEQ` (the whole log). Earlier values are clamped. */\n fromSeq?: number;\n /** Keep streaming live frames after replay catches up; defaults to true. */\n follow?: boolean;\n}\n\nexport interface TurnResultIface<MessageId extends string | null = string, Output = JsonValue> {\n messageId: MessageId;\n turnId: string;\n stopReason: string | null;\n /** Visible agent text of the turn. */\n text: string;\n /** Seq of the frame that ended the turn. */\n toSeq: number;\n /**\n * The result the turn was asked for (`output`), parsed by its schema; null\n * when none was asked for, or the turn ended without one (stop reason\n * `output_missing`, or a cancelled or failed turn).\n */\n output: Output | null;\n}\n\n/** An accepted prompt. `stream()` yields this turn's frames; `result()` waits for its end. */\nexport interface TurnHandleIface<\n MessageId extends string | null = string,\n Output = JsonValue,\n> extends Omit<PromptAcceptedIface, 'messageId'> {\n messageId: MessageId;\n sessionId: string;\n get: (options?: SignalOptionsIface) => Promise<AgentTurnIface>;\n stream: (options?: SignalOptionsIface) => AsyncIterableIterator<AcpFrameEventIface>;\n result: (options?: SignalOptionsIface) => Promise<TurnResultIface<MessageId, Output>>;\n /** The turn's visible agent text, once it ends. */\n text: (options?: SignalOptionsIface) => Promise<string>;\n}\n\nexport interface SendOptionsIface<\n Schema extends TurnOutputSchema | undefined = undefined,\n> extends SignalOptionsIface {\n turnPolicy?: EnumInput<AgentTurnPolicy>;\n idempotencyKey?: string;\n meta?: JsonObjectIface;\n /** When the person submitted, for the prompt-to-inference trace; defaults to now. */\n clientSubmittedAtMs?: number;\n /**\n * The result the turn must end with: a zod 4 schema (or another with Standard\n * JSON Schema support) or a JSON Schema, whose root is an object. The turn\n * waits for a running one to end instead of steering into it, and `result()`\n * returns the result as `output`.\n */\n output?: Schema;\n}\n\nexport interface ForkSessionOptionsIface extends SignalOptionsIface {\n /** Retain this key when retrying an interrupted fork. Defaults to a new key. */\n idempotencyKey?: string;\n title?: string;\n}\n\n/** An I/O-free handle on one session; every method is one HTTP call or one stream. */\nexport interface SessionHandleIface {\n id: string;\n /** Native fork of an idle source on its pinned agent hash; the standalone child has fresh scopes. */\n fork: (options?: ForkSessionOptionsIface) => Promise<CreatedSessionIface>;\n get: (options?: SignalOptionsIface) => Promise<AgentSessionIface>;\n /** Resolves a `final-attachment:` resource link from this session's frames. */\n attachment: (\n attachmentId: string,\n options?: SignalOptionsIface,\n ) => Promise<AttachmentDownloadIface>;\n send: <Schema extends TurnOutputSchema | undefined = undefined>(\n content: ContentInput,\n options?: SendOptionsIface<Schema>,\n ) => Promise<TurnHandleIface<string, TurnOutputOf<Schema>>>;\n /** Adds content to history without a model call (`_final/session/observe`). */\n observe: (\n content: ContentInput,\n options?: SignalOptionsIface & { idempotencyKey?: string; meta?: JsonObjectIface },\n ) => Promise<void>;\n stream: (options?: StreamOptionsIface) => AsyncIterableIterator<AcpFrameEventIface>;\n /** Full provisional frames and reset notices; never a durable replay cursor or receipt. */\n liveEvents: (options?: SignalOptionsIface) => AsyncIterableIterator<SessionLiveEvent>;\n /**\n * `acp.preview` events: the text of message and thought chunks as the session\n * publishes them, live only (never replayed), for surfaces that render text\n * ahead of the durable frames and the conversation's projected messages.\n */\n previews: (options?: SignalOptionsIface) => AsyncIterableIterator<AcpPreviewEventIface>;\n /**\n * The agent's text as it streams, in arrival order: the saved chunks (`acp.preview`) and the\n * model's live text ahead of them (`acp.live_text`). Live only; start from `liveText()`.\n */\n textEvents: (\n options?: SignalOptionsIface,\n ) => AsyncIterableIterator<AcpPreviewEventIface | AcpLiveTextEventIface>;\n /** What each agent message of the session's open turns has streamed so far. */\n liveText: (options?: SignalOptionsIface) => Promise<SessionLiveTextIface>;\n /** One replay page (`GET /sessions/:id/frames`). */\n frames: (\n options: SignalOptionsIface & { fromSeq: number; limit?: number },\n ) => Promise<SessionFramesPageIface>;\n /** The session's open decisions (`GET /sessions/:id/decisions`). */\n decisions: (options?: SignalOptionsIface) => Promise<DecisionRecordIface[]>;\n turn: (turnId: string, options?: SignalOptionsIface) => Promise<AgentTurnIface>;\n /** Reconstruct an accepted response from its durable turn id, without resending its prompt. */\n response: (\n turnId: string,\n options?: SignalOptionsIface,\n ) => Promise<TurnHandleIface<string | null>>;\n respond: (\n args: RespondArgs,\n options?: SignalOptionsIface,\n ) => Promise<RespondDecisionResponseIface>;\n cancel: (options?: SignalOptionsIface & { reason?: string }) => Promise<void>;\n /**\n * ACP `session/set_config_option` (model, reasoning, mode, ...): `configId` and a value\n * from the options the harness advertises (`get().configOptions`, `configSelectsOf`).\n * Changing them takes the session's owner, or a conversation owner or admin.\n */\n setConfigOption: (\n args: { configId: string; value: JsonValue },\n options?: SignalOptionsIface,\n ) => Promise<void>;\n close: (options?: SignalOptionsIface) => Promise<void>;\n /** The agent document the session pins and the provide document it was resolved with. */\n manifest: (options?: SignalOptionsIface) => Promise<SessionManifestIface>;\n /** Each of the agent's requirements and what provides it now. */\n requirements: (options?: SignalOptionsIface) => Promise<RequirementStatusIface[]>;\n /** What the session was provided; null before its first open. */\n provide: (options?: SignalOptionsIface) => Promise<ProvideDocumentViewIface | null>;\n /**\n * The latest plan the agent reported, with its history (`GET \u2026/plan`); null\n * until it reports one. Each update raises `revision` and emits a\n * `session.plan_updated` event.\n */\n plan: (options?: SignalOptionsIface) => Promise<SessionPlanIface | null>;\n}\n\nexport interface CreateSessionArgsIface<\n Schema extends TurnOutputSchema | undefined = undefined,\n> extends SignalOptionsIface {\n /**\n * A session id you chose, so whatever you create for it first (a sandbox it\n * owns) can name it. Creating with an id that exists returns that session.\n */\n id?: string;\n /** The agent you defined, or one fetched with `project.agents.get`; never a string. */\n agent: AgentInput;\n /**\n * What the agent requires. Files and shell left out run in this process\n * unless the client was created with `localCompute: false`.\n */\n provide: ProvideIface;\n /** Your app's end user the first turn acts for. */\n actor?: Omit<ActorIface, 'displayName'> & { displayName?: string };\n message?: ContentInput;\n /** The result the first turn must end with (see `SendOptionsIface.output`); requires `message`. */\n output?: Schema;\n turnPolicy?: EnumInput<AgentTurnPolicy>;\n idempotencyKey?: string;\n title?: string;\n meta?: JsonObjectIface;\n /** When the person submitted `message`; defaults to now. */\n clientSubmittedAtMs?: number;\n}\n\nexport interface CreatedSessionIface<Output = JsonValue> {\n session: AgentSessionIface;\n handle: SessionHandleIface;\n /** The first turn when `message` was given. */\n response: TurnHandleIface<string, Output> | null;\n}\n\nexport interface SessionsApiIface {\n fork: (sessionId: string, options?: ForkSessionOptionsIface) => Promise<CreatedSessionIface>;\n get: (sessionId: string, options?: SignalOptionsIface) => Promise<AgentSessionIface>;\n attach: (sessionId: string) => SessionHandleIface;\n}\n\nexport const outcomeOf = (args: RespondArgs): DecisionOutcomeInput =>\n 'optionId' in args ? { outcome: 'selected', optionId: args.optionId } : args.outcome;\n\nconst sessionPath = (sessionId: string, suffix = ''): string =>\n `/v1/sessions/${encodePath(sessionId)}${suffix}`;\n\ninterface TurnHandleArgsIface<MessageId extends string | null, Output> {\n context: ClientContextIface;\n sessionId: string;\n accepted: Omit<PromptAcceptedIface, 'messageId'> & { messageId: MessageId };\n // How `result()` reads the turn's stored result.\n output: (stored: JsonValue | null) => Promise<Output | null>;\n // The turn was asked for a result: it may outlast an idle (the platform asks\n // the agent once more), so `result()` reads on until the turn record ends.\n outputRequested: boolean;\n}\n\nconst storedOutput = async (stored: JsonValue | null): Promise<JsonValue | null> => stored;\n\nconst turnHandle = <MessageId extends string | null, Output>(\n args: TurnHandleArgsIface<MessageId, Output>,\n): TurnHandleIface<MessageId, Output> => {\n const { context, sessionId, accepted } = args;\n const get = (options?: SignalOptionsIface) =>\n getTurn({ context, sessionId, turnId: accepted.turnId, signal: options?.signal });\n const stream = (options?: SignalOptionsIface): AsyncIterableIterator<AcpFrameEventIface> => {\n // Without the prompt's seq, scan from the start for ACP's user message with this id.\n // `until` runs as frames are queued and `next` as they are consumed, so each tracks its own start.\n let queuedStart = accepted.messageId == null && accepted.fromSeq != null;\n let started = queuedStart;\n const frames = streamSessionFrames({\n sessionId,\n fromSeq: accepted.fromSeq ?? FIRST_ACP_FRAME_SEQ,\n follow: true,\n ...frameSources({ context, sessionId }),\n transport: context.realtime(),\n timing: context.timing,\n signal: options?.signal,\n closeSignal: context.closeSignal,\n terminal: async (signal) => {\n const receipt = await get({ signal });\n return receipt.endedAt == null ? null : { throughSeq: receipt.toSeq ?? 0 };\n },\n until: (event) => {\n if (\n !queuedStart &&\n accepted.messageId != null &&\n isUserMessageFor(event, accepted.messageId)\n )\n queuedStart = true;\n return queuedStart && turnEndOf(event) != null;\n },\n });\n const iterator: AsyncIterableIterator<AcpFrameEventIface> = {\n next: async () => {\n for (;;) {\n const next = await frames.next();\n if (next.done === true || started) return next;\n if (accepted.messageId != null && isUserMessageFor(next.value, accepted.messageId)) {\n started = true;\n return next;\n }\n }\n },\n return: () => frames.return?.() ?? Promise.resolve({ done: true, value: undefined }),\n [Symbol.asyncIterator]: () => iterator,\n };\n return iterator;\n };\n\n // The turn's frames after `fromSeq` through its next idle, or through its end\n // once the turn record has one.\n const streamOn = (\n fromSeq: number,\n options?: SignalOptionsIface,\n ): AsyncIterableIterator<AcpFrameEventIface> =>\n streamSessionFrames({\n sessionId,\n fromSeq,\n follow: true,\n ...frameSources({ context, sessionId }),\n transport: context.realtime(),\n timing: context.timing,\n signal: options?.signal,\n closeSignal: context.closeSignal,\n terminal: async (signal) => {\n const receipt = await get({ signal });\n return receipt.endedAt == null ? null : { throughSeq: receipt.toSeq ?? 0 };\n },\n until: (event) => turnEndOf(event) != null,\n });\n\n const result = async (\n options?: SignalOptionsIface,\n ): Promise<TurnResultIface<MessageId, Output>> => {\n const text = createTextCollector();\n let last: AcpFrameEventIface | null = null;\n for await (const event of stream(options)) {\n text.add(event);\n last = event;\n }\n let receipt = await get(options);\n while (args.outputRequested && receipt.endedAt == null) {\n // An idle without the result: the platform asks the agent once more, in the same turn.\n for await (const event of streamOn((last?.seq ?? accepted.fromSeq ?? 0) + 1, options)) {\n text.add(event);\n last = event;\n }\n receipt = await get(options);\n }\n const end = last == null ? null : turnEndOf(last);\n return {\n messageId: accepted.messageId,\n turnId: accepted.turnId,\n stopReason: receipt.stopReason ?? end?.stopReason ?? null,\n text: text.text(),\n toSeq: receipt.toSeq ?? last?.seq ?? accepted.fromSeq ?? 0,\n output: await args.output(receipt.output),\n };\n };\n\n return {\n ...accepted,\n sessionId,\n get,\n stream,\n result,\n text: async (options) => (await result(options)).text,\n };\n};\n\nconst getTurn = (args: {\n context: ClientContextIface;\n sessionId: string;\n turnId: string;\n signal?: AbortSignal;\n}): Promise<AgentTurnIface> =>\n args.context.http.request({\n method: HttpMethod.Get,\n path: sessionPath(args.sessionId, `/turns/${encodePath(args.turnId)}`),\n response: turnSchema,\n signal: args.signal,\n });\n\ninterface ReplayArgsIface extends SignalOptionsIface {\n context: ClientContextIface;\n sessionId: string;\n fromSeq: number;\n limit?: number;\n}\n\nconst replay = (args: ReplayArgsIface): Promise<SessionFramesPageIface> =>\n args.context.http.request({\n method: HttpMethod.Get,\n path: sessionPath(args.sessionId, '/frames'),\n query: { fromSeq: args.fromSeq, limit: args.limit },\n response: sessionFramesPageSchema,\n signal: args.signal,\n });\n\nconst openDecisions = async (args: {\n context: ClientContextIface;\n sessionId: string;\n signal?: AbortSignal;\n}): Promise<DecisionRecordIface[]> =>\n (\n await args.context.http.request({\n method: HttpMethod.Get,\n path: sessionPath(args.sessionId, '/decisions'),\n response: decisionRecordListSchema,\n signal: args.signal,\n })\n ).decisions;\n\n/** The session's frames over Streamable HTTP (`GET /sessions/:id/frames/stream`), from `fromSeq`. */\nasync function* streamFramesOverHttp(args: {\n context: ClientContextIface;\n sessionId: string;\n fromSeq: number;\n signal: AbortSignal;\n}): AsyncGenerator<AcpFrameEventIface> {\n for await (const message of streamServerSentEvents({\n http: args.context.http,\n path: sessionPath(args.sessionId, '/frames/stream'),\n query: { fromSeq: args.fromSeq },\n signal: AbortSignal.any([args.signal, args.context.closeSignal]),\n })) {\n if (message.event !== AgentRealtimeKind.AcpFrame) continue;\n try {\n const event = acpFrameEventSchema.safeParse(JSON.parse(message.data));\n if (event.success) yield event.data;\n } catch {\n // A malformed event is skipped; replay fills any gap it leaves.\n }\n }\n}\n\n/** Live `acp.preview` events of the session topic. */\nconst streamSessionEvents = <Value>(args: {\n context: ClientContextIface;\n sessionId: string;\n signal?: AbortSignal;\n /** The event a frame's kind and payload carry, or null to skip the frame. */\n parse: (kind: string, payload: unknown) => Value | null;\n}): AsyncIterableIterator<Value> => {\n const topic = agentRealtimeTopics.session(args.sessionId);\n let unsubscribe: (() => void) | null = null;\n let detachAbort: () => void = () => {};\n let detachClose: () => void = () => {};\n const queue = createAsyncQueue<Value>(() => {\n unsubscribe?.();\n detachAbort();\n detachClose();\n });\n const onFrame = (raw: RealtimeTransportFrameIface): void => {\n const frame = agentRealtimeFrameSchema.safeParse(raw);\n if (!frame.success) return;\n if (frame.data.type === AgentRealtimeFrameType.Error && isTerminalRealtimeError(frame.data)) {\n queue.fail(\n realtimeSubscriptionError({\n topic: frame.data.topic ?? topic,\n code: frame.data.code ?? 'unknown',\n message: frame.data.message ?? 'Realtime subscription was refused',\n }),\n );\n return;\n }\n if (frame.data.type !== AgentRealtimeFrameType.Event) return;\n const value = args.parse(frame.data.kind, frame.data.payload);\n if (value != null) queue.push(value);\n };\n detachAbort = failOnAbort(queue, args.signal);\n detachClose = failOnAbort(queue, args.context.closeSignal);\n if (!queue.closed()) {\n const stop = args.context.realtime().subscribe(topic, onFrame);\n if (queue.closed()) stop();\n else unsubscribe = stop;\n }\n return queue.iterator;\n};\n\nconst parsePreview = (kind: string, payload: unknown): AcpPreviewEventIface | null => {\n if (kind !== AgentRealtimeKind.AcpPreview) return null;\n const preview = acpPreviewEventSchema.safeParse(payload);\n return preview.success ? preview.data : null;\n};\n\nconst parseTextEvent = (\n kind: string,\n payload: unknown,\n): AcpPreviewEventIface | AcpLiveTextEventIface | null => {\n if (kind !== SessionRealtimeKind.AcpLiveText) return parsePreview(kind, payload);\n const live = acpLiveTextEventSchema.safeParse(payload);\n return live.success ? live.data : null;\n};\n\n/** Replay, open decisions and the Streamable HTTP fallback of one session's frame stream. */\nconst frameSources = (args: { context: ClientContextIface; sessionId: string }) => ({\n replay: (page: { fromSeq: number; limit: number; signal?: AbortSignal }) =>\n replay({ context: args.context, sessionId: args.sessionId, ...page }),\n decisions: (signal?: AbortSignal) => openDecisions({ ...args, signal }),\n httpStream: (stream: { fromSeq: number; signal: AbortSignal }) =>\n streamFramesOverHttp({ ...args, ...stream }),\n});\n\nexport const createSessionHandle = (\n context: ClientContextIface,\n sessionId: string,\n): SessionHandleIface => {\n const { http } = context;\n const post = async (args: {\n suffix: string;\n body?: HttpBodyIface;\n signal?: AbortSignal;\n }): Promise<void> => {\n await http.request({\n method: HttpMethod.Post,\n path: sessionPath(sessionId, args.suffix),\n body: args.body,\n response: okResponseSchema,\n signal: args.signal,\n context: { sessionId },\n });\n };\n\n return {\n id: sessionId,\n fork: async (options) => {\n const created = await http.request({\n method: HttpMethod.Post,\n path: sessionPath(sessionId, '/fork'),\n body: {\n schema: forkSessionRequestSchema,\n value: {\n idempotencyKey: options?.idempotencyKey ?? context.newKey(),\n title: options?.title,\n },\n },\n response: createSessionResponseSchema,\n signal: options?.signal,\n context: { sessionId },\n });\n return {\n session: created.session,\n handle: createSessionHandle(context, created.session.id),\n response: null,\n };\n },\n attachment: (attachmentId, options) =>\n http.request({\n method: HttpMethod.Get,\n path: sessionPath(sessionId, `/attachments/${encodePath(attachmentId)}`),\n response: attachmentDownloadSchema,\n signal: options?.signal,\n }),\n get: (options) =>\n http.request({\n method: HttpMethod.Get,\n path: sessionPath(sessionId),\n response: sessionSchema,\n signal: options?.signal,\n }),\n manifest: (options) =>\n http.request({\n method: HttpMethod.Get,\n path: sessionPath(sessionId, '/manifest'),\n response: sessionManifestSchema,\n signal: options?.signal,\n }),\n requirements: async (options) =>\n (\n await http.request({\n method: HttpMethod.Get,\n path: sessionPath(sessionId, '/requirements'),\n response: sessionRequirementsSchema,\n signal: options?.signal,\n })\n ).requirements,\n provide: async (options) =>\n (\n await http.request({\n method: HttpMethod.Get,\n path: sessionPath(sessionId, '/manifest'),\n response: sessionManifestSchema,\n signal: options?.signal,\n })\n ).provide,\n send: async <Schema extends TurnOutputSchema | undefined = undefined>(\n content: ContentInput,\n options?: SendOptionsIface<Schema>,\n ): Promise<TurnHandleIface<string, TurnOutputOf<Schema>>> => {\n const schema = options?.output;\n const accepted = await http.request({\n method: HttpMethod.Post,\n path: sessionPath(sessionId, '/prompt'),\n body: {\n schema: promptSessionRequestSchema,\n value: {\n content,\n output: schema == null ? undefined : outputJsonSchemaOf(schema),\n turnPolicy: options?.turnPolicy,\n idempotencyKey: options?.idempotencyKey ?? context.newKey(),\n meta: options?.meta,\n clientSubmittedAtMs: options?.clientSubmittedAtMs ?? context.now(),\n },\n },\n response: promptAcceptedSchema,\n signal: options?.signal,\n context: { sessionId },\n });\n return turnHandle({\n context,\n sessionId,\n accepted,\n output: turnOutputParser<Schema>(schema),\n outputRequested: schema != null,\n });\n },\n observe: (content, options) =>\n post({\n suffix: '/observe',\n body: {\n schema: observeSessionRequestSchema,\n value: {\n content,\n idempotencyKey: options?.idempotencyKey ?? context.newKey(),\n meta: options?.meta,\n },\n },\n signal: options?.signal,\n }),\n stream: (options) =>\n streamSessionFrames({\n sessionId,\n fromSeq: options?.fromSeq ?? FIRST_ACP_FRAME_SEQ,\n follow: options?.follow ?? true,\n ...frameSources({ context, sessionId }),\n transport: context.realtime(),\n timing: context.timing,\n signal: options?.signal,\n closeSignal: context.closeSignal,\n }),\n liveEvents: (options) =>\n streamSessionLiveEvents({ context, sessionId, signal: options?.signal }),\n previews: (options) =>\n streamSessionEvents({ context, sessionId, signal: options?.signal, parse: parsePreview }),\n textEvents: (options) =>\n streamSessionEvents({ context, sessionId, signal: options?.signal, parse: parseTextEvent }),\n liveText: (options) =>\n http.request({\n method: HttpMethod.Get,\n path: sessionPath(sessionId, '/live-text'),\n response: sessionLiveTextSchema,\n signal: options?.signal,\n }),\n frames: (options) => replay({ context, sessionId, ...options }),\n decisions: (options) => openDecisions({ context, sessionId, signal: options?.signal }),\n turn: (turnId, options) => getTurn({ context, sessionId, turnId, signal: options?.signal }),\n response: async (turnId, options) => {\n const receipt = await getTurn({ context, sessionId, turnId, signal: options?.signal });\n return turnHandle({\n context,\n sessionId,\n accepted: {\n turnId: receipt.id,\n messageId: receipt.promptMessageId,\n fromSeq: receipt.fromSeq,\n },\n output: storedOutput,\n outputRequested: false,\n });\n },\n respond: (args, options) =>\n http.request({\n method: HttpMethod.Post,\n path: sessionPath(sessionId, '/respond'),\n body: {\n schema: respondDecisionSchema,\n value: { decisionId: args.decisionId, outcome: outcomeOf(args) },\n },\n response: respondDecisionResponseSchema,\n signal: options?.signal,\n context: { sessionId, decisionId: args.decisionId },\n }),\n cancel: (options) =>\n post({\n suffix: '/cancel',\n body: { schema: cancelRequestSchema, value: { reason: options?.reason } },\n signal: options?.signal,\n }),\n setConfigOption: (args, options) =>\n post({\n suffix: '/config-option',\n body: { schema: setConfigOptionRequestSchema, value: args },\n signal: options?.signal,\n }),\n close: (options) => post({ suffix: '/close', signal: options?.signal }),\n plan: async (options) =>\n (\n await http.request({\n method: HttpMethod.Get,\n path: sessionPath(sessionId, '/plan'),\n response: sessionPlanResponseSchema,\n signal: options?.signal,\n })\n ).plan,\n };\n};\n\nexport const createSessionsApi = (context: ClientContextIface): SessionsApiIface => ({\n fork: (sessionId, options) => createSessionHandle(context, sessionId).fork(options),\n get: (sessionId, options) => createSessionHandle(context, sessionId).get(options),\n attach: (sessionId) => createSessionHandle(context, sessionId),\n});\n\nexport interface ProjectSessionsApiIface extends SessionsApiIface {\n /**\n * Starts a session. Fails with `requirements_unmet`, creating nothing, unless\n * every requirement the agent does not mark optional is provided.\n */\n create: <Schema extends TurnOutputSchema | undefined = undefined>(\n args: CreateSessionArgsIface<Schema>,\n ) => Promise<CreatedSessionIface<TurnOutputOf<Schema>>>;\n}\n\nexport const createProjectSessionsApi = (args: {\n context: ClientContextIface;\n projectId: string;\n start: AgentStartDepsIface;\n}): ProjectSessionsApiIface => {\n const { context } = args;\n return {\n ...createSessionsApi(context),\n create: async <Schema extends TurnOutputSchema | undefined = undefined>(\n create: CreateSessionArgsIface<Schema>,\n ): Promise<CreatedSessionIface<TurnOutputOf<Schema>>> => {\n const started = await startAgent(args.start, {\n projectId: args.projectId,\n agent: create.agent,\n provide: create.provide,\n owner: { kind: LocalHostOwnerKind.Session, id: create.id },\n signal: create.signal,\n });\n try {\n const created = await context.http.request({\n method: HttpMethod.Post,\n path: '/v1/sessions',\n body: {\n schema: createSessionRequestSchema,\n value: {\n id: started.ownerId ?? create.id,\n projectId: args.projectId,\n agent: started.ref,\n provide: started.provide,\n actor: create.actor,\n message: create.message,\n output: create.output == null ? undefined : outputJsonSchemaOf(create.output),\n turnPolicy: create.turnPolicy,\n idempotencyKey:\n create.idempotencyKey ?? (create.message == null ? undefined : context.newKey()),\n title: create.title,\n meta: create.meta,\n clientSubmittedAtMs:\n create.message == null ? undefined : (create.clientSubmittedAtMs ?? context.now()),\n },\n },\n response: createSessionResponseSchema,\n signal: create.signal,\n });\n const reserved = started.ownerId ?? create.id;\n if (reserved != null && created.session.id !== reserved) {\n // The idempotency key replayed an earlier creation: the session is that one, not\n // the id this call reserved, and what was started for that id serves nothing. Its\n // in-process code is served for it from here; its compute stays what that\n // creation named, which nothing can change now.\n started.abandon();\n if (started.host != null)\n await serveCodeFor(args.start, {\n projectId: args.projectId,\n agent: create.agent,\n owner: { kind: LocalHostOwnerKind.Session, id: created.session.id },\n signal: create.signal,\n });\n } else started.established();\n const handle = createSessionHandle(context, created.session.id);\n return {\n session: created.session,\n handle,\n response:\n created.turn == null\n ? null\n : turnHandle({\n context,\n sessionId: created.session.id,\n accepted: created.turn,\n output: turnOutputParser<Schema>(create.output),\n outputRequested: create.output != null,\n }),\n };\n } catch (cause) {\n started.abandon();\n throw cause;\n }\n },\n };\n};\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -0,0 +1,42 @@
1
+ import { type JsonObjectIface, type JsonValue } from '@finalai/agent-protocol';
2
+ interface StandardIssueIface {
3
+ readonly message: string;
4
+ }
5
+ type StandardResultType<Output> = {
6
+ readonly value: Output;
7
+ readonly issues?: undefined;
8
+ } | {
9
+ readonly issues: readonly StandardIssueIface[];
10
+ };
11
+ /** The Standard Schema and Standard JSON Schema surface `output` accepts. */
12
+ export interface TurnOutputStandardSchemaIface<Input = unknown, Output = Input> {
13
+ readonly '~standard': {
14
+ readonly version: 1;
15
+ readonly vendor: string;
16
+ readonly validate: (value: unknown) => StandardResultType<Output> | Promise<StandardResultType<Output>>;
17
+ readonly types?: {
18
+ readonly input: Input;
19
+ readonly output: Output;
20
+ } | undefined;
21
+ readonly jsonSchema: {
22
+ readonly input: (options: {
23
+ readonly target: string;
24
+ }) => Record<string, unknown>;
25
+ };
26
+ };
27
+ }
28
+ /** A turn's result format: a schema library value (zod 4) or a JSON Schema whose root is `type: 'object'`. */
29
+ export type TurnOutputSchema = TurnOutputStandardSchemaIface<unknown, unknown> | JsonObjectIface;
30
+ /** The type of `result().output` for an `output` schema: its parsed type, else JSON. */
31
+ export type TurnOutputOf<Schema> = Schema extends {
32
+ readonly '~standard': {
33
+ readonly types?: infer Types;
34
+ };
35
+ } ? NonNullable<Types> extends {
36
+ readonly output: infer Output;
37
+ } ? Output : JsonValue : JsonValue;
38
+ /** The JSON Schema sent for `output`; rejects one the platform would refuse. */
39
+ export declare const outputJsonSchemaOf: (schema: TurnOutputSchema) => JsonObjectIface;
40
+ /** Reads a turn's stored result with the schema it was asked for. */
41
+ export declare const turnOutputParser: <Schema extends TurnOutputSchema | undefined>(schema: Schema | undefined) => (output: JsonValue | null) => Promise<TurnOutputOf<Schema> | null>;
42
+ export {};
@@ -0,0 +1,51 @@
1
+ import { jsonObjectSchema } from "@finalai/agent-protocol";
2
+ import { turnOutputSchemaInputSchema } from "@finalai/agent-protocol/agent-platform";
3
+ import { clientError, ClientErrorCode } from "./errors.mjs";
4
+ const isStandardSchema = (schema) => "~standard" in schema;
5
+ const invalidOutputSchema = (message) => clientError({ message, status: 0, code: ClientErrorCode.InvalidRequest });
6
+ const outputJsonSchemaOf = (schema) => {
7
+ let converted = schema;
8
+ if (isStandardSchema(schema)) {
9
+ const convert = schema["~standard"].jsonSchema?.input;
10
+ if (typeof convert !== "function")
11
+ throw invalidOutputSchema(
12
+ "output must be a JSON Schema object or a schema with Standard JSON Schema support"
13
+ );
14
+ try {
15
+ converted = convert({ target: "draft-2020-12" });
16
+ } catch (cause) {
17
+ throw invalidOutputSchema(
18
+ `output could not be converted to JSON Schema: ${cause instanceof Error ? cause.message : String(cause)}`
19
+ );
20
+ }
21
+ }
22
+ const json = jsonObjectSchema.safeParse(JSON.parse(JSON.stringify(converted ?? null)));
23
+ if (!json.success) throw invalidOutputSchema("output is not a JSON Schema object");
24
+ const { $schema: _dialect, ...rest } = json.data;
25
+ const checked = turnOutputSchemaInputSchema.safeParse(
26
+ isStandardSchema(schema) ? rest : json.data
27
+ );
28
+ if (!checked.success)
29
+ throw invalidOutputSchema(checked.error.issues.map((issue) => issue.message).join("; "));
30
+ return checked.data;
31
+ };
32
+ const acceptedAs = (value, accepted) => accepted;
33
+ const turnOutputParser = (schema) => async (output) => {
34
+ if (output == null) return null;
35
+ if (schema == null || !isStandardSchema(schema))
36
+ return acceptedAs(output, true) ? output : null;
37
+ const parsed = await schema["~standard"].validate(output);
38
+ if (parsed.issues != null)
39
+ throw clientError({
40
+ message: `The turn's result does not match its output schema: ${parsed.issues.map((issue) => issue.message).join("; ")}`,
41
+ status: 0,
42
+ code: ClientErrorCode.InvalidResponse,
43
+ body: output
44
+ });
45
+ return acceptedAs(parsed.value, true) ? parsed.value : null;
46
+ };
47
+ export {
48
+ outputJsonSchemaOf,
49
+ turnOutputParser
50
+ };
51
+ //# sourceMappingURL=turn-output.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../src/agent-client/turn-output.ts"],
4
+ "sourcesContent": ["import { jsonObjectSchema, type JsonObjectIface, type JsonValue } from '@finalai/agent-protocol';\nimport { turnOutputSchemaInputSchema } from '@finalai/agent-protocol/agent-platform';\nimport { clientError, ClientErrorCode } from \"./errors.mjs\";\n\n// The result a turn must end with: a schema with Standard Schema validation and\n// Standard JSON Schema conversion (zod 4 and others), or a JSON Schema object.\n// The platform checks the agent's result against the JSON Schema; a library\n// schema also checks and parses it here, so `result().output` has its type.\n\ninterface StandardIssueIface {\n readonly message: string;\n}\n\ntype StandardResultType<Output> =\n | { readonly value: Output; readonly issues?: undefined }\n | { readonly issues: readonly StandardIssueIface[] };\n\n/** The Standard Schema and Standard JSON Schema surface `output` accepts. */\nexport interface TurnOutputStandardSchemaIface<Input = unknown, Output = Input> {\n readonly '~standard': {\n readonly version: 1;\n readonly vendor: string;\n readonly validate: (\n value: unknown,\n ) => StandardResultType<Output> | Promise<StandardResultType<Output>>;\n readonly types?: { readonly input: Input; readonly output: Output } | undefined;\n readonly jsonSchema: {\n readonly input: (options: { readonly target: string }) => Record<string, unknown>;\n };\n };\n}\n\n/** A turn's result format: a schema library value (zod 4) or a JSON Schema whose root is `type: 'object'`. */\nexport type TurnOutputSchema = TurnOutputStandardSchemaIface<unknown, unknown> | JsonObjectIface;\n\n/** The type of `result().output` for an `output` schema: its parsed type, else JSON. */\nexport type TurnOutputOf<Schema> = Schema extends {\n readonly '~standard': { readonly types?: infer Types };\n}\n ? NonNullable<Types> extends { readonly output: infer Output }\n ? Output\n : JsonValue\n : JsonValue;\n\nconst isStandardSchema = (\n schema: TurnOutputSchema,\n): schema is TurnOutputStandardSchemaIface<unknown, unknown> => '~standard' in schema;\n\nconst invalidOutputSchema = (message: string) =>\n clientError({ message, status: 0, code: ClientErrorCode.InvalidRequest });\n\n/** The JSON Schema sent for `output`; rejects one the platform would refuse. */\nexport const outputJsonSchemaOf = (schema: TurnOutputSchema): JsonObjectIface => {\n let converted: unknown = schema;\n if (isStandardSchema(schema)) {\n const convert = schema['~standard'].jsonSchema?.input;\n if (typeof convert !== 'function')\n throw invalidOutputSchema(\n 'output must be a JSON Schema object or a schema with Standard JSON Schema support',\n );\n try {\n converted = convert({ target: 'draft-2020-12' });\n } catch (cause) {\n throw invalidOutputSchema(\n `output could not be converted to JSON Schema: ${cause instanceof Error ? cause.message : String(cause)}`,\n );\n }\n }\n const json = jsonObjectSchema.safeParse(JSON.parse(JSON.stringify(converted ?? null)));\n if (!json.success) throw invalidOutputSchema('output is not a JSON Schema object');\n // A converter's dialect marker says nothing about the result.\n const { $schema: _dialect, ...rest } = json.data;\n const checked = turnOutputSchemaInputSchema.safeParse(\n isStandardSchema(schema) ? rest : json.data,\n );\n if (!checked.success)\n throw invalidOutputSchema(checked.error.issues.map((issue) => issue.message).join('; '));\n return checked.data;\n};\n\n// The platform checked a stored result against the turn's JSON Schema, and a\n// library schema's own `validate` accepted it here: either way it has the\n// schema's type.\nconst acceptedAs = <Schema>(value: unknown, accepted: boolean): value is TurnOutputOf<Schema> =>\n accepted;\n\n/** Reads a turn's stored result with the schema it was asked for. */\nexport const turnOutputParser =\n <Schema extends TurnOutputSchema | undefined>(schema: Schema | undefined) =>\n async (output: JsonValue | null): Promise<TurnOutputOf<Schema> | null> => {\n if (output == null) return null;\n if (schema == null || !isStandardSchema(schema))\n return acceptedAs<Schema>(output, true) ? output : null;\n const parsed = await schema['~standard'].validate(output);\n if (parsed.issues != null)\n throw clientError({\n message: `The turn's result does not match its output schema: ${parsed.issues.map((issue) => issue.message).join('; ')}`,\n status: 0,\n code: ClientErrorCode.InvalidResponse,\n body: output,\n });\n return acceptedAs<Schema>(parsed.value, true) ? parsed.value : null;\n };\n"],
5
+ "mappings": "AAAA,SAAS,wBAA8D;AACvE,SAAS,mCAAmC;AAC5C,SAAS,aAAa,uBAAuB;AA0C7C,MAAM,mBAAmB,CACvB,WAC8D,eAAe;AAE/E,MAAM,sBAAsB,CAAC,YAC3B,YAAY,EAAE,SAAS,QAAQ,GAAG,MAAM,gBAAgB,eAAe,CAAC;AAGnE,MAAM,qBAAqB,CAAC,WAA8C;AAC/E,MAAI,YAAqB;AACzB,MAAI,iBAAiB,MAAM,GAAG;AAC5B,UAAM,UAAU,OAAO,WAAW,EAAE,YAAY;AAChD,QAAI,OAAO,YAAY;AACrB,YAAM;AAAA,QACJ;AAAA,MACF;AACF,QAAI;AACF,kBAAY,QAAQ,EAAE,QAAQ,gBAAgB,CAAC;AAAA,IACjD,SAAS,OAAO;AACd,YAAM;AAAA,QACJ,iDAAiD,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,MACzG;AAAA,IACF;AAAA,EACF;AACA,QAAM,OAAO,iBAAiB,UAAU,KAAK,MAAM,KAAK,UAAU,aAAa,IAAI,CAAC,CAAC;AACrF,MAAI,CAAC,KAAK,QAAS,OAAM,oBAAoB,oCAAoC;AAEjF,QAAM,EAAE,SAAS,UAAU,GAAG,KAAK,IAAI,KAAK;AAC5C,QAAM,UAAU,4BAA4B;AAAA,IAC1C,iBAAiB,MAAM,IAAI,OAAO,KAAK;AAAA,EACzC;AACA,MAAI,CAAC,QAAQ;AACX,UAAM,oBAAoB,QAAQ,MAAM,OAAO,IAAI,CAAC,UAAU,MAAM,OAAO,EAAE,KAAK,IAAI,CAAC;AACzF,SAAO,QAAQ;AACjB;AAKA,MAAM,aAAa,CAAS,OAAgB,aAC1C;AAGK,MAAM,mBACX,CAA8C,WAC9C,OAAO,WAAmE;AACxE,MAAI,UAAU,KAAM,QAAO;AAC3B,MAAI,UAAU,QAAQ,CAAC,iBAAiB,MAAM;AAC5C,WAAO,WAAmB,QAAQ,IAAI,IAAI,SAAS;AACrD,QAAM,SAAS,MAAM,OAAO,WAAW,EAAE,SAAS,MAAM;AACxD,MAAI,OAAO,UAAU;AACnB,UAAM,YAAY;AAAA,MAChB,SAAS,uDAAuD,OAAO,OAAO,IAAI,CAAC,UAAU,MAAM,OAAO,EAAE,KAAK,IAAI,CAAC;AAAA,MACtH,QAAQ;AAAA,MACR,MAAM,gBAAgB;AAAA,MACtB,MAAM;AAAA,IACR,CAAC;AACH,SAAO,WAAmB,OAAO,OAAO,IAAI,IAAI,OAAO,QAAQ;AACjE;",
6
+ "names": []
7
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@finalai/agents",
3
- "version": "0.16.2",
3
+ "version": "0.17.0",
4
4
  "private": false,
5
5
  "description": "Agent authoring, client APIs, and CLI.",
6
6
  "license": "Apache-2.0",
@@ -115,10 +115,10 @@
115
115
  },
116
116
  "dependencies": {
117
117
  "@agentclientprotocol/sdk": "1.8.0",
118
- "@finalai/agent-definition": "0.13.0",
119
- "@finalai/agent-protocol": "0.13.0",
120
- "@finalai/agent-provider": "0.14.0",
121
- "@finalai/final-agent-provider": "0.15.2",
118
+ "@finalai/agent-definition": "0.14.0",
119
+ "@finalai/agent-protocol": "0.14.0",
120
+ "@finalai/agent-provider": "0.15.0",
121
+ "@finalai/final-agent-provider": "0.16.0",
122
122
  "@finalai/websockets": "0.1.8",
123
123
  "ws": "^8.21.3",
124
124
  "zod": "4.6.6"