@noodleseed/assistant 1.12.0 → 1.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -0
- package/dist/{chunk-ZPELSHUP.js → chunk-7WXGZJCA.js} +3 -5
- package/dist/chunk-7WXGZJCA.js.map +1 -0
- package/dist/{chunk-KRB2SXFD.js → chunk-RITHSCTD.js} +123 -32
- package/dist/{chunk-KRB2SXFD.js.map → chunk-RITHSCTD.js.map} +1 -1
- package/dist/client.cjs +122 -31
- package/dist/client.cjs.map +1 -1
- package/dist/client.js +1 -1
- package/dist/index.cjs +123 -34
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +2 -2
- package/dist/react/client.cjs +122 -31
- package/dist/react/client.cjs.map +1 -1
- package/dist/react/client.js +1 -1
- package/dist/react.cjs +123 -34
- package/dist/react.cjs.map +1 -1
- package/dist/react.js +2 -2
- package/dist/server.cjs +2 -1
- package/dist/server.cjs.map +1 -1
- package/dist/server.d.cts +4 -0
- package/dist/server.d.ts +4 -0
- package/dist/server.js +2 -1
- package/dist/server.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-ZPELSHUP.js.map +0 -1
package/dist/client.cjs
CHANGED
|
@@ -22643,7 +22643,7 @@ var AssistantChatStateStore = class {
|
|
|
22643
22643
|
this.#writeText(event.data.delta);
|
|
22644
22644
|
return;
|
|
22645
22645
|
case "tool_proposed":
|
|
22646
|
-
this.#writeConfirmation(event.data);
|
|
22646
|
+
this.#writeStandaloneData(() => this.#writeConfirmation(event.data));
|
|
22647
22647
|
return;
|
|
22648
22648
|
case "interaction_proposed":
|
|
22649
22649
|
this.#writeData("confirmation", event.data.id, {
|
|
@@ -22652,10 +22652,12 @@ var AssistantChatStateStore = class {
|
|
|
22652
22652
|
});
|
|
22653
22653
|
return;
|
|
22654
22654
|
case "input_requested":
|
|
22655
|
-
this.#
|
|
22656
|
-
|
|
22657
|
-
|
|
22658
|
-
|
|
22655
|
+
this.#writeStandaloneData(
|
|
22656
|
+
() => this.#writeData("input-request", event.data.id, {
|
|
22657
|
+
...event.data,
|
|
22658
|
+
status: "pending"
|
|
22659
|
+
})
|
|
22660
|
+
);
|
|
22659
22661
|
return;
|
|
22660
22662
|
case "tool_completed":
|
|
22661
22663
|
this.#writeData("tool-result", event.data.id, event.data);
|
|
@@ -22762,6 +22764,12 @@ var AssistantChatStateStore = class {
|
|
|
22762
22764
|
#writeConfirmation(data) {
|
|
22763
22765
|
this.#writeData("confirmation", data.id, { ...data, status: "pending" });
|
|
22764
22766
|
}
|
|
22767
|
+
#writeStandaloneData(write) {
|
|
22768
|
+
const standalone = this.#operation === void 0;
|
|
22769
|
+
if (standalone) this.#startOperation();
|
|
22770
|
+
write();
|
|
22771
|
+
if (standalone) this.#closeOperation("ready");
|
|
22772
|
+
}
|
|
22765
22773
|
#writeData(name21, id, data) {
|
|
22766
22774
|
const operation = this.#operation;
|
|
22767
22775
|
if (!operation || operation.closed) return;
|
|
@@ -23240,6 +23248,7 @@ var DefaultAssistantClient = class {
|
|
|
23240
23248
|
#context;
|
|
23241
23249
|
#modelContext;
|
|
23242
23250
|
#active;
|
|
23251
|
+
#pendingAppInteractions = /* @__PURE__ */ new Map();
|
|
23243
23252
|
constructor(options) {
|
|
23244
23253
|
if (!options.sessionEndpoint) throw new Error("sessionEndpoint is required");
|
|
23245
23254
|
this.#sessionEndpoint = options.sessionEndpoint;
|
|
@@ -23281,6 +23290,7 @@ var DefaultAssistantClient = class {
|
|
|
23281
23290
|
}
|
|
23282
23291
|
await this.#singleFlight(async (signal) => {
|
|
23283
23292
|
await this.#runChatOperation(signal, async () => {
|
|
23293
|
+
const pendingApp = this.#pendingAppInteractions.get(id);
|
|
23284
23294
|
const session = this.#session;
|
|
23285
23295
|
if (!session) {
|
|
23286
23296
|
throw clientError("confirmation_expired", "assistant session is not active", false);
|
|
@@ -23300,32 +23310,67 @@ var DefaultAssistantClient = class {
|
|
|
23300
23310
|
...resolution.action === "accept" && resolution.content !== void 0 ? { content: resolution.content } : {}
|
|
23301
23311
|
} : { id };
|
|
23302
23312
|
this.#emit({ event: "interaction_started", data: { id, action: resolution.action } });
|
|
23303
|
-
|
|
23304
|
-
|
|
23305
|
-
|
|
23306
|
-
|
|
23307
|
-
|
|
23308
|
-
|
|
23309
|
-
|
|
23310
|
-
|
|
23311
|
-
|
|
23312
|
-
|
|
23313
|
-
if (response.status === 401) {
|
|
23314
|
-
this.#session = void 0;
|
|
23315
|
-
this.#emit({ event: "session_expired", data: {} });
|
|
23316
|
-
}
|
|
23317
|
-
if (!response.ok) {
|
|
23318
|
-
const serverCode = await readStableErrorCode(response);
|
|
23319
|
-
const expired = response.status === 401 || response.status === 409;
|
|
23320
|
-
throw clientError(
|
|
23321
|
-
serverCode ?? (expired ? "confirmation_expired" : "confirmation_failed"),
|
|
23322
|
-
`Assistant interaction failed (${response.status})`,
|
|
23323
|
-
false,
|
|
23324
|
-
response.status
|
|
23313
|
+
try {
|
|
23314
|
+
const response = await this.#request(
|
|
23315
|
+
endpoint,
|
|
23316
|
+
{
|
|
23317
|
+
method: "POST",
|
|
23318
|
+
headers: authorizedHeaders(session.token, "text/event-stream"),
|
|
23319
|
+
body: JSON.stringify(body),
|
|
23320
|
+
signal
|
|
23321
|
+
},
|
|
23322
|
+
"confirmation_failed"
|
|
23325
23323
|
);
|
|
23324
|
+
if (response.status === 401) {
|
|
23325
|
+
this.#session = void 0;
|
|
23326
|
+
this.#emit({ event: "session_expired", data: {} });
|
|
23327
|
+
}
|
|
23328
|
+
if (!response.ok) {
|
|
23329
|
+
const serverCode = await readStableErrorCode(response);
|
|
23330
|
+
const expired = response.status === 401 || response.status === 409;
|
|
23331
|
+
throw clientError(
|
|
23332
|
+
serverCode ?? (expired ? "confirmation_expired" : "confirmation_failed"),
|
|
23333
|
+
`Assistant interaction failed (${response.status})`,
|
|
23334
|
+
false,
|
|
23335
|
+
response.status
|
|
23336
|
+
);
|
|
23337
|
+
}
|
|
23338
|
+
let completedResult;
|
|
23339
|
+
let nextInteractionId;
|
|
23340
|
+
await this.#consume(response, (event) => {
|
|
23341
|
+
if (event.event === "tool_completed" && event.data.id === id) {
|
|
23342
|
+
completedResult = event.data.result;
|
|
23343
|
+
}
|
|
23344
|
+
if ((event.event === "tool_proposed" || event.event === "input_requested") && event.data.id !== id) {
|
|
23345
|
+
nextInteractionId = event.data.id;
|
|
23346
|
+
}
|
|
23347
|
+
});
|
|
23348
|
+
this.#emit({ event: "interaction_completed", data: { id, action: resolution.action } });
|
|
23349
|
+
if (pendingApp) {
|
|
23350
|
+
this.#pendingAppInteractions.delete(id);
|
|
23351
|
+
if (nextInteractionId) {
|
|
23352
|
+
this.#pendingAppInteractions.set(nextInteractionId, pendingApp);
|
|
23353
|
+
} else if (resolution.action !== "accept") {
|
|
23354
|
+
pendingApp.resolve(appInteractionStopped(resolution.action));
|
|
23355
|
+
} else if (completedResult !== void 0) {
|
|
23356
|
+
pendingApp.resolve(appToolResult(completedResult));
|
|
23357
|
+
} else {
|
|
23358
|
+
pendingApp.reject(
|
|
23359
|
+
clientError(
|
|
23360
|
+
"invalid_response",
|
|
23361
|
+
"Assistant app interaction completed without a tool result",
|
|
23362
|
+
false
|
|
23363
|
+
)
|
|
23364
|
+
);
|
|
23365
|
+
}
|
|
23366
|
+
}
|
|
23367
|
+
} catch (error51) {
|
|
23368
|
+
if (pendingApp && this.#pendingAppInteractions.get(id) === pendingApp) {
|
|
23369
|
+
this.#pendingAppInteractions.delete(id);
|
|
23370
|
+
pendingApp.reject(error51);
|
|
23371
|
+
}
|
|
23372
|
+
throw error51;
|
|
23326
23373
|
}
|
|
23327
|
-
await this.#consume(response);
|
|
23328
|
-
this.#emit({ event: "interaction_completed", data: { id, action: resolution.action } });
|
|
23329
23374
|
});
|
|
23330
23375
|
});
|
|
23331
23376
|
}
|
|
@@ -23366,12 +23411,29 @@ var DefaultAssistantClient = class {
|
|
|
23366
23411
|
response.status
|
|
23367
23412
|
);
|
|
23368
23413
|
}
|
|
23369
|
-
|
|
23414
|
+
const value = await response.json();
|
|
23415
|
+
const interaction = parseAppInteraction(value);
|
|
23416
|
+
if (!interaction) return value;
|
|
23417
|
+
return new Promise((resolve2, reject) => {
|
|
23418
|
+
const id = interaction.data.id;
|
|
23419
|
+
const replaced = this.#pendingAppInteractions.get(id);
|
|
23420
|
+
if (replaced) {
|
|
23421
|
+
replaced.reject(
|
|
23422
|
+
clientError("invalid_response", "Assistant returned a duplicate app interaction", false)
|
|
23423
|
+
);
|
|
23424
|
+
}
|
|
23425
|
+
this.#pendingAppInteractions.set(id, { resolve: resolve2, reject });
|
|
23426
|
+
this.#emit(interaction);
|
|
23427
|
+
void this.#chat.flush();
|
|
23428
|
+
});
|
|
23370
23429
|
}
|
|
23371
23430
|
appSandboxUrl() {
|
|
23372
23431
|
return this.#session?.endpoints.sandbox;
|
|
23373
23432
|
}
|
|
23374
23433
|
resetSession() {
|
|
23434
|
+
this.#rejectPendingAppInteractions(
|
|
23435
|
+
clientError("confirmation_expired", "assistant session is not active", false)
|
|
23436
|
+
);
|
|
23375
23437
|
this.#session = void 0;
|
|
23376
23438
|
this.#emit({ event: "session_reset", data: {} });
|
|
23377
23439
|
}
|
|
@@ -23492,12 +23554,13 @@ var DefaultAssistantClient = class {
|
|
|
23492
23554
|
});
|
|
23493
23555
|
return session;
|
|
23494
23556
|
}
|
|
23495
|
-
async #consume(response) {
|
|
23557
|
+
async #consume(response, observe) {
|
|
23496
23558
|
let streamError;
|
|
23497
23559
|
try {
|
|
23498
23560
|
await consumeAssistantEvents(response, (event) => {
|
|
23499
23561
|
const clientEvent = toAssistantClientEvent(event);
|
|
23500
23562
|
this.#emit(clientEvent);
|
|
23563
|
+
observe?.(clientEvent);
|
|
23501
23564
|
if (clientEvent.event !== "error" || typeof clientEvent.data.code !== "string") return;
|
|
23502
23565
|
streamError = {
|
|
23503
23566
|
code: clientEvent.data.code,
|
|
@@ -23566,6 +23629,10 @@ var DefaultAssistantClient = class {
|
|
|
23566
23629
|
}
|
|
23567
23630
|
}
|
|
23568
23631
|
}
|
|
23632
|
+
#rejectPendingAppInteractions(error51) {
|
|
23633
|
+
for (const pending of this.#pendingAppInteractions.values()) pending.reject(error51);
|
|
23634
|
+
this.#pendingAppInteractions.clear();
|
|
23635
|
+
}
|
|
23569
23636
|
};
|
|
23570
23637
|
function createAssistantClient(options) {
|
|
23571
23638
|
return new DefaultAssistantClient(options);
|
|
@@ -23577,6 +23644,30 @@ function authorizedHeaders(token, accept) {
|
|
|
23577
23644
|
Accept: accept
|
|
23578
23645
|
};
|
|
23579
23646
|
}
|
|
23647
|
+
function parseAppInteraction(value) {
|
|
23648
|
+
if (!isRecord4(value) || !isRecord4(value.interaction)) return void 0;
|
|
23649
|
+
const event = value.interaction.event;
|
|
23650
|
+
const data = value.interaction.data;
|
|
23651
|
+
if (event !== "tool_proposed" && event !== "input_requested" || !isRecord4(data)) {
|
|
23652
|
+
return void 0;
|
|
23653
|
+
}
|
|
23654
|
+
const parsed = toAssistantClientEvent({ event, data });
|
|
23655
|
+
return parsed.event === "tool_proposed" || parsed.event === "input_requested" ? parsed : void 0;
|
|
23656
|
+
}
|
|
23657
|
+
function appToolResult(result) {
|
|
23658
|
+
const text2 = typeof result === "string" ? result : JSON.stringify(result);
|
|
23659
|
+
return result !== null && typeof result === "object" && !Array.isArray(result) ? {
|
|
23660
|
+
content: [{ type: "text", text: text2 }],
|
|
23661
|
+
structuredContent: result,
|
|
23662
|
+
isError: false
|
|
23663
|
+
} : { content: [{ type: "text", text: text2 }], isError: false };
|
|
23664
|
+
}
|
|
23665
|
+
function appInteractionStopped(action) {
|
|
23666
|
+
return {
|
|
23667
|
+
content: [{ type: "text", text: `interaction_${action}` }],
|
|
23668
|
+
isError: true
|
|
23669
|
+
};
|
|
23670
|
+
}
|
|
23580
23671
|
function parseSession(value) {
|
|
23581
23672
|
if (!isRecord4(value) || !isRecord4(value.endpoints)) {
|
|
23582
23673
|
throw clientError("session_failed", "Assistant session response is invalid", true);
|