@neetru/sdk 3.6.0 → 3.8.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/CHANGELOG.md +104 -0
- package/README.md +66 -1
- package/dist/ai.cjs +298 -391
- package/dist/ai.d.cts +1 -1
- package/dist/ai.d.ts +1 -1
- package/dist/ai.mjs +298 -391
- package/dist/auth.cjs +3717 -5005
- package/dist/auth.d.cts +1 -1
- package/dist/auth.d.ts +1 -1
- package/dist/auth.mjs +3714 -5002
- package/dist/build-guard.cjs +101 -119
- package/dist/build-guard.mjs +91 -109
- package/dist/catalog.cjs +220 -225
- package/dist/catalog.d.cts +1 -1
- package/dist/catalog.d.ts +1 -1
- package/dist/catalog.mjs +220 -225
- package/dist/checkout.cjs +307 -323
- package/dist/checkout.d.cts +1 -1
- package/dist/checkout.d.ts +1 -1
- package/dist/checkout.mjs +306 -322
- package/dist/db-react.cjs +59 -87
- package/dist/db-react.d.cts +1 -1
- package/dist/db-react.d.ts +1 -1
- package/dist/db-react.mjs +56 -84
- package/dist/db.cjs +2128 -3014
- package/dist/db.d.cts +1 -1
- package/dist/db.d.ts +1 -1
- package/dist/db.mjs +2141 -3027
- package/dist/entitlements.cjs +19 -20
- package/dist/entitlements.d.cts +1 -1
- package/dist/entitlements.d.ts +1 -1
- package/dist/entitlements.mjs +19 -20
- package/dist/errors.cjs +16 -12
- package/dist/errors.d.cts +59 -3
- package/dist/errors.d.ts +59 -3
- package/dist/errors.mjs +15 -12
- package/dist/firestore-compat.cjs +241 -297
- package/dist/firestore-compat.d.cts +1 -1
- package/dist/firestore-compat.d.ts +1 -1
- package/dist/firestore-compat.mjs +215 -271
- package/dist/index.cjs +3942 -5134
- package/dist/index.d.cts +181 -5
- package/dist/index.d.ts +181 -5
- package/dist/index.mjs +4040 -5239
- package/dist/mobile.cjs +459 -344
- package/dist/mobile.d.cts +59 -4
- package/dist/mobile.d.ts +59 -4
- package/dist/mobile.mjs +459 -344
- package/dist/mocks.cjs +319 -447
- package/dist/mocks.d.cts +1 -1
- package/dist/mocks.d.ts +1 -1
- package/dist/mocks.mjs +313 -441
- package/dist/notifications.cjs +296 -317
- package/dist/notifications.d.cts +1 -1
- package/dist/notifications.d.ts +1 -1
- package/dist/notifications.mjs +295 -316
- package/dist/react.cjs +557 -707
- package/dist/react.d.cts +1 -1
- package/dist/react.d.ts +1 -1
- package/dist/react.mjs +547 -697
- package/dist/support.cjs +402 -328
- package/dist/support.d.cts +29 -3
- package/dist/support.d.ts +29 -3
- package/dist/support.mjs +401 -328
- package/dist/telemetry.cjs +267 -304
- package/dist/telemetry.d.cts +1 -1
- package/dist/telemetry.d.ts +1 -1
- package/dist/telemetry.mjs +267 -304
- package/dist/{types-Du_iioJ7.d.cts → types-D-9bjlM0.d.cts} +74 -1
- package/dist/{types-BPATkXYu.d.ts → types-bVztFQTI.d.ts} +74 -1
- package/dist/usage.cjs +233 -230
- package/dist/usage.d.cts +1 -1
- package/dist/usage.d.ts +1 -1
- package/dist/usage.mjs +233 -230
- package/dist/webhooks.cjs +328 -362
- package/dist/webhooks.d.cts +1 -1
- package/dist/webhooks.d.ts +1 -1
- package/dist/webhooks.mjs +325 -359
- package/package.json +5 -3
- package/dist/ai.cjs.map +0 -1
- package/dist/ai.mjs.map +0 -1
- package/dist/auth.cjs.map +0 -1
- package/dist/auth.mjs.map +0 -1
- package/dist/build-guard.cjs.map +0 -1
- package/dist/build-guard.mjs.map +0 -1
- package/dist/catalog.cjs.map +0 -1
- package/dist/catalog.mjs.map +0 -1
- package/dist/checkout.cjs.map +0 -1
- package/dist/checkout.mjs.map +0 -1
- package/dist/db-react.cjs.map +0 -1
- package/dist/db-react.mjs.map +0 -1
- package/dist/db.cjs.map +0 -1
- package/dist/db.mjs.map +0 -1
- package/dist/entitlements.cjs.map +0 -1
- package/dist/entitlements.mjs.map +0 -1
- package/dist/errors.cjs.map +0 -1
- package/dist/errors.mjs.map +0 -1
- package/dist/firestore-compat.cjs.map +0 -1
- package/dist/firestore-compat.mjs.map +0 -1
- package/dist/index.cjs.map +0 -1
- package/dist/index.mjs.map +0 -1
- package/dist/mobile.cjs.map +0 -1
- package/dist/mobile.mjs.map +0 -1
- package/dist/mocks.cjs.map +0 -1
- package/dist/mocks.mjs.map +0 -1
- package/dist/notifications.cjs.map +0 -1
- package/dist/notifications.mjs.map +0 -1
- package/dist/react.cjs.map +0 -1
- package/dist/react.mjs.map +0 -1
- package/dist/support.cjs.map +0 -1
- package/dist/support.mjs.map +0 -1
- package/dist/telemetry.cjs.map +0 -1
- package/dist/telemetry.mjs.map +0 -1
- package/dist/usage.cjs.map +0 -1
- package/dist/usage.mjs.map +0 -1
- package/dist/webhooks.cjs.map +0 -1
- package/dist/webhooks.mjs.map +0 -1
package/dist/ai.cjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
// src/errors.ts
|
|
4
|
-
var
|
|
4
|
+
var u = class t extends Error {
|
|
5
5
|
code;
|
|
6
6
|
status;
|
|
7
7
|
requestId;
|
|
@@ -14,517 +14,424 @@ var NeetruError = class _NeetruError extends Error {
|
|
|
14
14
|
* para um `NeetruDbErrorCode` mais específico (recuperável vs não).
|
|
15
15
|
*/
|
|
16
16
|
reason;
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
17
|
+
/**
|
|
18
|
+
* 3.8.0: `x-correlation-id` da requisição que falhou. O SDK gera um UUID por
|
|
19
|
+
* chamada (ou usa o que o chamador passou) e manda no header; o Core grava o
|
|
20
|
+
* mesmo id nos logs/auditoria — cite-o ao abrir um ticket de suporte.
|
|
21
|
+
* `undefined` em erros que acontecem antes de qualquer requisição.
|
|
22
|
+
*/
|
|
23
|
+
correlationId;
|
|
24
|
+
constructor(e, i, r, n, o, s) {
|
|
25
|
+
super(i), this.name = "NeetruError", this.code = e, this.status = r, this.requestId = n, this.reason = o, this.correlationId = s, Object.setPrototypeOf(this, t.prototype);
|
|
25
26
|
}
|
|
26
27
|
};
|
|
27
28
|
|
|
29
|
+
// src/correlation.ts
|
|
30
|
+
var w = "x-correlation-id";
|
|
31
|
+
var V = /^[A-Za-z0-9._:\-]+$/;
|
|
32
|
+
function E(t) {
|
|
33
|
+
return typeof t == "string" && t.length > 0 && t.length <= 128 && V.test(t);
|
|
34
|
+
}
|
|
35
|
+
function J() {
|
|
36
|
+
let t = globalThis.crypto;
|
|
37
|
+
try {
|
|
38
|
+
if (t && typeof t.randomUUID == "function") return t.randomUUID();
|
|
39
|
+
} catch {
|
|
40
|
+
}
|
|
41
|
+
let e = new Uint8Array(16), i = false;
|
|
42
|
+
try {
|
|
43
|
+
t && typeof t.getRandomValues == "function" && (t.getRandomValues(e), i = !0);
|
|
44
|
+
} catch {
|
|
45
|
+
i = false;
|
|
46
|
+
}
|
|
47
|
+
if (!i)
|
|
48
|
+
for (let n = 0; n < e.length; n++) e[n] = Math.floor(Math.random() * 256);
|
|
49
|
+
e[6] = e[6] & 15 | 64, e[8] = e[8] & 63 | 128;
|
|
50
|
+
let r = Array.from(e, (n) => n.toString(16).padStart(2, "0")).join("");
|
|
51
|
+
return `${r.slice(0, 8)}-${r.slice(8, 12)}-${r.slice(12, 16)}-${r.slice(16, 20)}-${r.slice(20)}`;
|
|
52
|
+
}
|
|
53
|
+
function x(t, e) {
|
|
54
|
+
let i, r = {};
|
|
55
|
+
for (let [o, s] of Object.entries(t)) {
|
|
56
|
+
if (o.toLowerCase() === w) {
|
|
57
|
+
E(s) && (i = s);
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
r[o] = s;
|
|
61
|
+
}
|
|
62
|
+
let n = i ?? (E(e) ? e : void 0) ?? J();
|
|
63
|
+
return r[w] = n, { headers: r, correlationId: n };
|
|
64
|
+
}
|
|
65
|
+
|
|
28
66
|
// src/http.ts
|
|
29
|
-
var
|
|
67
|
+
var Y = {
|
|
30
68
|
// SDK major 3.x requer Core ≥ 2026.05.1 (suporte a X-Neetru-Version header,
|
|
31
69
|
// runTransaction write-after-read, verifyWebhookRequest, webhooks 3.0+)
|
|
32
70
|
3: "2026.05.1"
|
|
33
71
|
};
|
|
34
|
-
function
|
|
35
|
-
return
|
|
72
|
+
function A(t) {
|
|
73
|
+
return t.split("+")[0] ?? t;
|
|
36
74
|
}
|
|
37
|
-
function
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
const pa = partsA[i] ?? 0;
|
|
43
|
-
const pb = partsB[i] ?? 0;
|
|
44
|
-
if (pa !== pb) return pa - pb;
|
|
75
|
+
function Z(t, e) {
|
|
76
|
+
let i = A(t).split(".").map(Number), r = A(e).split(".").map(Number), n = Math.max(i.length, r.length);
|
|
77
|
+
for (let o = 0; o < n; o++) {
|
|
78
|
+
let s = i[o] ?? 0, c = r[o] ?? 0;
|
|
79
|
+
if (s !== c) return s - c;
|
|
45
80
|
}
|
|
46
81
|
return 0;
|
|
47
82
|
}
|
|
48
|
-
function
|
|
83
|
+
function Q() {
|
|
49
84
|
try {
|
|
50
|
-
return "3.
|
|
85
|
+
return "3.8.0";
|
|
51
86
|
} catch {
|
|
52
|
-
return
|
|
87
|
+
return;
|
|
53
88
|
}
|
|
54
89
|
}
|
|
55
|
-
function
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
return 3;
|
|
90
|
+
function ee() {
|
|
91
|
+
let t = Q();
|
|
92
|
+
return t ? parseInt(t.split(".")[0] ?? "3", 10) : 3;
|
|
59
93
|
}
|
|
60
|
-
var
|
|
61
|
-
function
|
|
62
|
-
if (!
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
console.warn(
|
|
72
|
-
`[Neetru SDK] Aten\xE7\xE3o: Core vers\xE3o "${coreVersion}" \xE9 anterior ao m\xEDnimo recomendado "${minCore}" para SDK major ${sdkMajor}. Alguns recursos podem n\xE3o funcionar corretamente. Atualize o Core para a vers\xE3o mais recente.`
|
|
73
|
-
);
|
|
74
|
-
}
|
|
94
|
+
var R = /* @__PURE__ */ new Set();
|
|
95
|
+
function k(t) {
|
|
96
|
+
if (!t) return;
|
|
97
|
+
let e = ee(), i = Y[e];
|
|
98
|
+
if (!i) return;
|
|
99
|
+
let r = A(t);
|
|
100
|
+
if (Z(r, i) < 0) {
|
|
101
|
+
let n = `${e}:${r}`;
|
|
102
|
+
R.has(n) || (R.add(n), console.warn(
|
|
103
|
+
`[Neetru SDK] Aten\xE7\xE3o: Core vers\xE3o "${t}" \xE9 anterior ao m\xEDnimo recomendado "${i}" para SDK major ${e}. Alguns recursos podem n\xE3o funcionar corretamente. Atualize o Core para a vers\xE3o mais recente.`
|
|
104
|
+
));
|
|
75
105
|
}
|
|
76
106
|
}
|
|
77
|
-
function
|
|
78
|
-
|
|
79
|
-
if (status === 403) return "forbidden";
|
|
80
|
-
if (status === 404) return "not_found";
|
|
81
|
-
if (status === 409) return "conflict";
|
|
82
|
-
if (status === 422 || status === 400) return "validation_failed";
|
|
83
|
-
if (status === 429) return "rate_limited";
|
|
84
|
-
if (status >= 500) return "server_error";
|
|
85
|
-
return "unknown";
|
|
107
|
+
function T(t) {
|
|
108
|
+
return t === 401 ? "unauthorized" : t === 403 ? "forbidden" : t === 404 ? "not_found" : t === 409 ? "conflict" : t === 410 ? "gone" : t === 422 || t === 400 ? "validation_failed" : t === 429 ? "rate_limited" : t >= 500 ? "server_error" : "unknown";
|
|
86
109
|
}
|
|
87
110
|
|
|
88
111
|
// src/validators.ts
|
|
89
|
-
var
|
|
90
|
-
function
|
|
91
|
-
if (typeof
|
|
92
|
-
throw new
|
|
112
|
+
var S = /^[a-z0-9][a-z0-9_-]{0,62}$/i;
|
|
113
|
+
function b(t, e) {
|
|
114
|
+
if (typeof e != "string" || !S.test(e))
|
|
115
|
+
throw new u(
|
|
93
116
|
"validation_failed",
|
|
94
|
-
`${
|
|
117
|
+
`${t} must match ${S.source} (lowercase alphanumeric, _, -; first char must be alphanumeric; max 63 chars)`
|
|
95
118
|
);
|
|
96
|
-
}
|
|
97
119
|
}
|
|
98
120
|
|
|
99
121
|
// src/ai.ts
|
|
100
|
-
var
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
var MAX_CONTENT_PARTS = 32;
|
|
104
|
-
var MAX_DATA_URL_LEN = 4194304;
|
|
105
|
-
var MAX_HTTPS_URL_LEN = 2048;
|
|
106
|
-
var DATA_IMAGE_URL_RE = /^data:image\/(?:png|jpe?g|gif|webp);base64,[A-Za-z0-9+/]+={0,2}$/;
|
|
107
|
-
var HTTPS_URL_RE = /^https:\/\/[^\s]+$/;
|
|
108
|
-
var IMAGE_DETAIL_VALUES = /* @__PURE__ */ new Set(["low", "high", "auto"]);
|
|
109
|
-
var AI_ROLES = /* @__PURE__ */ new Set(["system", "user", "assistant"]);
|
|
110
|
-
var MAX_MESSAGES = 100;
|
|
111
|
-
var MAX_MODEL_LEN = 128;
|
|
112
|
-
var MAX_TOKENS_CAP = 32768;
|
|
113
|
-
var MIN_TEMPERATURE = 0;
|
|
114
|
-
var MAX_TEMPERATURE = 2;
|
|
115
|
-
var MAX_TOTAL_CONTENT_PARTS = 200;
|
|
116
|
-
var MAX_TOTAL_IMAGES = 20;
|
|
117
|
-
var MAX_TOTAL_IMAGE_BYTES = 12 * 1024 * 1024;
|
|
118
|
-
var MAX_SCHEMA_JSON_LEN = 5e4;
|
|
119
|
-
var MAX_SCHEMA_DEPTH = 16;
|
|
120
|
-
var MAX_SCHEMA_KEYS = 500;
|
|
121
|
-
var FORBIDDEN_SCHEMA_KEYS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
|
|
122
|
-
var RESPONSE_FORMAT_NAME_RE = /^[a-zA-Z0-9_-]+$/;
|
|
123
|
-
function fail(msg) {
|
|
124
|
-
throw new NeetruError("validation_failed", msg);
|
|
122
|
+
var te = "/api/sdk/v1/ai/chat", v = 12e4, _ = 32768, C = 32, I = 4194304, M = 2048, ne = /^data:image\/(?:png|jpe?g|gif|webp);base64,[A-Za-z0-9+/]+={0,2}$/, re = /^https:\/\/[^\s]+$/, ie = /* @__PURE__ */ new Set(["low", "high", "auto"]), oe = /* @__PURE__ */ new Set(["system", "user", "assistant"]), j = 100, N = 128, O = 32768, $ = 0, P = 2, D = 200, q = 20, F = 12 * 1024 * 1024, L = 5e4, U = 16, H = 500, se = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]), ae = /^[a-zA-Z0-9_-]+$/;
|
|
123
|
+
function a(t) {
|
|
124
|
+
throw new u("validation_failed", t);
|
|
125
125
|
}
|
|
126
|
-
function
|
|
127
|
-
if (
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
return !body.includes("=");
|
|
126
|
+
function ce(t) {
|
|
127
|
+
if (t.length === 0 || t.length % 4 !== 0) return false;
|
|
128
|
+
let e = t.endsWith("==") ? 2 : t.endsWith("=") ? 1 : 0;
|
|
129
|
+
return !(e > 0 ? t.slice(0, t.length - e) : t).includes("=");
|
|
131
130
|
}
|
|
132
|
-
function
|
|
133
|
-
|
|
134
|
-
if (
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
return Math.max(0, Math.floor(b64.length * 3 / 4) - pad);
|
|
131
|
+
function ue(t) {
|
|
132
|
+
let e = t.indexOf(",");
|
|
133
|
+
if (e === -1) return 0;
|
|
134
|
+
let i = t.slice(e + 1), r = i.endsWith("==") ? 2 : i.endsWith("=") ? 1 : 0;
|
|
135
|
+
return Math.max(0, Math.floor(i.length * 3 / 4) - r);
|
|
138
136
|
}
|
|
139
|
-
function
|
|
140
|
-
let
|
|
141
|
-
let
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
if (totalImages > MAX_TOTAL_IMAGES) {
|
|
154
|
-
return `ai: total images exceeds ${MAX_TOTAL_IMAGES} per request`;
|
|
155
|
-
}
|
|
156
|
-
const url = part.image_url?.url;
|
|
157
|
-
if (typeof url === "string" && url.startsWith("data:")) {
|
|
158
|
-
totalImageBytes += dataUrlDecodedBytes(url);
|
|
159
|
-
if (totalImageBytes > MAX_TOTAL_IMAGE_BYTES) {
|
|
160
|
-
return `ai: aggregate image bytes exceeds ${MAX_TOTAL_IMAGE_BYTES} per request`;
|
|
161
|
-
}
|
|
137
|
+
function de(t) {
|
|
138
|
+
let e = 0, i = 0, r = 0;
|
|
139
|
+
for (let n of t) {
|
|
140
|
+
let o = n?.content;
|
|
141
|
+
if (Array.isArray(o))
|
|
142
|
+
for (let s of o) {
|
|
143
|
+
if (e++, e > D)
|
|
144
|
+
return `ai: total content parts exceeds ${D} per request`;
|
|
145
|
+
if (s && typeof s == "object" && s.type === "image_url") {
|
|
146
|
+
if (i++, i > q)
|
|
147
|
+
return `ai: total images exceeds ${q} per request`;
|
|
148
|
+
let c = s.image_url?.url;
|
|
149
|
+
if (typeof c == "string" && c.startsWith("data:") && (r += ue(c), r > F))
|
|
150
|
+
return `ai: aggregate image bytes exceeds ${F} per request`;
|
|
162
151
|
}
|
|
163
152
|
}
|
|
164
|
-
}
|
|
165
153
|
}
|
|
166
154
|
return null;
|
|
167
155
|
}
|
|
168
|
-
function
|
|
169
|
-
if (
|
|
170
|
-
if (
|
|
156
|
+
function le(t) {
|
|
157
|
+
if (t === void 0) return null;
|
|
158
|
+
if (t === null || typeof t != "object")
|
|
171
159
|
return "ai: responseFormat json_schema.schema must be an object";
|
|
172
|
-
|
|
173
|
-
let serialized;
|
|
160
|
+
let e;
|
|
174
161
|
try {
|
|
175
|
-
|
|
162
|
+
e = JSON.stringify(t);
|
|
176
163
|
} catch {
|
|
177
164
|
return "ai: responseFormat json_schema.schema is not serializable";
|
|
178
165
|
}
|
|
179
|
-
if (
|
|
180
|
-
if (
|
|
181
|
-
return `ai: responseFormat json_schema.schema exceeds ${
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
if (
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
for (const item of node) {
|
|
190
|
-
const e = walk(item, depth + 1);
|
|
191
|
-
if (e) return e;
|
|
166
|
+
if (e === void 0) return "ai: responseFormat json_schema.schema is invalid";
|
|
167
|
+
if (e.length > L)
|
|
168
|
+
return `ai: responseFormat json_schema.schema exceeds ${L} serialized chars`;
|
|
169
|
+
let i = 0, r = (n, o) => {
|
|
170
|
+
if (o > U)
|
|
171
|
+
return `ai: responseFormat json_schema.schema exceeds max depth ${U}`;
|
|
172
|
+
if (Array.isArray(n)) {
|
|
173
|
+
for (let s of n) {
|
|
174
|
+
let c = r(s, o + 1);
|
|
175
|
+
if (c) return c;
|
|
192
176
|
}
|
|
193
177
|
return null;
|
|
194
178
|
}
|
|
195
|
-
if (
|
|
196
|
-
for (
|
|
197
|
-
if (
|
|
198
|
-
return `ai: responseFormat json_schema.schema has forbidden key: ${
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
}
|
|
204
|
-
const e = walk(node[key], depth + 1);
|
|
205
|
-
if (e) return e;
|
|
179
|
+
if (n && typeof n == "object")
|
|
180
|
+
for (let s of Object.getOwnPropertyNames(n)) {
|
|
181
|
+
if (se.has(s))
|
|
182
|
+
return `ai: responseFormat json_schema.schema has forbidden key: ${s}`;
|
|
183
|
+
if (i++, i > H)
|
|
184
|
+
return `ai: responseFormat json_schema.schema exceeds ${H} keys`;
|
|
185
|
+
let c = r(n[s], o + 1);
|
|
186
|
+
if (c) return c;
|
|
206
187
|
}
|
|
207
|
-
}
|
|
208
188
|
return null;
|
|
209
189
|
};
|
|
210
|
-
return
|
|
190
|
+
return r(t, 0);
|
|
211
191
|
}
|
|
212
|
-
function
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
if (!DATA_IMAGE_URL_RE.test(u)) {
|
|
220
|
-
fail("ai: image_url.url data: must be data:image/<png|jpeg|jpg|gif|webp>;base64,<...>");
|
|
221
|
-
}
|
|
222
|
-
const b64 = u.slice(u.indexOf(",") + 1);
|
|
223
|
-
if (!isStrictBase64Payload(b64)) {
|
|
224
|
-
fail("ai: image_url.url data: has invalid base64 (length/padding)");
|
|
225
|
-
}
|
|
192
|
+
function fe(t) {
|
|
193
|
+
(typeof t != "string" || t.length === 0) && a("ai: image_url.url must be a non-empty string");
|
|
194
|
+
let e = t;
|
|
195
|
+
if (e.startsWith("data:")) {
|
|
196
|
+
e.length > I && a(`ai: image_url.url (data:) exceeds ${I} chars`), ne.test(e) || a("ai: image_url.url data: must be data:image/<png|jpeg|jpg|gif|webp>;base64,<...>");
|
|
197
|
+
let i = e.slice(e.indexOf(",") + 1);
|
|
198
|
+
ce(i) || a("ai: image_url.url data: has invalid base64 (length/padding)");
|
|
226
199
|
return;
|
|
227
200
|
}
|
|
228
|
-
if (
|
|
229
|
-
|
|
230
|
-
if (!HTTPS_URL_RE.test(u)) fail("ai: image_url.url https: is invalid");
|
|
201
|
+
if (e.startsWith("https://")) {
|
|
202
|
+
e.length > M && a(`ai: image_url.url (https:) exceeds ${M} chars`), re.test(e) || a("ai: image_url.url https: is invalid");
|
|
231
203
|
return;
|
|
232
204
|
}
|
|
233
|
-
|
|
205
|
+
a("ai: image_url.url must be a data:image/...;base64 or https:// URL (other schemes are rejected)");
|
|
234
206
|
}
|
|
235
|
-
function
|
|
236
|
-
if (typeof
|
|
237
|
-
|
|
238
|
-
if (content.length > MAX_TEXT_PART_LEN) fail(`ai: message content exceeds ${MAX_TEXT_PART_LEN} chars`);
|
|
207
|
+
function me(t, e) {
|
|
208
|
+
if (typeof t == "string") {
|
|
209
|
+
t.length === 0 && a("ai: message content string must be non-empty"), t.length > _ && a(`ai: message content exceeds ${_} chars`);
|
|
239
210
|
return;
|
|
240
211
|
}
|
|
241
|
-
|
|
242
|
-
|
|
212
|
+
(!Array.isArray(t) || t.length === 0) && a("ai: message content must be a non-empty string or array of parts"), t.length > C && a(`ai: message content has more than ${C} parts`);
|
|
213
|
+
for (let i of t) {
|
|
214
|
+
(!i || typeof i != "object") && a("ai: each content part must be an object");
|
|
215
|
+
let r = i.type;
|
|
216
|
+
if (r === "text") {
|
|
217
|
+
let n = i.text;
|
|
218
|
+
(typeof n != "string" || n.length === 0) && a("ai: text part must have non-empty { text: string }"), n.length > _ && a(`ai: text part exceeds ${_} chars`);
|
|
219
|
+
} else if (r === "image_url") {
|
|
220
|
+
e !== "user" && a(`ai: image_url is only allowed in role 'user' messages (got '${e}')`);
|
|
221
|
+
let n = i.image_url;
|
|
222
|
+
(!n || typeof n != "object") && a("ai: image_url part must have { image_url: { url } }"), fe(n.url);
|
|
223
|
+
let o = n.detail;
|
|
224
|
+
o !== void 0 && (typeof o != "string" || !ie.has(o)) && a("ai: image_url.detail must be 'low' | 'high' | 'auto'");
|
|
225
|
+
} else
|
|
226
|
+
a("ai: content part type must be 'text' or 'image_url'");
|
|
243
227
|
}
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
if (
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
const iu = part.image_url;
|
|
257
|
-
if (!iu || typeof iu !== "object") fail("ai: image_url part must have { image_url: { url } }");
|
|
258
|
-
validateImageUrl(iu.url);
|
|
259
|
-
const detail = iu.detail;
|
|
260
|
-
if (detail !== void 0 && (typeof detail !== "string" || !IMAGE_DETAIL_VALUES.has(detail))) {
|
|
261
|
-
fail("ai: image_url.detail must be 'low' | 'high' | 'auto'");
|
|
228
|
+
}
|
|
229
|
+
function pe(t) {
|
|
230
|
+
(!t || typeof t != "object") && a("ai: responseFormat must be an object");
|
|
231
|
+
let e = t.type;
|
|
232
|
+
if (!(e === "text" || e === "json_object")) {
|
|
233
|
+
if (e === "json_schema") {
|
|
234
|
+
let i = t.json_schema;
|
|
235
|
+
(!i || typeof i != "object") && a("ai: responseFormat json_schema requires { json_schema: { name } }");
|
|
236
|
+
let r = i, n = r.name;
|
|
237
|
+
if ((typeof n != "string" || n.length === 0) && a("ai: responseFormat json_schema.name is required"), n.length > 64 && a("ai: responseFormat json_schema.name exceeds 64 chars"), ae.test(n) || a("ai: responseFormat json_schema.name must match a-zA-Z0-9_-"), r.description !== void 0 && (typeof r.description != "string" && a("ai: responseFormat json_schema.description must be a string"), r.description.length > 1e3 && a("ai: responseFormat json_schema.description exceeds 1000 chars")), r.strict !== void 0 && typeof r.strict != "boolean" && a("ai: responseFormat json_schema.strict must be a boolean"), r.schema !== void 0) {
|
|
238
|
+
let o = le(r.schema);
|
|
239
|
+
o && a(o);
|
|
262
240
|
}
|
|
263
|
-
|
|
264
|
-
fail("ai: content part type must be 'text' or 'image_url'");
|
|
241
|
+
return;
|
|
265
242
|
}
|
|
243
|
+
a("ai: responseFormat.type must be 'text' | 'json_object' | 'json_schema'");
|
|
266
244
|
}
|
|
267
245
|
}
|
|
268
|
-
function
|
|
269
|
-
if (!
|
|
270
|
-
|
|
271
|
-
if (
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
if (
|
|
281
|
-
|
|
282
|
-
if (jso.description.length > 1e3) fail("ai: responseFormat json_schema.description exceeds 1000 chars");
|
|
283
|
-
}
|
|
284
|
-
if (jso.strict !== void 0 && typeof jso.strict !== "boolean") {
|
|
285
|
-
fail("ai: responseFormat json_schema.strict must be a boolean");
|
|
286
|
-
}
|
|
287
|
-
if (jso.schema !== void 0) {
|
|
288
|
-
const err = validateStructuredSchema(jso.schema);
|
|
289
|
-
if (err) fail(err);
|
|
290
|
-
}
|
|
291
|
-
return;
|
|
292
|
-
}
|
|
293
|
-
fail("ai: responseFormat.type must be 'text' | 'json_object' | 'json_schema'");
|
|
294
|
-
}
|
|
295
|
-
function resolveAiBody(config, opts, stream) {
|
|
296
|
-
if (!opts || typeof opts !== "object") {
|
|
297
|
-
throw new NeetruError("validation_failed", "ai: options object is required");
|
|
298
|
-
}
|
|
299
|
-
if (typeof opts.model !== "string" || opts.model.length === 0) {
|
|
300
|
-
throw new NeetruError("validation_failed", "ai: model is required");
|
|
301
|
-
}
|
|
302
|
-
if (opts.model.length > MAX_MODEL_LEN) {
|
|
303
|
-
throw new NeetruError("validation_failed", `ai: model exceeds ${MAX_MODEL_LEN} chars`);
|
|
304
|
-
}
|
|
305
|
-
if (!Array.isArray(opts.messages) || opts.messages.length === 0) {
|
|
306
|
-
throw new NeetruError("validation_failed", "ai: messages must be a non-empty array");
|
|
307
|
-
}
|
|
308
|
-
if (opts.messages.length > MAX_MESSAGES) {
|
|
309
|
-
throw new NeetruError("validation_failed", `ai: messages exceeds ${MAX_MESSAGES} per request`);
|
|
310
|
-
}
|
|
311
|
-
for (const m of opts.messages) {
|
|
312
|
-
if (!m || typeof m !== "object" || typeof m.role !== "string" || !AI_ROLES.has(m.role)) {
|
|
313
|
-
throw new NeetruError(
|
|
246
|
+
function K(t, e, i) {
|
|
247
|
+
if (!e || typeof e != "object")
|
|
248
|
+
throw new u("validation_failed", "ai: options object is required");
|
|
249
|
+
if (typeof e.model != "string" || e.model.length === 0)
|
|
250
|
+
throw new u("validation_failed", "ai: model is required");
|
|
251
|
+
if (e.model.length > N)
|
|
252
|
+
throw new u("validation_failed", `ai: model exceeds ${N} chars`);
|
|
253
|
+
if (!Array.isArray(e.messages) || e.messages.length === 0)
|
|
254
|
+
throw new u("validation_failed", "ai: messages must be a non-empty array");
|
|
255
|
+
if (e.messages.length > j)
|
|
256
|
+
throw new u("validation_failed", `ai: messages exceeds ${j} per request`);
|
|
257
|
+
for (let c of e.messages) {
|
|
258
|
+
if (!c || typeof c != "object" || typeof c.role != "string" || !oe.has(c.role))
|
|
259
|
+
throw new u(
|
|
314
260
|
"validation_failed",
|
|
315
261
|
"ai: each message role must be 'system' | 'user' | 'assistant'"
|
|
316
262
|
);
|
|
317
|
-
|
|
318
|
-
validateAiContent(m.content, m.role);
|
|
263
|
+
me(c.content, c.role);
|
|
319
264
|
}
|
|
320
|
-
|
|
321
|
-
if (
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
throw new NeetruError(
|
|
265
|
+
let r = de(e.messages);
|
|
266
|
+
if (r) throw new u("validation_failed", r);
|
|
267
|
+
let n = e.productId ?? t.productId, o = e.tenantId ?? t.tenantId;
|
|
268
|
+
if (!n)
|
|
269
|
+
throw new u(
|
|
326
270
|
"validation_failed",
|
|
327
271
|
"ai: productId required (pass to options or set on createNeetruClient)"
|
|
328
272
|
);
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
throw new NeetruError(
|
|
273
|
+
if (!o)
|
|
274
|
+
throw new u(
|
|
332
275
|
"validation_failed",
|
|
333
276
|
"ai: tenantId required (pass to options or set on createNeetruClient)"
|
|
334
277
|
);
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
messages: opts.messages,
|
|
343
|
-
stream
|
|
278
|
+
b("productId", n), b("tenantId", o);
|
|
279
|
+
let s = {
|
|
280
|
+
productId: n,
|
|
281
|
+
tenantId: o,
|
|
282
|
+
model: e.model,
|
|
283
|
+
messages: e.messages,
|
|
284
|
+
stream: i
|
|
344
285
|
};
|
|
345
|
-
if (
|
|
346
|
-
if (!Number.isInteger(
|
|
347
|
-
throw new
|
|
286
|
+
if (e.maxTokens !== void 0) {
|
|
287
|
+
if (!Number.isInteger(e.maxTokens) || e.maxTokens <= 0 || e.maxTokens > O)
|
|
288
|
+
throw new u(
|
|
348
289
|
"validation_failed",
|
|
349
|
-
`ai: maxTokens must be a positive integer <= ${
|
|
290
|
+
`ai: maxTokens must be a positive integer <= ${O}`
|
|
350
291
|
);
|
|
351
|
-
|
|
352
|
-
body.maxTokens = opts.maxTokens;
|
|
292
|
+
s.maxTokens = e.maxTokens;
|
|
353
293
|
}
|
|
354
|
-
if (
|
|
355
|
-
if (typeof
|
|
356
|
-
throw new
|
|
294
|
+
if (e.temperature !== void 0) {
|
|
295
|
+
if (typeof e.temperature != "number" || !Number.isFinite(e.temperature) || e.temperature < $ || e.temperature > P)
|
|
296
|
+
throw new u(
|
|
357
297
|
"validation_failed",
|
|
358
|
-
`ai: temperature must be a finite number between ${
|
|
298
|
+
`ai: temperature must be a finite number between ${$} and ${P}`
|
|
359
299
|
);
|
|
360
|
-
|
|
361
|
-
body.temperature = opts.temperature;
|
|
300
|
+
s.temperature = e.temperature;
|
|
362
301
|
}
|
|
363
|
-
|
|
364
|
-
validateResponseFormat(opts.responseFormat);
|
|
365
|
-
body.responseFormat = opts.responseFormat;
|
|
366
|
-
}
|
|
367
|
-
return body;
|
|
302
|
+
return e.responseFormat !== void 0 && (pe(e.responseFormat), s.responseFormat = e.responseFormat), s;
|
|
368
303
|
}
|
|
369
|
-
async function
|
|
304
|
+
async function B(t) {
|
|
370
305
|
try {
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
return JSON.parse(text);
|
|
306
|
+
let e = await t.text();
|
|
307
|
+
return e ? JSON.parse(e) : void 0;
|
|
374
308
|
} catch {
|
|
375
|
-
return
|
|
309
|
+
return;
|
|
376
310
|
}
|
|
377
311
|
}
|
|
378
|
-
function
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
return `${base}${p}`;
|
|
312
|
+
function ge(t, e) {
|
|
313
|
+
let i = t.replace(/\/+$/, ""), r = e.startsWith("/") ? e : `/${e}`;
|
|
314
|
+
return `${i}${r}`;
|
|
382
315
|
}
|
|
383
|
-
async function
|
|
384
|
-
if (!
|
|
385
|
-
throw new
|
|
316
|
+
async function X(t, e, i, r) {
|
|
317
|
+
if (!t.apiKey)
|
|
318
|
+
throw new u(
|
|
386
319
|
"missing_api_key",
|
|
387
320
|
"ai requires an apiKey. Pass it to createNeetruClient({ apiKey }) or set NEETRU_API_KEY env var."
|
|
388
321
|
);
|
|
389
|
-
}
|
|
390
|
-
const url = joinUrl(config.baseUrl, AI_CHAT_PATH);
|
|
391
|
-
const headers = {
|
|
322
|
+
let n = ge(t.baseUrl, te), { headers: o, correlationId: s } = x({
|
|
392
323
|
"content-type": "application/json",
|
|
393
|
-
accept:
|
|
394
|
-
authorization: `Bearer ${
|
|
395
|
-
};
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
if (signal) init.signal = signal;
|
|
399
|
-
} else {
|
|
400
|
-
init.signal = signal ?? AbortSignal.timeout(AI_NONSTREAM_TIMEOUT_MS);
|
|
401
|
-
}
|
|
402
|
-
let res;
|
|
324
|
+
accept: r ? "text/event-stream" : "application/json",
|
|
325
|
+
authorization: `Bearer ${t.apiKey}`
|
|
326
|
+
}), c = { method: "POST", headers: o, body: JSON.stringify(e) };
|
|
327
|
+
r ? i && (c.signal = i) : c.signal = i ?? AbortSignal.timeout(v);
|
|
328
|
+
let l;
|
|
403
329
|
try {
|
|
404
|
-
|
|
405
|
-
} catch (
|
|
406
|
-
|
|
407
|
-
throw new
|
|
408
|
-
}
|
|
409
|
-
|
|
410
|
-
if (!
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
const errField = parsed.error;
|
|
416
|
-
if (typeof errField === "string") {
|
|
417
|
-
message = errField;
|
|
418
|
-
} else if (errField && typeof errField === "object") {
|
|
419
|
-
if (typeof errField.code === "string") code = errField.code;
|
|
420
|
-
if (typeof errField.message === "string") message = errField.message;
|
|
421
|
-
}
|
|
330
|
+
l = await t.fetch(n, c);
|
|
331
|
+
} catch (d) {
|
|
332
|
+
let m = d instanceof DOMException && d.name === "TimeoutError" ? `Network error: timeout after ${v / 1e3}s` : d instanceof DOMException && d.name === "AbortError" ? "Network error: request aborted" : `Network error: ${d instanceof Error ? d.message : "fetch failed"}`;
|
|
333
|
+
throw new u("network_error", m, void 0, void 0, void 0, s);
|
|
334
|
+
}
|
|
335
|
+
let y = l.headers.get("x-request-id") ?? l.headers.get("x-correlation-id") ?? void 0;
|
|
336
|
+
if (!l.ok) {
|
|
337
|
+
let d = await B(l), m = T(l.status), g = `HTTP ${l.status}`;
|
|
338
|
+
if (d && typeof d == "object" && "error" in d) {
|
|
339
|
+
let f = d.error;
|
|
340
|
+
typeof f == "string" ? g = f : f && typeof f == "object" && (typeof f.code == "string" && (m = f.code), typeof f.message == "string" && (g = f.message));
|
|
422
341
|
}
|
|
423
|
-
throw new
|
|
342
|
+
throw new u(m, g, l.status, y, void 0, s);
|
|
424
343
|
}
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
return res;
|
|
344
|
+
let p = l.headers.get("x-neetru-version");
|
|
345
|
+
return p && k(p), l;
|
|
428
346
|
}
|
|
429
|
-
function
|
|
347
|
+
function z(t) {
|
|
430
348
|
return {
|
|
431
|
-
provider:
|
|
432
|
-
usageWarning:
|
|
349
|
+
provider: t.headers.get("x-neetru-provider") ?? "",
|
|
350
|
+
usageWarning: t.headers.get("x-neetru-ai-usage-warning") === "1"
|
|
433
351
|
};
|
|
434
352
|
}
|
|
435
|
-
function
|
|
436
|
-
|
|
437
|
-
for (
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
353
|
+
function W(t) {
|
|
354
|
+
let e = [];
|
|
355
|
+
for (let r of t.split(`
|
|
356
|
+
`)) {
|
|
357
|
+
let n = r.replace(/\r$/, "");
|
|
358
|
+
if (n.startsWith("data:")) {
|
|
359
|
+
let o = n.slice(5);
|
|
360
|
+
o.startsWith(" ") && (o = o.slice(1)), e.push(o);
|
|
443
361
|
}
|
|
444
362
|
}
|
|
445
|
-
if (
|
|
446
|
-
|
|
447
|
-
|
|
363
|
+
if (e.length === 0) return null;
|
|
364
|
+
let i = e.join(`
|
|
365
|
+
`);
|
|
366
|
+
if (i === "[DONE]") return { done: true };
|
|
448
367
|
try {
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
if (typeof content === "string" && content.length > 0) return { content };
|
|
452
|
-
return null;
|
|
368
|
+
let n = JSON.parse(i)?.choices?.[0]?.delta?.content;
|
|
369
|
+
return typeof n == "string" && n.length > 0 ? { content: n } : null;
|
|
453
370
|
} catch {
|
|
454
371
|
return null;
|
|
455
372
|
}
|
|
456
373
|
}
|
|
457
|
-
function
|
|
374
|
+
function ke(t) {
|
|
458
375
|
return {
|
|
459
|
-
async chat(
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
const raw = await safeJson(res);
|
|
464
|
-
if (!raw || raw.ok !== true || !Array.isArray(raw.choices)) {
|
|
465
|
-
throw new NeetruError("invalid_response", "ai.chat response missing ok/choices");
|
|
466
|
-
}
|
|
376
|
+
async chat(e) {
|
|
377
|
+
let i = K(t, e, false), r = await X(t, i, e.signal, false), { provider: n, usageWarning: o } = z(r), s = await B(r);
|
|
378
|
+
if (!s || s.ok !== true || !Array.isArray(s.choices))
|
|
379
|
+
throw new u("invalid_response", "ai.chat response missing ok/choices");
|
|
467
380
|
return {
|
|
468
|
-
choices:
|
|
469
|
-
usage:
|
|
470
|
-
model:
|
|
471
|
-
provider:
|
|
472
|
-
usageWarning
|
|
381
|
+
choices: s.choices,
|
|
382
|
+
usage: s.usage ?? { prompt_tokens: 0, completion_tokens: 0, total_tokens: 0 },
|
|
383
|
+
model: s.model ?? e.model,
|
|
384
|
+
provider: s.provider ?? n ?? "",
|
|
385
|
+
usageWarning: o
|
|
473
386
|
};
|
|
474
387
|
},
|
|
475
|
-
stream(
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
const meta = responsePromise.then(readMeta);
|
|
479
|
-
meta.catch(() => {
|
|
388
|
+
stream(e) {
|
|
389
|
+
let i = K(t, e, true), r = X(t, i, e.signal, true), n = r.then(z);
|
|
390
|
+
n.catch(() => {
|
|
480
391
|
});
|
|
481
|
-
async function*
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
}
|
|
487
|
-
const reader = stream.getReader();
|
|
488
|
-
const decoder = new TextDecoder();
|
|
489
|
-
let buffer = "";
|
|
392
|
+
async function* o() {
|
|
393
|
+
let c = (await r).body;
|
|
394
|
+
if (!c)
|
|
395
|
+
throw new u("invalid_response", "ai.stream: response has no body");
|
|
396
|
+
let l = c.getReader(), y = new TextDecoder(), p = "";
|
|
490
397
|
try {
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
if (
|
|
494
|
-
|
|
495
|
-
let
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
398
|
+
for (; ; ) {
|
|
399
|
+
let { done: m, value: g } = await l.read();
|
|
400
|
+
if (m) break;
|
|
401
|
+
p += y.decode(g, { stream: !0 });
|
|
402
|
+
let f;
|
|
403
|
+
for (; (f = p.indexOf(`
|
|
404
|
+
|
|
405
|
+
`)) !== -1; ) {
|
|
406
|
+
let G = p.slice(0, f);
|
|
407
|
+
p = p.slice(f + 2);
|
|
408
|
+
let h = W(G);
|
|
409
|
+
if (h && "done" in h) return;
|
|
410
|
+
h && "content" in h && (yield h.content);
|
|
502
411
|
}
|
|
503
412
|
}
|
|
504
|
-
|
|
505
|
-
if (
|
|
506
|
-
|
|
507
|
-
|
|
413
|
+
let d = p.trim();
|
|
414
|
+
if (d) {
|
|
415
|
+
let m = W(d);
|
|
416
|
+
m && "content" in m && (yield m.content);
|
|
508
417
|
}
|
|
509
418
|
} finally {
|
|
510
419
|
try {
|
|
511
|
-
|
|
420
|
+
l.releaseLock();
|
|
512
421
|
} catch {
|
|
513
422
|
}
|
|
514
423
|
try {
|
|
515
|
-
await
|
|
424
|
+
await c.cancel();
|
|
516
425
|
} catch {
|
|
517
426
|
}
|
|
518
427
|
}
|
|
519
428
|
}
|
|
520
429
|
return {
|
|
521
|
-
meta,
|
|
522
|
-
[Symbol.asyncIterator]:
|
|
430
|
+
meta: n,
|
|
431
|
+
[Symbol.asyncIterator]: o
|
|
523
432
|
};
|
|
524
433
|
}
|
|
525
434
|
};
|
|
526
435
|
}
|
|
527
436
|
|
|
528
|
-
exports.createAiNamespace =
|
|
529
|
-
//# sourceMappingURL=ai.cjs.map
|
|
530
|
-
//# sourceMappingURL=ai.cjs.map
|
|
437
|
+
exports.createAiNamespace = ke;
|