@mirasoth/soothe-client 0.1.0 → 0.2.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/dist/chunk-AQZACDIC.js +1399 -0
- package/dist/chunk-AQZACDIC.js.map +1 -0
- package/dist/client-CB6WKQYW.js +7 -0
- package/dist/index.cjs +2383 -419
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1110 -280
- package/dist/index.d.ts +1110 -280
- package/dist/index.js +1265 -91
- package/dist/index.js.map +1 -1
- package/package.json +34 -8
- package/dist/chunk-OMAC7LA7.js +0 -647
- package/dist/chunk-OMAC7LA7.js.map +0 -1
- package/dist/client-QS23U6WX.js +0 -7
- /package/dist/{client-QS23U6WX.js.map → client-CB6WKQYW.js.map} +0 -0
package/dist/index.d.cts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { EventEmitter } from 'node:events';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* Custom error types for the Soothe client.
|
|
4
|
+
* Custom error types for the Soothe client (RFC-450 protocol-1).
|
|
5
5
|
*/
|
|
6
6
|
/** Represents a WebSocket connection failure. */
|
|
7
7
|
declare class ConnectionError extends Error {
|
|
@@ -10,12 +10,20 @@ declare class ConnectionError extends Error {
|
|
|
10
10
|
readonly cause: Error;
|
|
11
11
|
constructor(url: string, attempt: number, cause: Error);
|
|
12
12
|
}
|
|
13
|
-
/**
|
|
13
|
+
/**
|
|
14
|
+
* Represents an error reported by the Soothe daemon (RFC-450 §7).
|
|
15
|
+
*
|
|
16
|
+
* The daemon's structured error object carries a numeric `code` from the
|
|
17
|
+
* reserved ranges, a human-readable `message`, and optional `data`.
|
|
18
|
+
*/
|
|
14
19
|
declare class DaemonError extends Error {
|
|
15
|
-
|
|
20
|
+
/** Numeric error code from the RFC-450 §7.3 registry. */
|
|
21
|
+
readonly code: number;
|
|
16
22
|
/** The daemon's error message text. */
|
|
17
23
|
readonly daemonMessage: string;
|
|
18
|
-
|
|
24
|
+
/** Optional machine-parseable error details. */
|
|
25
|
+
readonly data: unknown;
|
|
26
|
+
constructor(code: number, message: string, data?: unknown);
|
|
19
27
|
}
|
|
20
28
|
/** Represents a timeout waiting for a daemon response. */
|
|
21
29
|
declare class TimeoutError extends Error {
|
|
@@ -23,12 +31,45 @@ declare class TimeoutError extends Error {
|
|
|
23
31
|
readonly duration: string;
|
|
24
32
|
constructor(operation: string, duration: string);
|
|
25
33
|
}
|
|
34
|
+
/**
|
|
35
|
+
* Distinguishes clean vs unclean connection loss (RFC-450 §4, §8.3).
|
|
36
|
+
*
|
|
37
|
+
* A clean drop follows a `disconnect` notification (loops keep running
|
|
38
|
+
* server-side); an unclean drop is a read/write error or a missed pong
|
|
39
|
+
* (in-flight queries are cancelled). Pair with the Client's `'disconnected'`
|
|
40
|
+
* event: the cause is emitted exactly once when the connection drops.
|
|
41
|
+
*/
|
|
42
|
+
declare enum DisconnectCause {
|
|
43
|
+
/** Abrupt loss: read/write error or missed pong (RFC-450 §8.3). */
|
|
44
|
+
Unclean = 0,
|
|
45
|
+
/** Graceful peer-initiated `disconnect` notification (RFC-450 §9.2). */
|
|
46
|
+
Clean = 1
|
|
47
|
+
}
|
|
48
|
+
/** Human-readable cause name for logging. */
|
|
49
|
+
declare function disconnectCauseName(cause: DisconnectCause): string;
|
|
50
|
+
/** Indicates a failed reconnection attempt sequence. */
|
|
51
|
+
declare class ReconnectError extends Error {
|
|
52
|
+
readonly url: string;
|
|
53
|
+
readonly attempts: number;
|
|
54
|
+
readonly cause: Error;
|
|
55
|
+
constructor(url: string, attempts: number, cause: Error);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Returned by `reattachAndProbe` when a loop accepts the reattach handshake
|
|
59
|
+
* but fails the `loop_get` liveness probe. Callers should fall back to a
|
|
60
|
+
* fresh `loop_new` bootstrap.
|
|
61
|
+
*/
|
|
62
|
+
declare class StaleLoopError extends Error {
|
|
63
|
+
readonly loopID: string;
|
|
64
|
+
readonly cause?: Error;
|
|
65
|
+
constructor(loopID: string, cause?: Error);
|
|
66
|
+
}
|
|
26
67
|
|
|
27
68
|
/**
|
|
28
69
|
* Verbosity levels and tiers for event filtering.
|
|
29
70
|
*/
|
|
30
71
|
/** User-configurable verbosity setting. */
|
|
31
|
-
type VerbosityLevel =
|
|
72
|
+
type VerbosityLevel = "quiet" | "normal" | "debug";
|
|
32
73
|
/** Minimum verbosity level at which content is visible. */
|
|
33
74
|
declare enum VerbosityTier {
|
|
34
75
|
/** Always visible (errors, assistant text, final reports) */
|
|
@@ -62,12 +103,20 @@ interface Config {
|
|
|
62
103
|
reconnectDelay: number;
|
|
63
104
|
/** Application-level heartbeat interval in ms */
|
|
64
105
|
heartbeatInterval: number;
|
|
65
|
-
/** Handshake: wait for
|
|
106
|
+
/** Handshake: wait for connection_ack (readiness "ready") in ms */
|
|
66
107
|
daemonReadyTimeout: number;
|
|
67
108
|
/** Bootstrap: wait for status with loop_id in ms */
|
|
68
109
|
loopStatusTimeout: number;
|
|
69
|
-
/** After
|
|
110
|
+
/** After subscribe(method:"loop_events"): wait for confirmation in ms */
|
|
70
111
|
subscriptionTimeout: number;
|
|
112
|
+
/** Max reconnection attempts on a mid-session drop (0 = infinite). */
|
|
113
|
+
reconnectMaxAttempts: number;
|
|
114
|
+
/** Initial backoff delay (ms) between reconnect attempts. */
|
|
115
|
+
reconnectInitialDelay: number;
|
|
116
|
+
/** Cap (ms) on exponential backoff delay between reconnect attempts. */
|
|
117
|
+
reconnectMaxDelay: number;
|
|
118
|
+
/** `loop_get` liveness probe timeout (ms) in reattachAndProbe. */
|
|
119
|
+
reattachProbeTimeout: number;
|
|
71
120
|
}
|
|
72
121
|
/** Returns default configuration. */
|
|
73
122
|
declare function defaultConfig(): Config;
|
|
@@ -75,250 +124,260 @@ declare function defaultConfig(): Config;
|
|
|
75
124
|
declare function loadConfigFromEnv(): Config;
|
|
76
125
|
|
|
77
126
|
/**
|
|
78
|
-
*
|
|
79
|
-
* for the Soothe daemon wire protocol.
|
|
127
|
+
* Daemon ``loop_input`` intent_hint values (direct model turns, no agent graph).
|
|
80
128
|
*/
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
129
|
+
/** Text-only chat completion via the configured ``default`` role. */
|
|
130
|
+
declare const INTENT_HINT_TEXT_COMPLETION: "text_completion";
|
|
131
|
+
/** Vision / image understanding via the configured ``image`` role (attachments required). */
|
|
132
|
+
declare const INTENT_HINT_IMAGE_TO_TEXT: "image_to_text";
|
|
133
|
+
/** OCR via the configured ``ocr`` role (attachments required). */
|
|
134
|
+
declare const INTENT_HINT_OCR: "ocr";
|
|
135
|
+
/** Embedding via the configured ``embedding`` role (text-only; JSON vector response). */
|
|
136
|
+
declare const INTENT_HINT_EMBED: "embed";
|
|
137
|
+
/** Supported daemon direct-model intent hints. */
|
|
138
|
+
type IntentHint = typeof INTENT_HINT_TEXT_COMPLETION | typeof INTENT_HINT_IMAGE_TO_TEXT | typeof INTENT_HINT_OCR | typeof INTENT_HINT_EMBED;
|
|
139
|
+
/** Legacy intent_hint values removed from the daemon wire contract. */
|
|
140
|
+
declare const REMOVED_INTENT_HINTS: readonly ["direct_llm", "quiz"];
|
|
141
|
+
type RemovedIntentHint = (typeof REMOVED_INTENT_HINTS)[number];
|
|
142
|
+
/**
|
|
143
|
+
* Wire ``loop_input.intent_hint``: direct model hints or agent-path pass-through
|
|
144
|
+
* (e.g. ``resume_clarification``, ``skill:foo``). Legacy ``direct_llm`` and
|
|
145
|
+
* ``quiz`` are rejected before send.
|
|
146
|
+
*/
|
|
147
|
+
type LoopInputIntentHint = IntentHint | (string & {});
|
|
148
|
+
/** Returns an error message when ``hint`` is a removed legacy value; otherwise null. */
|
|
149
|
+
declare function validateLoopInputIntentHint(hint: string): string | null;
|
|
150
|
+
/** Phases emitted on ``mode=messages`` for user-visible loop assistant output. */
|
|
151
|
+
declare const LOOP_ASSISTANT_OUTPUT_PHASES: readonly ["goal_completion", "quiz", "autonomous_goal", "direct_model", "text_completion", "image_to_text", "ocr", "embed", "plan_direct"];
|
|
152
|
+
type LoopAssistantOutputPhase = (typeof LOOP_ASSISTANT_OUTPUT_PHASES)[number];
|
|
153
|
+
/** Default deliverable phases for triarch-style apps (direct hints + agent outputs). */
|
|
154
|
+
declare const DEFAULT_DELIVERABLE_PHASES: ReadonlySet<string>;
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Protocol-1 wire envelope: message types, encode/decode, NDJSON splitting,
|
|
158
|
+
* and factory functions for the Soothe daemon (RFC-450).
|
|
159
|
+
*
|
|
160
|
+
* The unified `{proto, type, method, params, id}` envelope combines
|
|
161
|
+
* JSON-RPC 2.0's `method`/`params`/`id` structure with graphql-ws's `type`
|
|
162
|
+
* semantics for message class distinction.
|
|
163
|
+
*/
|
|
164
|
+
|
|
165
|
+
/** Protocol version string (RFC-450 §8.1). */
|
|
166
|
+
declare const PROTO_VERSION = "1";
|
|
167
|
+
/** Default client capabilities declared in the connection_init handshake. */
|
|
168
|
+
declare const DEFAULT_CLIENT_CAPABILITIES: string[];
|
|
169
|
+
/** Client version reported in the connection_init handshake. */
|
|
170
|
+
declare const CLIENT_VERSION = "0.1.0";
|
|
171
|
+
type MessageType = "connection_init" | "connection_ack" | "request" | "response" | "notification" | "subscribe" | "next" | "error" | "complete" | "unsubscribe" | "ping" | "pong" | "receipt_response" | "disconnect" | "status";
|
|
172
|
+
/** Method names carried in the envelope `method` field (RFC-450 §9.2). */
|
|
173
|
+
type MethodName = "loop_list" | "loop_get" | "loop_tree" | "loop_prune" | "loop_delete" | "loop_new" | "loop_reattach" | "loop_detach" | "loop_input" | "loop_messages" | "loop_state_get" | "loop_state_update" | "loop_cards_fetch" | "loop_history_fetch" | "loop_events" | "autopilot_events" | "job_create" | "job_status" | "job_pause" | "job_resume" | "job_cancel" | "job_dag" | "job_guidance" | "daemon_status" | "daemon_shutdown" | "config_get" | "config_reload" | "skills_list" | "invoke_skill" | "models_list" | "mcp_status" | "auth" | "auth_refresh" | "slash_command" | "rpc_command" | "delivery_ack" | "cron_add" | "cron_list" | "cron_show" | "cron_cancel" | "disconnect";
|
|
174
|
+
/** Base fields shared by every protocol-1 message. */
|
|
175
|
+
interface BaseEnvelope {
|
|
176
|
+
proto: string;
|
|
177
|
+
type: MessageType;
|
|
126
178
|
}
|
|
127
|
-
/**
|
|
128
|
-
interface
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
/** @deprecated Use `client_workspace`. */
|
|
134
|
-
workspace?: string;
|
|
179
|
+
/** A client→server RPC request (expects a `response` correlated by `id`). */
|
|
180
|
+
interface RequestEnvelope extends BaseEnvelope {
|
|
181
|
+
type: "request";
|
|
182
|
+
method: MethodName;
|
|
183
|
+
params?: Record<string, unknown>;
|
|
184
|
+
id: string;
|
|
135
185
|
}
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
186
|
+
/** A server→client RPC success response. */
|
|
187
|
+
interface ResponseEnvelope extends BaseEnvelope {
|
|
188
|
+
type: "response";
|
|
189
|
+
result?: Record<string, unknown>;
|
|
190
|
+
id?: string;
|
|
141
191
|
}
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
192
|
+
/** A fire-and-forget client→server notification (no `id`, no response). */
|
|
193
|
+
interface NotificationEnvelope extends BaseEnvelope {
|
|
194
|
+
type: "notification";
|
|
195
|
+
method: MethodName;
|
|
196
|
+
params?: Record<string, unknown>;
|
|
197
|
+
/** Optional receipt id for delivery confirmation (RFC-450 §5.7). */
|
|
198
|
+
receipt?: string;
|
|
145
199
|
}
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
200
|
+
/** Start a subscription stream (events arrive as `next`). */
|
|
201
|
+
interface SubscribeEnvelope extends BaseEnvelope {
|
|
202
|
+
type: "subscribe";
|
|
203
|
+
method: "loop_events" | "autopilot_events";
|
|
204
|
+
params?: {
|
|
205
|
+
loop_id?: string;
|
|
206
|
+
verbosity?: string;
|
|
207
|
+
/** Stream delivery mode: batch (coalesce until turn end), adaptive (small payloads passthrough), streaming (real-time chunks). */
|
|
208
|
+
stream_delivery?: "batch" | "adaptive" | "streaming";
|
|
209
|
+
/** Wire serialization tier: full (all fields), compact (essential fields only). */
|
|
210
|
+
wire_tier?: "full" | "compact";
|
|
211
|
+
} & Record<string, unknown>;
|
|
212
|
+
id: string;
|
|
150
213
|
}
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
214
|
+
/** A stream event for an active subscription. */
|
|
215
|
+
interface NextEnvelope extends BaseEnvelope {
|
|
216
|
+
type: "next";
|
|
217
|
+
payload?: Record<string, unknown>;
|
|
218
|
+
id?: string;
|
|
155
219
|
}
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
220
|
+
/** Structured error response (terminates the operation). */
|
|
221
|
+
interface ErrorEnvelope extends BaseEnvelope {
|
|
222
|
+
type: "error";
|
|
223
|
+
error: {
|
|
224
|
+
code: number;
|
|
225
|
+
message: string;
|
|
226
|
+
data?: unknown;
|
|
227
|
+
};
|
|
228
|
+
id?: string;
|
|
160
229
|
}
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
dry_run?: boolean;
|
|
230
|
+
/** Explicit stream-completion signal. */
|
|
231
|
+
interface CompleteEnvelope extends BaseEnvelope {
|
|
232
|
+
type: "complete";
|
|
233
|
+
id?: string;
|
|
166
234
|
}
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
235
|
+
/** Cancel a subscription by `id`. */
|
|
236
|
+
interface UnsubscribeEnvelope extends BaseEnvelope {
|
|
237
|
+
type: "unsubscribe";
|
|
238
|
+
id: string;
|
|
170
239
|
}
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
240
|
+
/** Connection handshake (client→server, first message). */
|
|
241
|
+
interface ConnectionInitEnvelope extends BaseEnvelope {
|
|
242
|
+
type: "connection_init";
|
|
243
|
+
params?: {
|
|
244
|
+
client_version: string;
|
|
245
|
+
client_name?: string;
|
|
246
|
+
accept_proto?: string[];
|
|
247
|
+
capabilities?: string[];
|
|
248
|
+
};
|
|
174
249
|
}
|
|
175
|
-
|
|
176
|
-
|
|
250
|
+
/** Connection handshake response (server→client). */
|
|
251
|
+
interface ConnectionAckEnvelope extends BaseEnvelope {
|
|
252
|
+
type: "connection_ack";
|
|
253
|
+
result?: {
|
|
254
|
+
server_version?: string;
|
|
255
|
+
protocol_version?: string;
|
|
256
|
+
capabilities?: string[];
|
|
257
|
+
readiness_state?: string;
|
|
258
|
+
heartbeat_interval_ms?: number;
|
|
259
|
+
};
|
|
177
260
|
}
|
|
178
|
-
|
|
179
|
-
|
|
261
|
+
/** Heartbeat ping (either direction). */
|
|
262
|
+
interface PingEnvelope extends BaseEnvelope {
|
|
263
|
+
type: "ping";
|
|
180
264
|
}
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
args?: string;
|
|
265
|
+
/** Heartbeat pong response. */
|
|
266
|
+
interface PongEnvelope extends BaseEnvelope {
|
|
267
|
+
type: "pong";
|
|
185
268
|
}
|
|
186
|
-
|
|
187
|
-
|
|
269
|
+
/** Delivery confirmation for a notification that carried a `receipt`. */
|
|
270
|
+
interface ReceiptResponseEnvelope extends BaseEnvelope {
|
|
271
|
+
type: "receipt_response";
|
|
272
|
+
receipt: string;
|
|
188
273
|
}
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
namespace: string;
|
|
193
|
-
data: Record<string, unknown>;
|
|
194
|
-
timestamp?: string;
|
|
274
|
+
/** Clean connection close (daemon keeps loops running). */
|
|
275
|
+
interface DisconnectEnvelope extends BaseEnvelope {
|
|
276
|
+
type: "disconnect";
|
|
195
277
|
}
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
278
|
+
/**
|
|
279
|
+
* A daemon status frame. `status` is a defined protocol-1 top-level type
|
|
280
|
+
* (RFC-450 §9.1): it passes through the daemon's legacy→`next` translator
|
|
281
|
+
* unchanged, so it is NOT wrapped in a `next` envelope.
|
|
282
|
+
*/
|
|
283
|
+
interface StatusFrame extends BaseEnvelope {
|
|
284
|
+
type: "status";
|
|
285
|
+
state?: string;
|
|
199
286
|
loop_id?: string;
|
|
200
|
-
workspace
|
|
287
|
+
workspace?: string;
|
|
201
288
|
input_history?: string[];
|
|
202
289
|
conversation_history?: unknown[];
|
|
290
|
+
[key: string]: unknown;
|
|
203
291
|
}
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
client_id: string;
|
|
208
|
-
verbosity: string;
|
|
209
|
-
}
|
|
210
|
-
interface ErrorResponse extends BaseMessage {
|
|
211
|
-
type: 'error';
|
|
212
|
-
code: string;
|
|
213
|
-
message: string;
|
|
214
|
-
}
|
|
215
|
-
interface DaemonReadyResponse extends BaseMessage {
|
|
216
|
-
type: 'daemon_ready';
|
|
217
|
-
state: string;
|
|
218
|
-
message?: string;
|
|
219
|
-
}
|
|
220
|
-
interface DaemonStatusResponse extends BaseMessage {
|
|
221
|
-
type: 'daemon_status_response';
|
|
222
|
-
running: boolean;
|
|
223
|
-
port_live: boolean;
|
|
224
|
-
active_loops: number;
|
|
225
|
-
}
|
|
226
|
-
interface ShutdownAckResponse extends BaseMessage {
|
|
227
|
-
type: 'shutdown_ack';
|
|
228
|
-
status: string;
|
|
229
|
-
}
|
|
230
|
-
interface LoopNewResponse extends BaseMessage {
|
|
231
|
-
type: 'loop_new_response';
|
|
292
|
+
/** Discriminated union of all decoded protocol-1 messages. */
|
|
293
|
+
type DecodedMessage = RequestEnvelope | ResponseEnvelope | NotificationEnvelope | SubscribeEnvelope | NextEnvelope | ErrorEnvelope | CompleteEnvelope | UnsubscribeEnvelope | ConnectionInitEnvelope | ConnectionAckEnvelope | PingEnvelope | PongEnvelope | ReceiptResponseEnvelope | DisconnectEnvelope | StatusFrame | Record<string, unknown>;
|
|
294
|
+
interface LoopInputParams {
|
|
232
295
|
loop_id: string;
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
loops?: Record<string, unknown>[];
|
|
250
|
-
total?: number;
|
|
251
|
-
}
|
|
252
|
-
interface LoopGetResponse extends BaseMessage {
|
|
253
|
-
type: 'loop_get_response';
|
|
254
|
-
loop?: Record<string, unknown>;
|
|
255
|
-
}
|
|
256
|
-
interface LoopTreeResponse extends BaseMessage {
|
|
257
|
-
type: 'loop_tree_response';
|
|
258
|
-
tree?: Record<string, unknown>;
|
|
259
|
-
}
|
|
260
|
-
interface LoopPruneResponse extends BaseMessage {
|
|
261
|
-
type: 'loop_prune_response';
|
|
262
|
-
result?: Record<string, unknown>;
|
|
263
|
-
}
|
|
264
|
-
interface LoopDeleteResponse extends BaseMessage {
|
|
265
|
-
type: 'loop_delete_response';
|
|
266
|
-
success: boolean;
|
|
267
|
-
message?: string;
|
|
268
|
-
}
|
|
269
|
-
interface LoopReattachResponse extends BaseMessage {
|
|
270
|
-
type: 'loop_reattach_response';
|
|
271
|
-
loop_id?: string;
|
|
272
|
-
success?: boolean;
|
|
273
|
-
}
|
|
274
|
-
interface HistoryReplayMessage extends BaseMessage {
|
|
275
|
-
type: 'history_replay';
|
|
276
|
-
loop_id?: string;
|
|
277
|
-
events?: Record<string, unknown>[];
|
|
278
|
-
total_events?: number;
|
|
279
|
-
}
|
|
280
|
-
interface HistoryReplayCompleteMessage extends BaseMessage {
|
|
281
|
-
type: 'history_replay_complete';
|
|
282
|
-
loop_id?: string;
|
|
283
|
-
}
|
|
284
|
-
interface ReplayCompleteMessage extends BaseMessage {
|
|
285
|
-
type: 'replay_complete';
|
|
286
|
-
loop_id?: string;
|
|
287
|
-
event_count?: number;
|
|
288
|
-
}
|
|
289
|
-
interface LoopReattachedWireMessage extends BaseMessage {
|
|
290
|
-
type: 'loop_reattached';
|
|
291
|
-
loop_id?: string;
|
|
292
|
-
timestamp?: string;
|
|
296
|
+
content: string;
|
|
297
|
+
autonomous?: boolean;
|
|
298
|
+
max_iterations?: number;
|
|
299
|
+
preferred_subagent?: string;
|
|
300
|
+
/** @deprecated Ignored by daemon; loop_input always uses non-interactive autonomous mode. */
|
|
301
|
+
interactive?: boolean;
|
|
302
|
+
model?: string;
|
|
303
|
+
model_params?: Record<string, unknown>;
|
|
304
|
+
attachments?: Record<string, unknown>[];
|
|
305
|
+
intent_hint?: LoopInputIntentHint;
|
|
306
|
+
response_schema?: Record<string, unknown>;
|
|
307
|
+
response_schema_name?: string;
|
|
308
|
+
response_schema_strict?: boolean;
|
|
309
|
+
clarification_mode?: string;
|
|
310
|
+
clarification_answer?: boolean;
|
|
311
|
+
clarification_answers?: string[];
|
|
293
312
|
}
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
313
|
+
/** Options for `loop_new` workspace fields. */
|
|
314
|
+
interface LoopNewOptions {
|
|
315
|
+
client_workspace?: string;
|
|
316
|
+
client_workspace_id?: string;
|
|
317
|
+
user_id?: string;
|
|
318
|
+
is_ephemeral?: boolean;
|
|
319
|
+
/** @deprecated Use `client_workspace`. */
|
|
320
|
+
workspace?: string;
|
|
297
321
|
}
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
322
|
+
/**
|
|
323
|
+
* Shape of a `next` payload when the daemon wraps a legacy free-form frame.
|
|
324
|
+
* The original frame type becomes `mode`; `data` carries the frame body with
|
|
325
|
+
* `loop_id` preserved.
|
|
326
|
+
*/
|
|
327
|
+
interface StreamEventPayload {
|
|
328
|
+
namespace?: unknown;
|
|
329
|
+
mode?: string;
|
|
330
|
+
data?: Record<string, unknown>;
|
|
301
331
|
}
|
|
302
|
-
|
|
303
|
-
/** Encodes a message as JSON with newline delimiter. */
|
|
332
|
+
/** Encodes a message as JSON with a newline delimiter (NDJSON frame). */
|
|
304
333
|
declare function encodeMessage(msg: unknown): string;
|
|
305
|
-
/**
|
|
334
|
+
/**
|
|
335
|
+
* Decodes a JSON message and returns a typed object. Unknown types return a
|
|
336
|
+
* raw map. The decoder is permissive: it accepts protocol-1 envelopes and
|
|
337
|
+
* surfaces `response.result` / `next.payload` for consumers that read them,
|
|
338
|
+
* but always returns the full envelope so callers can inspect `type`/`id`.
|
|
339
|
+
*/
|
|
306
340
|
declare function decodeMessage(data: string): DecodedMessage | null;
|
|
341
|
+
/** Builds a `request` envelope. */
|
|
342
|
+
declare function requestEnvelope(method: MethodName, params?: Record<string, unknown>, id?: string): RequestEnvelope;
|
|
343
|
+
/** Builds a `notification` envelope (no `id`). */
|
|
344
|
+
declare function notificationEnvelope(method: MethodName, params?: Record<string, unknown>): NotificationEnvelope;
|
|
345
|
+
/** Builds a `subscribe` envelope. */
|
|
346
|
+
declare function subscribeEnvelope(method: "loop_events" | "autopilot_events", params?: Record<string, unknown>, id?: string): SubscribeEnvelope;
|
|
347
|
+
/** Builds an `unsubscribe` envelope. */
|
|
348
|
+
declare function unsubscribeEnvelope(id: string): UnsubscribeEnvelope;
|
|
349
|
+
/** Builds a `connection_init` handshake envelope. */
|
|
350
|
+
declare function connectionInitEnvelope(opts?: {
|
|
351
|
+
client_version?: string;
|
|
352
|
+
client_name?: string;
|
|
353
|
+
accept_proto?: string[];
|
|
354
|
+
capabilities?: string[];
|
|
355
|
+
}): ConnectionInitEnvelope;
|
|
356
|
+
/** Builds a `ping` heartbeat envelope. */
|
|
357
|
+
declare function pingEnvelope(): PingEnvelope;
|
|
358
|
+
/** Builds a `pong` heartbeat envelope. */
|
|
359
|
+
declare function pongEnvelope(): PongEnvelope;
|
|
360
|
+
/** Builds a `disconnect` notification envelope. */
|
|
361
|
+
declare function disconnectEnvelope(): DisconnectEnvelope;
|
|
307
362
|
/** Splits a single WebSocket text payload into individual JSON lines. */
|
|
308
363
|
declare function splitWirePayload(data: string): string[];
|
|
309
364
|
/**
|
|
310
|
-
* Returns the
|
|
311
|
-
*
|
|
365
|
+
* Returns the StrangeLoop id when present in a message.
|
|
366
|
+
*
|
|
367
|
+
* Under protocol-1, loop-scoped stream events arrive as `next` envelopes
|
|
368
|
+
* whose `payload.data` carries the original frame (with `loop_id`). Raw
|
|
369
|
+
* `status` frames carry `loop_id` at the top level. This helper inspects
|
|
370
|
+
* both shapes.
|
|
312
371
|
*/
|
|
313
372
|
declare function extractSootheLoopID(msg: unknown): [string, boolean];
|
|
314
|
-
/** Generates a new UUID
|
|
373
|
+
/** Generates a new UUID correlation ID (RFC-450 §5.2 `id`). */
|
|
315
374
|
declare function newRequestID(): string;
|
|
316
|
-
/** Creates a loop_input
|
|
317
|
-
declare function newLoopInputMessage(loopID: string, content: string):
|
|
318
|
-
/** Creates a loop_new
|
|
319
|
-
declare function newLoopNewMessage(opts?: LoopNewOptions | string):
|
|
320
|
-
/** Creates a
|
|
321
|
-
declare function newLoopSubscribeMessage(loopID: string, verbosity: string, streamDelivery?:
|
|
375
|
+
/** Creates a `loop_input` notification envelope. */
|
|
376
|
+
declare function newLoopInputMessage(loopID: string, content: string): NotificationEnvelope;
|
|
377
|
+
/** Creates a `loop_new` request envelope. */
|
|
378
|
+
declare function newLoopNewMessage(opts?: LoopNewOptions | string): RequestEnvelope;
|
|
379
|
+
/** Creates a `loop_events` subscribe envelope. */
|
|
380
|
+
declare function newLoopSubscribeMessage(loopID: string, verbosity: string, streamDelivery?: "batch" | "adaptive" | "streaming"): SubscribeEnvelope;
|
|
322
381
|
|
|
323
382
|
/**
|
|
324
383
|
* Client-facing event namespace constants for the Soothe daemon wire protocol.
|
|
@@ -339,18 +398,31 @@ declare const EventTacitusGatherSummary = "soothe.subagent.tacitus.gather.summar
|
|
|
339
398
|
declare const EventTacitusCompleted = "soothe.subagent.tacitus.completed";
|
|
340
399
|
declare const EventReplayComplete = "replay_complete";
|
|
341
400
|
declare const EventLoopReattachedWire = "loop_reattached";
|
|
401
|
+
declare const EventCardReplayBegin = "card.replay_begin";
|
|
402
|
+
declare const EventCardCreated = "card.created";
|
|
403
|
+
declare const EventCardReplayEnd = "card.replay_end";
|
|
342
404
|
declare const EventToolStarted = "soothe.tool.execution.started";
|
|
343
405
|
declare const EventToolCompleted = "soothe.tool.execution.completed";
|
|
344
406
|
declare const EventToolError = "soothe.tool.execution.error";
|
|
345
407
|
declare const EventStreamToolCallUpdate = "soothe.stream.tool_call.update";
|
|
346
408
|
declare const EventToolCallUpdatesBatch = "tool_call_updates_batch";
|
|
347
|
-
declare const
|
|
348
|
-
declare const
|
|
349
|
-
declare const
|
|
350
|
-
declare const
|
|
409
|
+
declare const EventStrangeLoopStarted = "soothe.cognition.strange_loop.started";
|
|
410
|
+
declare const EventStrangeLoopCompleted = "soothe.cognition.strange_loop.completed";
|
|
411
|
+
declare const EventStrangeLoopPlanDecision = "soothe.cognition.strange_loop.plan.decision";
|
|
412
|
+
declare const EventStrangeLoopReasoned = "soothe.cognition.strange_loop.reasoned";
|
|
413
|
+
declare const EventStrangeLoopStepStarted = "soothe.cognition.strange_loop.step.started";
|
|
414
|
+
declare const EventStrangeLoopStepQueued = "soothe.cognition.strange_loop.step.queued";
|
|
415
|
+
declare const EventStrangeLoopStepCompleted = "soothe.cognition.strange_loop.step.completed";
|
|
416
|
+
declare const EventStrangeLoopContextCompacted = "soothe.cognition.strange_loop.context.compacted";
|
|
351
417
|
declare const EventMessageReceived = "soothe.protocol.message.received";
|
|
352
418
|
declare const EventMessageSent = "soothe.protocol.message.sent";
|
|
353
419
|
declare const EventFinalReport = "soothe.output.autonomous.final_report.reported";
|
|
420
|
+
declare const EventAutopilotGoalStatus = "soothe.autopilot.goal.status";
|
|
421
|
+
declare const EventAutopilotGoalProgress = "soothe.autopilot.goal.progress";
|
|
422
|
+
declare const EventAutopilotGoalCreated = "soothe.autopilot.goal.created";
|
|
423
|
+
declare const EventAutopilotGoalCompleted = "soothe.autopilot.goal.completed";
|
|
424
|
+
declare const EventAutopilotWorkerAssigned = "soothe.autopilot.worker.assigned";
|
|
425
|
+
declare const EventAutopilotWorkerUnassigned = "soothe.autopilot.worker.unassigned";
|
|
354
426
|
declare const EventGeneralFailed = "soothe.error.general.failed";
|
|
355
427
|
/** Splits a 4-segment event namespace into domain, component, and action. */
|
|
356
428
|
declare function parseNamespace(ns: string): {
|
|
@@ -364,113 +436,365 @@ declare function classifyEventVerbosity(eventTypeOrNamespace: string): Verbosity
|
|
|
364
436
|
declare function isCompletionEvent(eventType: string): boolean;
|
|
365
437
|
/** Lifecycle subagent events (started/completed) for progress UI. */
|
|
366
438
|
declare function isSubagentProgressEvent(eventType: string): boolean;
|
|
367
|
-
/** Essential progress event types for minimal UI surfaces. */
|
|
368
|
-
declare const ESSENTIAL_EVENT_TYPES: ReadonlySet<string>;
|
|
369
439
|
|
|
370
440
|
/**
|
|
371
|
-
* Client manages a WebSocket session with the Soothe daemon.
|
|
372
|
-
*
|
|
441
|
+
* Client manages a WebSocket session with the Soothe daemon (RFC-450 protocol-1).
|
|
442
|
+
*
|
|
443
|
+
* After close(), a new Client must be created to reconnect. The connection
|
|
444
|
+
* begins with a bidirectional connection_init/connection_ack handshake; no
|
|
445
|
+
* requests are accepted until the daemon reports readiness_state "ready".
|
|
373
446
|
*/
|
|
374
447
|
|
|
448
|
+
/** Input options for `sendInput` (loop_input). */
|
|
375
449
|
interface InputOptions {
|
|
376
|
-
/** Subscribed
|
|
450
|
+
/** Subscribed StrangeLoop id (required for loop_input). */
|
|
377
451
|
loopID?: string;
|
|
378
452
|
autonomous?: boolean;
|
|
379
453
|
maxIterations?: number;
|
|
380
454
|
subagent?: string;
|
|
455
|
+
/** @deprecated Ignored by daemon; loop_input always uses non-interactive autonomous mode. */
|
|
381
456
|
interactive?: boolean;
|
|
382
457
|
model?: string;
|
|
383
458
|
modelParams?: Record<string, unknown>;
|
|
384
459
|
attachments?: Record<string, unknown>[];
|
|
460
|
+
/** Daemon direct-model hint or agent-path pass-through (resume_clarification, skill:foo). */
|
|
461
|
+
intentHint?: LoopInputIntentHint;
|
|
462
|
+
/** JSON Schema for structured output (text_completion or image_to_text). */
|
|
463
|
+
responseSchema?: Record<string, unknown>;
|
|
464
|
+
/** Provider schema name for structured output. */
|
|
465
|
+
responseSchemaName?: string;
|
|
466
|
+
/** Strict mode for JSON schema (default true). */
|
|
467
|
+
responseSchemaStrict?: boolean;
|
|
468
|
+
/** Clarification relay mode ("auto" / "manual"). */
|
|
469
|
+
clarificationMode?: string;
|
|
470
|
+
/** Treat this input as answer to pending clarification interrupt. */
|
|
471
|
+
clarificationAnswer?: boolean;
|
|
472
|
+
/** Per-question answers for multi-question clarifications. */
|
|
473
|
+
clarificationAnswers?: string[];
|
|
385
474
|
}
|
|
475
|
+
/** Capability set negotiated with the daemon. */
|
|
476
|
+
type NegotiatedCapabilities = ReadonlySet<string>;
|
|
386
477
|
declare class Client extends EventEmitter {
|
|
387
478
|
private url;
|
|
388
479
|
private config;
|
|
389
480
|
private ws;
|
|
390
481
|
private messageBuffer;
|
|
391
482
|
private resolvers;
|
|
483
|
+
private handshakeComplete;
|
|
484
|
+
private negotiatedCapabilities;
|
|
485
|
+
private protocolVersion;
|
|
486
|
+
private readinessState;
|
|
487
|
+
private heartbeatIntervalMs;
|
|
488
|
+
private heartbeatTimer;
|
|
489
|
+
private lastPongMonotonic;
|
|
490
|
+
private disconnFired;
|
|
491
|
+
private mux;
|
|
392
492
|
constructor(url: string, config?: Config);
|
|
393
|
-
/**
|
|
493
|
+
/**
|
|
494
|
+
* Dials the Soothe daemon WebSocket and completes the protocol-1 handshake
|
|
495
|
+
* (connection_init → connection_ack with readiness_state "ready").
|
|
496
|
+
*/
|
|
394
497
|
connect(): Promise<void>;
|
|
395
|
-
/**
|
|
498
|
+
/** Sends a `disconnect` notification and closes the WebSocket. */
|
|
396
499
|
close(): void;
|
|
397
|
-
/** Returns whether the client has an active WebSocket connection. */
|
|
500
|
+
/** Returns whether the client has an active, handshaked WebSocket connection. */
|
|
398
501
|
isConnected(): boolean;
|
|
502
|
+
/**
|
|
503
|
+
* Returns whether the connection has dropped (the `'disconnected'` event has
|
|
504
|
+
* fired). Pair with the `'disconnected'` event for the signal. Use
|
|
505
|
+
* `disconnectCause()` to read the cause.
|
|
506
|
+
*/
|
|
507
|
+
isDisconnected(): boolean;
|
|
508
|
+
/**
|
|
509
|
+
* Returns the cause of the most recent drop, or `null` if the connection has
|
|
510
|
+
* not dropped. Clean follows a `disconnect` notification (loops keep running
|
|
511
|
+
* server-side); unclean is a read/write error or missed pong.
|
|
512
|
+
*/
|
|
513
|
+
disconnectCause(): DisconnectCause | null;
|
|
514
|
+
private _lastCause;
|
|
515
|
+
/**
|
|
516
|
+
* Delivers the disconnect cause exactly once via the `'disconnected'` event.
|
|
517
|
+
* Safe to call from any path; subsequent calls are no-ops. Listeners receive
|
|
518
|
+
* the cause as the event argument.
|
|
519
|
+
*/
|
|
520
|
+
private _signalDisconnect;
|
|
521
|
+
/**
|
|
522
|
+
* Re-dials the daemon and re-handshakes after a connection drop (RFC-450
|
|
523
|
+
* §8.3). Does not re-establish loop subscriptions; follow with
|
|
524
|
+
* `reattachAndProbe()` to resume a loop session. The caller should invoke
|
|
525
|
+
* this after the `'disconnected'` event fires. Reuses the same Client,
|
|
526
|
+
* resetting the drop signal and multiplexer.
|
|
527
|
+
*
|
|
528
|
+
* Performs bounded-retry backoff using the configured reconnect knobs.
|
|
529
|
+
*/
|
|
530
|
+
reconnect(): Promise<void>;
|
|
531
|
+
/**
|
|
532
|
+
* Resumes an existing loop after a reconnect: issues `loop_reattach`,
|
|
533
|
+
* re-subscribes to `loop_events`, then runs a `loop_get` liveness probe to
|
|
534
|
+
* detect stale loops that accept the handshake but silently drop input.
|
|
535
|
+
* Returns a `StaleLoopError` when the probe fails; callers should fall back
|
|
536
|
+
* to a fresh `loop_new` bootstrap.
|
|
537
|
+
*
|
|
538
|
+
* Per RFC-629: connection-level readiness is the handshake's readiness_state
|
|
539
|
+
* (+ daemon_status); loop_get is a loop-scoped probe only, not a readiness
|
|
540
|
+
* probe.
|
|
541
|
+
*/
|
|
542
|
+
reattachAndProbe(loopID: string): Promise<void>;
|
|
543
|
+
/** Send connection_init and wait for connection_ack with readiness "ready". */
|
|
544
|
+
private _performHandshake;
|
|
545
|
+
private _startHeartbeat;
|
|
546
|
+
private _stopHeartbeat;
|
|
547
|
+
private _heartbeatTick;
|
|
548
|
+
private _sleep;
|
|
399
549
|
/** Serializes msg as JSON and sends it as a WebSocket text frame. */
|
|
400
550
|
sendMessage(msg: unknown): Promise<void>;
|
|
551
|
+
/** Low-level send that does not reject on a missing connection (best-effort). */
|
|
552
|
+
private _sendRaw;
|
|
401
553
|
/** Returns an async iterable of decoded messages. Ends when connection closes. */
|
|
402
554
|
receiveMessages(signal?: AbortSignal): AsyncGenerator<DecodedMessage>;
|
|
403
555
|
/** Reads a single event from the daemon. Returns null on connection close. */
|
|
404
556
|
readEvent(): Promise<Record<string, unknown> | null>;
|
|
405
|
-
/** Reads a single event with a timeout. Returns null on timeout or
|
|
557
|
+
/** Reads a single event with a timeout. Returns null on timeout or close. */
|
|
406
558
|
readEventWithTimeout(timeout: number): Promise<Record<string, unknown> | null>;
|
|
407
|
-
/**
|
|
559
|
+
/**
|
|
560
|
+
* Reads the next frame directly from the live socket (via a resolver),
|
|
561
|
+
* bypassing `messageBuffer`. Used by RPC waits so that stream events
|
|
562
|
+
* previously buffered for `readEvent()`/`receiveMessages()` consumers are
|
|
563
|
+
* not re-cycled through the RPC wait loop (which would stall behind a
|
|
564
|
+
* continuous subscription stream). Non-RPC frames read here are pushed to
|
|
565
|
+
* `messageBuffer` for the stream readers.
|
|
566
|
+
*/
|
|
567
|
+
private readLiveEventWithTimeout;
|
|
568
|
+
/**
|
|
569
|
+
* Sends a `request` envelope and waits for the matching `response` (or
|
|
570
|
+
* `error`) correlated by `id` (RFC-450 §5/§9). Returns the `result` object.
|
|
571
|
+
*
|
|
572
|
+
* Multiplexer-aware (RFC-629 constraint #1): registers a pending RPC wait
|
|
573
|
+
* keyed by the request id so that, even when a `receiveMessages()` reader
|
|
574
|
+
* is concurrently active, the matching `response`/`error` is routed to
|
|
575
|
+
* this caller instead of being discarded or buffered behind a stream.
|
|
576
|
+
* Non-matching frames are routed to their own waiters by the multiplexer
|
|
577
|
+
* or flow on to the resolver queue for stream readers.
|
|
578
|
+
*/
|
|
579
|
+
requestResponse(method: MethodName, params: Record<string, unknown>, responseType?: string, timeout?: number): Promise<Record<string, unknown>>;
|
|
580
|
+
/**
|
|
581
|
+
* Races the multiplexer's RPC promise against a timeout and the connection
|
|
582
|
+
* drop signal. Resolves with the `result` on `response`; rejects with a
|
|
583
|
+
* `DaemonError` on `error`; rejects with a timeout/close error otherwise.
|
|
584
|
+
* The disconnect listener is always removed to avoid accumulating handlers.
|
|
585
|
+
*/
|
|
586
|
+
private _raceRPC;
|
|
587
|
+
/**
|
|
588
|
+
* Sends a pre-built envelope (e.g. `unsubscribe`) that carries an `id` and
|
|
589
|
+
* waits for the matching `response`/`error`. Used for envelope types that
|
|
590
|
+
* are not `request` (e.g. `unsubscribe` → `autopilot_unsubscribe`) but still
|
|
591
|
+
* expect a correlated response from the daemon.
|
|
592
|
+
*/
|
|
593
|
+
private _requestResponseForEnvelope;
|
|
594
|
+
/** Sends a fire-and-forget `notification` envelope (no response expected). */
|
|
595
|
+
notify(method: MethodName, params: Record<string, unknown>): Promise<void>;
|
|
596
|
+
/**
|
|
597
|
+
* Starts a subscription stream. Returns the subscription `id` for later
|
|
598
|
+
* correlation and `unsubscribe()`. Stream events arrive as `next` frames
|
|
599
|
+
* carrying the same `id`.
|
|
600
|
+
*/
|
|
601
|
+
subscribe(method: "loop_events" | "autopilot_events", params: Record<string, unknown>, timeout?: number): Promise<string>;
|
|
602
|
+
/** Cancels an active subscription by id. */
|
|
603
|
+
unsubscribe(subscriptionId: string): Promise<void>;
|
|
604
|
+
/**
|
|
605
|
+
* Reads the next stream event from a subscription. For `next` frames the
|
|
606
|
+
* `payload` is returned; for `complete`/`error` the full envelope is
|
|
607
|
+
* returned so the caller can inspect termination.
|
|
608
|
+
*/
|
|
609
|
+
next(): Promise<Record<string, unknown> | null>;
|
|
610
|
+
/** Sends user input to the daemon (loop_input notification; requires loopID). */
|
|
408
611
|
sendInput(text: string, options?: InputOptions): Promise<void>;
|
|
409
|
-
/** Sends a slash command to the daemon. */
|
|
612
|
+
/** Sends a slash command to the daemon (slash_command notification). */
|
|
410
613
|
sendCommand(cmd: string): Promise<void>;
|
|
411
|
-
/** Requests the daemon to create a new
|
|
614
|
+
/** Requests the daemon to create a new StrangeLoop and waits for the response. */
|
|
412
615
|
sendLoopNew(opts?: LoopNewOptions | string): Promise<void>;
|
|
413
|
-
/** Subscribes to events for a loop. */
|
|
414
|
-
sendLoopSubscribe(loopID: string, verbosity: string, streamDelivery?:
|
|
415
|
-
/** Detaches from a loop (
|
|
416
|
-
sendLoopDetach(loopID: string
|
|
417
|
-
/** Notifies the daemon that this client is
|
|
616
|
+
/** Subscribes to events for a loop (subscribe → loop_events). */
|
|
617
|
+
sendLoopSubscribe(loopID: string, verbosity: string, streamDelivery?: "batch" | "adaptive" | "streaming"): Promise<void>;
|
|
618
|
+
/** Detaches from a loop (unsubscribe by subscription id). */
|
|
619
|
+
sendLoopDetach(loopID: string): Promise<void>;
|
|
620
|
+
/** Notifies the daemon that this client is leaving (disconnect notification). */
|
|
418
621
|
sendDetach(): Promise<void>;
|
|
419
|
-
/** Sends the daemon_ready handshake message. */
|
|
420
|
-
sendDaemonReady(): Promise<void>;
|
|
421
622
|
/** Requests daemon status check. */
|
|
422
|
-
sendDaemonStatus(
|
|
623
|
+
sendDaemonStatus(): Promise<void>;
|
|
423
624
|
/** Requests daemon shutdown. */
|
|
424
|
-
sendDaemonShutdown(
|
|
625
|
+
sendDaemonShutdown(): Promise<void>;
|
|
425
626
|
/** Requests a config section from the daemon. */
|
|
426
|
-
sendConfigGet(section: string
|
|
427
|
-
/** Requests the persisted loop list. */
|
|
428
|
-
sendLoopList(filter?: Record<string, unknown>, limit?: number, requestID?: string): Promise<void>;
|
|
429
|
-
/** Requests detailed loop metadata. */
|
|
430
|
-
sendLoopGet(loopID: string, verbose?: boolean, requestID?: string): Promise<void>;
|
|
431
|
-
/** Requests loop tree visualization. */
|
|
432
|
-
sendLoopTree(loopID: string, format?: string, requestID?: string): Promise<void>;
|
|
433
|
-
/** Requests pruning of old failed branches. */
|
|
434
|
-
sendLoopPrune(loopID: string, retentionDays?: number, dryRun?: boolean, requestID?: string): Promise<void>;
|
|
435
|
-
/** Requests loop deletion. */
|
|
436
|
-
sendLoopDelete(loopID: string, requestID?: string): Promise<void>;
|
|
437
|
-
/** Requests reattachment to a loop with history replay. */
|
|
438
|
-
sendLoopReattach(loopID: string, requestID?: string): Promise<void>;
|
|
439
|
-
/** Requests the skills catalog (RFC-400). */
|
|
440
|
-
sendSkillsList(requestID?: string): Promise<void>;
|
|
441
|
-
/** Requests the models catalog (RFC-400). */
|
|
442
|
-
sendModelsList(requestID?: string): Promise<void>;
|
|
443
|
-
/** Invokes a skill on the daemon (RFC-400). */
|
|
444
|
-
sendInvokeSkill(skill: string, args?: string, requestID?: string): Promise<void>;
|
|
445
|
-
/** Sends a request with a unique request_id and waits for a matching response. */
|
|
446
|
-
requestResponse(payload: Record<string, unknown>, responseType: string, timeout: number): Promise<Record<string, unknown>>;
|
|
627
|
+
sendConfigGet(section: string): Promise<void>;
|
|
447
628
|
/** Requests the skills catalog and waits for the response. */
|
|
448
629
|
listSkills(timeout?: number): Promise<Record<string, unknown>>;
|
|
449
630
|
/** Requests the models catalog and waits for the response. */
|
|
450
631
|
listModels(timeout?: number): Promise<Record<string, unknown>>;
|
|
451
|
-
/** Invokes a skill on the daemon host and receives echo
|
|
632
|
+
/** Invokes a skill on the daemon host and receives echo. */
|
|
452
633
|
invokeSkill(skill: string, args?: string, timeout?: number): Promise<Record<string, unknown>>;
|
|
453
634
|
/** Requests loop list and waits for response. */
|
|
454
|
-
listLoops(timeout?: number): Promise<Record<string, unknown>>;
|
|
635
|
+
listLoops(timeout?: number, workspace?: string): Promise<Record<string, unknown>>;
|
|
455
636
|
/** Requests loop details and waits for response. */
|
|
456
637
|
getLoop(loopID: string, timeout?: number): Promise<Record<string, unknown>>;
|
|
457
638
|
/** Requests loop tree and waits for response. */
|
|
458
639
|
getLoopTree(loopID: string, timeout?: number): Promise<Record<string, unknown>>;
|
|
459
640
|
/** Requests loop deletion and waits for response. */
|
|
460
641
|
deleteLoop(loopID: string, timeout?: number): Promise<Record<string, unknown>>;
|
|
461
|
-
/**
|
|
642
|
+
/** Requests persisted conversation/activity rows. */
|
|
643
|
+
sendLoopMessages(loopID: string, limit?: number, offset?: number, includeEvents?: boolean): Promise<void>;
|
|
644
|
+
/** Requests LangGraph checkpoint channel values. */
|
|
645
|
+
sendLoopStateGet(loopID: string): Promise<void>;
|
|
646
|
+
/** Applies partial checkpoint values. */
|
|
647
|
+
sendLoopStateUpdate(loopID: string, values: Record<string, unknown>, asNode?: string): Promise<void>;
|
|
648
|
+
/** Requests display card ledger snapshot. */
|
|
649
|
+
sendLoopCardsFetch(loopID: string): Promise<void>;
|
|
650
|
+
/** Requests the full loop history (RFC-631). */
|
|
651
|
+
sendLoopHistoryFetch(loopID: string): Promise<void>;
|
|
652
|
+
/** Requests MCP server status. */
|
|
653
|
+
sendMCPStatus(): Promise<void>;
|
|
654
|
+
/** Requests daemon config reload. */
|
|
655
|
+
sendConfigReload(): Promise<void>;
|
|
656
|
+
/** Submits credentials for daemon-side authentication. */
|
|
657
|
+
sendAuth(accessKey: string, secretKey: string): Promise<void>;
|
|
658
|
+
/** Refreshes the daemon-side auth token. */
|
|
659
|
+
sendAuthRefresh(refreshToken: string): Promise<void>;
|
|
660
|
+
/** Requests persisted messages and waits for response. */
|
|
661
|
+
getLoopMessages(loopID: string, limit?: number, offset?: number, includeEvents?: boolean, timeout?: number): Promise<Record<string, unknown>>;
|
|
662
|
+
/** Requests loop state and waits for response. */
|
|
663
|
+
getLoopState(loopID: string, timeout?: number): Promise<Record<string, unknown>>;
|
|
664
|
+
/** Updates loop state and waits for response. */
|
|
665
|
+
updateLoopState(loopID: string, values: Record<string, unknown>, asNode?: string, timeout?: number): Promise<Record<string, unknown>>;
|
|
666
|
+
/** Requests display cards and waits for response. */
|
|
667
|
+
fetchLoopCards(loopID: string, timeout?: number): Promise<Record<string, unknown>>;
|
|
668
|
+
/** Requests MCP status and waits for response. */
|
|
669
|
+
getMCPStatus(timeout?: number): Promise<Record<string, unknown>>;
|
|
670
|
+
/** Requests loop history and waits for response. */
|
|
671
|
+
fetchLoopHistory(loopID: string, timeout?: number): Promise<Record<string, unknown>>;
|
|
672
|
+
/** Requests daemon config reload and waits for response. */
|
|
673
|
+
reloadConfig(timeout?: number): Promise<Record<string, unknown>>;
|
|
674
|
+
/** Submits credentials for daemon-side authentication and waits for response. */
|
|
675
|
+
authenticate(accessKey: string, secretKey: string, timeout?: number): Promise<Record<string, unknown>>;
|
|
676
|
+
/** Refreshes the daemon-side auth token and waits for response. */
|
|
677
|
+
refreshAuthToken(refreshToken: string, timeout?: number): Promise<Record<string, unknown>>;
|
|
678
|
+
/** Creates an autopilot job and waits for the response. */
|
|
679
|
+
createJob(goal: string, verificationRules?: string, workspace?: string, timeout?: number): Promise<Record<string, unknown>>;
|
|
680
|
+
/** Queries job status and waits for the response. */
|
|
681
|
+
getJobStatus(jobId: string, timeout?: number): Promise<Record<string, unknown>>;
|
|
682
|
+
/** Pauses a running job. */
|
|
683
|
+
pauseJob(jobId: string, timeout?: number): Promise<Record<string, unknown>>;
|
|
684
|
+
/** Resumes a paused job. */
|
|
685
|
+
resumeJob(jobId: string, timeout?: number): Promise<Record<string, unknown>>;
|
|
686
|
+
/** Cancels a job. */
|
|
687
|
+
cancelJob(jobId: string, timeout?: number): Promise<Record<string, unknown>>;
|
|
688
|
+
/** Requests the DAG visualization for a job. */
|
|
689
|
+
getJobDag(jobId: string, timeout?: number): Promise<Record<string, unknown>>;
|
|
690
|
+
/** Sends guidance to a job or specific goal. */
|
|
691
|
+
sendJobGuidance(jobId: string, text: string, goalId?: string, timeout?: number): Promise<Record<string, unknown>>;
|
|
692
|
+
/** Subscribes to autopilot worker events. */
|
|
693
|
+
autopilotSubscribe(timeout?: number): Promise<string>;
|
|
694
|
+
/** Unsubscribes from autopilot worker events. */
|
|
695
|
+
autopilotUnsubscribe(timeout?: number): Promise<Record<string, unknown>>;
|
|
696
|
+
/** Creates a scheduled job from natural language. */
|
|
697
|
+
cronAdd(text: string, priority?: number, timeout?: number): Promise<Record<string, unknown>>;
|
|
698
|
+
/** Lists scheduled jobs. */
|
|
699
|
+
cronList(status?: string, timeout?: number): Promise<Record<string, unknown>>;
|
|
700
|
+
/** Shows a specific scheduled job. */
|
|
701
|
+
cronShow(jobId: string, timeout?: number): Promise<Record<string, unknown>>;
|
|
702
|
+
/** Cancels a scheduled job. */
|
|
703
|
+
cronCancel(jobId: string, timeout?: number): Promise<Record<string, unknown>>;
|
|
704
|
+
/**
|
|
705
|
+
* Waits for the connection_ack to report readiness (already done in
|
|
706
|
+
* connect(); kept for callers that reconnect manually). Resolves
|
|
707
|
+
* immediately if the handshake is already complete.
|
|
708
|
+
*/
|
|
462
709
|
waitForDaemonReady(timeout?: number): Promise<Record<string, unknown>>;
|
|
463
|
-
/** Waits for subscription confirmation matching loop id. */
|
|
464
|
-
waitForSubscriptionConfirmed(loopID: string, _verbosity: string, timeout?: number): Promise<void>;
|
|
465
710
|
}
|
|
466
711
|
|
|
467
712
|
/**
|
|
468
|
-
*
|
|
713
|
+
* Inbound-frame multiplexer for the protocol-1 client (RFC-629 constraint #1,
|
|
714
|
+
* RFC-450 §5.2/§5.5).
|
|
715
|
+
*
|
|
716
|
+
* Routes inbound protocol-1 frames to the correct waiter by `(type, id)`
|
|
717
|
+
* instead of discarding non-matching events. This makes the Client safe for
|
|
718
|
+
* concurrent RPCs and lets an active subscription stream coexist with RPC
|
|
719
|
+
* waits without starvation.
|
|
720
|
+
*
|
|
721
|
+
* Routing rules:
|
|
722
|
+
* - `response`/`error` with `id` in pending RPCs → pending RPC waiter
|
|
723
|
+
* - `next`/`complete` with `id` in pending subs → pending subscription waiter
|
|
724
|
+
* - `receipt_response` with `receipt` in receipts → receipt waiter
|
|
725
|
+
* - everything else → not consumed (flows to
|
|
726
|
+
* the application event
|
|
727
|
+
* stream / resolver queue)
|
|
728
|
+
*
|
|
729
|
+
* `ping`/`pong`/`connection_ack` are id-less lifecycle frames handled by the
|
|
730
|
+
* Client before reaching the multiplexer; the multiplexer leaves them
|
|
731
|
+
* un-consumed so the Client's existing handlers still see them.
|
|
732
|
+
*
|
|
733
|
+
* A frame routed to a waiter is consumed (returns `true`) and must NOT be
|
|
734
|
+
* forwarded to the resolver queue / event stream.
|
|
735
|
+
*/
|
|
736
|
+
/**
|
|
737
|
+
* Multiplexer holds pending RPC, subscription, and receipt waiters keyed by
|
|
738
|
+
* their correlation id. The Client consults `route()` for each inbound frame
|
|
739
|
+
* before pushing it to the resolver queue.
|
|
740
|
+
*/
|
|
741
|
+
declare class Multiplexer {
|
|
742
|
+
private rpcs;
|
|
743
|
+
private subs;
|
|
744
|
+
private receipts;
|
|
745
|
+
/**
|
|
746
|
+
* Installs a pending RPC wait keyed by `id`. Returns the pending call and an
|
|
747
|
+
* unregister function that MUST be called when the wait ends (success,
|
|
748
|
+
* timeout, or cancel) to avoid leaks. If a late response arrives after the
|
|
749
|
+
* caller has unregistered, it is dropped (log-and-drop) — no leak.
|
|
750
|
+
*/
|
|
751
|
+
registerRPC(id: string): {
|
|
752
|
+
call: Promise<Record<string, unknown>>;
|
|
753
|
+
unregister: () => void;
|
|
754
|
+
};
|
|
755
|
+
/**
|
|
756
|
+
* Installs a pending subscription stream keyed by `id`. Returns the stream
|
|
757
|
+
* channel (an async-iterable-like push sink), a `done` signal, and an
|
|
758
|
+
* unregister function. The Client pushes `next`/`complete` frames via
|
|
759
|
+
* `push`; the application reads from the channel.
|
|
760
|
+
*/
|
|
761
|
+
registerSubscription(id: string): {
|
|
762
|
+
push: (frame: Record<string, unknown>) => void;
|
|
763
|
+
done: Promise<void>;
|
|
764
|
+
unregister: () => void;
|
|
765
|
+
};
|
|
766
|
+
/**
|
|
767
|
+
* Installs a pending receipt wait keyed by `receipt`. Returns an unregister
|
|
768
|
+
* function.
|
|
769
|
+
*/
|
|
770
|
+
registerReceipt(receipt: string): {
|
|
771
|
+
wait: Promise<Record<string, unknown>>;
|
|
772
|
+
unregister: () => void;
|
|
773
|
+
};
|
|
774
|
+
/**
|
|
775
|
+
* Wires a real sink for a registered subscription's `push`. Called by the
|
|
776
|
+
* Client right after `registerSubscription` to install the channel/queue the
|
|
777
|
+
* application reads from.
|
|
778
|
+
*/
|
|
779
|
+
setSubscriptionSink(id: string, sink: (frame: Record<string, unknown>) => void): void;
|
|
780
|
+
/**
|
|
781
|
+
* Inspects one decoded frame, delivers it to a matching waiter if one
|
|
782
|
+
* exists, and returns `true` (consumed). Returns `false` for frames with no
|
|
783
|
+
* matching waiter — these flow on to the resolver queue / event stream.
|
|
784
|
+
* Safe to call from the message handler.
|
|
785
|
+
*/
|
|
786
|
+
route(frame: Record<string, unknown>): boolean;
|
|
787
|
+
/** Reports whether an RPC waiter is registered for `id`. */
|
|
788
|
+
hasRPCWaiter(id: string): boolean;
|
|
789
|
+
}
|
|
790
|
+
|
|
791
|
+
/**
|
|
792
|
+
* Convenience RPC helper functions for the Soothe client (RFC-450 protocol-1).
|
|
469
793
|
*/
|
|
470
794
|
|
|
471
795
|
/** Checks daemon status via RPC. */
|
|
472
796
|
declare function checkDaemonStatus(client: Client, timeout?: number): Promise<Record<string, unknown>>;
|
|
473
|
-
/** Performs a composite health check: connect + status RPC. */
|
|
797
|
+
/** Performs a composite health check: connect + handshake + status RPC. */
|
|
474
798
|
declare function isDaemonLive(wsURL: string, timeout?: number): Promise<boolean>;
|
|
475
799
|
/** Requests daemon shutdown via RPC. */
|
|
476
800
|
declare function requestDaemonShutdown(client: Client, timeout?: number): Promise<void>;
|
|
@@ -478,20 +802,526 @@ declare function requestDaemonShutdown(client: Client, timeout?: number): Promis
|
|
|
478
802
|
declare function fetchSkillsCatalog(client: Client, timeout?: number): Promise<Record<string, unknown>[]>;
|
|
479
803
|
/** Fetches a daemon config section via RPC. */
|
|
480
804
|
declare function fetchConfigSection(client: Client, section: string, timeout?: number): Promise<Record<string, unknown>>;
|
|
805
|
+
/** Requests daemon config reload via RPC. */
|
|
806
|
+
declare function requestDaemonConfigReload(client: Client, timeout?: number): Promise<Record<string, unknown>>;
|
|
807
|
+
/** Requests loop history (RFC-631) and waits for the response. */
|
|
808
|
+
declare function fetchLoopHistory(client: Client, loopID: string, timeout?: number): Promise<Record<string, unknown>>;
|
|
809
|
+
/** Submits credentials for daemon-side authentication and waits for the response. */
|
|
810
|
+
declare function authenticate(client: Client, accessKey: string, secretKey: string, timeout?: number): Promise<Record<string, unknown>>;
|
|
811
|
+
/** Refreshes the daemon-side auth token and waits for the response. */
|
|
812
|
+
declare function refreshAuthToken(client: Client, refreshToken: string, timeout?: number): Promise<Record<string, unknown>>;
|
|
481
813
|
|
|
482
814
|
/**
|
|
483
|
-
*
|
|
815
|
+
* loop_new (or reuse id) → subscribe(loop_events); returns the loop id.
|
|
816
|
+
* The protocol-1 handshake is assumed to have completed in `client.connect()`.
|
|
484
817
|
*/
|
|
485
|
-
|
|
486
|
-
/** Daemon ready → loop_new (or reuse id) → loop_subscribe; returns loop id. */
|
|
487
818
|
declare function bootstrapLoopSession(client: Client, resumeLoopId: string | null | undefined, config?: Config, loopNew?: LoopNewOptions): Promise<string>;
|
|
488
|
-
/**
|
|
819
|
+
/**
|
|
820
|
+
* Blocks until connection_ack reports readiness "ready". Resolves immediately
|
|
821
|
+
* if the handshake already completed during connect().
|
|
822
|
+
*/
|
|
489
823
|
declare function waitDaemonReady(client: Client, timeout: number): Promise<void>;
|
|
490
|
-
/** Waits for a status message with a non-empty
|
|
491
|
-
declare function waitLoopStatusWithID(client: Client, timeout: number): Promise<
|
|
492
|
-
/** Waits for
|
|
824
|
+
/** Waits for a status message with a non-empty loop_id. */
|
|
825
|
+
declare function waitLoopStatusWithID(client: Client, timeout: number): Promise<Record<string, unknown>>;
|
|
826
|
+
/** Waits for a subscription confirmation `next` matching loop id. */
|
|
493
827
|
declare function waitSubscriptionConfirmed(client: Client, wantLoopID: string, _wantVerbosity: string, timeout: number): Promise<void>;
|
|
494
828
|
/** Attempts to connect to the Soothe daemon with bounded retries. */
|
|
495
829
|
declare function connectWithRetries(client: Client, maxRetries?: number, retryDelay?: number): Promise<void>;
|
|
496
830
|
|
|
497
|
-
|
|
831
|
+
/**
|
|
832
|
+
* Persistence seam for appkit (RFC-629 Layer 1).
|
|
833
|
+
*
|
|
834
|
+
* SessionStore abstracts per-application storage: the session↔loop-id mapping
|
|
835
|
+
* that ConnectionPool consults to decide bootstrap vs reattach, and the
|
|
836
|
+
* message rows TurnRunner writes back when a turn completes. Applications
|
|
837
|
+
* implement this against their own store (Postgres, Redis, in-memory, …).
|
|
838
|
+
*
|
|
839
|
+
* Implementations must be safe for concurrent use.
|
|
840
|
+
*/
|
|
841
|
+
/** Persisted mapping between an application session id and the daemon loop id. */
|
|
842
|
+
interface SessionEntry {
|
|
843
|
+
workspaceID: string;
|
|
844
|
+
sessionID: string;
|
|
845
|
+
loopID: string;
|
|
846
|
+
/** App-defined taxonomy (e.g. "primary" | "ephemeral"). */
|
|
847
|
+
sessionType: string;
|
|
848
|
+
/** Optional app key for ephemeral internal features. */
|
|
849
|
+
purpose?: string;
|
|
850
|
+
isActive: boolean;
|
|
851
|
+
resetCount: number;
|
|
852
|
+
lastUsedAt: number;
|
|
853
|
+
}
|
|
854
|
+
/** A persisted message row (assistant reply or error). */
|
|
855
|
+
interface SessionMessage {
|
|
856
|
+
id?: string;
|
|
857
|
+
/** "assistant" | "user" | "error". */
|
|
858
|
+
role: string;
|
|
859
|
+
content: string;
|
|
860
|
+
context?: unknown;
|
|
861
|
+
metadata?: Record<string, unknown>;
|
|
862
|
+
}
|
|
863
|
+
/**
|
|
864
|
+
* Persistence seam between appkit and the application's storage backend.
|
|
865
|
+
*
|
|
866
|
+
* ConnectionPool consults the store to decide whether to bootstrap a fresh
|
|
867
|
+
* loop (no loop id on file) or reattach to an existing one, and records the
|
|
868
|
+
* loop id once bootstrapped. TurnRunner persists the final assistant reply
|
|
869
|
+
* and error rows via appendMessage.
|
|
870
|
+
*/
|
|
871
|
+
interface SessionStore {
|
|
872
|
+
/** Returns the persisted entry for sessionID, or null if no record exists. */
|
|
873
|
+
getSession(sessionID: string): Promise<SessionEntry | null>;
|
|
874
|
+
/** Persists a new session↔loop mapping. */
|
|
875
|
+
createSession(workspaceID: string, sessionID: string, loopID: string, sessionType: string): Promise<void>;
|
|
876
|
+
/** Stamps the session's last-used timestamp. */
|
|
877
|
+
updateLastUsed(sessionID: string): Promise<void>;
|
|
878
|
+
/** Bumps the reset counter (used to decide fresh bootstrap vs reattach). */
|
|
879
|
+
incrementResetCount(sessionID: string): Promise<void>;
|
|
880
|
+
/**
|
|
881
|
+
* Returns the daemon loop id for sessionID and whether one is on file.
|
|
882
|
+
* ok===false triggers a fresh loop_new bootstrap.
|
|
883
|
+
*/
|
|
884
|
+
getLoopIDForSession(sessionID: string): Promise<{
|
|
885
|
+
loopID: string;
|
|
886
|
+
ok: boolean;
|
|
887
|
+
}>;
|
|
888
|
+
/** Writes a message row (assistant reply, error, etc.) for the session. */
|
|
889
|
+
appendMessage(sessionID: string, message: SessionMessage): Promise<void>;
|
|
890
|
+
}
|
|
891
|
+
|
|
892
|
+
/**
|
|
893
|
+
* SSE-style pub/sub fan-out for appkit (RFC-629 Layer 1).
|
|
894
|
+
*
|
|
895
|
+
* Generic, string-keyed pub/sub for SSE-style event delivery. The
|
|
896
|
+
* application-agnostic successor to a domain-keyed broadcaster: applications
|
|
897
|
+
* convert from their domain key type to `string` at their own boundary.
|
|
898
|
+
*
|
|
899
|
+
* Slow consumers do not stall the broadcaster: each subscriber has a bounded
|
|
900
|
+
* queue and overflowing events are dropped (drop-on-full).
|
|
901
|
+
*/
|
|
902
|
+
/** One Server-Sent Event payload. The Type vocabulary is app-defined. */
|
|
903
|
+
interface SSEEvent {
|
|
904
|
+
type: string;
|
|
905
|
+
data: unknown;
|
|
906
|
+
}
|
|
907
|
+
/**
|
|
908
|
+
* SSEBroadcaster fans events out to all subscribers for a session id.
|
|
909
|
+
* Non-blocking: a full subscriber queue drops the event so one slow consumer
|
|
910
|
+
* cannot block the others.
|
|
911
|
+
*/
|
|
912
|
+
declare class SSEBroadcaster {
|
|
913
|
+
private subscribers;
|
|
914
|
+
private nextSubID;
|
|
915
|
+
/** Creates an empty broadcaster. */
|
|
916
|
+
constructor();
|
|
917
|
+
/**
|
|
918
|
+
* Registers a new subscriber channel for a session id. Returns an async
|
|
919
|
+
* iterable the subscriber reads events from. Unsubscribe via
|
|
920
|
+
* `unsubscribe()` or `close()`.
|
|
921
|
+
*/
|
|
922
|
+
subscribe(sessionID: string): {
|
|
923
|
+
iterable: AsyncIterable<SSEEvent>;
|
|
924
|
+
id: string;
|
|
925
|
+
};
|
|
926
|
+
/** Removes a subscriber by id and closes its iterable. Safe if unknown. */
|
|
927
|
+
unsubscribe(sessionID: string, subID: string): void;
|
|
928
|
+
/**
|
|
929
|
+
* Sends an event to all subscribers for a session id. Non-blocking: a full
|
|
930
|
+
* subscriber queue is skipped (drop-on-full) so one slow consumer cannot
|
|
931
|
+
* block the others.
|
|
932
|
+
*/
|
|
933
|
+
broadcast(sessionID: string, event: SSEEvent): void;
|
|
934
|
+
/** Closes all subscribers for a session id and removes the entry. */
|
|
935
|
+
close(sessionID: string): void;
|
|
936
|
+
/** Closes every subscriber channel across all sessions. */
|
|
937
|
+
closeAll(): void;
|
|
938
|
+
}
|
|
939
|
+
|
|
940
|
+
/**
|
|
941
|
+
* Thinking-step extraction for appkit (RFC-629 Layer 1).
|
|
942
|
+
*
|
|
943
|
+
* Maps an allowlisted progress event to one structured UI line. Free-form
|
|
944
|
+
* streams (tokens, reports, reasoning) are excluded. Ported from the Go
|
|
945
|
+
* appkit's thinking_step with the allowlist made configurable.
|
|
946
|
+
*/
|
|
947
|
+
/** Default thinking-step event allowlist (triarch's set). */
|
|
948
|
+
declare const DEFAULT_THINKING_STEP_EVENTS: ReadonlySet<string>;
|
|
949
|
+
/**
|
|
950
|
+
* Maps an allowlisted progress event to one structured UI line. Returns
|
|
951
|
+
* [line, true] for a recognized event; ["", false] otherwise. `allow` may be
|
|
952
|
+
* omitted to use the default allowlist.
|
|
953
|
+
*/
|
|
954
|
+
declare function extractThinkingStep(eventType: string, data: Record<string, unknown> | null, allow?: ReadonlySet<string>): [string, boolean];
|
|
955
|
+
|
|
956
|
+
/**
|
|
957
|
+
* Event classifier for appkit (RFC-629 Layer 1).
|
|
958
|
+
*
|
|
959
|
+
* Maps a stream of decoded daemon events into deliverable/streaming/terminal
|
|
960
|
+
* outcomes, keyed on (namespace, mode, phase) per RFC-614/RFC-403
|
|
961
|
+
* (RFC-629 constraint #4). The app-agnostic successor to triarch's
|
|
962
|
+
* ProcessChatEvent, with the deliverable phase set promoted from hardcoded
|
|
963
|
+
* constants to configuration.
|
|
964
|
+
*
|
|
965
|
+
* Event shape: a protocol-1 `next` envelope carries
|
|
966
|
+
* `{type:"next", payload:{namespace, mode, data, loop_id}}`. The daemon
|
|
967
|
+
* wraps legacy free-form frames as `{payload:{namespace, mode:<orig type>,
|
|
968
|
+
* data:<orig frame>}}` (RFC-450 §9.3). The classifier inspects the payload's
|
|
969
|
+
* `mode`/`data`/`namespace` and the inner message's `phase`/`type`/`content`.
|
|
970
|
+
*/
|
|
971
|
+
|
|
972
|
+
/** How a processed event should end the query loop. */
|
|
973
|
+
declare enum ChatEventTerminal {
|
|
974
|
+
/** Accumulate content; the query is still running. */
|
|
975
|
+
Continue = 0,
|
|
976
|
+
/** A user-visible final reply; persist it. */
|
|
977
|
+
DeliverableComplete = 1,
|
|
978
|
+
/** The query failed; persist an error. */
|
|
979
|
+
FailedComplete = 2
|
|
980
|
+
}
|
|
981
|
+
/** The structured outcome of classifying one daemon event. */
|
|
982
|
+
interface ChatEventResult {
|
|
983
|
+
content?: string;
|
|
984
|
+
/** User-visible progress line (not a final reply). */
|
|
985
|
+
thinkingStep?: string;
|
|
986
|
+
terminal: ChatEventTerminal;
|
|
987
|
+
/** soothe wire event type when terminal === DeliverableComplete. */
|
|
988
|
+
completionEvent?: string;
|
|
989
|
+
err?: Error;
|
|
990
|
+
}
|
|
991
|
+
/**
|
|
992
|
+
* Product-specific decisions an EventClassifier needs. The DeliverablePhases
|
|
993
|
+
* set is the key product knob: which message `phase` values count as
|
|
994
|
+
* user-facing deliverables (triarch uses quiz, goal_completion, direct_model, and
|
|
995
|
+
* direct intent_hint phases text_completion, image_to_text, ocr, embed;
|
|
996
|
+
* other apps pass their own).
|
|
997
|
+
*/
|
|
998
|
+
interface ClassifierConfig {
|
|
999
|
+
/** Recognizes loop-tagged message phases that may end a query with
|
|
1000
|
+
* user-facing text. Required. */
|
|
1001
|
+
deliverablePhases: ReadonlySet<string>;
|
|
1002
|
+
/** Minimum trimmed rune count for a reply to be persisted as final
|
|
1003
|
+
* (avoids finishing on stub ACKs like "..."). Defaults to 8. */
|
|
1004
|
+
minDeliverableRunes?: number;
|
|
1005
|
+
/** Optional app override of the default thinking-step event allowlist. */
|
|
1006
|
+
thinkingStepEvents?: ReadonlySet<string>;
|
|
1007
|
+
}
|
|
1008
|
+
/** Maps a stream of decoded daemon events into deliverable/streaming/terminal outcomes. */
|
|
1009
|
+
declare class EventClassifier {
|
|
1010
|
+
private deliverablePhases;
|
|
1011
|
+
private minDeliverableRunes;
|
|
1012
|
+
private thinkingStepEvents?;
|
|
1013
|
+
constructor(cfg: ClassifierConfig);
|
|
1014
|
+
/**
|
|
1015
|
+
* Inspects one decoded event and returns its outcome. `accumulated` is the
|
|
1016
|
+
* running assistant text so far, used to pick the final reply when a
|
|
1017
|
+
* deliverable event arrives.
|
|
1018
|
+
*/
|
|
1019
|
+
classify(msg: unknown, accumulated: string): ChatEventResult;
|
|
1020
|
+
/**
|
|
1021
|
+
* Reports whether a persisted completion_event is user-facing. Uses the
|
|
1022
|
+
* configured deliverable phase set; recognizes the protocol output namespace
|
|
1023
|
+
* and final_report component as deliverable.
|
|
1024
|
+
*/
|
|
1025
|
+
isDeliverableCompletionEvent(eventType: string): boolean;
|
|
1026
|
+
isDeliverableLoopPhase(phase: string): boolean;
|
|
1027
|
+
private deliverableResult;
|
|
1028
|
+
private continueResult;
|
|
1029
|
+
private failedResult;
|
|
1030
|
+
/** Reports whether trimmed assistant text is long enough to persist as final. */
|
|
1031
|
+
isSubstantiveAssistantReply(content: string): boolean;
|
|
1032
|
+
/**
|
|
1033
|
+
* Picks the user-visible reply for a completed query. Only a deliverable
|
|
1034
|
+
* terminal result with a recognized completion event yields a final reply.
|
|
1035
|
+
*/
|
|
1036
|
+
resolveDeliverableFinalContent(eventResult: ChatEventResult, _accumulated: string): [string, boolean];
|
|
1037
|
+
/** The event→outcome mapper, ported from triarch's ProcessChatEvent. */
|
|
1038
|
+
private processChatEvent;
|
|
1039
|
+
/** Classifies a `next` envelope by projecting its payload. */
|
|
1040
|
+
private classifyNextEnvelope;
|
|
1041
|
+
/**
|
|
1042
|
+
* Classifies an event payload by (namespace, mode, phase). `data` may be a
|
|
1043
|
+
* map or an array of messages (mode="messages").
|
|
1044
|
+
*/
|
|
1045
|
+
private classifyEventPayload;
|
|
1046
|
+
/** Classifies a mode="messages" payload (array of message objects). */
|
|
1047
|
+
private classifyMessagesMode;
|
|
1048
|
+
/**
|
|
1049
|
+
* Extracts plain assistant text from mode="messages" events that carry a
|
|
1050
|
+
* terminal AIMessage without loop-tagged phase metadata (legacy direct_llm turns
|
|
1051
|
+
* before phase tagging; prefer deliverablePhases including text_completion).
|
|
1052
|
+
*/
|
|
1053
|
+
private messagesModeAssistantContent;
|
|
1054
|
+
/** soothe output/responded events that carry user-facing final text. */
|
|
1055
|
+
private isFinalOutputEvent;
|
|
1056
|
+
}
|
|
1057
|
+
|
|
1058
|
+
/**
|
|
1059
|
+
* Single-flight query gate for appkit (RFC-629 Layer 1).
|
|
1060
|
+
*
|
|
1061
|
+
* Enforces single-flight query execution per session id and the
|
|
1062
|
+
* cancel-before-context ordering: when a query is cancelled, the daemon is
|
|
1063
|
+
* told to stop (command_request{command:"cancel"}) BEFORE the local abort
|
|
1064
|
+
* signal is cancelled, on a detached timeout so the caller's cancellation
|
|
1065
|
+
* cannot block the wire send.
|
|
1066
|
+
*
|
|
1067
|
+
* The app-agnostic successor to triarch's AcquireQuery/CancelQuery/
|
|
1068
|
+
* sendLoopCancelCommand.
|
|
1069
|
+
*/
|
|
1070
|
+
/** Returned when a session already has an in-flight query. */
|
|
1071
|
+
declare class ErrQueryBusy extends Error {
|
|
1072
|
+
constructor();
|
|
1073
|
+
}
|
|
1074
|
+
/**
|
|
1075
|
+
* QueryGate enforces single-flight query execution per session id.
|
|
1076
|
+
*/
|
|
1077
|
+
declare class QueryGate {
|
|
1078
|
+
private active;
|
|
1079
|
+
/** Constructs an empty gate. */
|
|
1080
|
+
constructor();
|
|
1081
|
+
/**
|
|
1082
|
+
* Reserves sessionID for one agent turn. Returns ErrQueryBusy if a query is
|
|
1083
|
+
* already in flight. `abort` is the AbortController for the query's timeout
|
|
1084
|
+
* context. `sendCancel` is the daemon-cancel sender; it is invoked from
|
|
1085
|
+
* `cancel()` on a detached 10s timeout.
|
|
1086
|
+
*/
|
|
1087
|
+
acquire(sessionID: string, abort: AbortController, sendCancel: ((signal: AbortSignal) => Promise<void>) | null): void;
|
|
1088
|
+
/**
|
|
1089
|
+
* Cooperatively stops a running query for sessionID. Sends the daemon cancel
|
|
1090
|
+
* (on a detached 10s-timeout abort so caller cancellation cannot block the
|
|
1091
|
+
* wire send) BEFORE aborting the local context. Returns silently if no query
|
|
1092
|
+
* is in flight (intent already satisfied).
|
|
1093
|
+
*/
|
|
1094
|
+
cancel(sessionID: string): Promise<void>;
|
|
1095
|
+
/**
|
|
1096
|
+
* Clears the gate for sessionID without sending a daemon cancel. Call when a
|
|
1097
|
+
* query completes normally (success or local failure) so the next turn can
|
|
1098
|
+
* acquire.
|
|
1099
|
+
*/
|
|
1100
|
+
release(sessionID: string): void;
|
|
1101
|
+
/** Reports whether a query is in flight for sessionID. */
|
|
1102
|
+
isActive(sessionID: string): boolean;
|
|
1103
|
+
}
|
|
1104
|
+
|
|
1105
|
+
/**
|
|
1106
|
+
* ManagedClient — the subset of the core Client that appkit's ConnectionPool
|
|
1107
|
+
* and TurnRunner depend on (RFC-629 Layer 1).
|
|
1108
|
+
*
|
|
1109
|
+
* The concrete `Client` satisfies it; tests supply a fake. Defining it as an
|
|
1110
|
+
* interface lets appkit be unit-tested without a live WebSocket daemon.
|
|
1111
|
+
*/
|
|
1112
|
+
|
|
1113
|
+
/**
|
|
1114
|
+
* ManagedClient is the subset of the core Client that appkit depends on.
|
|
1115
|
+
* Methods are async (TS) rather than channel-based (Go).
|
|
1116
|
+
*/
|
|
1117
|
+
interface ManagedClient {
|
|
1118
|
+
/** Dials and handshakes. */
|
|
1119
|
+
connect(): Promise<void>;
|
|
1120
|
+
/** Re-dials after a drop. */
|
|
1121
|
+
reconnect(): Promise<void>;
|
|
1122
|
+
/** Resumes a loop by id and probes liveness. */
|
|
1123
|
+
reattachAndProbe(loopID: string): Promise<void>;
|
|
1124
|
+
/** Sends a fire-and-forget notification (e.g. loop_input). */
|
|
1125
|
+
sendMessage(msg: unknown): Promise<void>;
|
|
1126
|
+
/** Sends user input to the daemon (loop_input notification). */
|
|
1127
|
+
sendInput(text: string, options?: InputOptions): Promise<void>;
|
|
1128
|
+
/** Starts the read loop, returning the event stream. */
|
|
1129
|
+
receiveMessages(signal?: AbortSignal): AsyncGenerator<DecodedMessage>;
|
|
1130
|
+
/** Returns whether the connection has dropped. */
|
|
1131
|
+
isDisconnected(): boolean;
|
|
1132
|
+
/** Returns the drop cause, or null if not dropped. */
|
|
1133
|
+
disconnectCause(): DisconnectCause | null;
|
|
1134
|
+
/** Reports connection liveness. */
|
|
1135
|
+
isConnected(): boolean;
|
|
1136
|
+
/** Tears down the connection. */
|
|
1137
|
+
close(): void;
|
|
1138
|
+
}
|
|
1139
|
+
/**
|
|
1140
|
+
* Builds a fresh ManagedClient for a daemon URL and config. ConnectionPool
|
|
1141
|
+
* calls it per pooled connection. Applications may supply a custom factory
|
|
1142
|
+
* (e.g. wrapping Client with logging/metrics).
|
|
1143
|
+
*/
|
|
1144
|
+
type ClientFactory = (url: string, config?: Config) => ManagedClient;
|
|
1145
|
+
/** Returns a ClientFactory that builds a core Client. */
|
|
1146
|
+
declare function defaultClientFactory(): ClientFactory;
|
|
1147
|
+
/**
|
|
1148
|
+
* Creates a new loop (loop_new + subscribe) on a connected client and returns
|
|
1149
|
+
* the new loop id. The default implementation calls bootstrapLoopSession;
|
|
1150
|
+
* apps may override it.
|
|
1151
|
+
*/
|
|
1152
|
+
type BootstrapFunc = (client: ManagedClient, workspaceID: string, userID: string, config?: Config) => Promise<string>;
|
|
1153
|
+
/** Default bootstrap: loop_new + subscribe(loop_events). */
|
|
1154
|
+
declare function defaultBootstrapFunc(): BootstrapFunc;
|
|
1155
|
+
|
|
1156
|
+
/**
|
|
1157
|
+
* Per-session connection pool for appkit (RFC-629 Layer 1).
|
|
1158
|
+
*
|
|
1159
|
+
* Manages a pool of daemon connections, one active per session. Reuses an
|
|
1160
|
+
* active connection when still live, otherwise bootstraps a fresh loop
|
|
1161
|
+
* (loop_new + subscribe) or reattaches an existing one (loop_reattach +
|
|
1162
|
+
* subscribe + reattachAndProbe). Persistence of session↔loop mappings is
|
|
1163
|
+
* abstracted behind SessionStore.
|
|
1164
|
+
*
|
|
1165
|
+
* The app-agnostic successor to triarch's SoothePoolManager connection
|
|
1166
|
+
* mechanics.
|
|
1167
|
+
*/
|
|
1168
|
+
|
|
1169
|
+
/** Returned when no free connection slot is available. */
|
|
1170
|
+
declare class ErrPoolExhausted extends Error {
|
|
1171
|
+
constructor();
|
|
1172
|
+
}
|
|
1173
|
+
/** Configures a ConnectionPool. Zero values use defaults. */
|
|
1174
|
+
interface PoolConfig {
|
|
1175
|
+
poolSize: number;
|
|
1176
|
+
queryTimeout: number;
|
|
1177
|
+
connectionTimeout: number;
|
|
1178
|
+
maxIdleTime: number;
|
|
1179
|
+
healthCheckInterval: number;
|
|
1180
|
+
}
|
|
1181
|
+
/** Returns env-overridable defaults (mirrors triarch). */
|
|
1182
|
+
declare function defaultPoolConfig(): PoolConfig;
|
|
1183
|
+
/** One connection slot in the pool. */
|
|
1184
|
+
declare class PooledConn {
|
|
1185
|
+
slotID: number;
|
|
1186
|
+
client: ManagedClient;
|
|
1187
|
+
eventStream: AsyncGenerator<DecodedMessage> | null;
|
|
1188
|
+
streamController: AbortController | null;
|
|
1189
|
+
sessionID: string;
|
|
1190
|
+
loopID: string;
|
|
1191
|
+
workspaceID: string;
|
|
1192
|
+
lastUsed: number;
|
|
1193
|
+
constructor(slotID: number, client: ManagedClient);
|
|
1194
|
+
/** Reports whether the underlying client signalled a drop. */
|
|
1195
|
+
isDisconnected(): boolean;
|
|
1196
|
+
isConnected(): boolean;
|
|
1197
|
+
getLoopID(): string;
|
|
1198
|
+
}
|
|
1199
|
+
/**
|
|
1200
|
+
* ConnectionPool manages a pool of daemon connections, one active per session.
|
|
1201
|
+
*/
|
|
1202
|
+
declare class ConnectionPool {
|
|
1203
|
+
private cfg;
|
|
1204
|
+
private scfg;
|
|
1205
|
+
private factory;
|
|
1206
|
+
private bootstrap;
|
|
1207
|
+
private store;
|
|
1208
|
+
private pool;
|
|
1209
|
+
private activeSlots;
|
|
1210
|
+
private nextSlotID;
|
|
1211
|
+
private url;
|
|
1212
|
+
/**
|
|
1213
|
+
* Constructs a pool. `url` is the daemon WebSocket URL. If cfg is null,
|
|
1214
|
+
* defaultPoolConfig is used; if scfg is null, defaultConfig is used; nil
|
|
1215
|
+
* factory/bootstrap fall back to the defaults.
|
|
1216
|
+
*/
|
|
1217
|
+
constructor(url: string, store: SessionStore, cfg?: PoolConfig | null, scfg?: Config | null, factory?: ClientFactory | null);
|
|
1218
|
+
/** Overrides the loop bootstrap function (useful for test fakes). */
|
|
1219
|
+
withBootstrap(f: BootstrapFunc): ConnectionPool;
|
|
1220
|
+
/**
|
|
1221
|
+
* Returns a live connection for sessionID, reusing an active slot or
|
|
1222
|
+
* bootstrapping/reattaching as needed. The caller must call `release()`
|
|
1223
|
+
* when done with the connection (a turn completes or the session is reset).
|
|
1224
|
+
*/
|
|
1225
|
+
acquire(sessionID: string, workspaceID: string, userID: string, _signal?: AbortSignal): Promise<PooledConn>;
|
|
1226
|
+
/** Tears down the connection for sessionID and returns the slot. */
|
|
1227
|
+
release(sessionID: string): Promise<void>;
|
|
1228
|
+
/**
|
|
1229
|
+
* Tears down the connection for sessionID so the next acquire bootstraps
|
|
1230
|
+
* fresh. The store should archive the loop id so getLoopIDForSession returns
|
|
1231
|
+
* false next time.
|
|
1232
|
+
*/
|
|
1233
|
+
resetSession(sessionID: string): Promise<void>;
|
|
1234
|
+
/** Gracefully shuts down all active connections. */
|
|
1235
|
+
stop(): void;
|
|
1236
|
+
/** Stats snapshot for observability. */
|
|
1237
|
+
stats(): {
|
|
1238
|
+
active: number;
|
|
1239
|
+
idle: number;
|
|
1240
|
+
};
|
|
1241
|
+
/** Bootstrap a fresh loop and start the reader. */
|
|
1242
|
+
private bootstrapNew;
|
|
1243
|
+
/** Reconnect + reattach an existing loop, then start the reader. */
|
|
1244
|
+
private resumeAndReattach;
|
|
1245
|
+
/** Starts a receiveMessages generator and stores the stream + controller. */
|
|
1246
|
+
private startReader;
|
|
1247
|
+
}
|
|
1248
|
+
|
|
1249
|
+
/**
|
|
1250
|
+
* Turn runner for appkit (RFC-629 Layer 1).
|
|
1251
|
+
*
|
|
1252
|
+
* Executes one query turn end-to-end: acquire a pooled connection, enforce
|
|
1253
|
+
* single-flight, send loop_input, consume the event stream, classify events,
|
|
1254
|
+
* resolve the deliverable, persist the reply, and broadcast completion.
|
|
1255
|
+
*
|
|
1256
|
+
* The app-agnostic successor to triarch's ExecuteQuery.
|
|
1257
|
+
*/
|
|
1258
|
+
|
|
1259
|
+
/** Returned when a turn exceeds the configured timeout. */
|
|
1260
|
+
declare class ErrQueryTimeout extends Error {
|
|
1261
|
+
constructor();
|
|
1262
|
+
}
|
|
1263
|
+
/** Configures a TurnRunner. */
|
|
1264
|
+
interface TurnConfig {
|
|
1265
|
+
/** Per-turn deadline in ms. Defaults to 30m. */
|
|
1266
|
+
queryTimeout: number;
|
|
1267
|
+
}
|
|
1268
|
+
/** Carries optional daemon hints on a loop_input payload. */
|
|
1269
|
+
interface InputOpts {
|
|
1270
|
+
intentHint?: LoopInputIntentHint;
|
|
1271
|
+
preferredSubagent?: string;
|
|
1272
|
+
responseSchema?: Record<string, unknown>;
|
|
1273
|
+
responseSchemaName?: string;
|
|
1274
|
+
responseSchemaStrict?: boolean;
|
|
1275
|
+
}
|
|
1276
|
+
/** Optional attachment shape (IG-327: {mime_type, data(base64)}). */
|
|
1277
|
+
type Attachment = Record<string, unknown>;
|
|
1278
|
+
/**
|
|
1279
|
+
* Builds a loop_input payload with optional attachments. Apps build this from
|
|
1280
|
+
* their product modes (e.g. triarch's ask/agent/deep-research).
|
|
1281
|
+
*/
|
|
1282
|
+
declare function inputMessageForLoop(text: string, loopID: string, attachments?: Attachment[], opts?: InputOpts): Record<string, unknown>;
|
|
1283
|
+
/** Completion hook signature. */
|
|
1284
|
+
type OnComplete = (sessionID: string, loopID: string, content: string, completionEvent: string, elapsedMs: number) => void;
|
|
1285
|
+
/** Error hook signature. */
|
|
1286
|
+
type OnError = (sessionID: string, loopID: string, err: Error) => void;
|
|
1287
|
+
/**
|
|
1288
|
+
* TurnRunner executes one query turn end-to-end.
|
|
1289
|
+
*/
|
|
1290
|
+
declare class TurnRunner {
|
|
1291
|
+
private pool;
|
|
1292
|
+
private gate;
|
|
1293
|
+
private classifier;
|
|
1294
|
+
private store;
|
|
1295
|
+
private broadcaster;
|
|
1296
|
+
private cfg;
|
|
1297
|
+
private buildInput;
|
|
1298
|
+
private onComplete;
|
|
1299
|
+
private onError;
|
|
1300
|
+
/**
|
|
1301
|
+
* Constructs a TurnRunner. pool, gate, classifier, and store are required;
|
|
1302
|
+
* broadcaster may be null.
|
|
1303
|
+
*/
|
|
1304
|
+
constructor(pool: ConnectionPool, gate: QueryGate, classifier: EventClassifier, store: SessionStore, broadcaster: SSEBroadcaster | null, cfg: TurnConfig);
|
|
1305
|
+
/** Overrides the loop_input payload builder. */
|
|
1306
|
+
withInputBuilder(f: typeof inputMessageForLoop): TurnRunner;
|
|
1307
|
+
/** Sets a completion hook (runs inline on success). */
|
|
1308
|
+
withOnComplete(f: OnComplete): TurnRunner;
|
|
1309
|
+
/** Sets an error hook (runs inline on failure). */
|
|
1310
|
+
withOnError(f: OnError): TurnRunner;
|
|
1311
|
+
/**
|
|
1312
|
+
* Runs one query turn. The response is broadcast via the SSE broadcaster and
|
|
1313
|
+
* persisted via the SessionStore; it is not returned to the caller (SSE
|
|
1314
|
+
* subscribers receive it). Resolves on success; rejects on failure
|
|
1315
|
+
* (ErrQueryTimeout, AbortError, or a daemon/processing error).
|
|
1316
|
+
*/
|
|
1317
|
+
execute(sessionID: string, message: string, userID: string, workspaceID: string, attachments: Attachment[] | null, opts: InputOpts | null, signal?: AbortSignal): Promise<void>;
|
|
1318
|
+
/** Asks the daemon to cooperatively stop the loop runner on a detached signal. */
|
|
1319
|
+
private sendLoopCancel;
|
|
1320
|
+
private persistResponse;
|
|
1321
|
+
private persistFailed;
|
|
1322
|
+
private broadcastThinkingStep;
|
|
1323
|
+
private broadcastComplete;
|
|
1324
|
+
private broadcastError;
|
|
1325
|
+
}
|
|
1326
|
+
|
|
1327
|
+
export { type Attachment, type BaseEnvelope, type BootstrapFunc, CLIENT_VERSION, type ChatEventResult, ChatEventTerminal, type ClassifierConfig, Client, type ClientFactory, type CompleteEnvelope, type Config, type ConnectionAckEnvelope, ConnectionError, type ConnectionInitEnvelope, ConnectionPool, DEFAULT_CLIENT_CAPABILITIES, DEFAULT_DELIVERABLE_PHASES, DEFAULT_THINKING_STEP_EVENTS, DaemonError, type DecodedMessage, DisconnectCause, type DisconnectEnvelope, ErrPoolExhausted, ErrQueryBusy, ErrQueryTimeout, type ErrorEnvelope, EventAutopilotGoalCompleted, EventAutopilotGoalCreated, EventAutopilotGoalProgress, EventAutopilotGoalStatus, EventAutopilotWorkerAssigned, EventAutopilotWorkerUnassigned, EventCardCreated, EventCardReplayBegin, EventCardReplayEnd, EventClassifier, EventExploreCompleted, EventExploreMilestone, EventExploreStarted, EventExploreStepCompleted, EventFinalReport, EventGeneralFailed, EventLoopReattachedWire, EventMessageReceived, EventMessageSent, EventPlanCreated, EventReplayComplete, EventStrangeLoopCompleted, EventStrangeLoopContextCompacted, EventStrangeLoopPlanDecision, EventStrangeLoopReasoned, EventStrangeLoopStarted, EventStrangeLoopStepCompleted, EventStrangeLoopStepQueued, EventStrangeLoopStepStarted, EventStreamToolCallUpdate, EventTacitusCompleted, EventTacitusGatherSummary, EventTacitusStarted, EventToolCallUpdatesBatch, EventToolCompleted, EventToolError, EventToolStarted, INTENT_HINT_EMBED, INTENT_HINT_IMAGE_TO_TEXT, INTENT_HINT_OCR, INTENT_HINT_TEXT_COMPLETION, type InputOptions, type InputOpts, type IntentHint, LOOP_ASSISTANT_OUTPUT_PHASES, type LoopAssistantOutputPhase, type LoopInputIntentHint, type LoopInputParams, type LoopNewOptions, type ManagedClient, type MessageType, type MethodName, Multiplexer, type NegotiatedCapabilities, type NextEnvelope, type NotificationEnvelope, type OnComplete, type OnError, PROTO_VERSION, type PingEnvelope, type PongEnvelope, type PoolConfig, PooledConn, QueryGate, REMOVED_INTENT_HINTS, type ReceiptResponseEnvelope, ReconnectError, type RemovedIntentHint, type RequestEnvelope, type ResponseEnvelope, SSEBroadcaster, type SSEEvent, type SessionEntry, type SessionMessage, type SessionStore, StaleLoopError, type StatusFrame, type StreamEventPayload, type SubscribeEnvelope, TimeoutError, type TurnConfig, TurnRunner, type UnsubscribeEnvelope, type VerbosityLevel, VerbosityTier, authenticate, bootstrapLoopSession, checkDaemonStatus, classifyEventVerbosity, connectWithRetries, connectionInitEnvelope, decodeMessage, defaultBootstrapFunc, defaultClientFactory, defaultConfig, defaultPoolConfig, disconnectCauseName, disconnectEnvelope, encodeMessage, extractSootheLoopID, extractThinkingStep, fetchConfigSection, fetchLoopHistory, fetchSkillsCatalog, inputMessageForLoop, isCompletionEvent, isDaemonLive, isSubagentProgressEvent, isValidVerbosityLevel, loadConfigFromEnv, newLoopInputMessage, newLoopNewMessage, newLoopSubscribeMessage, newRequestID, notificationEnvelope, parseNamespace, pingEnvelope, pongEnvelope, refreshAuthToken, requestDaemonConfigReload, requestDaemonShutdown, requestEnvelope, shouldShow, splitWirePayload, subscribeEnvelope, unsubscribeEnvelope, validateLoopInputIntentHint, waitDaemonReady, waitLoopStatusWithID, waitSubscriptionConfirmed };
|