@byokit/openclaw 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/CHANGELOG.md +47 -0
  2. package/LICENSE +202 -0
  3. package/README.md +174 -0
  4. package/dist/approvals.d.ts +29 -0
  5. package/dist/approvals.js +200 -0
  6. package/dist/bridge.d.ts +78 -0
  7. package/dist/bridge.js +345 -0
  8. package/dist/classify.d.ts +4 -0
  9. package/dist/classify.js +14 -0
  10. package/dist/config.d.ts +13 -0
  11. package/dist/config.js +74 -0
  12. package/dist/constants.d.ts +3 -0
  13. package/dist/constants.js +13 -0
  14. package/dist/device.d.ts +63 -0
  15. package/dist/device.js +192 -0
  16. package/dist/engine.d.ts +43 -0
  17. package/dist/engine.js +212 -0
  18. package/dist/generated/events.d.ts +61 -0
  19. package/dist/generated/events.js +1 -0
  20. package/dist/generated/methods.d.ts +2368 -0
  21. package/dist/generated/methods.js +1 -0
  22. package/dist/generated/params.d.ts +1717 -0
  23. package/dist/generated/params.js +5 -0
  24. package/dist/generated/report.json +1356 -0
  25. package/dist/index.d.ts +4 -0
  26. package/dist/index.js +5 -0
  27. package/dist/kit.d.ts +108 -0
  28. package/dist/kit.js +655 -0
  29. package/dist/link.d.ts +24 -0
  30. package/dist/link.js +273 -0
  31. package/dist/members.d.ts +11 -0
  32. package/dist/members.js +23 -0
  33. package/dist/migrate.d.ts +22 -0
  34. package/dist/migrate.js +118 -0
  35. package/dist/notices.d.ts +9 -0
  36. package/dist/notices.js +75 -0
  37. package/dist/routes.d.ts +9 -0
  38. package/dist/routes.js +15 -0
  39. package/dist/routes.json +398 -0
  40. package/dist/runs.d.ts +14 -0
  41. package/dist/runs.js +110 -0
  42. package/dist/signin.d.ts +24 -0
  43. package/dist/signin.js +251 -0
  44. package/dist/testing/contract.d.ts +12 -0
  45. package/dist/testing/contract.js +250 -0
  46. package/dist/testing/fake-gateway.d.ts +19 -0
  47. package/dist/testing/fake-gateway.js +378 -0
  48. package/dist/testing/index.d.ts +3 -0
  49. package/dist/testing/index.js +4 -0
  50. package/dist/testing/model-stub.d.ts +29 -0
  51. package/dist/testing/model-stub.js +182 -0
  52. package/dist/transport.d.ts +22 -0
  53. package/dist/transport.js +94 -0
  54. package/dist/types.d.ts +125 -0
  55. package/dist/types.js +2 -0
  56. package/dist/words.d.ts +12 -0
  57. package/dist/words.js +26 -0
  58. package/dist/words.json +20 -0
  59. package/engine/package-lock.json +4680 -0
  60. package/engine/package.json +1 -0
  61. package/package.json +68 -0
  62. package/plugin/index.js +183 -0
  63. package/plugin/package.json +1 -0
  64. package/policy/policy.mjs +197 -0
