@noodleseed/assistant 1.13.0 → 1.15.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 +5 -0
- package/dist/{chunk-KRB2SXFD.js → chunk-RRJIK473.js} +211 -51
- package/dist/chunk-RRJIK473.js.map +1 -0
- package/dist/{chunk-ZPELSHUP.js → chunk-SUHNNWKP.js} +37 -20
- package/dist/chunk-SUHNNWKP.js.map +1 -0
- package/dist/{client-BKIeuSVS.d.cts → client-B_l59rWg.d.cts} +29 -2
- package/dist/{client-BccAX_om.d.ts → client-MnLfiyo2.d.ts} +29 -2
- package/dist/client.cjs +206 -50
- package/dist/client.cjs.map +1 -1
- package/dist/client.d.cts +1 -1
- package/dist/client.d.ts +1 -1
- package/dist/client.js +1 -1
- package/dist/embed.global.js +540 -0
- package/dist/index.cjs +242 -67
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -2
- package/dist/index.d.ts +6 -2
- package/dist/index.js +2 -2
- package/dist/react/client.cjs +217 -54
- package/dist/react/client.cjs.map +1 -1
- package/dist/react/client.d.cts +3 -3
- package/dist/react/client.d.ts +3 -3
- package/dist/react/client.js +12 -5
- package/dist/react/client.js.map +1 -1
- package/dist/react.cjs +251 -70
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +7 -2
- package/dist/react.d.ts +7 -2
- package/dist/react.js +11 -5
- package/dist/react.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-KRB2SXFD.js.map +0 -1
- package/dist/chunk-ZPELSHUP.js.map +0 -1
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { d as AssistantViewAvailableDetail, f as AssistantClientEvent, a as AssistantContext, e as AssistantModelContextUpdate, A as AssistantPageContext, h as AssistantInteractionResponse } from './client-
|
|
2
|
-
export { g as AssistantErrorDetail, i as AssistantEvent, j as AssistantViewAvailableEvent } from './client-
|
|
1
|
+
import { d as AssistantViewAvailableDetail, f as AssistantClientEvent, a as AssistantContext, e as AssistantModelContextUpdate, A as AssistantPageContext, h as AssistantInteractionResponse } from './client-B_l59rWg.cjs';
|
|
2
|
+
export { g as AssistantErrorDetail, i as AssistantEvent, j as AssistantViewAvailableEvent } from './client-B_l59rWg.cjs';
|
|
3
3
|
import './appearance-Cc-eqSbp.cjs';
|
|
4
4
|
import 'ai';
|
|
5
5
|
|
|
@@ -58,6 +58,10 @@ declare class NoodleAssistantElement extends HTMLElementBase {
|
|
|
58
58
|
#private;
|
|
59
59
|
static readonly observedAttributes: string[];
|
|
60
60
|
sessionEndpoint: string;
|
|
61
|
+
/** Public mount: the non-secret embed id `noodle deploy` printed. Mutually exclusive with the above. */
|
|
62
|
+
embedId: string;
|
|
63
|
+
/** Only for a dev or self-hosted service; the published snippet needs no origin. */
|
|
64
|
+
serviceUrl: string;
|
|
61
65
|
get appearance(): AssistantAppearance | undefined;
|
|
62
66
|
set appearance(value: AssistantAppearance | undefined);
|
|
63
67
|
connectedCallback(): void;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { d as AssistantViewAvailableDetail, f as AssistantClientEvent, a as AssistantContext, e as AssistantModelContextUpdate, A as AssistantPageContext, h as AssistantInteractionResponse } from './client-
|
|
2
|
-
export { g as AssistantErrorDetail, i as AssistantEvent, j as AssistantViewAvailableEvent } from './client-
|
|
1
|
+
import { d as AssistantViewAvailableDetail, f as AssistantClientEvent, a as AssistantContext, e as AssistantModelContextUpdate, A as AssistantPageContext, h as AssistantInteractionResponse } from './client-MnLfiyo2.js';
|
|
2
|
+
export { g as AssistantErrorDetail, i as AssistantEvent, j as AssistantViewAvailableEvent } from './client-MnLfiyo2.js';
|
|
3
3
|
import './appearance-Cc-eqSbp.js';
|
|
4
4
|
import 'ai';
|
|
5
5
|
|
|
@@ -58,6 +58,10 @@ declare class NoodleAssistantElement extends HTMLElementBase {
|
|
|
58
58
|
#private;
|
|
59
59
|
static readonly observedAttributes: string[];
|
|
60
60
|
sessionEndpoint: string;
|
|
61
|
+
/** Public mount: the non-secret embed id `noodle deploy` printed. Mutually exclusive with the above. */
|
|
62
|
+
embedId: string;
|
|
63
|
+
/** Only for a dev or self-hosted service; the published snippet needs no origin. */
|
|
64
|
+
serviceUrl: string;
|
|
61
65
|
get appearance(): AssistantAppearance | undefined;
|
|
62
66
|
set appearance(value: AssistantAppearance | undefined);
|
|
63
67
|
connectedCallback(): void;
|
package/dist/index.js
CHANGED
|
@@ -2,8 +2,8 @@ import {
|
|
|
2
2
|
ASSISTANT_TAG_NAME,
|
|
3
3
|
NoodleAssistantElement,
|
|
4
4
|
registerNoodleAssistant
|
|
5
|
-
} from "./chunk-
|
|
6
|
-
import "./chunk-
|
|
5
|
+
} from "./chunk-SUHNNWKP.js";
|
|
6
|
+
import "./chunk-RRJIK473.js";
|
|
7
7
|
import "./chunk-3YYTUJPJ.js";
|
|
8
8
|
import "./chunk-5FUTL2UF.js";
|
|
9
9
|
|
package/dist/react/client.cjs
CHANGED
|
@@ -22644,7 +22644,7 @@ var AssistantChatStateStore = class {
|
|
|
22644
22644
|
this.#writeText(event.data.delta);
|
|
22645
22645
|
return;
|
|
22646
22646
|
case "tool_proposed":
|
|
22647
|
-
this.#writeConfirmation(event.data);
|
|
22647
|
+
this.#writeStandaloneData(() => this.#writeConfirmation(event.data));
|
|
22648
22648
|
return;
|
|
22649
22649
|
case "interaction_proposed":
|
|
22650
22650
|
this.#writeData("confirmation", event.data.id, {
|
|
@@ -22653,10 +22653,12 @@ var AssistantChatStateStore = class {
|
|
|
22653
22653
|
});
|
|
22654
22654
|
return;
|
|
22655
22655
|
case "input_requested":
|
|
22656
|
-
this.#
|
|
22657
|
-
|
|
22658
|
-
|
|
22659
|
-
|
|
22656
|
+
this.#writeStandaloneData(
|
|
22657
|
+
() => this.#writeData("input-request", event.data.id, {
|
|
22658
|
+
...event.data,
|
|
22659
|
+
status: "pending"
|
|
22660
|
+
})
|
|
22661
|
+
);
|
|
22660
22662
|
return;
|
|
22661
22663
|
case "tool_completed":
|
|
22662
22664
|
this.#writeData("tool-result", event.data.id, event.data);
|
|
@@ -22763,6 +22765,12 @@ var AssistantChatStateStore = class {
|
|
|
22763
22765
|
#writeConfirmation(data) {
|
|
22764
22766
|
this.#writeData("confirmation", data.id, { ...data, status: "pending" });
|
|
22765
22767
|
}
|
|
22768
|
+
#writeStandaloneData(write) {
|
|
22769
|
+
const standalone = this.#operation === void 0;
|
|
22770
|
+
if (standalone) this.#startOperation();
|
|
22771
|
+
write();
|
|
22772
|
+
if (standalone) this.#closeOperation("ready");
|
|
22773
|
+
}
|
|
22766
22774
|
#writeData(name21, id, data) {
|
|
22767
22775
|
const operation = this.#operation;
|
|
22768
22776
|
if (!operation || operation.closed) return;
|
|
@@ -23095,6 +23103,21 @@ function hasToJsonProperty(value) {
|
|
|
23095
23103
|
return false;
|
|
23096
23104
|
}
|
|
23097
23105
|
|
|
23106
|
+
// src/session-source.ts
|
|
23107
|
+
var NOODLE_CLOUD_URL = "https://cloud.noodleseed.dev";
|
|
23108
|
+
var PUBLIC_SESSION_PATH = "/v1/assistant/public-sessions";
|
|
23109
|
+
function resolveSessionSource(options) {
|
|
23110
|
+
const { sessionEndpoint, embedId, serviceUrl } = options;
|
|
23111
|
+
if (Boolean(embedId) === Boolean(sessionEndpoint)) {
|
|
23112
|
+
throw new Error("pass either embedId or sessionEndpoint, not both and not neither");
|
|
23113
|
+
}
|
|
23114
|
+
if (embedId) {
|
|
23115
|
+
const base = (serviceUrl ?? NOODLE_CLOUD_URL).replace(/\/+$/, "");
|
|
23116
|
+
return { kind: "public", url: `${base}${PUBLIC_SESSION_PATH}`, embedId };
|
|
23117
|
+
}
|
|
23118
|
+
return { kind: "exchange", url: sessionEndpoint };
|
|
23119
|
+
}
|
|
23120
|
+
|
|
23098
23121
|
// src/transport.ts
|
|
23099
23122
|
var AssistantTransportError = class extends Error {
|
|
23100
23123
|
code = "invalid_response";
|
|
@@ -23222,6 +23245,19 @@ function isAbortError2(error51) {
|
|
|
23222
23245
|
}
|
|
23223
23246
|
|
|
23224
23247
|
// src/client.ts
|
|
23248
|
+
async function refusalCode(response) {
|
|
23249
|
+
try {
|
|
23250
|
+
const body = await response.clone().json();
|
|
23251
|
+
const code = body.code;
|
|
23252
|
+
return typeof code === "string" ? code : void 0;
|
|
23253
|
+
} catch {
|
|
23254
|
+
return void 0;
|
|
23255
|
+
}
|
|
23256
|
+
}
|
|
23257
|
+
var UNRETRYABLE_SERVICE_CODES = /* @__PURE__ */ new Set([
|
|
23258
|
+
"daily_turn_budget_exhausted",
|
|
23259
|
+
"daily_session_budget_exhausted"
|
|
23260
|
+
]);
|
|
23225
23261
|
var AssistantClientError = class extends Error {
|
|
23226
23262
|
detail;
|
|
23227
23263
|
constructor(detail, message, options) {
|
|
@@ -23231,7 +23267,7 @@ var AssistantClientError = class extends Error {
|
|
|
23231
23267
|
}
|
|
23232
23268
|
};
|
|
23233
23269
|
var DefaultAssistantClient = class {
|
|
23234
|
-
#
|
|
23270
|
+
#source;
|
|
23235
23271
|
#fetch;
|
|
23236
23272
|
#listeners = /* @__PURE__ */ new Set();
|
|
23237
23273
|
#chat = new AssistantChatStateStore();
|
|
@@ -23241,9 +23277,9 @@ var DefaultAssistantClient = class {
|
|
|
23241
23277
|
#context;
|
|
23242
23278
|
#modelContext;
|
|
23243
23279
|
#active;
|
|
23280
|
+
#pendingAppInteractions = /* @__PURE__ */ new Map();
|
|
23244
23281
|
constructor(options) {
|
|
23245
|
-
|
|
23246
|
-
this.#sessionEndpoint = options.sessionEndpoint;
|
|
23282
|
+
this.#source = resolveSessionSource(options);
|
|
23247
23283
|
this.#fetch = options.fetch ?? ((input, init) => globalThis.fetch(input, init));
|
|
23248
23284
|
this.#context = options.context ? { ...options.context } : void 0;
|
|
23249
23285
|
this.#modelContext = options.modelContext ? copyAssistantModelContext(options.modelContext) : void 0;
|
|
@@ -23282,6 +23318,7 @@ var DefaultAssistantClient = class {
|
|
|
23282
23318
|
}
|
|
23283
23319
|
await this.#singleFlight(async (signal) => {
|
|
23284
23320
|
await this.#runChatOperation(signal, async () => {
|
|
23321
|
+
const pendingApp = this.#pendingAppInteractions.get(id);
|
|
23285
23322
|
const session = this.#session;
|
|
23286
23323
|
if (!session) {
|
|
23287
23324
|
throw clientError("confirmation_expired", "assistant session is not active", false);
|
|
@@ -23301,32 +23338,67 @@ var DefaultAssistantClient = class {
|
|
|
23301
23338
|
...resolution.action === "accept" && resolution.content !== void 0 ? { content: resolution.content } : {}
|
|
23302
23339
|
} : { id };
|
|
23303
23340
|
this.#emit({ event: "interaction_started", data: { id, action: resolution.action } });
|
|
23304
|
-
|
|
23305
|
-
|
|
23306
|
-
|
|
23307
|
-
|
|
23308
|
-
|
|
23309
|
-
|
|
23310
|
-
|
|
23311
|
-
|
|
23312
|
-
|
|
23313
|
-
|
|
23314
|
-
if (response.status === 401) {
|
|
23315
|
-
this.#session = void 0;
|
|
23316
|
-
this.#emit({ event: "session_expired", data: {} });
|
|
23317
|
-
}
|
|
23318
|
-
if (!response.ok) {
|
|
23319
|
-
const serverCode = await readStableErrorCode(response);
|
|
23320
|
-
const expired = response.status === 401 || response.status === 409;
|
|
23321
|
-
throw clientError(
|
|
23322
|
-
serverCode ?? (expired ? "confirmation_expired" : "confirmation_failed"),
|
|
23323
|
-
`Assistant interaction failed (${response.status})`,
|
|
23324
|
-
false,
|
|
23325
|
-
response.status
|
|
23341
|
+
try {
|
|
23342
|
+
const response = await this.#request(
|
|
23343
|
+
endpoint,
|
|
23344
|
+
{
|
|
23345
|
+
method: "POST",
|
|
23346
|
+
headers: authorizedHeaders(session.token, "text/event-stream"),
|
|
23347
|
+
body: JSON.stringify(body),
|
|
23348
|
+
signal
|
|
23349
|
+
},
|
|
23350
|
+
"confirmation_failed"
|
|
23326
23351
|
);
|
|
23352
|
+
if (response.status === 401) {
|
|
23353
|
+
this.#session = void 0;
|
|
23354
|
+
this.#emit({ event: "session_expired", data: {} });
|
|
23355
|
+
}
|
|
23356
|
+
if (!response.ok) {
|
|
23357
|
+
const serverCode = await readStableErrorCode(response);
|
|
23358
|
+
const expired = response.status === 401 || response.status === 409;
|
|
23359
|
+
throw clientError(
|
|
23360
|
+
serverCode ?? (expired ? "confirmation_expired" : "confirmation_failed"),
|
|
23361
|
+
`Assistant interaction failed (${response.status})`,
|
|
23362
|
+
false,
|
|
23363
|
+
response.status
|
|
23364
|
+
);
|
|
23365
|
+
}
|
|
23366
|
+
let completedResult;
|
|
23367
|
+
let nextInteractionId;
|
|
23368
|
+
await this.#consume(response, (event) => {
|
|
23369
|
+
if (event.event === "tool_completed" && event.data.id === id) {
|
|
23370
|
+
completedResult = event.data.result;
|
|
23371
|
+
}
|
|
23372
|
+
if ((event.event === "tool_proposed" || event.event === "input_requested") && event.data.id !== id) {
|
|
23373
|
+
nextInteractionId = event.data.id;
|
|
23374
|
+
}
|
|
23375
|
+
});
|
|
23376
|
+
this.#emit({ event: "interaction_completed", data: { id, action: resolution.action } });
|
|
23377
|
+
if (pendingApp) {
|
|
23378
|
+
this.#pendingAppInteractions.delete(id);
|
|
23379
|
+
if (nextInteractionId) {
|
|
23380
|
+
this.#pendingAppInteractions.set(nextInteractionId, pendingApp);
|
|
23381
|
+
} else if (resolution.action !== "accept") {
|
|
23382
|
+
pendingApp.resolve(appInteractionStopped(resolution.action));
|
|
23383
|
+
} else if (completedResult !== void 0) {
|
|
23384
|
+
pendingApp.resolve(appToolResult(completedResult));
|
|
23385
|
+
} else {
|
|
23386
|
+
pendingApp.reject(
|
|
23387
|
+
clientError(
|
|
23388
|
+
"invalid_response",
|
|
23389
|
+
"Assistant app interaction completed without a tool result",
|
|
23390
|
+
false
|
|
23391
|
+
)
|
|
23392
|
+
);
|
|
23393
|
+
}
|
|
23394
|
+
}
|
|
23395
|
+
} catch (error51) {
|
|
23396
|
+
if (pendingApp && this.#pendingAppInteractions.get(id) === pendingApp) {
|
|
23397
|
+
this.#pendingAppInteractions.delete(id);
|
|
23398
|
+
pendingApp.reject(error51);
|
|
23399
|
+
}
|
|
23400
|
+
throw error51;
|
|
23327
23401
|
}
|
|
23328
|
-
await this.#consume(response);
|
|
23329
|
-
this.#emit({ event: "interaction_completed", data: { id, action: resolution.action } });
|
|
23330
23402
|
});
|
|
23331
23403
|
});
|
|
23332
23404
|
}
|
|
@@ -23367,12 +23439,29 @@ var DefaultAssistantClient = class {
|
|
|
23367
23439
|
response.status
|
|
23368
23440
|
);
|
|
23369
23441
|
}
|
|
23370
|
-
|
|
23442
|
+
const value = await response.json();
|
|
23443
|
+
const interaction = parseAppInteraction(value);
|
|
23444
|
+
if (!interaction) return value;
|
|
23445
|
+
return new Promise((resolve2, reject) => {
|
|
23446
|
+
const id = interaction.data.id;
|
|
23447
|
+
const replaced = this.#pendingAppInteractions.get(id);
|
|
23448
|
+
if (replaced) {
|
|
23449
|
+
replaced.reject(
|
|
23450
|
+
clientError("invalid_response", "Assistant returned a duplicate app interaction", false)
|
|
23451
|
+
);
|
|
23452
|
+
}
|
|
23453
|
+
this.#pendingAppInteractions.set(id, { resolve: resolve2, reject });
|
|
23454
|
+
this.#emit(interaction);
|
|
23455
|
+
void this.#chat.flush();
|
|
23456
|
+
});
|
|
23371
23457
|
}
|
|
23372
23458
|
appSandboxUrl() {
|
|
23373
23459
|
return this.#session?.endpoints.sandbox;
|
|
23374
23460
|
}
|
|
23375
23461
|
resetSession() {
|
|
23462
|
+
this.#rejectPendingAppInteractions(
|
|
23463
|
+
clientError("confirmation_expired", "assistant session is not active", false)
|
|
23464
|
+
);
|
|
23376
23465
|
this.#session = void 0;
|
|
23377
23466
|
this.#emit({ event: "session_reset", data: {} });
|
|
23378
23467
|
}
|
|
@@ -23406,11 +23495,14 @@ var DefaultAssistantClient = class {
|
|
|
23406
23495
|
return;
|
|
23407
23496
|
}
|
|
23408
23497
|
if (!response.ok) {
|
|
23498
|
+
const serviceCode = await refusalCode(response);
|
|
23409
23499
|
throw clientError(
|
|
23410
23500
|
"turn_failed",
|
|
23411
23501
|
`Assistant turn failed (${response.status})`,
|
|
23412
23502
|
false,
|
|
23413
|
-
response.status
|
|
23503
|
+
response.status,
|
|
23504
|
+
void 0,
|
|
23505
|
+
serviceCode
|
|
23414
23506
|
);
|
|
23415
23507
|
}
|
|
23416
23508
|
await this.#consume(response);
|
|
@@ -23449,23 +23541,25 @@ var DefaultAssistantClient = class {
|
|
|
23449
23541
|
}
|
|
23450
23542
|
}
|
|
23451
23543
|
async #createSession(signal) {
|
|
23452
|
-
const
|
|
23453
|
-
|
|
23454
|
-
|
|
23455
|
-
|
|
23456
|
-
|
|
23457
|
-
|
|
23458
|
-
|
|
23459
|
-
|
|
23460
|
-
|
|
23461
|
-
|
|
23462
|
-
);
|
|
23544
|
+
const source = this.#source;
|
|
23545
|
+
const response = await this.#requestSession(source, {
|
|
23546
|
+
method: "POST",
|
|
23547
|
+
headers: { Accept: "application/json", "Content-Type": "application/json" },
|
|
23548
|
+
body: JSON.stringify(
|
|
23549
|
+
source.kind === "public" ? { embedId: source.embedId } : this.#context ? { context: this.#context } : {}
|
|
23550
|
+
),
|
|
23551
|
+
credentials: source.kind === "public" ? "omit" : "same-origin",
|
|
23552
|
+
signal
|
|
23553
|
+
});
|
|
23463
23554
|
if (!response.ok) {
|
|
23555
|
+
const serviceCode = await refusalCode(response);
|
|
23464
23556
|
throw clientError(
|
|
23465
23557
|
"session_failed",
|
|
23466
23558
|
`Assistant session failed (${response.status})`,
|
|
23467
|
-
|
|
23468
|
-
response.status
|
|
23559
|
+
serviceCode === void 0 || !UNRETRYABLE_SERVICE_CODES.has(serviceCode),
|
|
23560
|
+
response.status,
|
|
23561
|
+
void 0,
|
|
23562
|
+
serviceCode
|
|
23469
23563
|
);
|
|
23470
23564
|
}
|
|
23471
23565
|
let value;
|
|
@@ -23493,12 +23587,13 @@ var DefaultAssistantClient = class {
|
|
|
23493
23587
|
});
|
|
23494
23588
|
return session;
|
|
23495
23589
|
}
|
|
23496
|
-
async #consume(response) {
|
|
23590
|
+
async #consume(response, observe) {
|
|
23497
23591
|
let streamError;
|
|
23498
23592
|
try {
|
|
23499
23593
|
await consumeAssistantEvents(response, (event) => {
|
|
23500
23594
|
const clientEvent = toAssistantClientEvent(event);
|
|
23501
23595
|
this.#emit(clientEvent);
|
|
23596
|
+
observe?.(clientEvent);
|
|
23502
23597
|
if (clientEvent.event !== "error" || typeof clientEvent.data.code !== "string") return;
|
|
23503
23598
|
streamError = {
|
|
23504
23599
|
code: clientEvent.data.code,
|
|
@@ -23521,6 +23616,34 @@ var DefaultAssistantClient = class {
|
|
|
23521
23616
|
);
|
|
23522
23617
|
}
|
|
23523
23618
|
}
|
|
23619
|
+
/**
|
|
23620
|
+
* The mint, with the one failure a public page hits that an in-app embed cannot.
|
|
23621
|
+
*
|
|
23622
|
+
* A page that loads the embed script and then blocks `connect-src` fails here as a bare network
|
|
23623
|
+
* rejection — no status, no body, nothing to read. "Assistant request failed" sends a developer
|
|
23624
|
+
* hunting through their own code; naming the directive and the origin ends the search. The message
|
|
23625
|
+
* covers a plain outage too, because from inside the browser the two are indistinguishable.
|
|
23626
|
+
*/
|
|
23627
|
+
async #requestSession(source, init) {
|
|
23628
|
+
try {
|
|
23629
|
+
return await this.#fetch(source.url, init);
|
|
23630
|
+
} catch (error51) {
|
|
23631
|
+
if (init.signal?.aborted) throw error51;
|
|
23632
|
+
if (source.kind !== "public") {
|
|
23633
|
+
throw clientError("session_failed", "Assistant request failed", true, void 0, {
|
|
23634
|
+
cause: error51
|
|
23635
|
+
});
|
|
23636
|
+
}
|
|
23637
|
+
throw clientError(
|
|
23638
|
+
"session_failed",
|
|
23639
|
+
`Assistant could not reach ${new URL(source.url).origin}. If the page sets a Content-Security-Policy, allow that origin in connect-src (and in script-src and frame-src).`,
|
|
23640
|
+
true,
|
|
23641
|
+
void 0,
|
|
23642
|
+
{ cause: error51 },
|
|
23643
|
+
"blocked_by_page"
|
|
23644
|
+
);
|
|
23645
|
+
}
|
|
23646
|
+
}
|
|
23524
23647
|
async #request(input, init, failureCode) {
|
|
23525
23648
|
try {
|
|
23526
23649
|
return await this.#fetch(input, init);
|
|
@@ -23567,6 +23690,10 @@ var DefaultAssistantClient = class {
|
|
|
23567
23690
|
}
|
|
23568
23691
|
}
|
|
23569
23692
|
}
|
|
23693
|
+
#rejectPendingAppInteractions(error51) {
|
|
23694
|
+
for (const pending of this.#pendingAppInteractions.values()) pending.reject(error51);
|
|
23695
|
+
this.#pendingAppInteractions.clear();
|
|
23696
|
+
}
|
|
23570
23697
|
};
|
|
23571
23698
|
function createAssistantClient(options) {
|
|
23572
23699
|
return new DefaultAssistantClient(options);
|
|
@@ -23578,6 +23705,30 @@ function authorizedHeaders(token, accept) {
|
|
|
23578
23705
|
Accept: accept
|
|
23579
23706
|
};
|
|
23580
23707
|
}
|
|
23708
|
+
function parseAppInteraction(value) {
|
|
23709
|
+
if (!isRecord4(value) || !isRecord4(value.interaction)) return void 0;
|
|
23710
|
+
const event = value.interaction.event;
|
|
23711
|
+
const data = value.interaction.data;
|
|
23712
|
+
if (event !== "tool_proposed" && event !== "input_requested" || !isRecord4(data)) {
|
|
23713
|
+
return void 0;
|
|
23714
|
+
}
|
|
23715
|
+
const parsed = toAssistantClientEvent({ event, data });
|
|
23716
|
+
return parsed.event === "tool_proposed" || parsed.event === "input_requested" ? parsed : void 0;
|
|
23717
|
+
}
|
|
23718
|
+
function appToolResult(result) {
|
|
23719
|
+
const text2 = typeof result === "string" ? result : JSON.stringify(result);
|
|
23720
|
+
return result !== null && typeof result === "object" && !Array.isArray(result) ? {
|
|
23721
|
+
content: [{ type: "text", text: text2 }],
|
|
23722
|
+
structuredContent: result,
|
|
23723
|
+
isError: false
|
|
23724
|
+
} : { content: [{ type: "text", text: text2 }], isError: false };
|
|
23725
|
+
}
|
|
23726
|
+
function appInteractionStopped(action) {
|
|
23727
|
+
return {
|
|
23728
|
+
content: [{ type: "text", text: `interaction_${action}` }],
|
|
23729
|
+
isError: true
|
|
23730
|
+
};
|
|
23731
|
+
}
|
|
23581
23732
|
function parseSession(value) {
|
|
23582
23733
|
if (!isRecord4(value) || !isRecord4(value.endpoints)) {
|
|
23583
23734
|
throw clientError("session_failed", "Assistant session response is invalid", true);
|
|
@@ -23614,9 +23765,14 @@ async function readStableErrorCode(response) {
|
|
|
23614
23765
|
if (!isRecord4(value) || typeof value.code !== "string") return void 0;
|
|
23615
23766
|
return /^[A-Za-z0-9_.-]{1,64}$/.test(value.code) ? value.code : void 0;
|
|
23616
23767
|
}
|
|
23617
|
-
function clientError(code, message, retryable, status, options) {
|
|
23768
|
+
function clientError(code, message, retryable, status, options, serviceCode) {
|
|
23618
23769
|
return new AssistantClientError(
|
|
23619
|
-
{
|
|
23770
|
+
{
|
|
23771
|
+
code,
|
|
23772
|
+
...status === void 0 ? {} : { status },
|
|
23773
|
+
retryable,
|
|
23774
|
+
...serviceCode === void 0 ? {} : { serviceCode }
|
|
23775
|
+
},
|
|
23620
23776
|
message,
|
|
23621
23777
|
options
|
|
23622
23778
|
);
|
|
@@ -23626,16 +23782,23 @@ function clientError(code, message, retryable, status, options) {
|
|
|
23626
23782
|
var useCommittedLayoutEffect = typeof window === "undefined" ? import_react.useEffect : import_react.useLayoutEffect;
|
|
23627
23783
|
function useNoodleAssistant(options) {
|
|
23628
23784
|
const optionsRef = (0, import_react.useRef)(options);
|
|
23629
|
-
const { fetch: injectedFetch, principalKey, sessionEndpoint } = options;
|
|
23785
|
+
const { fetch: injectedFetch, principalKey, sessionEndpoint, embedId, serviceUrl } = options;
|
|
23630
23786
|
const client = (0, import_react.useMemo)(() => {
|
|
23631
23787
|
if (!principalKey.trim()) throw new Error("principalKey is required");
|
|
23632
|
-
|
|
23633
|
-
sessionEndpoint,
|
|
23788
|
+
const behavior = {
|
|
23634
23789
|
...injectedFetch ? { fetch: injectedFetch } : {},
|
|
23635
23790
|
clientContext: () => readProvider(optionsRef.current.clientContext),
|
|
23636
23791
|
pageContext: () => readProvider(optionsRef.current.pageContext)
|
|
23792
|
+
};
|
|
23793
|
+
return embedId !== void 0 ? createAssistantClient({
|
|
23794
|
+
embedId,
|
|
23795
|
+
...serviceUrl !== void 0 ? { serviceUrl } : {},
|
|
23796
|
+
...behavior
|
|
23797
|
+
}) : createAssistantClient({
|
|
23798
|
+
sessionEndpoint: sessionEndpoint ?? "",
|
|
23799
|
+
...behavior
|
|
23637
23800
|
});
|
|
23638
|
-
}, [injectedFetch, principalKey, sessionEndpoint]);
|
|
23801
|
+
}, [injectedFetch, principalKey, sessionEndpoint, embedId, serviceUrl]);
|
|
23639
23802
|
const store = (0, import_react.useMemo)(() => createAssistantReactStore(client), [client]);
|
|
23640
23803
|
const state = (0, import_react.useSyncExternalStore)(store.subscribe, store.getSnapshot, store.getSnapshot);
|
|
23641
23804
|
const synchronized = (0, import_react.useRef)(void 0);
|