@noodleseed/assistant 1.14.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/dist/{chunk-RITHSCTD.js → chunk-RRJIK473.js} +89 -20
- package/dist/chunk-RRJIK473.js.map +1 -0
- package/dist/{chunk-7WXGZJCA.js → chunk-SUHNNWKP.js} +36 -17
- package/dist/{chunk-7WXGZJCA.js.map → chunk-SUHNNWKP.js.map} +1 -1
- 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 +84 -19
- 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 +119 -33
- 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 +95 -23
- 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 +128 -36
- 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-RITHSCTD.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
|
@@ -23103,6 +23103,21 @@ function hasToJsonProperty(value) {
|
|
|
23103
23103
|
return false;
|
|
23104
23104
|
}
|
|
23105
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
|
+
|
|
23106
23121
|
// src/transport.ts
|
|
23107
23122
|
var AssistantTransportError = class extends Error {
|
|
23108
23123
|
code = "invalid_response";
|
|
@@ -23230,6 +23245,19 @@ function isAbortError2(error51) {
|
|
|
23230
23245
|
}
|
|
23231
23246
|
|
|
23232
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
|
+
]);
|
|
23233
23261
|
var AssistantClientError = class extends Error {
|
|
23234
23262
|
detail;
|
|
23235
23263
|
constructor(detail, message, options) {
|
|
@@ -23239,7 +23267,7 @@ var AssistantClientError = class extends Error {
|
|
|
23239
23267
|
}
|
|
23240
23268
|
};
|
|
23241
23269
|
var DefaultAssistantClient = class {
|
|
23242
|
-
#
|
|
23270
|
+
#source;
|
|
23243
23271
|
#fetch;
|
|
23244
23272
|
#listeners = /* @__PURE__ */ new Set();
|
|
23245
23273
|
#chat = new AssistantChatStateStore();
|
|
@@ -23251,8 +23279,7 @@ var DefaultAssistantClient = class {
|
|
|
23251
23279
|
#active;
|
|
23252
23280
|
#pendingAppInteractions = /* @__PURE__ */ new Map();
|
|
23253
23281
|
constructor(options) {
|
|
23254
|
-
|
|
23255
|
-
this.#sessionEndpoint = options.sessionEndpoint;
|
|
23282
|
+
this.#source = resolveSessionSource(options);
|
|
23256
23283
|
this.#fetch = options.fetch ?? ((input, init) => globalThis.fetch(input, init));
|
|
23257
23284
|
this.#context = options.context ? { ...options.context } : void 0;
|
|
23258
23285
|
this.#modelContext = options.modelContext ? copyAssistantModelContext(options.modelContext) : void 0;
|
|
@@ -23468,11 +23495,14 @@ var DefaultAssistantClient = class {
|
|
|
23468
23495
|
return;
|
|
23469
23496
|
}
|
|
23470
23497
|
if (!response.ok) {
|
|
23498
|
+
const serviceCode = await refusalCode(response);
|
|
23471
23499
|
throw clientError(
|
|
23472
23500
|
"turn_failed",
|
|
23473
23501
|
`Assistant turn failed (${response.status})`,
|
|
23474
23502
|
false,
|
|
23475
|
-
response.status
|
|
23503
|
+
response.status,
|
|
23504
|
+
void 0,
|
|
23505
|
+
serviceCode
|
|
23476
23506
|
);
|
|
23477
23507
|
}
|
|
23478
23508
|
await this.#consume(response);
|
|
@@ -23511,23 +23541,25 @@ var DefaultAssistantClient = class {
|
|
|
23511
23541
|
}
|
|
23512
23542
|
}
|
|
23513
23543
|
async #createSession(signal) {
|
|
23514
|
-
const
|
|
23515
|
-
|
|
23516
|
-
|
|
23517
|
-
|
|
23518
|
-
|
|
23519
|
-
|
|
23520
|
-
|
|
23521
|
-
|
|
23522
|
-
|
|
23523
|
-
|
|
23524
|
-
);
|
|
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
|
+
});
|
|
23525
23554
|
if (!response.ok) {
|
|
23555
|
+
const serviceCode = await refusalCode(response);
|
|
23526
23556
|
throw clientError(
|
|
23527
23557
|
"session_failed",
|
|
23528
23558
|
`Assistant session failed (${response.status})`,
|
|
23529
|
-
|
|
23530
|
-
response.status
|
|
23559
|
+
serviceCode === void 0 || !UNRETRYABLE_SERVICE_CODES.has(serviceCode),
|
|
23560
|
+
response.status,
|
|
23561
|
+
void 0,
|
|
23562
|
+
serviceCode
|
|
23531
23563
|
);
|
|
23532
23564
|
}
|
|
23533
23565
|
let value;
|
|
@@ -23584,6 +23616,34 @@ var DefaultAssistantClient = class {
|
|
|
23584
23616
|
);
|
|
23585
23617
|
}
|
|
23586
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
|
+
}
|
|
23587
23647
|
async #request(input, init, failureCode) {
|
|
23588
23648
|
try {
|
|
23589
23649
|
return await this.#fetch(input, init);
|
|
@@ -23705,9 +23765,14 @@ async function readStableErrorCode(response) {
|
|
|
23705
23765
|
if (!isRecord4(value) || typeof value.code !== "string") return void 0;
|
|
23706
23766
|
return /^[A-Za-z0-9_.-]{1,64}$/.test(value.code) ? value.code : void 0;
|
|
23707
23767
|
}
|
|
23708
|
-
function clientError(code, message, retryable, status, options) {
|
|
23768
|
+
function clientError(code, message, retryable, status, options, serviceCode) {
|
|
23709
23769
|
return new AssistantClientError(
|
|
23710
|
-
{
|
|
23770
|
+
{
|
|
23771
|
+
code,
|
|
23772
|
+
...status === void 0 ? {} : { status },
|
|
23773
|
+
retryable,
|
|
23774
|
+
...serviceCode === void 0 ? {} : { serviceCode }
|
|
23775
|
+
},
|
|
23711
23776
|
message,
|
|
23712
23777
|
options
|
|
23713
23778
|
);
|
|
@@ -23717,16 +23782,23 @@ function clientError(code, message, retryable, status, options) {
|
|
|
23717
23782
|
var useCommittedLayoutEffect = typeof window === "undefined" ? import_react.useEffect : import_react.useLayoutEffect;
|
|
23718
23783
|
function useNoodleAssistant(options) {
|
|
23719
23784
|
const optionsRef = (0, import_react.useRef)(options);
|
|
23720
|
-
const { fetch: injectedFetch, principalKey, sessionEndpoint } = options;
|
|
23785
|
+
const { fetch: injectedFetch, principalKey, sessionEndpoint, embedId, serviceUrl } = options;
|
|
23721
23786
|
const client = (0, import_react.useMemo)(() => {
|
|
23722
23787
|
if (!principalKey.trim()) throw new Error("principalKey is required");
|
|
23723
|
-
|
|
23724
|
-
sessionEndpoint,
|
|
23788
|
+
const behavior = {
|
|
23725
23789
|
...injectedFetch ? { fetch: injectedFetch } : {},
|
|
23726
23790
|
clientContext: () => readProvider(optionsRef.current.clientContext),
|
|
23727
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
|
|
23728
23800
|
});
|
|
23729
|
-
}, [injectedFetch, principalKey, sessionEndpoint]);
|
|
23801
|
+
}, [injectedFetch, principalKey, sessionEndpoint, embedId, serviceUrl]);
|
|
23730
23802
|
const store = (0, import_react.useMemo)(() => createAssistantReactStore(client), [client]);
|
|
23731
23803
|
const state = (0, import_react.useSyncExternalStore)(store.subscribe, store.getSnapshot, store.getSnapshot);
|
|
23732
23804
|
const synchronized = (0, import_react.useRef)(void 0);
|