@noodleseed/assistant 1.14.0 → 1.16.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-7WXGZJCA.js → chunk-7L52WJ2E.js} +101 -17
- package/dist/chunk-7L52WJ2E.js.map +1 -0
- package/dist/{chunk-RITHSCTD.js → chunk-NPV64PUX.js} +94 -20
- package/dist/chunk-NPV64PUX.js.map +1 -0
- package/dist/{client-BKIeuSVS.d.cts → client-401BAJqk.d.cts} +42 -3
- package/dist/{client-BccAX_om.d.ts → client-Ii_xTV09.d.ts} +42 -3
- package/dist/client.cjs +89 -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 +189 -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 +100 -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 +198 -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-7WXGZJCA.js.map +0 -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-401BAJqk.cjs';
|
|
2
|
+
export { g as AssistantErrorDetail, i as AssistantEvent, j as AssistantViewAvailableEvent } from './client-401BAJqk.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-Ii_xTV09.js';
|
|
2
|
+
export { g as AssistantErrorDetail, i as AssistantEvent, j as AssistantViewAvailableEvent } from './client-Ii_xTV09.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-7L52WJ2E.js";
|
|
6
|
+
import "./chunk-NPV64PUX.js";
|
|
7
7
|
import "./chunk-3YYTUJPJ.js";
|
|
8
8
|
import "./chunk-5FUTL2UF.js";
|
|
9
9
|
|
package/dist/react/client.cjs
CHANGED
|
@@ -22919,6 +22919,11 @@ function toAssistantClientEvent(event) {
|
|
|
22919
22919
|
return event;
|
|
22920
22920
|
}
|
|
22921
22921
|
break;
|
|
22922
|
+
case "auth_requested":
|
|
22923
|
+
if (hasString(value, "id") && hasString(value, "tool") && hasString(value, "continuation") && hasString(value, "expiresAt") && hasOptionalTurnId(value)) {
|
|
22924
|
+
return event;
|
|
22925
|
+
}
|
|
22926
|
+
break;
|
|
22922
22927
|
case "interaction_resolved":
|
|
22923
22928
|
if (hasString(value, "id") && (value.action === void 0 || isInteractionAction(value.action)) && hasOptionalTurnId(value)) {
|
|
22924
22929
|
return event;
|
|
@@ -23103,6 +23108,21 @@ function hasToJsonProperty(value) {
|
|
|
23103
23108
|
return false;
|
|
23104
23109
|
}
|
|
23105
23110
|
|
|
23111
|
+
// src/session-source.ts
|
|
23112
|
+
var NOODLE_CLOUD_URL = "https://cloud.noodleseed.dev";
|
|
23113
|
+
var PUBLIC_SESSION_PATH = "/v1/assistant/public-sessions";
|
|
23114
|
+
function resolveSessionSource(options) {
|
|
23115
|
+
const { sessionEndpoint, embedId, serviceUrl } = options;
|
|
23116
|
+
if (Boolean(embedId) === Boolean(sessionEndpoint)) {
|
|
23117
|
+
throw new Error("pass either embedId or sessionEndpoint, not both and not neither");
|
|
23118
|
+
}
|
|
23119
|
+
if (embedId) {
|
|
23120
|
+
const base = (serviceUrl ?? NOODLE_CLOUD_URL).replace(/\/+$/, "");
|
|
23121
|
+
return { kind: "public", url: `${base}${PUBLIC_SESSION_PATH}`, embedId };
|
|
23122
|
+
}
|
|
23123
|
+
return { kind: "exchange", url: sessionEndpoint };
|
|
23124
|
+
}
|
|
23125
|
+
|
|
23106
23126
|
// src/transport.ts
|
|
23107
23127
|
var AssistantTransportError = class extends Error {
|
|
23108
23128
|
code = "invalid_response";
|
|
@@ -23230,6 +23250,19 @@ function isAbortError2(error51) {
|
|
|
23230
23250
|
}
|
|
23231
23251
|
|
|
23232
23252
|
// src/client.ts
|
|
23253
|
+
async function refusalCode(response) {
|
|
23254
|
+
try {
|
|
23255
|
+
const body = await response.clone().json();
|
|
23256
|
+
const code = body.code;
|
|
23257
|
+
return typeof code === "string" ? code : void 0;
|
|
23258
|
+
} catch {
|
|
23259
|
+
return void 0;
|
|
23260
|
+
}
|
|
23261
|
+
}
|
|
23262
|
+
var UNRETRYABLE_SERVICE_CODES = /* @__PURE__ */ new Set([
|
|
23263
|
+
"daily_turn_budget_exhausted",
|
|
23264
|
+
"daily_session_budget_exhausted"
|
|
23265
|
+
]);
|
|
23233
23266
|
var AssistantClientError = class extends Error {
|
|
23234
23267
|
detail;
|
|
23235
23268
|
constructor(detail, message, options) {
|
|
@@ -23239,7 +23272,7 @@ var AssistantClientError = class extends Error {
|
|
|
23239
23272
|
}
|
|
23240
23273
|
};
|
|
23241
23274
|
var DefaultAssistantClient = class {
|
|
23242
|
-
#
|
|
23275
|
+
#source;
|
|
23243
23276
|
#fetch;
|
|
23244
23277
|
#listeners = /* @__PURE__ */ new Set();
|
|
23245
23278
|
#chat = new AssistantChatStateStore();
|
|
@@ -23251,8 +23284,7 @@ var DefaultAssistantClient = class {
|
|
|
23251
23284
|
#active;
|
|
23252
23285
|
#pendingAppInteractions = /* @__PURE__ */ new Map();
|
|
23253
23286
|
constructor(options) {
|
|
23254
|
-
|
|
23255
|
-
this.#sessionEndpoint = options.sessionEndpoint;
|
|
23287
|
+
this.#source = resolveSessionSource(options);
|
|
23256
23288
|
this.#fetch = options.fetch ?? ((input, init) => globalThis.fetch(input, init));
|
|
23257
23289
|
this.#context = options.context ? { ...options.context } : void 0;
|
|
23258
23290
|
this.#modelContext = options.modelContext ? copyAssistantModelContext(options.modelContext) : void 0;
|
|
@@ -23468,11 +23500,14 @@ var DefaultAssistantClient = class {
|
|
|
23468
23500
|
return;
|
|
23469
23501
|
}
|
|
23470
23502
|
if (!response.ok) {
|
|
23503
|
+
const serviceCode = await refusalCode(response);
|
|
23471
23504
|
throw clientError(
|
|
23472
23505
|
"turn_failed",
|
|
23473
23506
|
`Assistant turn failed (${response.status})`,
|
|
23474
23507
|
false,
|
|
23475
|
-
response.status
|
|
23508
|
+
response.status,
|
|
23509
|
+
void 0,
|
|
23510
|
+
serviceCode
|
|
23476
23511
|
);
|
|
23477
23512
|
}
|
|
23478
23513
|
await this.#consume(response);
|
|
@@ -23511,23 +23546,25 @@ var DefaultAssistantClient = class {
|
|
|
23511
23546
|
}
|
|
23512
23547
|
}
|
|
23513
23548
|
async #createSession(signal) {
|
|
23514
|
-
const
|
|
23515
|
-
|
|
23516
|
-
|
|
23517
|
-
|
|
23518
|
-
|
|
23519
|
-
|
|
23520
|
-
|
|
23521
|
-
|
|
23522
|
-
|
|
23523
|
-
|
|
23524
|
-
);
|
|
23549
|
+
const source = this.#source;
|
|
23550
|
+
const response = await this.#requestSession(source, {
|
|
23551
|
+
method: "POST",
|
|
23552
|
+
headers: { Accept: "application/json", "Content-Type": "application/json" },
|
|
23553
|
+
body: JSON.stringify(
|
|
23554
|
+
source.kind === "public" ? { embedId: source.embedId } : this.#context ? { context: this.#context } : {}
|
|
23555
|
+
),
|
|
23556
|
+
credentials: source.kind === "public" ? "omit" : "same-origin",
|
|
23557
|
+
signal
|
|
23558
|
+
});
|
|
23525
23559
|
if (!response.ok) {
|
|
23560
|
+
const serviceCode = await refusalCode(response);
|
|
23526
23561
|
throw clientError(
|
|
23527
23562
|
"session_failed",
|
|
23528
23563
|
`Assistant session failed (${response.status})`,
|
|
23529
|
-
|
|
23530
|
-
response.status
|
|
23564
|
+
serviceCode === void 0 || !UNRETRYABLE_SERVICE_CODES.has(serviceCode),
|
|
23565
|
+
response.status,
|
|
23566
|
+
void 0,
|
|
23567
|
+
serviceCode
|
|
23531
23568
|
);
|
|
23532
23569
|
}
|
|
23533
23570
|
let value;
|
|
@@ -23584,6 +23621,34 @@ var DefaultAssistantClient = class {
|
|
|
23584
23621
|
);
|
|
23585
23622
|
}
|
|
23586
23623
|
}
|
|
23624
|
+
/**
|
|
23625
|
+
* The mint, with the one failure a public page hits that an in-app embed cannot.
|
|
23626
|
+
*
|
|
23627
|
+
* A page that loads the embed script and then blocks `connect-src` fails here as a bare network
|
|
23628
|
+
* rejection — no status, no body, nothing to read. "Assistant request failed" sends a developer
|
|
23629
|
+
* hunting through their own code; naming the directive and the origin ends the search. The message
|
|
23630
|
+
* covers a plain outage too, because from inside the browser the two are indistinguishable.
|
|
23631
|
+
*/
|
|
23632
|
+
async #requestSession(source, init) {
|
|
23633
|
+
try {
|
|
23634
|
+
return await this.#fetch(source.url, init);
|
|
23635
|
+
} catch (error51) {
|
|
23636
|
+
if (init.signal?.aborted) throw error51;
|
|
23637
|
+
if (source.kind !== "public") {
|
|
23638
|
+
throw clientError("session_failed", "Assistant request failed", true, void 0, {
|
|
23639
|
+
cause: error51
|
|
23640
|
+
});
|
|
23641
|
+
}
|
|
23642
|
+
throw clientError(
|
|
23643
|
+
"session_failed",
|
|
23644
|
+
`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).`,
|
|
23645
|
+
true,
|
|
23646
|
+
void 0,
|
|
23647
|
+
{ cause: error51 },
|
|
23648
|
+
"blocked_by_page"
|
|
23649
|
+
);
|
|
23650
|
+
}
|
|
23651
|
+
}
|
|
23587
23652
|
async #request(input, init, failureCode) {
|
|
23588
23653
|
try {
|
|
23589
23654
|
return await this.#fetch(input, init);
|
|
@@ -23705,9 +23770,14 @@ async function readStableErrorCode(response) {
|
|
|
23705
23770
|
if (!isRecord4(value) || typeof value.code !== "string") return void 0;
|
|
23706
23771
|
return /^[A-Za-z0-9_.-]{1,64}$/.test(value.code) ? value.code : void 0;
|
|
23707
23772
|
}
|
|
23708
|
-
function clientError(code, message, retryable, status, options) {
|
|
23773
|
+
function clientError(code, message, retryable, status, options, serviceCode) {
|
|
23709
23774
|
return new AssistantClientError(
|
|
23710
|
-
{
|
|
23775
|
+
{
|
|
23776
|
+
code,
|
|
23777
|
+
...status === void 0 ? {} : { status },
|
|
23778
|
+
retryable,
|
|
23779
|
+
...serviceCode === void 0 ? {} : { serviceCode }
|
|
23780
|
+
},
|
|
23711
23781
|
message,
|
|
23712
23782
|
options
|
|
23713
23783
|
);
|
|
@@ -23717,16 +23787,23 @@ function clientError(code, message, retryable, status, options) {
|
|
|
23717
23787
|
var useCommittedLayoutEffect = typeof window === "undefined" ? import_react.useEffect : import_react.useLayoutEffect;
|
|
23718
23788
|
function useNoodleAssistant(options) {
|
|
23719
23789
|
const optionsRef = (0, import_react.useRef)(options);
|
|
23720
|
-
const { fetch: injectedFetch, principalKey, sessionEndpoint } = options;
|
|
23790
|
+
const { fetch: injectedFetch, principalKey, sessionEndpoint, embedId, serviceUrl } = options;
|
|
23721
23791
|
const client = (0, import_react.useMemo)(() => {
|
|
23722
23792
|
if (!principalKey.trim()) throw new Error("principalKey is required");
|
|
23723
|
-
|
|
23724
|
-
sessionEndpoint,
|
|
23793
|
+
const behavior = {
|
|
23725
23794
|
...injectedFetch ? { fetch: injectedFetch } : {},
|
|
23726
23795
|
clientContext: () => readProvider(optionsRef.current.clientContext),
|
|
23727
23796
|
pageContext: () => readProvider(optionsRef.current.pageContext)
|
|
23797
|
+
};
|
|
23798
|
+
return embedId !== void 0 ? createAssistantClient({
|
|
23799
|
+
embedId,
|
|
23800
|
+
...serviceUrl !== void 0 ? { serviceUrl } : {},
|
|
23801
|
+
...behavior
|
|
23802
|
+
}) : createAssistantClient({
|
|
23803
|
+
sessionEndpoint: sessionEndpoint ?? "",
|
|
23804
|
+
...behavior
|
|
23728
23805
|
});
|
|
23729
|
-
}, [injectedFetch, principalKey, sessionEndpoint]);
|
|
23806
|
+
}, [injectedFetch, principalKey, sessionEndpoint, embedId, serviceUrl]);
|
|
23730
23807
|
const store = (0, import_react.useMemo)(() => createAssistantReactStore(client), [client]);
|
|
23731
23808
|
const state = (0, import_react.useSyncExternalStore)(store.subscribe, store.getSnapshot, store.getSnapshot);
|
|
23732
23809
|
const synchronized = (0, import_react.useRef)(void 0);
|