@finalai/agents 0.16.1 → 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 +35 -0
- package/dist/modules/agent-client/api.d.mts +2 -1
- package/dist/modules/agent-client/api.mjs.map +1 -1
- package/dist/modules/agent-client/integrations.d.mts +25 -1
- package/dist/modules/agent-client/integrations.mjs +24 -1
- package/dist/modules/agent-client/integrations.mjs.map +2 -2
- package/dist/modules/agent-client/sessions.d.mts +25 -9
- package/dist/modules/agent-client/sessions.mjs +50 -5
- package/dist/modules/agent-client/sessions.mjs.map +2 -2
- package/dist/modules/agent-client/turn-output.d.mts +42 -0
- package/dist/modules/agent-client/turn-output.mjs +51 -0
- package/dist/modules/agent-client/turn-output.mjs.map +7 -0
- package/package.json +5 -5
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
|
|
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": "AAAA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,
|
|
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({
|
|
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({
|
|
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": "AACA;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,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,EACA;AAAA,EACA;AAAA,OAoBK;AACP,SAAS,qBAAqB,kBAAkB,iBAAiB;AAEjE,SAAS,kBAAkB,mBAAmB;AAC9C;AAAA,EACE;AAAA,OAIK;AACP,SAAS,yBAAyB,iCAAiC;AACnE,SAAS,8BAA8B;AACvC,SAAS,2BAA2B;AACpC,SAAS,kBAAsC;AAC/C,SAAS,+BAAsD;AAC/D,SAAS,0BAA0B;AAGnC,SAAS,cAAc,kBAA4C;AACnE;AAAA,EACE;AAAA,EACA;AAAA,OAGK;AA2LA,MAAM,YAAY,CAAC,SACxB,cAAc,OAAO,EAAE,SAAS,YAAY,UAAU,KAAK,SAAS,IAAI,KAAK;AAE/E,MAAM,cAAc,CAAC,WAAmB,SAAS,OAC/C,gBAAgB,WAAW,SAAS,CAAC,GAAG,MAAM;AAahD,MAAM,eAAe,OAAO,WAAwD;AAEpF,MAAM,aAAa,CACjB,SACuC;AACvC,QAAM,EAAE,SAAS,WAAW,SAAS,IAAI;AACzC,QAAM,MAAM,CAAC,YACX,QAAQ,EAAE,SAAS,WAAW,QAAQ,SAAS,QAAQ,QAAQ,SAAS,OAAO,CAAC;AAClF,QAAM,SAAS,CAAC,YAA4E;AAG1F,QAAI,cAAc,SAAS,aAAa,QAAQ,SAAS,WAAW;AACpE,QAAI,UAAU;AACd,UAAM,SAAS,oBAAoB;AAAA,MACjC;AAAA,MACA,SAAS,SAAS,WAAW;AAAA,MAC7B,QAAQ;AAAA,MACR,GAAG,aAAa,EAAE,SAAS,UAAU,CAAC;AAAA,MACtC,WAAW,QAAQ,SAAS;AAAA,MAC5B,QAAQ,QAAQ;AAAA,MAChB,QAAQ,SAAS;AAAA,MACjB,aAAa,QAAQ;AAAA,MACrB,UAAU,OAAO,WAAW;AAC1B,cAAM,UAAU,MAAM,IAAI,EAAE,OAAO,CAAC;AACpC,eAAO,QAAQ,WAAW,OAAO,OAAO,EAAE,YAAY,QAAQ,SAAS,EAAE;AAAA,MAC3E;AAAA,MACA,OAAO,CAAC,UAAU;AAChB,YACE,CAAC,eACD,SAAS,aAAa,QACtB,iBAAiB,OAAO,SAAS,SAAS;AAE1C,wBAAc;AAChB,eAAO,eAAe,UAAU,KAAK,KAAK;AAAA,MAC5C;AAAA,IACF,CAAC;AACD,UAAM,WAAsD;AAAA,MAC1D,MAAM,YAAY;AAChB,mBAAS;AACP,gBAAM,OAAO,MAAM,OAAO,KAAK;AAC/B,cAAI,KAAK,SAAS,QAAQ,QAAS,QAAO;AAC1C,cAAI,SAAS,aAAa,QAAQ,iBAAiB,KAAK,OAAO,SAAS,SAAS,GAAG;AAClF,sBAAU;AACV,mBAAO;AAAA,UACT;AAAA,QACF;AAAA,MACF;AAAA,MACA,QAAQ,MAAM,OAAO,SAAS,KAAK,QAAQ,QAAQ,EAAE,MAAM,MAAM,OAAO,OAAU,CAAC;AAAA,MACnF,CAAC,OAAO,aAAa,GAAG,MAAM;AAAA,IAChC;AACA,WAAO;AAAA,EACT;AAIA,QAAM,WAAW,CACf,SACA,YAEA,oBAAoB;AAAA,IAClB;AAAA,IACA;AAAA,IACA,QAAQ;AAAA,IACR,GAAG,aAAa,EAAE,SAAS,UAAU,CAAC;AAAA,IACtC,WAAW,QAAQ,SAAS;AAAA,IAC5B,QAAQ,QAAQ;AAAA,IAChB,QAAQ,SAAS;AAAA,IACjB,aAAa,QAAQ;AAAA,IACrB,UAAU,OAAO,WAAW;AAC1B,YAAM,UAAU,MAAM,IAAI,EAAE,OAAO,CAAC;AACpC,aAAO,QAAQ,WAAW,OAAO,OAAO,EAAE,YAAY,QAAQ,SAAS,EAAE;AAAA,IAC3E;AAAA,IACA,OAAO,CAAC,UAAU,UAAU,KAAK,KAAK;AAAA,EACxC,CAAC;AAEH,QAAM,SAAS,OACb,YACgD;AAChD,UAAM,OAAO,oBAAoB;AACjC,QAAI,OAAkC;AACtC,qBAAiB,SAAS,OAAO,OAAO,GAAG;AACzC,WAAK,IAAI,KAAK;AACd,aAAO;AAAA,IACT;AACA,QAAI,UAAU,MAAM,IAAI,OAAO;AAC/B,WAAO,KAAK,mBAAmB,QAAQ,WAAW,MAAM;AAEtD,uBAAiB,SAAS,UAAU,MAAM,OAAO,SAAS,WAAW,KAAK,GAAG,OAAO,GAAG;AACrF,aAAK,IAAI,KAAK;AACd,eAAO;AAAA,MACT;AACA,gBAAU,MAAM,IAAI,OAAO;AAAA,IAC7B;AACA,UAAM,MAAM,QAAQ,OAAO,OAAO,UAAU,IAAI;AAChD,WAAO;AAAA,MACL,WAAW,SAAS;AAAA,MACpB,QAAQ,SAAS;AAAA,MACjB,YAAY,QAAQ,cAAc,KAAK,cAAc;AAAA,MACrD,MAAM,KAAK,KAAK;AAAA,MAChB,OAAO,QAAQ,SAAS,MAAM,OAAO,SAAS,WAAW;AAAA,MACzD,QAAQ,MAAM,KAAK,OAAO,QAAQ,MAAM;AAAA,IAC1C;AAAA,EACF;AAEA,SAAO;AAAA,IACL,GAAG;AAAA,IACH;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,MAAM,OAAO,aAAa,MAAM,OAAO,OAAO,GAAG;AAAA,EACnD;AACF;AAEA,MAAM,UAAU,CAAC,SAMf,KAAK,QAAQ,KAAK,QAAQ;AAAA,EACxB,QAAQ,WAAW;AAAA,EACnB,MAAM,YAAY,KAAK,WAAW,UAAU,WAAW,KAAK,MAAM,CAAC,EAAE;AAAA,EACrE,UAAU;AAAA,EACV,QAAQ,KAAK;AACf,CAAC;AASH,MAAM,SAAS,CAAC,SACd,KAAK,QAAQ,KAAK,QAAQ;AAAA,EACxB,QAAQ,WAAW;AAAA,EACnB,MAAM,YAAY,KAAK,WAAW,SAAS;AAAA,EAC3C,OAAO,EAAE,SAAS,KAAK,SAAS,OAAO,KAAK,MAAM;AAAA,EAClD,UAAU;AAAA,EACV,QAAQ,KAAK;AACf,CAAC;AAEH,MAAM,gBAAgB,OAAO,UAMzB,MAAM,KAAK,QAAQ,KAAK,QAAQ;AAAA,EAC9B,QAAQ,WAAW;AAAA,EACnB,MAAM,YAAY,KAAK,WAAW,YAAY;AAAA,EAC9C,UAAU;AAAA,EACV,QAAQ,KAAK;AACf,CAAC,GACD;AAGJ,gBAAgB,qBAAqB,MAKE;AACrC,mBAAiB,WAAW,uBAAuB;AAAA,IACjD,MAAM,KAAK,QAAQ;AAAA,IACnB,MAAM,YAAY,KAAK,WAAW,gBAAgB;AAAA,IAClD,OAAO,EAAE,SAAS,KAAK,QAAQ;AAAA,IAC/B,QAAQ,YAAY,IAAI,CAAC,KAAK,QAAQ,KAAK,QAAQ,WAAW,CAAC;AAAA,EACjE,CAAC,GAAG;AACF,QAAI,QAAQ,UAAU,kBAAkB,SAAU;AAClD,QAAI;AACF,YAAM,QAAQ,oBAAoB,UAAU,KAAK,MAAM,QAAQ,IAAI,CAAC;AACpE,UAAI,MAAM,QAAS,OAAM,MAAM;AAAA,IACjC,QAAQ;AAAA,IAER;AAAA,EACF;AACF;AAGA,MAAM,sBAAsB,CAAQ,SAMA;AAClC,QAAM,QAAQ,oBAAoB,QAAQ,KAAK,SAAS;AACxD,MAAI,cAAmC;AACvC,MAAI,cAA0B,MAAM;AAAA,EAAC;AACrC,MAAI,cAA0B,MAAM;AAAA,EAAC;AACrC,QAAM,QAAQ,iBAAwB,MAAM;AAC1C,kBAAc;AACd,gBAAY;AACZ,gBAAY;AAAA,EACd,CAAC;AACD,QAAM,UAAU,CAAC,QAA2C;AAC1D,UAAM,QAAQ,yBAAyB,UAAU,GAAG;AACpD,QAAI,CAAC,MAAM,QAAS;AACpB,QAAI,MAAM,KAAK,SAAS,uBAAuB,SAAS,wBAAwB,MAAM,IAAI,GAAG;AAC3F,YAAM;AAAA,QACJ,0BAA0B;AAAA,UACxB,OAAO,MAAM,KAAK,SAAS;AAAA,UAC3B,MAAM,MAAM,KAAK,QAAQ;AAAA,UACzB,SAAS,MAAM,KAAK,WAAW;AAAA,QACjC,CAAC;AAAA,MACH;AACA;AAAA,IACF;AACA,QAAI,MAAM,KAAK,SAAS,uBAAuB,MAAO;AACtD,UAAM,QAAQ,KAAK,MAAM,MAAM,KAAK,MAAM,MAAM,KAAK,OAAO;AAC5D,QAAI,SAAS,KAAM,OAAM,KAAK,KAAK;AAAA,EACrC;AACA,gBAAc,YAAY,OAAO,KAAK,MAAM;AAC5C,gBAAc,YAAY,OAAO,KAAK,QAAQ,WAAW;AACzD,MAAI,CAAC,MAAM,OAAO,GAAG;AACnB,UAAM,OAAO,KAAK,QAAQ,SAAS,EAAE,UAAU,OAAO,OAAO;AAC7D,QAAI,MAAM,OAAO,EAAG,MAAK;AAAA,QACpB,eAAc;AAAA,EACrB;AACA,SAAO,MAAM;AACf;AAEA,MAAM,eAAe,CAAC,MAAc,YAAkD;AACpF,MAAI,SAAS,kBAAkB,WAAY,QAAO;AAClD,QAAM,UAAU,sBAAsB,UAAU,OAAO;AACvD,SAAO,QAAQ,UAAU,QAAQ,OAAO;AAC1C;AAEA,MAAM,iBAAiB,CACrB,MACA,YACwD;AACxD,MAAI,SAAS,oBAAoB,YAAa,QAAO,aAAa,MAAM,OAAO;AAC/E,QAAM,OAAO,uBAAuB,UAAU,OAAO;AACrD,SAAO,KAAK,UAAU,KAAK,OAAO;AACpC;AAGA,MAAM,eAAe,CAAC,UAA8D;AAAA,EAClF,QAAQ,CAAC,SACP,OAAO,EAAE,SAAS,KAAK,SAAS,WAAW,KAAK,WAAW,GAAG,KAAK,CAAC;AAAA,EACtE,WAAW,CAAC,WAAyB,cAAc,EAAE,GAAG,MAAM,OAAO,CAAC;AAAA,EACtE,YAAY,CAAC,WACX,qBAAqB,EAAE,GAAG,MAAM,GAAG,OAAO,CAAC;AAC/C;AAEO,MAAM,sBAAsB,CACjC,SACA,cACuB;AACvB,QAAM,EAAE,KAAK,IAAI;AACjB,QAAM,OAAO,OAAO,SAIC;AACnB,UAAM,KAAK,QAAQ;AAAA,MACjB,QAAQ,WAAW;AAAA,MACnB,MAAM,YAAY,WAAW,KAAK,MAAM;AAAA,MACxC,MAAM,KAAK;AAAA,MACX,UAAU;AAAA,MACV,QAAQ,KAAK;AAAA,MACb,SAAS,EAAE,UAAU;AAAA,IACvB,CAAC;AAAA,EACH;AAEA,SAAO;AAAA,IACL,IAAI;AAAA,IACJ,MAAM,OAAO,YAAY;AACvB,YAAM,UAAU,MAAM,KAAK,QAAQ;AAAA,QACjC,QAAQ,WAAW;AAAA,QACnB,MAAM,YAAY,WAAW,OAAO;AAAA,QACpC,MAAM;AAAA,UACJ,QAAQ;AAAA,UACR,OAAO;AAAA,YACL,gBAAgB,SAAS,kBAAkB,QAAQ,OAAO;AAAA,YAC1D,OAAO,SAAS;AAAA,UAClB;AAAA,QACF;AAAA,QACA,UAAU;AAAA,QACV,QAAQ,SAAS;AAAA,QACjB,SAAS,EAAE,UAAU;AAAA,MACvB,CAAC;AACD,aAAO;AAAA,QACL,SAAS,QAAQ;AAAA,QACjB,QAAQ,oBAAoB,SAAS,QAAQ,QAAQ,EAAE;AAAA,QACvD,UAAU;AAAA,MACZ;AAAA,IACF;AAAA,IACA,YAAY,CAAC,cAAc,YACzB,KAAK,QAAQ;AAAA,MACX,QAAQ,WAAW;AAAA,MACnB,MAAM,YAAY,WAAW,gBAAgB,WAAW,YAAY,CAAC,EAAE;AAAA,MACvE,UAAU;AAAA,MACV,QAAQ,SAAS;AAAA,IACnB,CAAC;AAAA,IACH,KAAK,CAAC,YACJ,KAAK,QAAQ;AAAA,MACX,QAAQ,WAAW;AAAA,MACnB,MAAM,YAAY,SAAS;AAAA,MAC3B,UAAU;AAAA,MACV,QAAQ,SAAS;AAAA,IACnB,CAAC;AAAA,IACH,UAAU,CAAC,YACT,KAAK,QAAQ;AAAA,MACX,QAAQ,WAAW;AAAA,MACnB,MAAM,YAAY,WAAW,WAAW;AAAA,MACxC,UAAU;AAAA,MACV,QAAQ,SAAS;AAAA,IACnB,CAAC;AAAA,IACH,cAAc,OAAO,aAEjB,MAAM,KAAK,QAAQ;AAAA,MACjB,QAAQ,WAAW;AAAA,MACnB,MAAM,YAAY,WAAW,eAAe;AAAA,MAC5C,UAAU;AAAA,MACV,QAAQ,SAAS;AAAA,IACnB,CAAC,GACD;AAAA,IACJ,SAAS,OAAO,aAEZ,MAAM,KAAK,QAAQ;AAAA,MACjB,QAAQ,WAAW;AAAA,MACnB,MAAM,YAAY,WAAW,WAAW;AAAA,MACxC,UAAU;AAAA,MACV,QAAQ,SAAS;AAAA,IACnB,CAAC,GACD;AAAA,IACJ,MAAM,OACJ,SACA,YAC2D;AAC3D,YAAM,SAAS,SAAS;AACxB,YAAM,WAAW,MAAM,KAAK,QAAQ;AAAA,QAClC,QAAQ,WAAW;AAAA,QACnB,MAAM,YAAY,WAAW,SAAS;AAAA,QACtC,MAAM;AAAA,UACJ,QAAQ;AAAA,UACR,OAAO;AAAA,YACL;AAAA,YACA,QAAQ,UAAU,OAAO,SAAY,mBAAmB,MAAM;AAAA,YAC9D,YAAY,SAAS;AAAA,YACrB,gBAAgB,SAAS,kBAAkB,QAAQ,OAAO;AAAA,YAC1D,MAAM,SAAS;AAAA,YACf,qBAAqB,SAAS,uBAAuB,QAAQ,IAAI;AAAA,UACnE;AAAA,QACF;AAAA,QACA,UAAU;AAAA,QACV,QAAQ,SAAS;AAAA,QACjB,SAAS,EAAE,UAAU;AAAA,MACvB,CAAC;AACD,aAAO,WAAW;AAAA,QAChB;AAAA,QACA;AAAA,QACA;AAAA,QACA,QAAQ,iBAAyB,MAAM;AAAA,QACvC,iBAAiB,UAAU;AAAA,MAC7B,CAAC;AAAA,IACH;AAAA,IACA,SAAS,CAAC,SAAS,YACjB,KAAK;AAAA,MACH,QAAQ;AAAA,MACR,MAAM;AAAA,QACJ,QAAQ;AAAA,QACR,OAAO;AAAA,UACL;AAAA,UACA,gBAAgB,SAAS,kBAAkB,QAAQ,OAAO;AAAA,UAC1D,MAAM,SAAS;AAAA,QACjB;AAAA,MACF;AAAA,MACA,QAAQ,SAAS;AAAA,IACnB,CAAC;AAAA,IACH,QAAQ,CAAC,YACP,oBAAoB;AAAA,MAClB;AAAA,MACA,SAAS,SAAS,WAAW;AAAA,MAC7B,QAAQ,SAAS,UAAU;AAAA,MAC3B,GAAG,aAAa,EAAE,SAAS,UAAU,CAAC;AAAA,MACtC,WAAW,QAAQ,SAAS;AAAA,MAC5B,QAAQ,QAAQ;AAAA,MAChB,QAAQ,SAAS;AAAA,MACjB,aAAa,QAAQ;AAAA,IACvB,CAAC;AAAA,IACH,YAAY,CAAC,YACX,wBAAwB,EAAE,SAAS,WAAW,QAAQ,SAAS,OAAO,CAAC;AAAA,IACzE,UAAU,CAAC,YACT,oBAAoB,EAAE,SAAS,WAAW,QAAQ,SAAS,QAAQ,OAAO,aAAa,CAAC;AAAA,IAC1F,YAAY,CAAC,YACX,oBAAoB,EAAE,SAAS,WAAW,QAAQ,SAAS,QAAQ,OAAO,eAAe,CAAC;AAAA,IAC5F,UAAU,CAAC,YACT,KAAK,QAAQ;AAAA,MACX,QAAQ,WAAW;AAAA,MACnB,MAAM,YAAY,WAAW,YAAY;AAAA,MACzC,UAAU;AAAA,MACV,QAAQ,SAAS;AAAA,IACnB,CAAC;AAAA,IACH,QAAQ,CAAC,YAAY,OAAO,EAAE,SAAS,WAAW,GAAG,QAAQ,CAAC;AAAA,IAC9D,WAAW,CAAC,YAAY,cAAc,EAAE,SAAS,WAAW,QAAQ,SAAS,OAAO,CAAC;AAAA,IACrF,MAAM,CAAC,QAAQ,YAAY,QAAQ,EAAE,SAAS,WAAW,QAAQ,QAAQ,SAAS,OAAO,CAAC;AAAA,IAC1F,UAAU,OAAO,QAAQ,YAAY;AACnC,YAAM,UAAU,MAAM,QAAQ,EAAE,SAAS,WAAW,QAAQ,QAAQ,SAAS,OAAO,CAAC;AACrF,aAAO,WAAW;AAAA,QAChB;AAAA,QACA;AAAA,QACA,UAAU;AAAA,UACR,QAAQ,QAAQ;AAAA,UAChB,WAAW,QAAQ;AAAA,UACnB,SAAS,QAAQ;AAAA,QACnB;AAAA,QACA,QAAQ;AAAA,QACR,iBAAiB;AAAA,MACnB,CAAC;AAAA,IACH;AAAA,IACA,SAAS,CAAC,MAAM,YACd,KAAK,QAAQ;AAAA,MACX,QAAQ,WAAW;AAAA,MACnB,MAAM,YAAY,WAAW,UAAU;AAAA,MACvC,MAAM;AAAA,QACJ,QAAQ;AAAA,QACR,OAAO,EAAE,YAAY,KAAK,YAAY,SAAS,UAAU,IAAI,EAAE;AAAA,MACjE;AAAA,MACA,UAAU;AAAA,MACV,QAAQ,SAAS;AAAA,MACjB,SAAS,EAAE,WAAW,YAAY,KAAK,WAAW;AAAA,IACpD,CAAC;AAAA,IACH,QAAQ,CAAC,YACP,KAAK;AAAA,MACH,QAAQ;AAAA,MACR,MAAM,EAAE,QAAQ,qBAAqB,OAAO,EAAE,QAAQ,SAAS,OAAO,EAAE;AAAA,MACxE,QAAQ,SAAS;AAAA,IACnB,CAAC;AAAA,IACH,iBAAiB,CAAC,MAAM,YACtB,KAAK;AAAA,MACH,QAAQ;AAAA,MACR,MAAM,EAAE,QAAQ,8BAA8B,OAAO,KAAK;AAAA,MAC1D,QAAQ,SAAS;AAAA,IACnB,CAAC;AAAA,IACH,OAAO,CAAC,YAAY,KAAK,EAAE,QAAQ,UAAU,QAAQ,SAAS,OAAO,CAAC;AAAA,IACtE,MAAM,OAAO,aAET,MAAM,KAAK,QAAQ;AAAA,MACjB,QAAQ,WAAW;AAAA,MACnB,MAAM,YAAY,WAAW,OAAO;AAAA,MACpC,UAAU;AAAA,MACV,QAAQ,SAAS;AAAA,IACnB,CAAC,GACD;AAAA,EACN;AACF;AAEO,MAAM,oBAAoB,CAAC,aAAmD;AAAA,EACnF,MAAM,CAAC,WAAW,YAAY,oBAAoB,SAAS,SAAS,EAAE,KAAK,OAAO;AAAA,EAClF,KAAK,CAAC,WAAW,YAAY,oBAAoB,SAAS,SAAS,EAAE,IAAI,OAAO;AAAA,EAChF,QAAQ,CAAC,cAAc,oBAAoB,SAAS,SAAS;AAC/D;AAYO,MAAM,2BAA2B,CAAC,SAIV;AAC7B,QAAM,EAAE,QAAQ,IAAI;AACpB,SAAO;AAAA,IACL,GAAG,kBAAkB,OAAO;AAAA,IAC5B,QAAQ,OACN,WACuD;AACvD,YAAM,UAAU,MAAM,WAAW,KAAK,OAAO;AAAA,QAC3C,WAAW,KAAK;AAAA,QAChB,OAAO,OAAO;AAAA,QACd,SAAS,OAAO;AAAA,QAChB,OAAO,EAAE,MAAM,mBAAmB,SAAS,IAAI,OAAO,GAAG;AAAA,QACzD,QAAQ,OAAO;AAAA,MACjB,CAAC;AACD,UAAI;AACF,cAAM,UAAU,MAAM,QAAQ,KAAK,QAAQ;AAAA,UACzC,QAAQ,WAAW;AAAA,UACnB,MAAM;AAAA,UACN,MAAM;AAAA,YACJ,QAAQ;AAAA,YACR,OAAO;AAAA,cACL,IAAI,QAAQ,WAAW,OAAO;AAAA,cAC9B,WAAW,KAAK;AAAA,cAChB,OAAO,QAAQ;AAAA,cACf,SAAS,QAAQ;AAAA,cACjB,OAAO,OAAO;AAAA,cACd,SAAS,OAAO;AAAA,cAChB,QAAQ,OAAO,UAAU,OAAO,SAAY,mBAAmB,OAAO,MAAM;AAAA,cAC5E,YAAY,OAAO;AAAA,cACnB,gBACE,OAAO,mBAAmB,OAAO,WAAW,OAAO,SAAY,QAAQ,OAAO;AAAA,cAChF,OAAO,OAAO;AAAA,cACd,MAAM,OAAO;AAAA,cACb,qBACE,OAAO,WAAW,OAAO,SAAa,OAAO,uBAAuB,QAAQ,IAAI;AAAA,YACpF;AAAA,UACF;AAAA,UACA,UAAU;AAAA,UACV,QAAQ,OAAO;AAAA,QACjB,CAAC;AACD,cAAM,WAAW,QAAQ,WAAW,OAAO;AAC3C,YAAI,YAAY,QAAQ,QAAQ,QAAQ,OAAO,UAAU;AAKvD,kBAAQ,QAAQ;AAChB,cAAI,QAAQ,QAAQ;AAClB,kBAAM,aAAa,KAAK,OAAO;AAAA,cAC7B,WAAW,KAAK;AAAA,cAChB,OAAO,OAAO;AAAA,cACd,OAAO,EAAE,MAAM,mBAAmB,SAAS,IAAI,QAAQ,QAAQ,GAAG;AAAA,cAClE,QAAQ,OAAO;AAAA,YACjB,CAAC;AAAA,QACL,MAAO,SAAQ,YAAY;AAC3B,cAAM,SAAS,oBAAoB,SAAS,QAAQ,QAAQ,EAAE;AAC9D,eAAO;AAAA,UACL,SAAS,QAAQ;AAAA,UACjB;AAAA,UACA,UACE,QAAQ,QAAQ,OACZ,OACA,WAAW;AAAA,YACT;AAAA,YACA,WAAW,QAAQ,QAAQ;AAAA,YAC3B,UAAU,QAAQ;AAAA,YAClB,QAAQ,iBAAyB,OAAO,MAAM;AAAA,YAC9C,iBAAiB,OAAO,UAAU;AAAA,UACpC,CAAC;AAAA,QACT;AAAA,MACF,SAAS,OAAO;AACd,gBAAQ,QAAQ;AAChB,cAAM;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACF;",
|
|
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.
|
|
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.
|
|
119
|
-
"@finalai/agent-protocol": "0.
|
|
120
|
-
"@finalai/agent-provider": "0.
|
|
121
|
-
"@finalai/final-agent-provider": "0.
|
|
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"
|