@theoremjs/react 0.3.0 → 0.3.1
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 +728 -202
- package/client/composer-hints.js +1 -1
- package/client/decision-images.d.ts +76 -0
- package/client/decision-images.js +139 -0
- package/client/decision-transport.d.ts +26 -4
- package/client/decision-transport.js +79 -6
- package/client/embedding-input.d.ts +84 -0
- package/client/embedding-input.js +194 -0
- package/client/embedding-space.d.ts +82 -0
- package/client/embedding-space.js +389 -0
- package/client/embedding-transport.d.ts +40 -0
- package/client/embedding-transport.js +71 -0
- package/client/failure.d.ts +7 -10
- package/client/failure.js +9 -9
- package/client/host-call.d.ts +1 -1
- package/client/host-call.js +7 -2
- package/client/host-transport.d.ts +2 -0
- package/client/host-transport.js +3 -2
- package/client/index.d.ts +19 -11
- package/client/index.js +14 -10
- package/client/ink-waveform.d.ts +1 -1
- package/client/ink-waveform.js +1 -2
- package/client/live/apply-live-turn-tool-event.js +1 -1
- package/client/live/live-captions.d.ts +30 -0
- package/client/live/live-captions.js +105 -1
- package/client/live/live-mic-forward.d.ts +1 -0
- package/client/live/live-mic-forward.js +11 -2
- package/client/live/live-page-tool.d.ts +34 -0
- package/client/live/live-page-tool.js +11 -0
- package/client/live/live-state.d.ts +4 -2
- package/client/live/live-state.js +2 -0
- package/client/live/live-video.js +1 -1
- package/client/live/run-live-tool-call.d.ts +7 -2
- package/client/live/run-live-tool-call.js +48 -10
- package/client/live/use-live-caption-log.d.ts +17 -0
- package/client/live/use-live-caption-log.js +51 -0
- package/client/live-client.d.ts +52 -4
- package/client/live-client.js +250 -59
- package/client/live-messages.d.ts +51 -13
- package/client/live-messages.js +42 -9
- package/client/page-dispatch.d.ts +15 -0
- package/client/page-dispatch.js +63 -0
- package/client/run-commit.d.ts +16 -43
- package/client/run-commit.js +26 -101
- package/client/run-session.d.ts +40 -41
- package/client/run-session.js +104 -112
- package/client/schema-fields.js +27 -6
- package/client/shaped-data.js +37 -8
- package/client/source-citations.js +1 -1
- package/client/space-geometry.d.ts +39 -0
- package/client/space-geometry.js +183 -0
- package/client/state-fields.js +1 -1
- package/client/tool-result.js +30 -12
- package/client/tool-resume.d.ts +18 -1
- package/client/tool-resume.js +4 -1
- package/client/trace-feed.d.ts +1 -1
- package/client/trace-story.d.ts +2 -2
- package/client/trace-story.js +43 -19
- package/client/trace-view.d.ts +2 -2
- package/client/trace-view.js +56 -16
- package/client/transcript-groups.d.ts +28 -2
- package/client/transcript-groups.js +63 -13
- package/client/transcript-schema.d.ts +10 -0
- package/client/transcript-schema.js +120 -0
- package/client/transport.d.ts +114 -26
- package/client/transport.js +106 -32
- package/client/turn-client.d.ts +17 -8
- package/client/turn-client.js +26 -31
- package/client/voice-recorder.d.ts +1 -1
- package/client/voice-recorder.js +2 -5
- package/client/wire-line.js +5 -5
- package/client/worklets/mic-capture.js +9 -9
- package/components/InkWaveform.d.ts +12 -1
- package/components/InkWaveform.js +65 -42
- package/components/live/use-live-runner-controls.d.ts +3 -4
- package/components/live/use-live-runner-controls.js +6 -10
- package/components/live/use-live-runner-model.d.ts +10 -6
- package/components/live/use-live-runner-model.js +29 -14
- package/components/live/use-live-runner-ui.d.ts +10 -8
- package/components/live/use-live-runner-ui.js +19 -11
- package/components/live/use-live-session-client.d.ts +4 -4
- package/components/live/use-live-session-client.js +11 -8
- package/components/use-composer-voice.d.ts +4 -4
- package/components/use-composer-voice.js +8 -8
- package/components/use-editor-selection.js +4 -1
- package/components/use-voice-playback.d.ts +2 -1
- package/components/use-voice-playback.js +4 -4
- package/hooks/use-described.d.ts +5 -1
- package/hooks/use-described.js +11 -9
- package/hooks/use-embedding-index.d.ts +27 -0
- package/hooks/use-embedding-index.js +43 -0
- package/hooks/use-one-call.d.ts +31 -0
- package/hooks/use-one-call.js +76 -0
- package/hooks/use-page-tool-warnings.d.ts +6 -0
- package/hooks/use-page-tool-warnings.js +25 -0
- package/hooks/use-second-ticker.d.ts +2 -0
- package/hooks/use-second-ticker.js +13 -0
- package/hooks/use-theorem-chat-actions.d.ts +25 -21
- package/hooks/use-theorem-chat-actions.js +67 -45
- package/hooks/use-theorem-chat-state.d.ts +6 -6
- package/hooks/use-theorem-chat-state.js +13 -9
- package/hooks/use-theorem-chat.d.ts +48 -14
- package/hooks/use-theorem-chat.js +329 -141
- package/hooks/use-theorem-decision.d.ts +5 -10
- package/hooks/use-theorem-decision.js +4 -67
- package/hooks/use-theorem-embedding.d.ts +18 -0
- package/hooks/use-theorem-embedding.js +12 -0
- package/hooks/use-theorem-host.d.ts +5 -4
- package/hooks/use-theorem-host.js +26 -8
- package/hooks/use-theorem-interface.d.ts +6 -3
- package/hooks/use-theorem-interface.js +12 -22
- package/index.d.ts +6 -3
- package/index.js +5 -2
- package/live.d.ts +1 -0
- package/live.js +1 -1
- package/package.json +6 -5
- package/server/checkpoint-ownership.d.ts +6 -0
- package/server/checkpoint-ownership.js +42 -0
- package/server/conversation-store.d.ts +92 -0
- package/server/conversation-store.js +131 -0
- package/server/conversation.d.ts +193 -0
- package/server/conversation.js +552 -0
- package/server/decision-handler.d.ts +12 -4
- package/server/decision-handler.js +29 -38
- package/server/embedding-handler.d.ts +33 -0
- package/server/embedding-handler.js +45 -0
- package/server/handler.d.ts +58 -20
- package/server/handler.js +441 -238
- package/server/mod.d.ts +15 -6
- package/server/mod.js +13 -5
- package/server/page-dispatch.d.ts +22 -0
- package/server/page-dispatch.js +127 -0
- package/server/request-body.d.ts +2 -0
- package/server/request-body.js +42 -0
- package/server/request-check.d.ts +6 -1
- package/server/request-check.js +27 -12
- package/server/session-authority.d.ts +8 -0
- package/server/session-authority.js +78 -0
- package/server/session-boundary.d.ts +26 -0
- package/server/session-boundary.js +64 -0
- package/server/session-identity.d.ts +16 -0
- package/server/session-identity.js +41 -0
- package/server/session-limits.d.ts +12 -0
- package/server/session-limits.js +59 -0
- package/server/session-store.d.ts +69 -20
- package/server/session-store.js +220 -5
- package/server/single-action.d.ts +21 -0
- package/server/single-action.js +30 -0
- package/server/steer-inbox.js +1 -1
- package/server/tool-operations.d.ts +6 -0
- package/server/tool-operations.js +132 -0
- package/server/turn-input.d.ts +10 -0
- package/server/turn-input.js +29 -0
- package/styles/ink-controls.css +78 -78
- package/ui/CardWall.d.ts +10 -0
- package/ui/CardWall.js +61 -0
- package/ui/ChatComposerBar.d.ts +28 -5
- package/ui/ChatComposerBar.js +85 -30
- package/ui/ChatTranscript.d.ts +14 -1
- package/ui/ChatTranscript.js +110 -57
- package/ui/ConsoleFrame.d.ts +61 -4
- package/ui/ConsoleFrame.js +109 -9
- package/ui/DecisionAnswers.d.ts +40 -2
- package/ui/DecisionAnswers.js +166 -35
- package/ui/DecisionImages.d.ts +16 -0
- package/ui/DecisionImages.js +46 -0
- package/ui/EmbeddingDocuments.d.ts +78 -0
- package/ui/EmbeddingDocuments.js +278 -0
- package/ui/EmbeddingQuery.d.ts +27 -0
- package/ui/EmbeddingQuery.js +95 -0
- package/ui/EmbeddingResults.d.ts +41 -0
- package/ui/EmbeddingResults.js +165 -0
- package/ui/EmbeddingSpace.d.ts +26 -0
- package/ui/EmbeddingSpace.js +106 -0
- package/ui/LiveCaptionsPanel.d.ts +22 -0
- package/ui/LiveCaptionsPanel.js +27 -0
- package/ui/LiveRunner.d.ts +6 -4
- package/ui/LiveRunner.js +42 -55
- package/ui/PaneState.d.ts +33 -0
- package/ui/PaneState.js +50 -0
- package/ui/SchemaFields.d.ts +1 -1
- package/ui/SchemaFields.js +54 -26
- package/ui/ShapedData.js +73 -28
- package/ui/SidePanel.d.ts +74 -5
- package/ui/SidePanel.js +82 -9
- package/ui/StateFields.d.ts +10 -2
- package/ui/StateFields.js +56 -13
- package/ui/TheoremChat.d.ts +65 -14
- package/ui/TheoremChat.js +66 -78
- package/ui/TheoremDecision.d.ts +12 -20
- package/ui/TheoremDecision.js +78 -35
- package/ui/TheoremEmbedding.d.ts +27 -0
- package/ui/TheoremEmbedding.js +122 -0
- package/ui/TheoremHost.d.ts +22 -5
- package/ui/TheoremHost.js +127 -37
- package/ui/ToolGateCard.d.ts +5 -1
- package/ui/ToolGateCard.js +30 -23
- package/ui/ToolResult.js +12 -10
- package/ui/ToolResultCharts.js +29 -12
- package/ui/TraceCharts.d.ts +2 -2
- package/ui/TraceCharts.js +48 -17
- package/ui/TraceGuardrails.d.ts +3 -2
- package/ui/TraceGuardrails.js +24 -6
- package/ui/TraceInspector.d.ts +11 -1
- package/ui/TraceInspector.js +45 -28
- package/ui/TraceInspectorPanel.d.ts +31 -9
- package/ui/TraceInspectorPanel.js +77 -39
- package/ui/TraceOverview.d.ts +7 -3
- package/ui/TraceOverview.js +44 -14
- package/ui/TraceSpanDetail.js +24 -22
- package/ui/TraceStory.js +9 -8
- package/ui/TraceValues.js +19 -9
- package/ui/TraceWaterfall.js +12 -9
- package/ui/VoiceNote.js +4 -4
- package/ui/approval-heading.d.ts +4 -0
- package/ui/approval-heading.js +9 -0
- package/ui/arrive.d.ts +18 -0
- package/ui/arrive.js +46 -0
- package/ui/built/theme.css +86 -68
- package/ui/built/theme.css.d.ts +9 -0
- package/ui/built/theorem.d.ts +3 -3
- package/ui/built/theorem.js +34 -5
- package/ui/built/theorem.variants.d.ts +8 -2
- package/ui/code-language.d.ts +12 -0
- package/ui/code-language.js +50 -0
- package/ui/disclosure-motion.js +53 -9
- package/ui/embedding-space-gl.d.ts +37 -0
- package/ui/embedding-space-gl.js +663 -0
- package/ui/embedding-space-view.d.ts +8 -0
- package/ui/embedding-space-view.js +8 -0
- package/ui/glide.d.ts +7 -0
- package/ui/glide.js +44 -0
- package/ui/icons.js +2 -1
- package/ui/index.d.ts +20 -9
- package/ui/index.js +20 -10
- package/ui/labels-provider.js +5 -2
- package/ui/labels.d.ts +374 -85
- package/ui/labels.js +1028 -188
- package/ui/markdown-plugins.d.ts +9 -0
- package/ui/markdown-plugins.js +13 -0
- package/ui/mcp-icon.d.ts +6 -0
- package/ui/mcp-icon.js +8 -0
- package/ui/row-keys.d.ts +19 -0
- package/ui/row-keys.js +33 -0
- package/ui/theme.d.ts +1 -1
- package/ui/theme.js +2 -2
- package/ui/theorem-theme.js +32 -10
- package/ui/trace-palette.d.ts +2 -16
- package/ui/trace-palette.js +2 -16
- package/ui/trace-patterns.d.ts +11 -3
- package/ui/trace-patterns.js +16 -3
- package/ui/transcript-copy-text.js +1 -0
- package/ui/wall-columns.d.ts +8 -0
- package/ui/wall-columns.js +19 -0
- package/client/walk-away.d.ts +0 -34
- package/client/walk-away.js +0 -48
- package/server/walk-away.d.ts +0 -22
- package/server/walk-away.js +0 -41
package/client/transport.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { type GateReference, type ToolGate } from '@theoremjs/agents';
|
|
2
|
+
import type { PageDispatchResult } from './page-dispatch.ts';
|
|
1
3
|
/**
|
|
2
4
|
* Transport contract between a Theorem chat UI and the host that runs turns.
|
|
3
5
|
*
|
|
@@ -9,7 +11,9 @@
|
|
|
9
11
|
* @module
|
|
10
12
|
*/
|
|
11
13
|
import { type ErrorKind, type TurnEvent, type TurnHistoryMessage, type TurnToolSnapshot, z } from '@theoremjs/agents';
|
|
12
|
-
import { type
|
|
14
|
+
import { type ErrorCopies } from '@theoremjs/agents/guardrails';
|
|
15
|
+
import { type ProfileInterface, type TranscriptBlock } from '@theoremjs/agents/interface';
|
|
16
|
+
import type { PagePart } from './tool-resume.ts';
|
|
13
17
|
import type { TraceFeed } from './trace-feed.ts';
|
|
14
18
|
import { type MalformedEvent, type UnsupportedEvent, type WireLines } from './wire-line.ts';
|
|
15
19
|
export type { MalformedEvent, UnsupportedEvent, WireLines } from './wire-line.ts';
|
|
@@ -23,49 +27,55 @@ export type TheoremTurnInput = {
|
|
|
23
27
|
text?: string;
|
|
24
28
|
attachments?: EncodedBlob[];
|
|
25
29
|
voice?: EncodedBlob[];
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
30
|
+
/** The value chosen for each of the profile's `inputs.slots`. */
|
|
31
|
+
slots?: Record<string, string>;
|
|
32
|
+
/** What the page wants the agent to know: any JSON. The host reads it as untrusted. */
|
|
33
|
+
context?: unknown;
|
|
29
34
|
};
|
|
30
35
|
/**
|
|
31
36
|
* State only the client holds, for hosts whose profile also lives in the browser
|
|
32
|
-
* (the
|
|
37
|
+
* (the studio). `createHttpTransport` never sends it: `createTheoremHandler`
|
|
33
38
|
* keeps permissions, paused calls, and tool snapshots in its own session.
|
|
34
39
|
*/
|
|
35
40
|
export type TheoremReplay = {
|
|
41
|
+
gateKind?: ToolGate['kind'];
|
|
36
42
|
sessionPermissions?: string[];
|
|
37
43
|
name?: string;
|
|
38
44
|
input?: unknown;
|
|
39
|
-
turnInput?: TheoremTurnInput;
|
|
40
45
|
snapshot?: TurnToolSnapshot;
|
|
41
46
|
promoted?: string[];
|
|
42
47
|
model?: string;
|
|
43
48
|
effort?: string;
|
|
44
|
-
path?: string;
|
|
45
49
|
};
|
|
46
|
-
/** For a host that reads the
|
|
50
|
+
/** For a host that reads the studio's client-held state. */
|
|
47
51
|
export declare const theoremReplaySchema: z.ZodType<TheoremReplay>;
|
|
48
52
|
/**
|
|
49
|
-
* One
|
|
53
|
+
* One message. The host resolves the profile and owns the conversation: the
|
|
54
|
+
* client sends only the message and the ref of the conversation it continues.
|
|
50
55
|
*
|
|
51
56
|
* A message sent while the reply waits on gates walks away from them: `abandon`
|
|
52
|
-
* names the waiting calls
|
|
53
|
-
*
|
|
54
|
-
* and gives the model each call's answer before the message.
|
|
57
|
+
* names the waiting calls. The host settles each one cancelled, streams those
|
|
58
|
+
* events first, and gives the model each call's answer before the message.
|
|
55
59
|
*/
|
|
56
60
|
export type TheoremTurnRequest = {
|
|
57
61
|
input: TheoremTurnInput;
|
|
58
|
-
|
|
62
|
+
/** The ref of the conversation this message continues; none starts one. */
|
|
63
|
+
conversation?: string;
|
|
59
64
|
model?: string;
|
|
60
65
|
effort?: string;
|
|
61
66
|
/** Client-generated id so mid-turn steers can find this turn's inbox. */
|
|
62
67
|
turnId?: string;
|
|
63
|
-
/**
|
|
64
|
-
abandon?:
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
68
|
+
/** invariant: Both issued IDs identify each paused action that this message abandons. */
|
|
69
|
+
abandon?: GateReference[];
|
|
70
|
+
/** The tools the person allowed for the page, for a host without a session (the studio). */
|
|
71
|
+
replay?: Pick<TheoremReplay, 'sessionPermissions'>;
|
|
72
|
+
/**
|
|
73
|
+
* The page's transcript before this message, sent only after the host answered that it can no
|
|
74
|
+
* longer open `conversation` (`session.conversation_unknown`). A host that restores from it (the
|
|
75
|
+
* studio) goes on from it under a new ref; `createTheoremHandler` keeps the conversation its own
|
|
76
|
+
* and does not.
|
|
77
|
+
*/
|
|
78
|
+
transcript?: TranscriptBlock[];
|
|
69
79
|
};
|
|
70
80
|
/** A `/turn` body as `createTheoremHandler` reads it. */
|
|
71
81
|
export declare const theoremTurnRequestSchema: z.ZodType<TheoremTurnRequest>;
|
|
@@ -80,6 +90,7 @@ declare const INVOKE_DECISIONS: readonly ["approve", "deny"];
|
|
|
80
90
|
export type TheoremInvokeRequest = {
|
|
81
91
|
/** Call id of the paused tool call (`tool.callId` on its gate event). */
|
|
82
92
|
gateId: string;
|
|
93
|
+
operationId: string;
|
|
83
94
|
decision: (typeof INVOKE_DECISIONS)[number];
|
|
84
95
|
/** The user's edit of the model's input; only with `approve`. */
|
|
85
96
|
input?: unknown;
|
|
@@ -90,6 +101,12 @@ export type TheoremInvokeRequest = {
|
|
|
90
101
|
* callback saved the token.
|
|
91
102
|
*/
|
|
92
103
|
secret?: string;
|
|
104
|
+
/** The page's answer to a `page` gate, only with `approve`: the tool's output schema checks it. */
|
|
105
|
+
page?: PagePart;
|
|
106
|
+
/** The ref of the conversation whose reply waits on the gate. */
|
|
107
|
+
conversation?: string;
|
|
108
|
+
/** Client-generated id so steers sent while the reply goes on find its inbox. */
|
|
109
|
+
turnId?: string;
|
|
93
110
|
replay?: TheoremReplay;
|
|
94
111
|
};
|
|
95
112
|
/** An `/invoke` body as `createTheoremHandler` reads it. */
|
|
@@ -103,40 +120,97 @@ export type TheoremSteerRequest = {
|
|
|
103
120
|
};
|
|
104
121
|
/** A `/steer` body as `createTheoremHandler` reads it. */
|
|
105
122
|
export declare const theoremSteerRequestSchema: z.ZodType<TheoremSteerRequest>;
|
|
123
|
+
/**
|
|
124
|
+
* The ref the store issued for the conversation a run wrote: the client sends
|
|
125
|
+
* it with its next request. It comes before the run's error, which ends the stream.
|
|
126
|
+
* `posted` marks the write that holds the person's new message: a run that
|
|
127
|
+
* fails before it leaves the message unsent.
|
|
128
|
+
*/
|
|
129
|
+
export type ConversationLine = {
|
|
130
|
+
type: 'conversation';
|
|
131
|
+
ref: string;
|
|
132
|
+
posted?: true;
|
|
133
|
+
};
|
|
134
|
+
/** The lines a chat's reply streams: turn events, and the conversation's ref. */
|
|
135
|
+
export declare const CHAT_LINES: WireLines<TurnEvent | ConversationLine>;
|
|
136
|
+
/** What the browser draws: the transcript, and the reply that waits on gates. */
|
|
137
|
+
export type ConversationView = {
|
|
138
|
+
transcript: TranscriptBlock[];
|
|
139
|
+
/** The reply that waits on gates: its events, and its blocks as the transcript will keep them. */
|
|
140
|
+
paused?: {
|
|
141
|
+
events: TurnEvent[];
|
|
142
|
+
blocks: TranscriptBlock[];
|
|
143
|
+
};
|
|
144
|
+
};
|
|
145
|
+
/** Read a conversation: a `/conversation` body. */
|
|
146
|
+
export type TheoremConversationRequest = {
|
|
147
|
+
conversation: string;
|
|
148
|
+
};
|
|
149
|
+
/** A `/conversation` body as `createTheoremHandler` reads it. */
|
|
150
|
+
export declare const theoremConversationRequestSchema: z.ZodType<TheoremConversationRequest>;
|
|
151
|
+
/**
|
|
152
|
+
* Cut the conversation after transcript block `at` (-1 empties it): a
|
|
153
|
+
* `/rewind` body. A reply waiting on gates is walked away from first.
|
|
154
|
+
*/
|
|
155
|
+
export type TheoremRewindRequest = {
|
|
156
|
+
conversation: string;
|
|
157
|
+
at: number;
|
|
158
|
+
};
|
|
159
|
+
/** A `/rewind` body as `createTheoremHandler` reads it. */
|
|
160
|
+
export declare const theoremRewindRequestSchema: z.ZodType<TheoremRewindRequest>;
|
|
161
|
+
/** A rewound conversation: its new ref, and what the browser draws. */
|
|
162
|
+
export type TheoremRewound = {
|
|
163
|
+
conversation: string;
|
|
164
|
+
view: ConversationView;
|
|
165
|
+
};
|
|
106
166
|
/** A turn event, one of a kind this client does not know (`unsupported`), or one that failed its check (`malformed`). */
|
|
107
167
|
export type ClientTurnEvent = TurnEvent | UnsupportedEvent | MalformedEvent;
|
|
108
168
|
export type TurnEventSink = (event: ClientTurnEvent) => void;
|
|
169
|
+
/** A line of a chat's reply: a turn event, or the ref of the conversation it wrote. */
|
|
170
|
+
export type ChatLine = ClientTurnEvent | ConversationLine;
|
|
171
|
+
export type ChatLineSink = (line: ChatLine) => void;
|
|
109
172
|
export interface TheoremTransport {
|
|
110
173
|
/** Client-safe interface for the host's profile (inputs, models, guardrail view). */
|
|
111
174
|
describe(signal?: AbortSignal): Promise<ProfileInterface>;
|
|
112
|
-
turn(request: TheoremTurnRequest,
|
|
113
|
-
invoke(request: TheoremInvokeRequest,
|
|
175
|
+
turn(request: TheoremTurnRequest, onLine: ChatLineSink, signal?: AbortSignal): Promise<void>;
|
|
176
|
+
invoke(request: TheoremInvokeRequest, onLine: ChatLineSink, signal?: AbortSignal): Promise<void>;
|
|
114
177
|
steer(request: TheoremSteerRequest): Promise<void>;
|
|
115
|
-
/**
|
|
178
|
+
/** The conversation under `ref`, as the host shows it. */
|
|
179
|
+
conversation(request: TheoremConversationRequest, signal?: AbortSignal): Promise<ConversationView>;
|
|
180
|
+
/** The conversation cut after a transcript block, under the ref the host issued for it. */
|
|
181
|
+
rewind(request: TheoremRewindRequest, signal?: AbortSignal): Promise<TheoremRewound>;
|
|
182
|
+
pageResult?(result: PageDispatchResult, signal?: AbortSignal): Promise<void>;
|
|
183
|
+
/** Trace records the host sends back, when it delivers them (the studio does). */
|
|
116
184
|
traces?: TraceFeed;
|
|
117
185
|
}
|
|
118
186
|
/**
|
|
119
187
|
* A failure the host reported: its kind, the host's wording when it sent one
|
|
120
|
-
* (the profile's
|
|
188
|
+
* (the profile's labels, applied on the host), and raw detail when the host
|
|
121
189
|
* exposes it. `clientFailure` words it for the user.
|
|
122
190
|
*/
|
|
123
191
|
export declare class TheoremStreamError extends Error {
|
|
124
192
|
readonly kind: ErrorKind;
|
|
125
193
|
readonly publicMessage?: string;
|
|
126
194
|
readonly internalMessage?: string;
|
|
127
|
-
|
|
195
|
+
/** The labels key behind `publicMessage`, when the host gave one: what failed, more exactly than `kind`. */
|
|
196
|
+
readonly copy?: ErrorCopies;
|
|
197
|
+
constructor(kind: ErrorKind, publicMessage?: string, internalMessage?: string, copy?: ErrorCopies);
|
|
128
198
|
}
|
|
129
199
|
export declare function isTheoremStreamError(err: unknown): err is TheoremStreamError;
|
|
130
200
|
/** A host error reply's body (JSON reply or `{ type: 'error' }` stream line). */
|
|
131
201
|
export type HostErrorBody = {
|
|
132
202
|
error?: string;
|
|
133
203
|
errorKind?: ErrorKind;
|
|
204
|
+
/** The labels key behind `error`, when more specific than the kind's. */
|
|
205
|
+
errorCopy?: ErrorCopies;
|
|
134
206
|
errorInternal?: string;
|
|
135
207
|
};
|
|
136
208
|
/** A host's error body, as the transport and the live client read it. */
|
|
137
209
|
export declare const hostErrorBodySchema: z.ZodType<HostErrorBody>;
|
|
138
210
|
/** A host's error body as a failure: its kind (else `fallbackKind`), wording, and detail. */
|
|
139
211
|
export declare function hostError(body: HostErrorBody, fallbackKind: ErrorKind): TheoremStreamError;
|
|
212
|
+
/** The host could not open the message's conversation (`session.conversation_unknown`). */
|
|
213
|
+
export declare function isUnknownConversation(err: unknown): boolean;
|
|
140
214
|
/**
|
|
141
215
|
* Read an NDJSON reply, checking each line against `lines`: a kind it doesn't
|
|
142
216
|
* list reaches `onLine` as `unsupported`, and a line that fails its check as
|
|
@@ -162,12 +236,26 @@ export declare function postNdjson<Line extends {
|
|
|
162
236
|
signal?: AbortSignal;
|
|
163
237
|
}): Promise<void>;
|
|
164
238
|
/** POST JSON; a non-OK reply throws its failure. The OK reply's body is not read. */
|
|
165
|
-
export declare function postJson(url: string, body: unknown, options?: HttpOptions
|
|
166
|
-
|
|
239
|
+
export declare function postJson(url: string, body: unknown, options?: HttpOptions & {
|
|
240
|
+
signal?: AbortSignal;
|
|
241
|
+
}): Promise<void>;
|
|
242
|
+
/**
|
|
243
|
+
* GET, or POST `body` as JSON, and read the JSON reply; a non-OK reply throws its failure, after
|
|
244
|
+
* `failed` has read whatever else its JSON body carries.
|
|
245
|
+
*/
|
|
167
246
|
export declare function fetchJson(url: string, init: {
|
|
168
247
|
body?: unknown;
|
|
169
248
|
signal?: AbortSignal;
|
|
249
|
+
failed?: (body: unknown) => void;
|
|
170
250
|
}, options?: HttpOptions): Promise<unknown>;
|
|
251
|
+
/** POST a conversation's read to `url`, and check the view the host answers. */
|
|
252
|
+
export declare function fetchConversation(url: string, body: unknown, options?: HttpOptions & {
|
|
253
|
+
signal?: AbortSignal;
|
|
254
|
+
}): Promise<ConversationView>;
|
|
255
|
+
/** POST a rewind to `url`, and check the rewound conversation the host answers. */
|
|
256
|
+
export declare function fetchRewound(url: string, body: unknown, options?: HttpOptions & {
|
|
257
|
+
signal?: AbortSignal;
|
|
258
|
+
}): Promise<TheoremRewound>;
|
|
171
259
|
export type HttpTransportOptions = HttpOptions & {
|
|
172
260
|
/** Base URL where `createTheoremHandler` is mounted. Default `/api/theorem`. */
|
|
173
261
|
endpoint?: string;
|
package/client/transport.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { gateReferenceSchema, TOOL_GATE_KINDS, } from '@theoremjs/agents';
|
|
1
2
|
/**
|
|
2
3
|
* Transport contract between a Theorem chat UI and the host that runs turns.
|
|
3
4
|
*
|
|
@@ -8,59 +9,67 @@
|
|
|
8
9
|
*
|
|
9
10
|
* @module
|
|
10
11
|
*/
|
|
11
|
-
import { describeError, errorKindSchema, isAbortError, TheoremError, TURN_EVENT_SCHEMAS, throwIfAborted, turnHistoryMessageSchema, turnToolSnapshotSchema, z, } from '@theoremjs/agents';
|
|
12
|
-
import { kindOfHttpStatus } from '@theoremjs/agents/guardrails';
|
|
13
|
-
import { profileInterfaceSchema } from '@theoremjs/agents/interface';
|
|
12
|
+
import { describeError, errorKindSchema, isAbortError, TheoremError, TURN_EVENT_SCHEMAS, throwIfAborted, turnEventSchema, turnHistoryMessageSchema, turnToolSnapshotSchema, z, } from '@theoremjs/agents';
|
|
13
|
+
import { errorCopiesSchema, kindOfHttpStatus, } from '@theoremjs/agents/guardrails';
|
|
14
|
+
import { profileInterfaceSchema, } from '@theoremjs/agents/interface';
|
|
15
|
+
import { transcriptBlockSchema } from "./transcript-schema.js";
|
|
14
16
|
import { checkWire, parseWireJson, readWireLine, } from "./wire-line.js";
|
|
15
17
|
const encodedBlob = z.object({ name: z.string(), mimeType: z.string(), data: z.string() });
|
|
16
18
|
true;
|
|
17
19
|
const theoremTurnInput = z.object({
|
|
20
|
+
slots: z.record(z.string(), z.string()).optional(),
|
|
21
|
+
context: z.unknown().optional(),
|
|
18
22
|
text: z.string().optional(),
|
|
19
23
|
attachments: z.array(encodedBlob).optional(),
|
|
20
24
|
voice: z.array(encodedBlob).optional(),
|
|
21
|
-
history: z.array(turnHistoryMessageSchema).optional(),
|
|
22
|
-
historyTokens: z.number().optional(),
|
|
23
|
-
inputTokens: z.number().optional(),
|
|
24
25
|
});
|
|
25
26
|
true;
|
|
26
27
|
const theoremReplay = z.object({
|
|
28
|
+
gateKind: z.enum(TOOL_GATE_KINDS).optional(),
|
|
27
29
|
sessionPermissions: z.array(z.string()).optional(),
|
|
28
30
|
name: z.string().optional(),
|
|
29
31
|
input: z.unknown().optional(),
|
|
30
|
-
turnInput: theoremTurnInput.optional(),
|
|
31
32
|
snapshot: turnToolSnapshotSchema.optional(),
|
|
32
33
|
promoted: z.array(z.string()).optional(),
|
|
33
34
|
model: z.string().optional(),
|
|
34
35
|
effort: z.string().optional(),
|
|
35
|
-
path: z.string().optional(),
|
|
36
36
|
});
|
|
37
37
|
true;
|
|
38
|
-
/** For a host that reads the
|
|
38
|
+
/** For a host that reads the studio's client-held state. */
|
|
39
39
|
export const theoremReplaySchema = theoremReplay;
|
|
40
40
|
/** An id the client made: trimmed, never blank. */
|
|
41
41
|
const clientId = z.string().trim().min(1);
|
|
42
42
|
const theoremTurnRequest = z.object({
|
|
43
43
|
input: theoremTurnInput,
|
|
44
|
-
|
|
44
|
+
conversation: z.string().min(1).optional(),
|
|
45
45
|
model: z.string().optional(),
|
|
46
46
|
effort: z.string().optional(),
|
|
47
47
|
turnId: clientId.optional(),
|
|
48
|
-
abandon: z.array(
|
|
49
|
-
replay: theoremReplay
|
|
50
|
-
|
|
51
|
-
.extend({ abandon: z.record(z.string(), theoremReplay).optional() })
|
|
52
|
-
.optional(),
|
|
48
|
+
abandon: z.array(gateReferenceSchema).min(1).optional(),
|
|
49
|
+
replay: theoremReplay.pick({ sessionPermissions: true }).optional(),
|
|
50
|
+
transcript: z.array(transcriptBlockSchema).optional(),
|
|
53
51
|
});
|
|
54
52
|
true;
|
|
55
53
|
/** A `/turn` body as `createTheoremHandler` reads it. */
|
|
56
54
|
export const theoremTurnRequestSchema = theoremTurnRequest;
|
|
57
55
|
/** What the user answers a gate with; walking away rides on the next message (`TheoremTurnRequest.abandon`). */
|
|
58
56
|
const INVOKE_DECISIONS = ['approve', 'deny'];
|
|
57
|
+
const pagePart = z.union([
|
|
58
|
+
z.strictObject({ unanswered: z.literal(true) }),
|
|
59
|
+
z
|
|
60
|
+
.strictObject({ output: z.unknown() })
|
|
61
|
+
.refine((part) => 'output' in part)
|
|
62
|
+
.transform((part) => ({ output: part.output })),
|
|
63
|
+
]);
|
|
59
64
|
const theoremInvokeRequest = z.object({
|
|
60
65
|
gateId: z.string().min(1),
|
|
66
|
+
operationId: z.string().min(1).max(256),
|
|
61
67
|
decision: z.enum(INVOKE_DECISIONS),
|
|
62
68
|
input: z.unknown().optional(),
|
|
63
69
|
secret: z.string().optional(),
|
|
70
|
+
page: pagePart.optional(),
|
|
71
|
+
conversation: z.string().min(1).optional(),
|
|
72
|
+
turnId: clientId.optional(),
|
|
64
73
|
replay: theoremReplay.optional(),
|
|
65
74
|
});
|
|
66
75
|
true;
|
|
@@ -74,16 +83,49 @@ const theoremSteerRequest = z.object({
|
|
|
74
83
|
true;
|
|
75
84
|
/** A `/steer` body as `createTheoremHandler` reads it. */
|
|
76
85
|
export const theoremSteerRequestSchema = theoremSteerRequest;
|
|
86
|
+
const conversationLine = z.object({
|
|
87
|
+
type: z.literal('conversation'),
|
|
88
|
+
ref: z.string().min(1),
|
|
89
|
+
posted: z.literal(true).optional(),
|
|
90
|
+
});
|
|
91
|
+
true;
|
|
92
|
+
/** The lines a chat's reply streams: turn events, and the conversation's ref. */
|
|
93
|
+
export const CHAT_LINES = {
|
|
94
|
+
...TURN_EVENT_SCHEMAS,
|
|
95
|
+
conversation: conversationLine,
|
|
96
|
+
};
|
|
97
|
+
const conversationView = z.object({
|
|
98
|
+
transcript: z.array(transcriptBlockSchema),
|
|
99
|
+
paused: z
|
|
100
|
+
.object({ events: z.array(turnEventSchema), blocks: z.array(transcriptBlockSchema) })
|
|
101
|
+
.optional(),
|
|
102
|
+
});
|
|
103
|
+
true;
|
|
104
|
+
const theoremConversationRequest = z.object({ conversation: z.string().min(1) });
|
|
105
|
+
true;
|
|
106
|
+
/** A `/conversation` body as `createTheoremHandler` reads it. */
|
|
107
|
+
export const theoremConversationRequestSchema = theoremConversationRequest;
|
|
108
|
+
const theoremRewindRequest = z.object({
|
|
109
|
+
conversation: z.string().min(1),
|
|
110
|
+
at: z.number().int().min(-1),
|
|
111
|
+
});
|
|
112
|
+
true;
|
|
113
|
+
/** A `/rewind` body as `createTheoremHandler` reads it. */
|
|
114
|
+
export const theoremRewindRequestSchema = theoremRewindRequest;
|
|
115
|
+
const theoremRewound = z.object({ conversation: z.string().min(1), view: conversationView });
|
|
116
|
+
true;
|
|
77
117
|
/**
|
|
78
118
|
* A failure the host reported: its kind, the host's wording when it sent one
|
|
79
|
-
* (the profile's
|
|
119
|
+
* (the profile's labels, applied on the host), and raw detail when the host
|
|
80
120
|
* exposes it. `clientFailure` words it for the user.
|
|
81
121
|
*/
|
|
82
122
|
export class TheoremStreamError extends Error {
|
|
83
123
|
kind;
|
|
84
124
|
publicMessage;
|
|
85
125
|
internalMessage;
|
|
86
|
-
|
|
126
|
+
/** The labels key behind `publicMessage`, when the host gave one: what failed, more exactly than `kind`. */
|
|
127
|
+
copy;
|
|
128
|
+
constructor(kind, publicMessage, internalMessage, copy) {
|
|
87
129
|
super(internalMessage ?? publicMessage ?? kind);
|
|
88
130
|
this.name = 'TheoremStreamError';
|
|
89
131
|
this.kind = kind;
|
|
@@ -91,6 +133,8 @@ export class TheoremStreamError extends Error {
|
|
|
91
133
|
this.publicMessage = publicMessage;
|
|
92
134
|
if (internalMessage)
|
|
93
135
|
this.internalMessage = internalMessage;
|
|
136
|
+
if (copy)
|
|
137
|
+
this.copy = copy;
|
|
94
138
|
}
|
|
95
139
|
}
|
|
96
140
|
export function isTheoremStreamError(err) {
|
|
@@ -103,6 +147,7 @@ function textOf(value) {
|
|
|
103
147
|
const hostErrorBody = z.object({
|
|
104
148
|
error: z.string().optional(),
|
|
105
149
|
errorKind: errorKindSchema.optional(),
|
|
150
|
+
errorCopy: errorCopiesSchema.optional(),
|
|
106
151
|
errorInternal: z.string().optional(),
|
|
107
152
|
});
|
|
108
153
|
true;
|
|
@@ -112,12 +157,19 @@ export const hostErrorBodySchema = hostErrorBody;
|
|
|
112
157
|
export function hostError(body, fallbackKind) {
|
|
113
158
|
const publicMessage = textOf(body.error);
|
|
114
159
|
const internal = textOf(body.errorInternal);
|
|
115
|
-
return new TheoremStreamError(body.errorKind ?? fallbackKind, publicMessage, internal && internal !== publicMessage ? internal : undefined);
|
|
160
|
+
return new TheoremStreamError(body.errorKind ?? fallbackKind, publicMessage, internal && internal !== publicMessage ? internal : undefined, body.errorCopy);
|
|
161
|
+
}
|
|
162
|
+
/** The host could not open the message's conversation (`session.conversation_unknown`). */
|
|
163
|
+
export function isUnknownConversation(err) {
|
|
164
|
+
if (!isTheoremStreamError(err) || err.copy === undefined)
|
|
165
|
+
return false;
|
|
166
|
+
const copies = Array.isArray(err.copy) ? err.copy : [err.copy];
|
|
167
|
+
return copies.some((copy) => copy.key === 'session.conversation_unknown');
|
|
116
168
|
}
|
|
117
169
|
/** One NDJSON line checked against `lines`; an `error` line ends the stream as a {@link TheoremStreamError}. */
|
|
118
170
|
function parseStreamLine(lines, text) {
|
|
119
171
|
const line = readWireLine(lines, text);
|
|
120
|
-
// An `error` line passed the error event's schema, whose fields include the body's.
|
|
172
|
+
// why: An `error` line passed the error event's schema, whose fields include the body's.
|
|
121
173
|
if (line.type === 'error')
|
|
122
174
|
throw hostError(hostErrorBody.parse(line), 'internal');
|
|
123
175
|
return line;
|
|
@@ -139,7 +191,7 @@ function flushNdjsonChunk(buffer, lines, onLine) {
|
|
|
139
191
|
*/
|
|
140
192
|
export async function readNdjsonStream(response, lines, onLine, signal) {
|
|
141
193
|
if (!response.body)
|
|
142
|
-
throw new TheoremError('bad_response', 'stream reply has no body'); //
|
|
194
|
+
throw new TheoremError('bad_response', 'stream reply has no body'); // labels-exempt: internal diagnostic
|
|
143
195
|
const reader = response.body.getReader();
|
|
144
196
|
const decoder = new TextDecoder();
|
|
145
197
|
let buffer = '';
|
|
@@ -174,18 +226,19 @@ async function resolveHeaders(options) {
|
|
|
174
226
|
* kind. A body that is not JSON (a proxy's page) leaves the status to speak; a
|
|
175
227
|
* JSON body that fails the error body's schema is `bad_response`.
|
|
176
228
|
*/
|
|
177
|
-
async function failureFromResponse(response) {
|
|
229
|
+
async function failureFromResponse(response, failed) {
|
|
178
230
|
const text = await response.text();
|
|
179
231
|
let raw;
|
|
180
232
|
try {
|
|
181
233
|
raw = JSON.parse(text);
|
|
234
|
+
failed?.(raw);
|
|
182
235
|
}
|
|
183
236
|
catch {
|
|
184
237
|
return hostError({ errorInternal: `HTTP ${String(response.status)}` }, kindOfHttpStatus(response.status));
|
|
185
238
|
}
|
|
186
239
|
const body = hostErrorBody.safeParse(raw);
|
|
187
240
|
if (!body.success) {
|
|
188
|
-
//
|
|
241
|
+
// labels-exempt: internal diagnostic; the user reads error.bad_response
|
|
189
242
|
return new TheoremError('bad_response', `HTTP ${String(response.status)} error body failed its wire check`);
|
|
190
243
|
}
|
|
191
244
|
return hostError({ ...body.data, errorInternal: body.data.errorInternal ?? `HTTP ${String(response.status)}` }, kindOfHttpStatus(response.status));
|
|
@@ -210,25 +263,43 @@ async function request(url, init, options) {
|
|
|
210
263
|
* events ({@link TURN_EVENT_SCHEMAS}), or a host's own schema beside them.
|
|
211
264
|
*/
|
|
212
265
|
export async function postNdjson(url, body, lines, onLine, options = {}) {
|
|
266
|
+
const response = await jsonPostResponse(url, body, options);
|
|
267
|
+
await readNdjsonStream(response, lines, onLine, options.signal);
|
|
268
|
+
}
|
|
269
|
+
async function jsonPostResponse(url, body, options) {
|
|
213
270
|
const response = await request(url, { method: 'POST', body: JSON.stringify(body), signal: options.signal }, options);
|
|
214
271
|
if (!response.ok)
|
|
215
272
|
throw await failureFromResponse(response);
|
|
216
|
-
|
|
273
|
+
return response;
|
|
217
274
|
}
|
|
218
275
|
/** POST JSON; a non-OK reply throws its failure. The OK reply's body is not read. */
|
|
219
276
|
export async function postJson(url, body, options = {}) {
|
|
220
|
-
|
|
221
|
-
if (!response.ok)
|
|
222
|
-
throw await failureFromResponse(response);
|
|
277
|
+
await jsonPostResponse(url, body, options);
|
|
223
278
|
}
|
|
224
|
-
/**
|
|
279
|
+
/**
|
|
280
|
+
* GET, or POST `body` as JSON, and read the JSON reply; a non-OK reply throws its failure, after
|
|
281
|
+
* `failed` has read whatever else its JSON body carries.
|
|
282
|
+
*/
|
|
225
283
|
export async function fetchJson(url, init, options = {}) {
|
|
226
|
-
const method = init.body === undefined
|
|
284
|
+
const method = init.body === undefined
|
|
285
|
+
? { method: 'GET' }
|
|
286
|
+
: { method: 'POST', body: JSON.stringify(init.body) };
|
|
227
287
|
const response = await request(url, { ...method, signal: init.signal }, options);
|
|
228
288
|
if (!response.ok)
|
|
229
|
-
throw await failureFromResponse(response);
|
|
289
|
+
throw await failureFromResponse(response, init.failed);
|
|
230
290
|
return parseWireJson(await response.text());
|
|
231
291
|
}
|
|
292
|
+
/** POST a conversation's read to `url`, and check the view the host answers. */
|
|
293
|
+
export async function fetchConversation(url, body, options = {}) {
|
|
294
|
+
const { signal, ...http } = options;
|
|
295
|
+
// labels-exempt: internal diagnostic; the user reads error.bad_response
|
|
296
|
+
return checkWire(conversationView, await fetchJson(url, { body, signal }, http), 'the conversation');
|
|
297
|
+
}
|
|
298
|
+
/** POST a rewind to `url`, and check the rewound conversation the host answers. */
|
|
299
|
+
export async function fetchRewound(url, body, options = {}) {
|
|
300
|
+
const { signal, ...http } = options;
|
|
301
|
+
return checkWire(theoremRewound, await fetchJson(url, { body, signal }, http), 'the rewound conversation');
|
|
302
|
+
}
|
|
232
303
|
/** Drops trailing '/'s by scanning back, not with a regex (a `/\/+$/` scan is quadratic on long runs of '/'). */
|
|
233
304
|
function withoutTrailingSlashes(url) {
|
|
234
305
|
let end = url.length;
|
|
@@ -246,11 +317,14 @@ export function createHttpTransport(options = {}) {
|
|
|
246
317
|
const response = await request(base, { method: 'GET', signal }, options);
|
|
247
318
|
if (!response.ok)
|
|
248
319
|
throw await failureFromResponse(response);
|
|
249
|
-
//
|
|
320
|
+
// labels-exempt: internal diagnostic; the user reads error.bad_response
|
|
250
321
|
return checkWire(describedSchema, parseWireJson(await response.text()), 'the profile description').interface;
|
|
251
322
|
},
|
|
252
|
-
turn: ({ replay: _replay, ...body }, onEvent, signal) => postNdjson(`${base}/turn`, body,
|
|
253
|
-
invoke: ({ replay: _replay, ...body }, onEvent, signal) => postNdjson(`${base}/invoke`, body,
|
|
323
|
+
turn: ({ replay: _replay, ...body }, onEvent, signal) => postNdjson(`${base}/turn`, body, CHAT_LINES, onEvent, { ...options, signal }),
|
|
324
|
+
invoke: ({ replay: _replay, ...body }, onEvent, signal) => postNdjson(`${base}/invoke`, body, CHAT_LINES, onEvent, { ...options, signal }),
|
|
325
|
+
conversation: (body, signal) => fetchConversation(`${base}/conversation`, body, { ...options, signal }),
|
|
326
|
+
rewind: (body, signal) => fetchRewound(`${base}/rewind`, body, { ...options, signal }),
|
|
327
|
+
pageResult: (body, signal) => postJson(`${base}/page-result`, body, { ...options, signal }),
|
|
254
328
|
steer: (body) => postJson(`${base}/steer`, body, options),
|
|
255
329
|
};
|
|
256
330
|
}
|
package/client/turn-client.d.ts
CHANGED
|
@@ -1,28 +1,37 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type TurnEvent } from '@theoremjs/agents';
|
|
2
2
|
import { type AttachmentValidationIssue, type ComposerProfileInterface, type GatedToolContext, type InterfaceTurnSession, type TranscriptBlock, type UserTurnDraft } from '@theoremjs/agents/interface';
|
|
3
|
-
import type {
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
import type { PagePart } from './tool-resume.ts';
|
|
4
|
+
import type { TheoremInvokeRequest, TheoremReplay, TheoremTurnInput, TheoremTurnRequest } from './transport.ts';
|
|
5
|
+
export declare function issuedOperationId(call: {
|
|
6
|
+
operationId?: string;
|
|
7
|
+
}): string;
|
|
8
|
+
/** A gated call as the client holds it, for a host without a session (the studio). */
|
|
6
9
|
export type HeldCall = {
|
|
7
10
|
name: string;
|
|
8
11
|
/** The model's input to the call. */
|
|
9
12
|
input: unknown;
|
|
13
|
+
gateKind?: TheoremReplay['gateKind'];
|
|
10
14
|
sessionPermissions?: string[];
|
|
11
15
|
};
|
|
12
|
-
/**
|
|
16
|
+
/** The calls a paused reply waits on that a message walks away from. */
|
|
13
17
|
export type WalkAway = {
|
|
14
|
-
paused: InterfaceTurnSession;
|
|
15
18
|
calls: readonly GatedToolContext[];
|
|
16
19
|
};
|
|
17
|
-
|
|
20
|
+
/** Where a request goes on from: the ref of the conversation the host keeps, and the run's id for steers. */
|
|
21
|
+
export type RunScope = {
|
|
22
|
+
conversation?: string;
|
|
18
23
|
turnId?: string;
|
|
24
|
+
};
|
|
25
|
+
export declare function buildTurnRequest(iface: ComposerProfileInterface, session: InterfaceTurnSession, input: TheoremTurnInput, options?: RunScope & {
|
|
19
26
|
walkAway?: WalkAway;
|
|
20
27
|
}): TheoremTurnRequest;
|
|
21
28
|
export declare function buildInvokeRequest(iface: ComposerProfileInterface, session: InterfaceTurnSession, args: HeldCall & {
|
|
22
29
|
gateId: string;
|
|
30
|
+
operationId: string;
|
|
23
31
|
decision: TheoremInvokeRequest['decision'];
|
|
24
32
|
secret?: string;
|
|
25
|
-
|
|
33
|
+
page?: PagePart;
|
|
34
|
+
}, scope?: RunScope): TheoremInvokeRequest;
|
|
26
35
|
export declare function projectUserTurn(iface: ComposerProfileInterface, draft: UserTurnDraft): {
|
|
27
36
|
ok: true;
|
|
28
37
|
blocks: TranscriptBlock[];
|
package/client/turn-client.js
CHANGED
|
@@ -1,13 +1,11 @@
|
|
|
1
|
+
import { labelText, TheoremError } from '@theoremjs/agents';
|
|
1
2
|
import { foldTurnEvents, prepareUserTurn, streamThoughtsEnabled, } from '@theoremjs/agents/interface';
|
|
2
3
|
import { filesToPending } from "./encode-files.js";
|
|
3
4
|
import { defaultModel } from "./generation-selection.js";
|
|
4
|
-
export function
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
...(session.inputTokens !== undefined ? { inputTokens: session.inputTokens } : {}),
|
|
9
|
-
...(session.historyTokens !== undefined ? { historyTokens: session.historyTokens } : {}),
|
|
10
|
-
};
|
|
5
|
+
export function issuedOperationId(call) {
|
|
6
|
+
if (!call.operationId)
|
|
7
|
+
throw new TheoremError('request', labelText('session.gate_expired'));
|
|
8
|
+
return call.operationId;
|
|
11
9
|
}
|
|
12
10
|
function resolveModelId(iface, session) {
|
|
13
11
|
return session.selectedModel ?? defaultModel(iface);
|
|
@@ -31,48 +29,45 @@ function gateReplay(iface, session, call) {
|
|
|
31
29
|
return {
|
|
32
30
|
name: call.name,
|
|
33
31
|
input: call.input,
|
|
32
|
+
...(call.gateKind ? { gateKind: call.gateKind } : {}),
|
|
34
33
|
sessionPermissions: call.sessionPermissions ?? session.sessionPermissions,
|
|
35
|
-
turnInput: turnInputFromSession(session),
|
|
36
34
|
...(session.toolSnapshot ? { snapshot: session.toolSnapshot } : {}),
|
|
37
35
|
...(session.promotedToolIds.length ? { promoted: [...session.promotedToolIds] } : {}),
|
|
38
36
|
...generationFields(iface, session),
|
|
39
37
|
};
|
|
40
38
|
}
|
|
41
|
-
|
|
42
|
-
* The paused calls a message walks away from: their ids, and each call as a
|
|
43
|
-
* host without a session replays it, from the session as it paused.
|
|
44
|
-
*/
|
|
45
|
-
function abandonFields(iface, walkAway) {
|
|
46
|
-
if (!walkAway.calls.length)
|
|
47
|
-
return undefined;
|
|
39
|
+
function scopeFields(scope) {
|
|
48
40
|
return {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
call.callId,
|
|
52
|
-
gateReplay(iface, walkAway.paused, { name: call.name, input: call.arguments }),
|
|
53
|
-
])),
|
|
41
|
+
...(scope.conversation ? { conversation: scope.conversation } : {}),
|
|
42
|
+
...(scope.turnId ? { turnId: scope.turnId } : {}),
|
|
54
43
|
};
|
|
55
44
|
}
|
|
56
45
|
export function buildTurnRequest(iface, session, input, options = {}) {
|
|
57
|
-
const
|
|
46
|
+
const abandon = (options.walkAway?.calls ?? []).map((call) => ({
|
|
47
|
+
callId: call.callId,
|
|
48
|
+
operationId: issuedOperationId(call),
|
|
49
|
+
}));
|
|
58
50
|
return {
|
|
59
|
-
|
|
60
|
-
...(options.turnId ? { turnId: options.turnId } : {}),
|
|
51
|
+
...scopeFields(options),
|
|
61
52
|
...generationFields(iface, session),
|
|
62
53
|
input,
|
|
63
|
-
...(
|
|
64
|
-
replay: {
|
|
65
|
-
sessionPermissions: session.sessionPermissions,
|
|
66
|
-
...(walked ? { abandon: walked.replays } : {}),
|
|
67
|
-
},
|
|
54
|
+
...(abandon.length ? { abandon } : {}),
|
|
55
|
+
replay: { sessionPermissions: session.sessionPermissions },
|
|
68
56
|
};
|
|
69
57
|
}
|
|
70
|
-
export function buildInvokeRequest(iface, session, args) {
|
|
58
|
+
export function buildInvokeRequest(iface, session, args, scope = {}) {
|
|
71
59
|
return {
|
|
60
|
+
...scopeFields(scope),
|
|
72
61
|
gateId: args.gateId,
|
|
62
|
+
operationId: args.operationId,
|
|
73
63
|
decision: args.decision,
|
|
74
64
|
...(args.secret === undefined ? {} : { secret: args.secret }),
|
|
75
|
-
|
|
65
|
+
...(args.page === undefined ? {} : { page: args.page }),
|
|
66
|
+
replay: gateReplay(iface, session, {
|
|
67
|
+
...args,
|
|
68
|
+
gateKind: args.gateKind ??
|
|
69
|
+
(session.gatedTool?.callId === args.gateId ? session.gatedTool.gateKind : undefined),
|
|
70
|
+
}),
|
|
76
71
|
};
|
|
77
72
|
}
|
|
78
73
|
export function projectUserTurn(iface, draft) {
|
|
@@ -86,7 +81,7 @@ export function prepareComposerTurn(iface, text, pendingFiles, pendingVoice = []
|
|
|
86
81
|
});
|
|
87
82
|
}
|
|
88
83
|
export function foldAssistantTurn(iface, events) {
|
|
89
|
-
// Its `turn-done` blocks stay: hidden in the view, they carry the reply's worked time.
|
|
84
|
+
// why: Its `turn-done` blocks stay: hidden in the view, they carry the reply's worked time.
|
|
90
85
|
return foldTurnEvents(events, {
|
|
91
86
|
showThoughts: streamThoughtsEnabled(iface.outputs),
|
|
92
87
|
});
|