@@ -0,0 +1,398 @@
1
+ [
2
+ {
3
+ "choice": "openai",
4
+ "provider": "openai",
5
+ "plugin": "openai",
6
+ "billing": "subscription",
7
+ "via": "browser",
8
+ "prerequisite": null,
9
+ "offer": true,
10
+ "reason": "ChatGPT/Codex subscription sign-in: the engine writes the redirect to the app's callback port.",
11
+ "source": "dist/provider-contract-api-*.js (2026.8.1)"
12
+ },
13
+ {
14
+ "choice": "openai-device-code",
15
+ "provider": "openai",
16
+ "plugin": "openai",
17
+ "billing": "subscription",
18
+ "via": "code",
19
+ "prerequisite": null,
20
+ "offer": true,
21
+ "reason": "ChatGPT subscription sign-in by device code: the code is shown, no browser on this computer needed.",
22
+ "source": "dist/provider-contract-api-*.js (2026.8.1)"
23
+ },
24
+ {
25
+ "choice": "xai-oauth",
26
+ "provider": "xai",
27
+ "plugin": "xai",
28
+ "billing": "subscription",
29
+ "via": "code",
30
+ "prerequisite": null,
31
+ "offer": true,
32
+ "reason": "Grok subscription sign-in through the engine's own wizard.",
33
+ "source": "dist/extensions/xai/openclaw.plugin.json (2026.8.1)"
34
+ },
35
+ {
36
+ "choice": "github-copilot",
37
+ "provider": "github-copilot",
38
+ "plugin": "github-copilot",
39
+ "billing": "subscription",
40
+ "via": "code",
41
+ "prerequisite": null,
42
+ "offer": true,
43
+ "reason": "GitHub Copilot subscription sign-in; the login stays in the engine's own folder.",
44
+ "source": "dist/extensions/github-copilot/openclaw.plugin.json (2026.8.1)"
45
+ },
46
+ {
47
+ "choice": "github-copilot-enterprise",
48
+ "provider": "github-copilot",
49
+ "plugin": "github-copilot",
50
+ "billing": "subscription",
51
+ "via": "code",
52
+ "prerequisite": null,
53
+ "offer": true,
54
+ "reason": "GitHub Copilot Enterprise sign-in; the login stays in the engine's own folder.",
55
+ "source": "dist/extensions/github-copilot/openclaw.plugin.json (2026.8.1)"
56
+ },
57
+ {
58
+ "choice": "minimax-global-oauth",
59
+ "provider": "minimax",
60
+ "plugin": "minimax",
61
+ "billing": "subscription",
62
+ "via": "code",
63
+ "prerequisite": null,
64
+ "offer": true,
65
+ "reason": "MiniMax subscription sign-in (global endpoint).",
66
+ "source": "dist/extensions/minimax/openclaw.plugin.json (2026.8.1)"
67
+ },
68
+ {
69
+ "choice": "minimax-cn-oauth",
70
+ "provider": "minimax",
71
+ "plugin": "minimax",
72
+ "billing": "subscription",
73
+ "via": "code",
74
+ "prerequisite": null,
75
+ "offer": true,
76
+ "reason": "MiniMax subscription sign-in (CN endpoint).",
77
+ "source": "dist/extensions/minimax/openclaw.plugin.json (2026.8.1)"
78
+ },
79
+ {
80
+ "choice": "openrouter-oauth",
81
+ "provider": "openrouter",
82
+ "plugin": "openrouter",
83
+ "billing": "api",
84
+ "via": "browser",
85
+ "prerequisite": null,
86
+ "offer": false,
87
+ "reason": "API billing, not a subscription; upstream OAuth yields a credit-billed key.",
88
+ "source": "dist/extensions/openrouter/openclaw.plugin.json (2026.8.1)"
89
+ },
90
+ {
91
+ "choice": "xai-device-code",
92
+ "provider": "xai",
93
+ "plugin": "xai",
94
+ "billing": "subscription",
95
+ "via": "code",
96
+ "prerequisite": null,
97
+ "offer": false,
98
+ "reason": "Compatibility alias the Gateway does not offer; use xai-oauth.",
99
+ "source": "dist/extensions/xai/openclaw.plugin.json (2026.8.1)"
100
+ },
101
+ {
102
+ "choice": "alibaba-model-studio-api-key",
103
+ "provider": "alibaba",
104
+ "plugin": "alibaba",
105
+ "billing": "api",
106
+ "via": "browser",
107
+ "prerequisite": null,
108
+ "offer": false,
109
+ "reason": "API billing, not a subscription; shown only when an app asks.",
110
+ "source": "dist/extensions/alibaba/openclaw.plugin.json (2026.8.1)"
111
+ },
112
+ {
113
+ "choice": "anthropic-cli",
114
+ "provider": "anthropic",
115
+ "plugin": "anthropic",
116
+ "billing": "subscription",
117
+ "via": "browser",
118
+ "prerequisite": "the Claude CLI, signed in inside the engine's own folder",
119
+ "offer": false,
120
+ "reason": "byokit never adds Claude plan sign-in",
121
+ "source": "dist/extensions/anthropic/openclaw.plugin.json (2026.8.1)"
122
+ },
123
+ {
124
+ "choice": "apiKey",
125
+ "provider": "anthropic",
126
+ "plugin": "anthropic",
127
+ "billing": "api",
128
+ "via": "browser",
129
+ "prerequisite": null,
130
+ "offer": false,
131
+ "reason": "API billing, not a subscription; never offered (D12): no Anthropic API fallback.",
132
+ "source": "dist/extensions/anthropic/openclaw.plugin.json (2026.8.1)"
133
+ },
134
+ {
135
+ "choice": "clawrouter-api-key",
136
+ "provider": "clawrouter",
137
+ "plugin": "clawrouter",
138
+ "billing": "api",
139
+ "via": "browser",
140
+ "prerequisite": null,
141
+ "offer": false,
142
+ "reason": "API billing, not a subscription; shown only when an app asks.",
143
+ "source": "dist/extensions/clawrouter/openclaw.plugin.json (2026.8.1)"
144
+ },
145
+ {
146
+ "choice": "copilot-proxy",
147
+ "provider": "copilot-proxy",
148
+ "plugin": "copilot-proxy",
149
+ "billing": "local",
150
+ "via": "browser",
151
+ "prerequisite": null,
152
+ "offer": false,
153
+ "reason": "Local runtime on this computer; no account and no billing.",
154
+ "source": "dist/extensions/copilot-proxy/openclaw.plugin.json (2026.8.1)"
155
+ },
156
+ {
157
+ "choice": "custom-api-key",
158
+ "provider": "custom",
159
+ "plugin": "",
160
+ "billing": "api",
161
+ "via": "browser",
162
+ "prerequisite": null,
163
+ "offer": false,
164
+ "reason": "API billing, not a subscription; shown only when an app asks.",
165
+ "source": "dist/auth-choice-options-BLHNSTXX.js (2026.8.1)"
166
+ },
167
+ {
168
+ "choice": "fal-api-key",
169
+ "provider": "fal",
170
+ "plugin": "fal",
171
+ "billing": "api",
172
+ "via": "browser",
173
+ "prerequisite": null,
174
+ "offer": false,
175
+ "reason": "API billing, not a subscription; shown only when an app asks.",
176
+ "source": "dist/extensions/fal/openclaw.plugin.json (2026.8.1)"
177
+ },
178
+ {
179
+ "choice": "gemini-api-key",
180
+ "provider": "google",
181
+ "plugin": "google",
182
+ "billing": "api",
183
+ "via": "browser",
184
+ "prerequisite": null,
185
+ "offer": false,
186
+ "reason": "API billing, not a subscription; shown only when an app asks.",
187
+ "source": "dist/provider-contract-api-*.js (2026.8.1)"
188
+ },
189
+ {
190
+ "choice": "huggingface-api-key",
191
+ "provider": "huggingface",
192
+ "plugin": "huggingface",
193
+ "billing": "api",
194
+ "via": "browser",
195
+ "prerequisite": null,
196
+ "offer": false,
197
+ "reason": "API billing, not a subscription; shown only when an app asks.",
198
+ "source": "dist/extensions/huggingface/openclaw.plugin.json (2026.8.1)"
199
+ },
200
+ {
201
+ "choice": "litellm-api-key",
202
+ "provider": "litellm",
203
+ "plugin": "litellm",
204
+ "billing": "api",
205
+ "via": "browser",
206
+ "prerequisite": null,
207
+ "offer": false,
208
+ "reason": "API billing, not a subscription; shown only when an app asks.",
209
+ "source": "dist/extensions/litellm/openclaw.plugin.json (2026.8.1)"
210
+ },
211
+ {
212
+ "choice": "lmstudio",
213
+ "provider": "lmstudio",
214
+ "plugin": "lmstudio",
215
+ "billing": "local",
216
+ "via": "browser",
217
+ "prerequisite": null,
218
+ "offer": false,
219
+ "reason": "Local runtime on this computer; no account and no billing.",
220
+ "source": "dist/extensions/lmstudio/openclaw.plugin.json (2026.8.1)"
221
+ },
222
+ {
223
+ "choice": "microsoft-foundry-apikey",
224
+ "provider": "microsoft-foundry",
225
+ "plugin": "microsoft-foundry",
226
+ "billing": "api",
227
+ "via": "browser",
228
+ "prerequisite": null,
229
+ "offer": false,
230
+ "reason": "API billing, not a subscription; shown only when an app asks.",
231
+ "source": "dist/extensions/microsoft-foundry/openclaw.plugin.json (2026.8.1)"
232
+ },
233
+ {
234
+ "choice": "microsoft-foundry-entra",
235
+ "provider": "microsoft-foundry",
236
+ "plugin": "microsoft-foundry",
237
+ "billing": "api",
238
+ "via": "browser",
239
+ "prerequisite": null,
240
+ "offer": false,
241
+ "reason": "API billing, not a subscription; shown only when an app asks.",
242
+ "source": "dist/extensions/microsoft-foundry/openclaw.plugin.json (2026.8.1)"
243
+ },
244
+ {
245
+ "choice": "minimax-cn-api",
246
+ "provider": "minimax",
247
+ "plugin": "minimax",
248
+ "billing": "api",
249
+ "via": "browser",
250
+ "prerequisite": null,
251
+ "offer": false,
252
+ "reason": "API billing, not a subscription; shown only when an app asks.",
253
+ "source": "dist/extensions/minimax/openclaw.plugin.json (2026.8.1)"
254
+ },
255
+ {
256
+ "choice": "minimax-global-api",
257
+ "provider": "minimax",
258
+ "plugin": "minimax",
259
+ "billing": "api",
260
+ "via": "browser",
261
+ "prerequisite": null,
262
+ "offer": false,
263
+ "reason": "API billing, not a subscription; shown only when an app asks.",
264
+ "source": "dist/extensions/minimax/openclaw.plugin.json (2026.8.1)"
265
+ },
266
+ {
267
+ "choice": "nvidia-api-key",
268
+ "provider": "nvidia",
269
+ "plugin": "nvidia",
270
+ "billing": "api",
271
+ "via": "browser",
272
+ "prerequisite": null,
273
+ "offer": false,
274
+ "reason": "API billing, not a subscription; shown only when an app asks.",
275
+ "source": "dist/extensions/nvidia/openclaw.plugin.json (2026.8.1)"
276
+ },
277
+ {
278
+ "choice": "ollama",
279
+ "provider": "ollama",
280
+ "plugin": "ollama",
281
+ "billing": "local",
282
+ "via": "browser",
283
+ "prerequisite": null,
284
+ "offer": false,
285
+ "reason": "Local runtime on this computer; no account and no billing.",
286
+ "source": "dist/extensions/ollama/openclaw.plugin.json (2026.8.1)"
287
+ },
288
+ {
289
+ "choice": "ollama-cloud",
290
+ "provider": "ollama-cloud",
291
+ "plugin": "ollama",
292
+ "billing": "api",
293
+ "via": "browser",
294
+ "prerequisite": null,
295
+ "offer": false,
296
+ "reason": "API billing, not a subscription; shown only when an app asks.",
297
+ "source": "dist/extensions/ollama/openclaw.plugin.json (2026.8.1)"
298
+ },
299
+ {
300
+ "choice": "openai-api-key",
301
+ "provider": "openai",
302
+ "plugin": "openai",
303
+ "billing": "api",
304
+ "via": "browser",
305
+ "prerequisite": null,
306
+ "offer": false,
307
+ "reason": "API billing, not a subscription; shown only when an app asks.",
308
+ "source": "dist/provider-contract-api-*.js (2026.8.1)"
309
+ },
310
+ {
311
+ "choice": "opencode-go",
312
+ "provider": "opencode-go",
313
+ "plugin": "opencode-go",
314
+ "billing": "api",
315
+ "via": "browser",
316
+ "prerequisite": null,
317
+ "offer": false,
318
+ "reason": "API billing, not a subscription; shown only when an app asks.",
319
+ "source": "dist/extensions/opencode-go/openclaw.plugin.json (2026.8.1)"
320
+ },
321
+ {
322
+ "choice": "openrouter-api-key",
323
+ "provider": "openrouter",
324
+ "plugin": "openrouter",
325
+ "billing": "api",
326
+ "via": "browser",
327
+ "prerequisite": null,
328
+ "offer": false,
329
+ "reason": "API billing, not a subscription; shown only when an app asks.",
330
+ "source": "dist/extensions/openrouter/openclaw.plugin.json (2026.8.1)"
331
+ },
332
+ {
333
+ "choice": "runway-api-key",
334
+ "provider": "runway",
335
+ "plugin": "runway",
336
+ "billing": "api",
337
+ "via": "browser",
338
+ "prerequisite": null,
339
+ "offer": false,
340
+ "reason": "API billing, not a subscription; shown only when an app asks.",
341
+ "source": "dist/extensions/runway/openclaw.plugin.json (2026.8.1)"
342
+ },
343
+ {
344
+ "choice": "setup-token",
345
+ "provider": "anthropic",
346
+ "plugin": "anthropic",
347
+ "billing": "subscription",
348
+ "via": "browser",
349
+ "prerequisite": null,
350
+ "offer": false,
351
+ "reason": "byokit never adds Claude plan sign-in",
352
+ "source": "dist/extensions/anthropic/openclaw.plugin.json (2026.8.1)"
353
+ },
354
+ {
355
+ "choice": "sglang",
356
+ "provider": "sglang",
357
+ "plugin": "sglang",
358
+ "billing": "local",
359
+ "via": "browser",
360
+ "prerequisite": null,
361
+ "offer": false,
362
+ "reason": "Local runtime on this computer; no account and no billing.",
363
+ "source": "dist/extensions/sglang/openclaw.plugin.json (2026.8.1)"
364
+ },
365
+ {
366
+ "choice": "together-api-key",
367
+ "provider": "together",
368
+ "plugin": "together",
369
+ "billing": "api",
370
+ "via": "browser",
371
+ "prerequisite": null,
372
+ "offer": false,
373
+ "reason": "API billing, not a subscription; shown only when an app asks.",
374
+ "source": "dist/extensions/together/openclaw.plugin.json (2026.8.1)"
375
+ },
376
+ {
377
+ "choice": "vllm",
378
+ "provider": "vllm",
379
+ "plugin": "vllm",
380
+ "billing": "local",
381
+ "via": "browser",
382
+ "prerequisite": null,
383
+ "offer": false,
384
+ "reason": "Local runtime on this computer; no account and no billing.",
385
+ "source": "dist/extensions/vllm/openclaw.plugin.json (2026.8.1)"
386
+ },
387
+ {
388
+ "choice": "xai-api-key",
389
+ "provider": "xai",
390
+ "plugin": "xai",
391
+ "billing": "api",
392
+ "via": "browser",
393
+ "prerequisite": null,
394
+ "offer": false,
395
+ "reason": "API billing, not a subscription; shown only when an app asks.",
396
+ "source": "dist/extensions/xai/openclaw.plugin.json (2026.8.1)"
397
+ }
398
+ ]
package/dist/runs.d.ts ADDED
@@ -0,0 +1,14 @@
1
+ import type { Bridge } from './bridge.ts';
2
+ import type { GatewayTransport, Member, RunEnd, RunEvent, RunSpec } from './types.ts';
3
+ export declare function createRuns(ctx: {
4
+ request: GatewayTransport['request'];
5
+ onEvent: GatewayTransport['onEvent'];
6
+ ensure(member: Member): Promise<{
7
+ agentId: string;
8
+ }>;
9
+ bridge: Pick<Bridge, 'register' | 'unregister'>;
10
+ }): {
11
+ run(spec: RunSpec, on?: (e: RunEvent) => void): Promise<RunEnd>;
12
+ steer(k: string, t: string): Promise<void>;
13
+ abort(k: string): Promise<void>;
14
+ };
package/dist/runs.js ADDED
@@ -0,0 +1,110 @@
1
+ // Runs: one Gateway run per spec, streamed through typed events, ending in a classified RunEnd (5.8, O8).
2
+ import { randomUUID } from 'node:crypto';
3
+ import { classify } from "./classify.js";
4
+ // The gateway gives up on a silent run after an hour; we wait ten minutes longer for the reply frame itself.
5
+ const WAIT_MS = 3_600_000;
6
+ const WAIT_CLIENT_MS = 3_610_000;
7
+ const USABLE = new Set(['ok', 'expiring', 'static']);
8
+ const usable = (row) => typeof row === 'string'
9
+ || (Array.isArray(row.profiles) && row.profiles.length > 0 ? row.profiles.some((p) => USABLE.has(String(p?.status)))
10
+ : row.status === undefined || USABLE.has(String(row.status)));
11
+ /**
12
+ * The account a run names, `provider/model`, split for the `agent` request's per-run `provider`/`model` override.
13
+ * Refused before any request when malformed or when it carries an `@profile` pin: the pin only reaches the engine as
14
+ * a session preference it may rotate away from (docs/runtime-kits.md 5.8), so the kit never sends one.
15
+ */
16
+ function account(model) {
17
+ const at = model.indexOf('/');
18
+ if (at <= 0 || at === model.length - 1 || /[\s@]/.test(model))
19
+ throw new Error(`refused: "${model}" is not a provider/model reference`);
20
+ return { provider: model.slice(0, at).toLowerCase(), model: model.slice(at + 1) }; // the engine lowercases ids
21
+ }
22
+ export function createRuns(ctx) {
23
+ const run = async (spec, on) => {
24
+ // Member boundary first: a member never speaks in another member's session, refused before any request.
25
+ if (!spec.sessionKey.startsWith(`agent:${spec.member}:`))
26
+ throw new Error(`refused: "${spec.sessionKey}" is not a session of member "${spec.member}"`);
27
+ const picked = spec.model === undefined ? undefined : account(spec.model);
28
+ const { agentId } = await ctx.ensure(spec.member);
29
+ const registered = spec.register !== false;
30
+ if (registered)
31
+ ctx.bridge.register({ sessionKey: spec.sessionKey, member: spec.member });
32
+ let last = '';
33
+ let runId = ''; // gateway events for other runs carry a real runId and never match the empty one
34
+ let ended = false;
35
+ // The engine flags an aborted run on its lifecycle end event; the wait receipt itself only says
36
+ // `status: 'error', stopReason: 'rpc'` (O11), so the flag is what maps the receipt to aborted.
37
+ let abortedByEngine = false;
38
+ const unsubscribe = ctx.onEvent((e) => {
39
+ if (ended || e.event !== 'agent')
40
+ return;
41
+ const p = e.payload;
42
+ if (!p || p.runId !== runId)
43
+ return;
44
+ if (p.stream === 'lifecycle' && p.data?.phase === 'end'
45
+ && p.data.aborted === true)
46
+ abortedByEngine = true;
47
+ if (p.stream === 'assistant' && typeof p.data?.text === 'string') {
48
+ last = p.data.text;
49
+ on?.({ type: 'text', text: p.data.text });
50
+ }
51
+ else if (p.stream === 'tool' && typeof p.data?.name === 'string') {
52
+ // The real engine marks completion `phase: 'result'` (O11); anything but `start` ends the pair.
53
+ on?.({ type: 'tool', name: p.data.name, phase: p.data.phase === 'start' ? 'start' : 'end' });
54
+ }
55
+ });
56
+ try {
57
+ if (picked) {
58
+ // The picked account must be the one called: check it is signed in for this member before the run, since
59
+ // the engine would otherwise fail the run only after admitting it. An explicit provider/model is strict on
60
+ // the pinned engine (never another provider or model), so this check plus the override is the guarantee.
61
+ const status = (refresh) => ctx.request('models.authStatus', { agentId, ...(refresh ? { refresh: true } : {}) });
62
+ let auth = await status(false);
63
+ if (auth.unavailable)
64
+ auth = await status(true); // no prepared snapshot yet: build it once
65
+ if (auth.unavailable)
66
+ return { ok: false, kind: 'other', message: String(auth.unavailable.message ?? 'account status unavailable') };
67
+ const row = (auth.providers ?? []).find((e) => (typeof e === 'string' ? e : e?.provider) === picked.provider);
68
+ if (!row || !usable(row))
69
+ return { ok: false, kind: 'signed-out', message: `${picked.provider} is not signed in for ${spec.member}` };
70
+ }
71
+ const started = await ctx.request('agent', {
72
+ agentId,
73
+ sessionKey: spec.sessionKey,
74
+ message: spec.message,
75
+ idempotencyKey: randomUUID(),
76
+ ...(picked ?? {}),
77
+ ...(spec.system ? { extraSystemPrompt: spec.system } : {}),
78
+ ...(spec.images ? { attachments: spec.images.map((image) => ({ mimeType: image.mimeType, content: image.data })) } : {}),
79
+ ...(spec.thinking ? { thinking: spec.thinking } : {}),
80
+ });
81
+ runId = started.runId;
82
+ const result = await ctx.request('agent.wait', { runId, timeoutMs: WAIT_MS }, { timeoutMs: WAIT_CLIENT_MS });
83
+ if (result.status === 'ok') {
84
+ const text = typeof result.terminalReply?.text === 'string' ? result.terminalReply.text : last;
85
+ on?.({ type: 'text', text }); // the final cumulative text
86
+ return { ok: true, text };
87
+ }
88
+ if (result.stopReason === 'aborted' || (abortedByEngine && result.status !== 'ok'))
89
+ return { ok: false, aborted: true };
90
+ const message = typeof result.error === 'string' ? result.error
91
+ : typeof result.message === 'string' ? result.message : '';
92
+ return { ok: false, ...classify(message), message };
93
+ }
94
+ catch (error) {
95
+ const message = error instanceof Error ? error.message : String(error);
96
+ return { ok: false, ...classify(message), message };
97
+ }
98
+ finally {
99
+ ended = true;
100
+ unsubscribe();
101
+ if (registered)
102
+ ctx.bridge.unregister(spec.sessionKey);
103
+ }
104
+ };
105
+ return {
106
+ run,
107
+ steer: (k, t) => ctx.request('sessions.steer', { sessionKey: k, message: t }),
108
+ abort: (k) => ctx.request('chat.abort', { sessionKey: k }),
109
+ };
110
+ }
@@ -0,0 +1,24 @@
1
+ import type { GatewayTransport, Member, SignInView } from './types.ts';
2
+ export type SignInCtx = {
3
+ request: GatewayTransport['request'];
4
+ ensure(member: Member): Promise<{
5
+ agentId: string;
6
+ }>;
7
+ callbackPort: number;
8
+ };
9
+ /**
10
+ * Drive the engine's provider-owned login. `on` sees every view the person watches; `done` resolves once, and
11
+ * `paste` hands a returned browser address to a waiting wizard text step. Every exit short of done cancels this
12
+ * session and its callback listener only.
13
+ */
14
+ export declare function signIn(ctx: SignInCtx, member: Member, o: {
15
+ authChoice: string;
16
+ via?: 'browser' | 'code';
17
+ }, on: (v: SignInView) => void): {
18
+ paste(text: string): void;
19
+ cancel(): void;
20
+ done: Promise<SignInView>;
21
+ };
22
+ /** The providers this member's engine reports as signed in, from `models.authStatus` (a string or `{ provider }`). */
23
+ export declare function providers(ctx: SignInCtx, member: Member, refresh?: boolean): Promise<string[]>;
24
+ export declare function signOut(ctx: SignInCtx, member: Member, provider: string): Promise<void>;