@corenel/harness 0.19.0 → 0.21.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chat/engine.d.ts +47 -0
- package/dist/chat/engine.d.ts.map +1 -0
- package/dist/chat/engine.js +803 -0
- package/dist/chat/engine.js.map +1 -0
- package/dist/chat/events.d.ts +5 -0
- package/dist/chat/events.d.ts.map +1 -0
- package/dist/chat/events.js +100 -0
- package/dist/chat/events.js.map +1 -0
- package/dist/chat/index.d.ts +9 -0
- package/dist/chat/index.d.ts.map +1 -0
- package/dist/chat/index.js +9 -0
- package/dist/chat/index.js.map +1 -0
- package/dist/chat/liveFold.d.ts +10 -0
- package/dist/chat/liveFold.d.ts.map +1 -0
- package/dist/chat/liveFold.js +31 -0
- package/dist/chat/liveFold.js.map +1 -0
- package/dist/chat/messages.d.ts +20 -0
- package/dist/chat/messages.d.ts.map +1 -0
- package/dist/chat/messages.js +56 -0
- package/dist/chat/messages.js.map +1 -0
- package/dist/chat/persist.d.ts +39 -0
- package/dist/chat/persist.d.ts.map +1 -0
- package/dist/chat/persist.js +107 -0
- package/dist/chat/persist.js.map +1 -0
- package/dist/chat/runWatchdog.d.ts +21 -0
- package/dist/chat/runWatchdog.d.ts.map +1 -0
- package/dist/chat/runWatchdog.js +92 -0
- package/dist/chat/runWatchdog.js.map +1 -0
- package/dist/chat/stitch.d.ts +26 -0
- package/dist/chat/stitch.d.ts.map +1 -0
- package/dist/chat/stitch.js +40 -0
- package/dist/chat/stitch.js.map +1 -0
- package/dist/chat/types.d.ts +163 -0
- package/dist/chat/types.d.ts.map +1 -0
- package/dist/chat/types.js +2 -0
- package/dist/chat/types.js.map +1 -0
- package/dist/core/loop.d.ts.map +1 -1
- package/dist/core/loop.js +50 -15
- package/dist/core/loop.js.map +1 -1
- package/dist/core/spawn.d.ts +17 -0
- package/dist/core/spawn.d.ts.map +1 -1
- package/dist/core/spawn.js +48 -14
- package/dist/core/spawn.js.map +1 -1
- package/dist/fileSchema.js +1 -1
- package/dist/guardrail/builtins.d.ts.map +1 -1
- package/dist/guardrail/builtins.js +11 -6
- package/dist/guardrail/builtins.js.map +1 -1
- package/dist/guardrail/glob.d.ts +1 -2
- package/dist/guardrail/glob.d.ts.map +1 -1
- package/dist/guardrail/glob.js +4 -29
- package/dist/guardrail/glob.js.map +1 -1
- package/dist/guardrail/guardrail.d.ts +8 -0
- package/dist/guardrail/guardrail.d.ts.map +1 -1
- package/dist/guardrail/guardrail.js +12 -0
- package/dist/guardrail/guardrail.js.map +1 -1
- package/dist/guardrail/index.d.ts +1 -1
- package/dist/guardrail/index.d.ts.map +1 -1
- package/dist/guardrail/index.js +1 -1
- package/dist/guardrail/index.js.map +1 -1
- package/dist/guardrail/serialize.d.ts.map +1 -1
- package/dist/guardrail/serialize.js +3 -0
- package/dist/guardrail/serialize.js.map +1 -1
- package/dist/guardrail/validate.d.ts.map +1 -1
- package/dist/guardrail/validate.js +4 -0
- package/dist/guardrail/validate.js.map +1 -1
- package/dist/install/lockfile.d.ts +25 -5
- package/dist/install/lockfile.d.ts.map +1 -1
- package/dist/install/lockfile.js +60 -4
- package/dist/install/lockfile.js.map +1 -1
- package/dist/install/nameEntries.d.ts +28 -0
- package/dist/install/nameEntries.d.ts.map +1 -0
- package/dist/install/nameEntries.js +198 -0
- package/dist/install/nameEntries.js.map +1 -0
- package/dist/install/pinRefusal.d.ts +4 -0
- package/dist/install/pinRefusal.d.ts.map +1 -0
- package/dist/install/pinRefusal.js +19 -0
- package/dist/install/pinRefusal.js.map +1 -0
- package/dist/install/requirements.d.ts +7 -0
- package/dist/install/requirements.d.ts.map +1 -0
- package/dist/install/requirements.js +23 -0
- package/dist/install/requirements.js.map +1 -0
- package/dist/orchestrator/sidecarTools.d.ts.map +1 -1
- package/dist/orchestrator/sidecarTools.js +8 -4
- package/dist/orchestrator/sidecarTools.js.map +1 -1
- package/dist/prompts/fitProject.d.ts +6 -0
- package/dist/prompts/fitProject.d.ts.map +1 -0
- package/dist/prompts/fitProject.js +6 -0
- package/dist/prompts/fitProject.js.map +1 -0
- package/dist/prompts/library/defaults.generated.js +7 -7
- package/dist/prompts/library/defaults.generated.js.map +1 -1
- package/dist/prompts/library/index.d.ts +2 -1
- package/dist/prompts/library/index.d.ts.map +1 -1
- package/dist/prompts/library/index.js +11 -16
- package/dist/prompts/library/index.js.map +1 -1
- package/dist/providers/egressGuard.d.ts +17 -0
- package/dist/providers/egressGuard.d.ts.map +1 -0
- package/dist/providers/egressGuard.js +26 -0
- package/dist/providers/egressGuard.js.map +1 -0
- package/dist/providers/gateway.d.ts +34 -0
- package/dist/providers/gateway.d.ts.map +1 -1
- package/dist/providers/gateway.js +43 -2
- package/dist/providers/gateway.js.map +1 -1
- package/dist/sidecar/askUserBroker.d.ts +40 -0
- package/dist/sidecar/askUserBroker.d.ts.map +1 -0
- package/dist/sidecar/askUserBroker.js +103 -0
- package/dist/sidecar/askUserBroker.js.map +1 -0
- package/dist/sidecar/fleetJwe.d.ts +25 -0
- package/dist/sidecar/fleetJwe.d.ts.map +1 -0
- package/dist/sidecar/fleetJwe.js +115 -0
- package/dist/sidecar/fleetJwe.js.map +1 -0
- package/dist/sidecar/fleetJws.d.ts +15 -0
- package/dist/sidecar/fleetJws.d.ts.map +1 -0
- package/dist/sidecar/fleetJws.js +47 -0
- package/dist/sidecar/fleetJws.js.map +1 -0
- package/dist/sidecar/host.d.ts +81 -1
- package/dist/sidecar/host.d.ts.map +1 -1
- package/dist/sidecar/host.js +227 -6
- package/dist/sidecar/host.js.map +1 -1
- package/dist/sidecar/identity.d.ts +9 -0
- package/dist/sidecar/identity.d.ts.map +1 -1
- package/dist/sidecar/memberGate.d.ts.map +1 -1
- package/dist/sidecar/memberGate.js +5 -0
- package/dist/sidecar/memberGate.js.map +1 -1
- package/dist/sidecar/server.d.ts +61 -10
- package/dist/sidecar/server.d.ts.map +1 -1
- package/dist/sidecar/server.js +592 -15
- package/dist/sidecar/server.js.map +1 -1
- package/dist/skills.d.ts +18 -0
- package/dist/skills.d.ts.map +1 -1
- package/dist/skills.js +93 -12
- package/dist/skills.js.map +1 -1
- package/dist/systemParts.d.ts +0 -1
- package/dist/systemParts.d.ts.map +1 -1
- package/dist/systemParts.js +6 -2
- package/dist/systemParts.js.map +1 -1
- package/dist/todos.d.ts +8 -0
- package/dist/todos.d.ts.map +1 -1
- package/dist/todos.js +21 -17
- package/dist/todos.js.map +1 -1
- package/dist/tools/builtins.d.ts +8 -0
- package/dist/tools/builtins.d.ts.map +1 -1
- package/dist/tools/builtins.js +21 -1
- package/dist/tools/builtins.js.map +1 -1
- package/dist/tools/namespaces.d.ts +8 -0
- package/dist/tools/namespaces.d.ts.map +1 -1
- package/dist/tools/namespaces.js +18 -0
- package/dist/tools/namespaces.js.map +1 -1
- package/dist/tools/skillTool.d.ts.map +1 -1
- package/dist/tools/skillTool.js +22 -1
- package/dist/tools/skillTool.js.map +1 -1
- package/dist/tools/toolFacts.d.ts +9 -0
- package/dist/tools/toolFacts.d.ts.map +1 -0
- package/dist/tools/toolFacts.js +19 -0
- package/dist/tools/toolFacts.js.map +1 -0
- package/dist/tools/toolSearch.d.ts +25 -6
- package/dist/tools/toolSearch.d.ts.map +1 -1
- package/dist/tools/toolSearch.js +62 -14
- package/dist/tools/toolSearch.js.map +1 -1
- package/dist/tools/workflowTool.d.ts +34 -0
- package/dist/tools/workflowTool.d.ts.map +1 -0
- package/dist/tools/workflowTool.js +122 -0
- package/dist/tools/workflowTool.js.map +1 -0
- package/package.json +8 -4
package/dist/sidecar/host.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import { CHAT_FEATURE, CHAT_ID_RE } from '@corenel/protocol';
|
|
1
2
|
import { asEcPublicJwk, jwkThumbprint, verifySignature, randomToken, serverProofPayload, clientProofPayload, parseEnrollmentCode, bytesToB64url, codeProof, codeHash, } from './deviceKeys.js';
|
|
2
3
|
import { capabilityMissingMessage } from './hostCapability.js';
|
|
3
|
-
import { SIDECAR_PROTOCOL, HOST_METHODS, errMessage, RUN_TASK_FEATURE, RUN_PLAN_FEATURE, CREW_DEPLOY_FEATURE, DEVICES_FEATURE, AGENT_ACCESS_FEATURE, AGENT_RUNS_FEATURE, PEER_LINKS_FEATURE, CHILD_EVENTS_FEATURE, PEER_DAEMON_FEATURE, TEAM_MEMBERS_FEATURE, SPEECH_FEATURE, encodePcm16, isClerkOrgId, WORKFLOW_RUNNER_FEATURE, readWorkflowOkReply, readWorkflowResultsListReply, readWorkflowResultsTakeReply, } from '@corenel/protocol';
|
|
4
|
+
import { SIDECAR_PROTOCOL, HOST_METHODS, errMessage, RUN_TASK_FEATURE, RUN_PLAN_FEATURE, CREW_DEPLOY_FEATURE, DEVICES_FEATURE, AGENT_ACCESS_FEATURE, AGENT_RUNS_FEATURE, PEER_LINKS_FEATURE, CHILD_EVENTS_FEATURE, PEER_DAEMON_FEATURE, TEAM_MEMBERS_FEATURE, SPEECH_FEATURE, encodePcm16, FLEET_LOGINS_DENIED, SIGN_IN_PAUSED_DENIED, isClerkOrgId, WORKFLOW_RUNNER_FEATURE, readWorkflowOkReply, readWorkflowResultsListReply, readWorkflowResultsTakeReply, } from '@corenel/protocol';
|
|
4
5
|
const NO_WORKFLOWS = 'this daemon does not run workflows';
|
|
5
6
|
const WRONG_REPLY = 'the daemon answered with the wrong reply';
|
|
6
7
|
/** A reply that failed its check (protocol workflowWire.ts readers). */
|
|
@@ -69,6 +70,19 @@ export function isSidecarAccountRefusal(e) {
|
|
|
69
70
|
const msg = e instanceof Error ? e.message : String(e);
|
|
70
71
|
return msg.startsWith(SIDECAR_NOT_ADMITTED);
|
|
71
72
|
}
|
|
73
|
+
/** The sidecar refused this ACCOUNT because its fleet policy limits sign-in
|
|
74
|
+
* (slice 4). The device is fine and stays paired; retrying changes nothing
|
|
75
|
+
* until a fleet admin changes the policy. */
|
|
76
|
+
export function isFleetLoginsRefusal(e) {
|
|
77
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
78
|
+
return msg === `${SIDECAR_NOT_ADMITTED}: ${FLEET_LOGINS_DENIED}`;
|
|
79
|
+
}
|
|
80
|
+
/** The sidecar's fleet sign-in is paused for a reason that clears by itself (SIGN_IN_PAUSED_DENIED). The device is
|
|
81
|
+
* fine and stays paired, and unlike every other account refusal a retry is expected to succeed later. */
|
|
82
|
+
export function isSignInPausedRefusal(e) {
|
|
83
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
84
|
+
return msg === `${SIDECAR_NOT_ADMITTED}: ${SIGN_IN_PAUSED_DENIED}`;
|
|
85
|
+
}
|
|
72
86
|
export class SidecarHost {
|
|
73
87
|
constructor(opts) {
|
|
74
88
|
Object.defineProperty(this, "ch", {
|
|
@@ -131,6 +145,51 @@ export class SidecarHost {
|
|
|
131
145
|
writable: true,
|
|
132
146
|
value: new Map()
|
|
133
147
|
});
|
|
148
|
+
/** Daemon chat (Harness Chat Plan 2): run-inject, chat-list and chat-get replies, by request id. */
|
|
149
|
+
Object.defineProperty(this, "chatSeq", {
|
|
150
|
+
enumerable: true,
|
|
151
|
+
configurable: true,
|
|
152
|
+
writable: true,
|
|
153
|
+
value: 0
|
|
154
|
+
});
|
|
155
|
+
Object.defineProperty(this, "injectPending", {
|
|
156
|
+
enumerable: true,
|
|
157
|
+
configurable: true,
|
|
158
|
+
writable: true,
|
|
159
|
+
value: new Map()
|
|
160
|
+
});
|
|
161
|
+
Object.defineProperty(this, "chatListPending", {
|
|
162
|
+
enumerable: true,
|
|
163
|
+
configurable: true,
|
|
164
|
+
writable: true,
|
|
165
|
+
value: new Map()
|
|
166
|
+
});
|
|
167
|
+
Object.defineProperty(this, "chatGetPending", {
|
|
168
|
+
enumerable: true,
|
|
169
|
+
configurable: true,
|
|
170
|
+
writable: true,
|
|
171
|
+
value: new Map()
|
|
172
|
+
});
|
|
173
|
+
/** Chat ask_user prompts not yet answered or resolved, by the daemon's ask id,
|
|
174
|
+
* so a handler registered after one arrived still sees it. */
|
|
175
|
+
Object.defineProperty(this, "askUserOpen", {
|
|
176
|
+
enumerable: true,
|
|
177
|
+
configurable: true,
|
|
178
|
+
writable: true,
|
|
179
|
+
value: new Map()
|
|
180
|
+
});
|
|
181
|
+
Object.defineProperty(this, "askUserHandlers", {
|
|
182
|
+
enumerable: true,
|
|
183
|
+
configurable: true,
|
|
184
|
+
writable: true,
|
|
185
|
+
value: new Set()
|
|
186
|
+
});
|
|
187
|
+
Object.defineProperty(this, "askUserResolvedHandlers", {
|
|
188
|
+
enumerable: true,
|
|
189
|
+
configurable: true,
|
|
190
|
+
writable: true,
|
|
191
|
+
value: new Set()
|
|
192
|
+
});
|
|
134
193
|
Object.defineProperty(this, "acpSeq", {
|
|
135
194
|
enumerable: true,
|
|
136
195
|
configurable: true,
|
|
@@ -854,6 +913,18 @@ export class SidecarHost {
|
|
|
854
913
|
for (const p of this.cancelPending.values())
|
|
855
914
|
p({ ok: false, reason: 'unsupported' });
|
|
856
915
|
this.cancelPending.clear();
|
|
916
|
+
// Same reasoning for an inject: answered, not thrown, so a send during a drop settles.
|
|
917
|
+
for (const p of this.injectPending.values())
|
|
918
|
+
p({ ok: false, reason });
|
|
919
|
+
this.injectPending.clear();
|
|
920
|
+
for (const p of this.chatListPending.values())
|
|
921
|
+
p.reject(new Error(reason));
|
|
922
|
+
this.chatListPending.clear();
|
|
923
|
+
for (const p of this.chatGetPending.values())
|
|
924
|
+
p.reject(new Error(reason));
|
|
925
|
+
this.chatGetPending.clear();
|
|
926
|
+
// The daemon delivers any still-open ask again when the connection comes back.
|
|
927
|
+
this.askUserOpen.clear();
|
|
857
928
|
for (const p of this.acpPending.values())
|
|
858
929
|
p.reject(new Error(reason));
|
|
859
930
|
this.acpPending.clear();
|
|
@@ -1152,10 +1223,14 @@ export class SidecarHost {
|
|
|
1152
1223
|
}
|
|
1153
1224
|
case 'run-accepted': {
|
|
1154
1225
|
const p = this.runPending.get(m.id);
|
|
1155
|
-
if (p)
|
|
1156
|
-
|
|
1226
|
+
if (!p)
|
|
1227
|
+
return;
|
|
1228
|
+
p.runId = m.runId;
|
|
1229
|
+
// Runtime-validated: a conversation id is only ever a chat id.
|
|
1230
|
+
if (typeof m.conversationId === 'string' && CHAT_ID_RE.test(m.conversationId))
|
|
1231
|
+
p.onAccepted?.(m.runId, m.conversationId);
|
|
1232
|
+
else
|
|
1157
1233
|
p.onAccepted?.(m.runId);
|
|
1158
|
-
}
|
|
1159
1234
|
return;
|
|
1160
1235
|
}
|
|
1161
1236
|
case 'event': {
|
|
@@ -1171,7 +1246,10 @@ export class SidecarHost {
|
|
|
1171
1246
|
if (!p)
|
|
1172
1247
|
return;
|
|
1173
1248
|
this.runPending.delete(m.id);
|
|
1174
|
-
p.resolve({
|
|
1249
|
+
p.resolve({
|
|
1250
|
+
runId: m.runId, text: m.text, stopReason: m.stopReason,
|
|
1251
|
+
...(m.outcome === 'done' || m.outcome === 'stopped' ? { outcome: m.outcome } : {}),
|
|
1252
|
+
});
|
|
1175
1253
|
return;
|
|
1176
1254
|
}
|
|
1177
1255
|
case 'run-error': {
|
|
@@ -1179,7 +1257,59 @@ export class SidecarHost {
|
|
|
1179
1257
|
if (!p)
|
|
1180
1258
|
return;
|
|
1181
1259
|
this.runPending.delete(m.id);
|
|
1182
|
-
|
|
1260
|
+
if (p.fail)
|
|
1261
|
+
p.fail(m.error || 'run failed', m.outcome === 'failed' || m.outcome === 'refused' ? m.outcome : undefined);
|
|
1262
|
+
else
|
|
1263
|
+
p.reject(new Error(m.error || 'run failed'));
|
|
1264
|
+
return;
|
|
1265
|
+
}
|
|
1266
|
+
case 'run-inject-result': {
|
|
1267
|
+
const p = this.injectPending.get(m.id);
|
|
1268
|
+
if (!p)
|
|
1269
|
+
return;
|
|
1270
|
+
this.injectPending.delete(m.id);
|
|
1271
|
+
p(m.ok === true ? { ok: true } : { ok: false, ...(typeof m.reason === 'string' ? { reason: m.reason } : {}) });
|
|
1272
|
+
return;
|
|
1273
|
+
}
|
|
1274
|
+
case 'chat-list-result': {
|
|
1275
|
+
const p = this.chatListPending.get(m.id);
|
|
1276
|
+
if (!p)
|
|
1277
|
+
return;
|
|
1278
|
+
this.chatListPending.delete(m.id);
|
|
1279
|
+
if (m.ok)
|
|
1280
|
+
p.resolve(Array.isArray(m.chats) ? m.chats : []);
|
|
1281
|
+
else
|
|
1282
|
+
p.reject(new Error(m.error || 'could not list chats'));
|
|
1283
|
+
return;
|
|
1284
|
+
}
|
|
1285
|
+
case 'chat-get-result': {
|
|
1286
|
+
const p = this.chatGetPending.get(m.id);
|
|
1287
|
+
if (!p)
|
|
1288
|
+
return;
|
|
1289
|
+
this.chatGetPending.delete(m.id);
|
|
1290
|
+
if (m.ok)
|
|
1291
|
+
p.resolve(m.conversation);
|
|
1292
|
+
else
|
|
1293
|
+
p.reject(new Error(m.error || 'could not read the chat'));
|
|
1294
|
+
return;
|
|
1295
|
+
}
|
|
1296
|
+
case 'ask-user': {
|
|
1297
|
+
// Runtime-validated like the rest of what crosses the wire.
|
|
1298
|
+
if (!Number.isSafeInteger(m.id) || typeof m.runId !== 'string' || typeof m.agent !== 'string'
|
|
1299
|
+
|| !Array.isArray(m.questions) || typeof m.deadline !== 'number')
|
|
1300
|
+
return;
|
|
1301
|
+
const ask = { id: m.id, runId: m.runId, agent: m.agent, questions: m.questions, deadline: m.deadline };
|
|
1302
|
+
this.askUserOpen.set(ask.id, ask);
|
|
1303
|
+
for (const h of [...this.askUserHandlers])
|
|
1304
|
+
h(ask);
|
|
1305
|
+
return;
|
|
1306
|
+
}
|
|
1307
|
+
case 'ask-user-resolved': {
|
|
1308
|
+
if (!this.askUserOpen.delete(m.id))
|
|
1309
|
+
return;
|
|
1310
|
+
const by = m.by === 'client' ? 'client' : 'timeout';
|
|
1311
|
+
for (const h of [...this.askUserResolvedHandlers])
|
|
1312
|
+
h({ id: m.id, by });
|
|
1183
1313
|
return;
|
|
1184
1314
|
}
|
|
1185
1315
|
case 'cancel-run-result': {
|
|
@@ -2096,6 +2226,97 @@ export class SidecarHost {
|
|
|
2096
2226
|
this.ch.send({ t: 'cancel-run', id, runId });
|
|
2097
2227
|
});
|
|
2098
2228
|
}
|
|
2229
|
+
/** True when the connected daemon holds chats (Harness Chat Plan 2):
|
|
2230
|
+
* `runChat`, `injectRun`, `listChats`, `getChat` and ask_user prompts. An
|
|
2231
|
+
* older daemon would run a chat turn as a plain one-shot run, so check this
|
|
2232
|
+
* before calling any of them. */
|
|
2233
|
+
supportsChat() { return this.features.includes(CHAT_FEATURE); }
|
|
2234
|
+
/** One turn of a daemon chat. `chat.conversationId` absent starts a new
|
|
2235
|
+
* chat; the daemon mints its id and hands it to `onAccepted` with the run
|
|
2236
|
+
* id. Resolves with how the turn ended, a refused or failed one included
|
|
2237
|
+
* (with `error`); rejects only when the connection drops mid-turn. */
|
|
2238
|
+
runChat(agent, text, chat, onEvent, opts) {
|
|
2239
|
+
const id = ++this.runSeq;
|
|
2240
|
+
return new Promise((resolve, reject) => {
|
|
2241
|
+
let runId = null;
|
|
2242
|
+
let conversationId = chat.conversationId ?? null;
|
|
2243
|
+
this.runPending.set(id, {
|
|
2244
|
+
resolve: (r) => resolve({ runId: r.runId, conversationId, text: r.text, stopReason: r.stopReason, outcome: r.outcome ?? 'done' }),
|
|
2245
|
+
reject,
|
|
2246
|
+
fail: (error, outcome) => resolve({ runId, conversationId, text: '', stopReason: '', outcome: outcome ?? 'failed', error }),
|
|
2247
|
+
onEvent,
|
|
2248
|
+
onAccepted: (rid, cid) => {
|
|
2249
|
+
runId = rid;
|
|
2250
|
+
if (cid !== undefined)
|
|
2251
|
+
conversationId = cid;
|
|
2252
|
+
if (conversationId !== null)
|
|
2253
|
+
opts?.onAccepted?.(rid, conversationId);
|
|
2254
|
+
},
|
|
2255
|
+
});
|
|
2256
|
+
this.ch.send({
|
|
2257
|
+
t: 'run', id, agent, input: text,
|
|
2258
|
+
chat: {
|
|
2259
|
+
...(chat.conversationId !== undefined ? { conversationId: chat.conversationId } : {}),
|
|
2260
|
+
...(chat.maxUsd !== undefined ? { maxUsd: chat.maxUsd } : {}),
|
|
2261
|
+
...(chat.ref !== undefined ? { ref: chat.ref } : {}),
|
|
2262
|
+
},
|
|
2263
|
+
});
|
|
2264
|
+
});
|
|
2265
|
+
}
|
|
2266
|
+
/** Messages typed while a chat turn runs; `hard` interrupts it. Never
|
|
2267
|
+
* rejects: a refusal or a dropped connection answers `ok: false`. */
|
|
2268
|
+
injectRun(runId, messages, hard) {
|
|
2269
|
+
const id = ++this.chatSeq;
|
|
2270
|
+
return new Promise((resolve) => {
|
|
2271
|
+
this.injectPending.set(id, resolve);
|
|
2272
|
+
this.ch.send({ t: 'run-inject', id, runId, messages, hard });
|
|
2273
|
+
});
|
|
2274
|
+
}
|
|
2275
|
+
/** This user's chats with `agent`; the admin may name a `member`. Rejects
|
|
2276
|
+
* with the daemon's refusal. */
|
|
2277
|
+
listChats(agent, opts) {
|
|
2278
|
+
const id = ++this.chatSeq;
|
|
2279
|
+
return new Promise((resolve, reject) => {
|
|
2280
|
+
this.chatListPending.set(id, { resolve, reject });
|
|
2281
|
+
this.ch.send({
|
|
2282
|
+
t: 'chat-list', id, agent,
|
|
2283
|
+
...(opts?.ref !== undefined ? { ref: opts.ref } : {}),
|
|
2284
|
+
...(opts?.member !== undefined ? { member: opts.member } : {}),
|
|
2285
|
+
});
|
|
2286
|
+
});
|
|
2287
|
+
}
|
|
2288
|
+
/** One conversation, to its member or the admin. Rejects with the daemon's
|
|
2289
|
+
* refusal (CHAT_NOT_YOURS, CHAT_NOT_FOUND). */
|
|
2290
|
+
getChat(agent, conversationId, opts) {
|
|
2291
|
+
const id = ++this.chatSeq;
|
|
2292
|
+
return new Promise((resolve, reject) => {
|
|
2293
|
+
this.chatGetPending.set(id, { resolve, reject });
|
|
2294
|
+
this.ch.send({
|
|
2295
|
+
t: 'chat-get', id, agent, conversationId,
|
|
2296
|
+
...(opts?.ref !== undefined ? { ref: opts.ref } : {}),
|
|
2297
|
+
...(opts?.member !== undefined ? { member: opts.member } : {}),
|
|
2298
|
+
});
|
|
2299
|
+
});
|
|
2300
|
+
}
|
|
2301
|
+
/** Chat ask_user prompts for this user. Prompts still open when the handler
|
|
2302
|
+
* is added are handed to it at once. Returns the unsubscribe function. */
|
|
2303
|
+
onAskUser(handler) {
|
|
2304
|
+
this.askUserHandlers.add(handler);
|
|
2305
|
+
for (const ask of [...this.askUserOpen.values()])
|
|
2306
|
+
handler(ask);
|
|
2307
|
+
return () => { this.askUserHandlers.delete(handler); };
|
|
2308
|
+
}
|
|
2309
|
+
/** A prompt was answered on another connection, or timed out: drop it. */
|
|
2310
|
+
onAskUserResolved(handler) {
|
|
2311
|
+
this.askUserResolvedHandlers.add(handler);
|
|
2312
|
+
return () => { this.askUserResolvedHandlers.delete(handler); };
|
|
2313
|
+
}
|
|
2314
|
+
/** Answer prompt `id`; null declines. The first answer from any of this
|
|
2315
|
+
* user's or the admin's connections wins; a late one is ignored. */
|
|
2316
|
+
answerAskUser(id, answers) {
|
|
2317
|
+
this.askUserOpen.delete(id);
|
|
2318
|
+
this.ch.send({ t: 'ask-user-answer', id, answers });
|
|
2319
|
+
}
|
|
2099
2320
|
/** True when the connected sidecar's runner supports cancelling a run. */
|
|
2100
2321
|
supportsRunCancel() { return this.features.includes('run-cancel'); }
|
|
2101
2322
|
/** True when the connected daemon fans a delegated callee's own node events
|