@ai-matrx/api 0.1.9 → 0.1.10
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 +5 -0
- package/README.md +1 -1
- package/dist/account.d.cts +1 -1
- package/dist/account.d.ts +1 -1
- package/dist/agents.cjs +12 -12
- package/dist/agents.d.cts +1 -1
- package/dist/agents.d.ts +1 -1
- package/dist/agents.js +2 -2
- package/dist/ai.cjs +3 -3
- package/dist/ai.d.cts +1 -1
- package/dist/ai.d.ts +1 -1
- package/dist/ai.js +2 -2
- package/dist/apps.cjs +6 -6
- package/dist/apps.d.cts +1 -1
- package/dist/apps.d.ts +1 -1
- package/dist/apps.js +2 -2
- package/dist/architecture.cjs +11 -11
- package/dist/architecture.d.cts +1 -1
- package/dist/architecture.d.ts +1 -1
- package/dist/architecture.js +2 -2
- package/dist/audio.cjs +5 -5
- package/dist/audio.d.cts +1 -1
- package/dist/audio.d.ts +1 -1
- package/dist/audio.js +2 -2
- package/dist/chat.cjs +12 -12
- package/dist/chat.d.cts +1 -1
- package/dist/chat.d.ts +1 -1
- package/dist/chat.js +2 -2
- package/dist/{chunk-PIVTHTVR.js → chunk-FLANGLCG.js} +260 -36
- package/dist/{chunk-KIEAFMKB.js → chunk-PIPE5OML.js} +100 -46
- package/dist/{chunk-2SXAAKGV.cjs → chunk-PKYPPATQ.cjs} +100 -45
- package/dist/{chunk-PMGKZ4FT.cjs → chunk-SPASYIUH.cjs} +268 -34
- package/dist/code.cjs +7 -7
- package/dist/code.d.cts +1 -1
- package/dist/code.d.ts +1 -1
- package/dist/code.js +2 -2
- package/dist/commerce.d.cts +1 -1
- package/dist/commerce.d.ts +1 -1
- package/dist/communications.cjs +5 -5
- package/dist/communications.d.cts +1 -1
- package/dist/communications.d.ts +1 -1
- package/dist/communications.js +2 -2
- package/dist/computer.cjs +4 -4
- package/dist/computer.d.cts +1 -1
- package/dist/computer.d.ts +1 -1
- package/dist/computer.js +2 -2
- package/dist/content.cjs +5 -5
- package/dist/content.d.cts +1 -1
- package/dist/content.d.ts +1 -1
- package/dist/content.js +2 -2
- package/dist/crm.cjs +3 -3
- package/dist/crm.d.cts +1 -1
- package/dist/crm.d.ts +1 -1
- package/dist/crm.js +2 -2
- package/dist/data.d.cts +1 -1
- package/dist/data.d.ts +1 -1
- package/dist/education.cjs +5 -5
- package/dist/education.d.cts +1 -1
- package/dist/education.d.ts +1 -1
- package/dist/education.js +2 -2
- package/dist/files.cjs +21 -21
- package/dist/files.d.cts +1 -1
- package/dist/files.d.ts +1 -1
- package/dist/files.js +2 -2
- package/dist/human-resources.d.cts +1 -1
- package/dist/human-resources.d.ts +1 -1
- package/dist/{index-C3ZlP3BI.d.cts → index-Gj30ybjE.d.cts} +42 -3
- package/dist/{index-C3ZlP3BI.d.ts → index-Gj30ybjE.d.ts} +42 -3
- package/dist/index.cjs +183 -288
- package/dist/index.d.cts +129 -180
- package/dist/index.d.ts +129 -180
- package/dist/index.js +76 -206
- package/dist/integrations.cjs +4 -4
- package/dist/integrations.d.cts +1 -1
- package/dist/integrations.d.ts +1 -1
- package/dist/integrations.js +2 -2
- package/dist/intelligence.cjs +10 -8
- package/dist/intelligence.d.cts +13 -13
- package/dist/intelligence.d.ts +13 -13
- package/dist/intelligence.js +5 -3
- package/dist/{keys.generated-CK_C5UXG.d.cts → keys.generated-DZUiM-uA.d.cts} +5 -3
- package/dist/{keys.generated-CK_C5UXG.d.ts → keys.generated-DZUiM-uA.d.ts} +5 -3
- package/dist/knowledge.cjs +43 -43
- package/dist/knowledge.d.cts +13 -13
- package/dist/knowledge.d.ts +13 -13
- package/dist/knowledge.js +2 -2
- package/dist/legal.cjs +7 -7
- package/dist/legal.d.cts +1 -1
- package/dist/legal.d.ts +1 -1
- package/dist/legal.js +2 -2
- package/dist/marketing.cjs +77 -77
- package/dist/marketing.d.cts +27 -27
- package/dist/marketing.d.ts +27 -27
- package/dist/marketing.js +2 -2
- package/dist/masterwork.cjs +33 -33
- package/dist/masterwork.d.cts +1 -1
- package/dist/masterwork.d.ts +1 -1
- package/dist/masterwork.js +2 -2
- package/dist/media.cjs +12 -12
- package/dist/media.d.cts +1 -1
- package/dist/media.d.ts +1 -1
- package/dist/media.js +2 -2
- package/dist/net.cjs +19 -20
- package/dist/net.d.cts +41 -41
- package/dist/net.d.ts +41 -41
- package/dist/net.js +1 -2
- package/dist/platform.cjs +4 -4
- package/dist/platform.d.cts +1 -1
- package/dist/platform.d.ts +1 -1
- package/dist/platform.js +2 -2
- package/dist/publish.cjs +8 -8
- package/dist/publish.d.cts +1 -1
- package/dist/publish.d.ts +1 -1
- package/dist/publish.js +2 -2
- package/dist/schemas.d.cts +78 -15
- package/dist/schemas.d.ts +78 -15
- package/dist/stream.cjs +11 -11
- package/dist/stream.d.cts +1 -1
- package/dist/stream.d.ts +1 -1
- package/dist/stream.js +2 -2
- package/dist/types.cjs +2 -0
- package/dist/types.d.cts +49823 -0
- package/dist/types.d.ts +49823 -0
- package/dist/types.js +1 -0
- package/dist/web.cjs +27 -27
- package/dist/web.d.cts +17 -17
- package/dist/web.d.ts +17 -17
- package/dist/web.js +2 -2
- package/dist/workflows.cjs +14 -14
- package/dist/workflows.d.cts +23 -26
- package/dist/workflows.d.ts +23 -26
- package/dist/workflows.js +2 -2
- package/package.json +14 -4
- package/dist/chunk-FNIYADWI.cjs +0 -59
- package/dist/chunk-YTEOFGFC.js +0 -57
|
@@ -1,6 +1,89 @@
|
|
|
1
|
-
import { withRetry, isTransportFailure,
|
|
1
|
+
import { resilientFetch, isNetError, withRetry, isTransportFailure, AbortedError } from './chunk-PIPE5OML.js';
|
|
2
2
|
import { isUuidShape } from '@ai-matrx/kit/uuid';
|
|
3
|
-
import { toCredentialsPort, MATRX_HEADERS
|
|
3
|
+
import { credentialToHeaders, toCredentialsPort, MATRX_HEADERS } from '@ai-matrx/auth/credentials';
|
|
4
|
+
|
|
5
|
+
// src/core/protocol.ts
|
|
6
|
+
var MATRX_AI_API_VERSION_DEFAULT = "v2";
|
|
7
|
+
var V2_COVERED_AI_PATH_TEMPLATES = [
|
|
8
|
+
"/ai/manual",
|
|
9
|
+
"/ai/chat",
|
|
10
|
+
"/ai/agents/{agent_id}",
|
|
11
|
+
"/ai/agent/{agent_id}",
|
|
12
|
+
// singular alias — behaves identically
|
|
13
|
+
"/ai/conversations/{conversation_id}",
|
|
14
|
+
"/ai/conversation/{conversation_id}",
|
|
15
|
+
// singular alias
|
|
16
|
+
"/ai/prompts/{prompt_id}",
|
|
17
|
+
// saved-prompt execution
|
|
18
|
+
"/ai/mandates/{mandate_key}"
|
|
19
|
+
// THE MANDATE DOOR — `/v2` sibling exists (routers/v2.py)
|
|
20
|
+
];
|
|
21
|
+
function toV2Path(path) {
|
|
22
|
+
const withLead = path.startsWith("/") ? path : `/${path}`;
|
|
23
|
+
if (withLead.startsWith("/api/")) {
|
|
24
|
+
const rest = withLead.slice("/api".length);
|
|
25
|
+
return rest.startsWith("/v2/") ? withLead : `/api/v2${rest}`;
|
|
26
|
+
}
|
|
27
|
+
return withLead.startsWith("/v2/") ? withLead : `/v2${withLead}`;
|
|
28
|
+
}
|
|
29
|
+
var COVERED_INTERPOLATED_PATH = [
|
|
30
|
+
/^(?:\/api)?\/ai\/manual$/,
|
|
31
|
+
/^(?:\/api)?\/ai\/chat$/,
|
|
32
|
+
/^(?:\/api)?\/ai\/agents\/[^/]+$/,
|
|
33
|
+
/^(?:\/api)?\/ai\/agent\/[^/]+$/,
|
|
34
|
+
/^(?:\/api)?\/ai\/conversations\/[^/]+$/,
|
|
35
|
+
/^(?:\/api)?\/ai\/conversation\/[^/]+$/,
|
|
36
|
+
/^(?:\/api)?\/ai\/prompts\/[^/]+$/,
|
|
37
|
+
// `/warm` etc. deliberately don't match
|
|
38
|
+
/^(?:\/api)?\/ai\/mandates\/[^/]+$/
|
|
39
|
+
// the mandate door
|
|
40
|
+
];
|
|
41
|
+
function isCoveredAiPath(path) {
|
|
42
|
+
return COVERED_INTERPOLATED_PATH.some((re) => re.test(path));
|
|
43
|
+
}
|
|
44
|
+
function isV2Path(pathOrUrl) {
|
|
45
|
+
return /\/v2\/ai\//.test(pathOrUrl);
|
|
46
|
+
}
|
|
47
|
+
function toV1FallbackUrl(url) {
|
|
48
|
+
return url.replace(/\/v2\/ai\//, "/ai/");
|
|
49
|
+
}
|
|
50
|
+
function applyAiApiVersion(path, version) {
|
|
51
|
+
if (version !== "v2") return path;
|
|
52
|
+
return isCoveredAiPath(path) ? toV2Path(path) : path;
|
|
53
|
+
}
|
|
54
|
+
async function fetchWithMatrxProtocolFallback(url, init, opts = {}) {
|
|
55
|
+
const { onDowngrade, ...fetchOpts } = opts;
|
|
56
|
+
const logDowngrade = (reason, status2) => {
|
|
57
|
+
console.warn(
|
|
58
|
+
`[matrx] ai_v2_downgrade \u2192 retrying on v1. v2=${url} reason=${reason}`
|
|
59
|
+
);
|
|
60
|
+
onDowngrade?.({ url, reason, ...status2 !== void 0 ? { status: status2 } : {} });
|
|
61
|
+
};
|
|
62
|
+
if (!isV2Path(url)) return resilientFetch(url, init, fetchOpts);
|
|
63
|
+
let result;
|
|
64
|
+
try {
|
|
65
|
+
result = await resilientFetch(url, init, fetchOpts);
|
|
66
|
+
} catch (err) {
|
|
67
|
+
const isAbort = isNetError(err) && err.code === "aborted" || err instanceof Error && err.name === "AbortError";
|
|
68
|
+
if (isAbort) throw err;
|
|
69
|
+
logDowngrade(String(err));
|
|
70
|
+
return resilientFetch(toV1FallbackUrl(url), init, fetchOpts);
|
|
71
|
+
}
|
|
72
|
+
const status = result.response.status;
|
|
73
|
+
if (status === 404 || status === 405 || status >= 500) {
|
|
74
|
+
logDowngrade(`HTTP ${status}`, status);
|
|
75
|
+
return resilientFetch(toV1FallbackUrl(url), init, fetchOpts);
|
|
76
|
+
}
|
|
77
|
+
return result;
|
|
78
|
+
}
|
|
79
|
+
function aiVersionPathOverrides(version) {
|
|
80
|
+
if (version !== "v2") return {};
|
|
81
|
+
const map = {};
|
|
82
|
+
for (const template of V2_COVERED_AI_PATH_TEMPLATES) {
|
|
83
|
+
map[template] = toV2Path(template);
|
|
84
|
+
}
|
|
85
|
+
return map;
|
|
86
|
+
}
|
|
4
87
|
|
|
5
88
|
// src/core/backend-errors.ts
|
|
6
89
|
var BackendApiError = class extends Error {
|
|
@@ -822,7 +905,167 @@ var DEPLOYMENTS = {
|
|
|
822
905
|
}
|
|
823
906
|
};
|
|
824
907
|
var DOMAINS = ["account", "agents", "ai", "apps", "architecture", "audio", "chat", "code", "commerce", "communications", "computer", "content", "crm", "data", "education", "files", "human-resources", "integrations", "intelligence", "knowledge", "legal", "marketing", "masterwork", "media", "platform", "publish", "web", "workflows"];
|
|
908
|
+
var SESSION_READY_TIMEOUT_MS = 3e3;
|
|
825
909
|
var DEFAULT_CONNECT_TIMEOUT_MS = 15e3;
|
|
910
|
+
function isBodyInit(body) {
|
|
911
|
+
return typeof body === "string" || typeof Blob !== "undefined" && body instanceof Blob || typeof FormData !== "undefined" && body instanceof FormData || typeof URLSearchParams !== "undefined" && body instanceof URLSearchParams || body instanceof ArrayBuffer || ArrayBuffer.isView(body) || typeof ReadableStream !== "undefined" && body instanceof ReadableStream;
|
|
912
|
+
}
|
|
913
|
+
async function waitForSessionReady(credentials, timeoutMs = SESSION_READY_TIMEOUT_MS) {
|
|
914
|
+
const ready = credentials?.ready;
|
|
915
|
+
if (!ready) return;
|
|
916
|
+
let timer;
|
|
917
|
+
try {
|
|
918
|
+
await Promise.race([
|
|
919
|
+
ready.call(credentials).catch(() => void 0),
|
|
920
|
+
new Promise((resolve) => {
|
|
921
|
+
timer = setTimeout(resolve, Math.max(0, timeoutMs));
|
|
922
|
+
})
|
|
923
|
+
]);
|
|
924
|
+
} finally {
|
|
925
|
+
if (timer !== void 0) clearTimeout(timer);
|
|
926
|
+
}
|
|
927
|
+
}
|
|
928
|
+
function headerBag(headers) {
|
|
929
|
+
return { ...headers ?? {} };
|
|
930
|
+
}
|
|
931
|
+
function hasHeader(headers, name) {
|
|
932
|
+
const lower = name.toLowerCase();
|
|
933
|
+
return Object.keys(headers).some((key) => key.toLowerCase() === lower);
|
|
934
|
+
}
|
|
935
|
+
function encodeBody(method, body, headers) {
|
|
936
|
+
const upper = method.toUpperCase();
|
|
937
|
+
if (body === void 0 || upper === "GET" || upper === "HEAD") return void 0;
|
|
938
|
+
if (isBodyInit(body)) return body;
|
|
939
|
+
if (!hasHeader(headers, "content-type")) headers["Content-Type"] = "application/json";
|
|
940
|
+
return JSON.stringify(body);
|
|
941
|
+
}
|
|
942
|
+
function bodySize(body) {
|
|
943
|
+
if (body === void 0) return 0;
|
|
944
|
+
if (typeof body === "string") return new TextEncoder().encode(body).byteLength;
|
|
945
|
+
if (typeof Blob !== "undefined" && body instanceof Blob) return body.size;
|
|
946
|
+
if (body instanceof ArrayBuffer) return body.byteLength;
|
|
947
|
+
if (ArrayBuffer.isView(body)) return body.byteLength;
|
|
948
|
+
return 0;
|
|
949
|
+
}
|
|
950
|
+
function parseXhrHeaders(raw) {
|
|
951
|
+
const headers = new Headers();
|
|
952
|
+
for (const line of raw.trim().split(/[\r\n]+/)) {
|
|
953
|
+
const index = line.indexOf(":");
|
|
954
|
+
if (index <= 0) continue;
|
|
955
|
+
try {
|
|
956
|
+
headers.append(line.slice(0, index).trim(), line.slice(index + 1).trim());
|
|
957
|
+
} catch {
|
|
958
|
+
}
|
|
959
|
+
}
|
|
960
|
+
return headers;
|
|
961
|
+
}
|
|
962
|
+
function sendWithXhr(url, init, signal, totalTimeoutMs, onUploadProgress) {
|
|
963
|
+
const controller = new AbortController();
|
|
964
|
+
return new Promise((resolve, reject) => {
|
|
965
|
+
const xhr = new XMLHttpRequest();
|
|
966
|
+
xhr.open(init.method, url, true);
|
|
967
|
+
xhr.responseType = "arraybuffer";
|
|
968
|
+
for (const [name, value] of Object.entries(init.headers)) xhr.setRequestHeader(name, value);
|
|
969
|
+
if (totalTimeoutMs !== null && totalTimeoutMs > 0) xhr.timeout = totalTimeoutMs;
|
|
970
|
+
let lastLoaded = 0;
|
|
971
|
+
xhr.upload.onprogress = (event) => {
|
|
972
|
+
const loaded = Math.max(lastLoaded, event.loaded);
|
|
973
|
+
lastLoaded = loaded;
|
|
974
|
+
onUploadProgress({ loaded, total: event.lengthComputable ? event.total : 0 });
|
|
975
|
+
};
|
|
976
|
+
const onAbort = () => xhr.abort();
|
|
977
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
978
|
+
controller.signal.addEventListener("abort", onAbort, { once: true });
|
|
979
|
+
const cleanup = () => signal?.removeEventListener("abort", onAbort);
|
|
980
|
+
xhr.onload = () => {
|
|
981
|
+
cleanup();
|
|
982
|
+
const status = xhr.status === 0 ? 200 : xhr.status;
|
|
983
|
+
const nullBody = status === 204 || status === 205 || status === 304;
|
|
984
|
+
const response = new Response(nullBody ? null : xhr.response, {
|
|
985
|
+
status,
|
|
986
|
+
statusText: xhr.statusText,
|
|
987
|
+
headers: parseXhrHeaders(xhr.getAllResponseHeaders())
|
|
988
|
+
});
|
|
989
|
+
resolve({ response, controller });
|
|
990
|
+
};
|
|
991
|
+
xhr.onerror = () => {
|
|
992
|
+
cleanup();
|
|
993
|
+
reject(new TypeError(`Network failure uploading to ${url}`));
|
|
994
|
+
};
|
|
995
|
+
xhr.ontimeout = () => {
|
|
996
|
+
cleanup();
|
|
997
|
+
reject(new DOMException(`Upload to ${url} exceeded ${totalTimeoutMs}ms`, "TimeoutError"));
|
|
998
|
+
};
|
|
999
|
+
xhr.onabort = () => {
|
|
1000
|
+
cleanup();
|
|
1001
|
+
reject(new DOMException("The upload was cancelled.", "AbortError"));
|
|
1002
|
+
};
|
|
1003
|
+
if (signal?.aborted) {
|
|
1004
|
+
xhr.abort();
|
|
1005
|
+
return;
|
|
1006
|
+
}
|
|
1007
|
+
xhr.send(init.body ?? null);
|
|
1008
|
+
});
|
|
1009
|
+
}
|
|
1010
|
+
async function sendOnWire(request, auth = {}) {
|
|
1011
|
+
const method = request.method.toUpperCase();
|
|
1012
|
+
const headers = headerBag(request.headers);
|
|
1013
|
+
const body = encodeBody(method, request.body, headers);
|
|
1014
|
+
await waitForSessionReady(auth.credentials, auth.readyTimeoutMs);
|
|
1015
|
+
const credentialHeaders = auth.credentials ? credentialToHeaders(await auth.credentials.get()) : {};
|
|
1016
|
+
const attempt = (sendHeaders) => {
|
|
1017
|
+
if (request.signal?.aborted) return Promise.reject(new AbortedError(request.signal.reason));
|
|
1018
|
+
const merged = { ...sendHeaders };
|
|
1019
|
+
if (request.onUploadProgress && body !== void 0) {
|
|
1020
|
+
if (typeof XMLHttpRequest !== "undefined" && !(typeof ReadableStream !== "undefined" && body instanceof ReadableStream)) {
|
|
1021
|
+
return sendWithXhr(
|
|
1022
|
+
request.url,
|
|
1023
|
+
{ method, headers: merged, body },
|
|
1024
|
+
request.signal,
|
|
1025
|
+
request.totalTimeoutMs ?? null,
|
|
1026
|
+
request.onUploadProgress
|
|
1027
|
+
);
|
|
1028
|
+
}
|
|
1029
|
+
}
|
|
1030
|
+
return fetchWithMatrxProtocolFallback(
|
|
1031
|
+
request.url,
|
|
1032
|
+
{ method, headers: merged, ...body !== void 0 ? { body } : {} },
|
|
1033
|
+
{
|
|
1034
|
+
...request.signal ? { signal: request.signal } : {},
|
|
1035
|
+
connectTimeoutMs: request.connectTimeoutMs ?? DEFAULT_CONNECT_TIMEOUT_MS,
|
|
1036
|
+
totalTimeoutMs: request.totalTimeoutMs !== void 0 ? request.totalTimeoutMs : null,
|
|
1037
|
+
throwOnHttpError: false,
|
|
1038
|
+
...request.onProtocolDowngrade ? { onDowngrade: request.onProtocolDowngrade } : {}
|
|
1039
|
+
}
|
|
1040
|
+
).then((result) => {
|
|
1041
|
+
if (request.onUploadProgress && body !== void 0) {
|
|
1042
|
+
const total = bodySize(body);
|
|
1043
|
+
request.onUploadProgress({ loaded: total, total });
|
|
1044
|
+
}
|
|
1045
|
+
return result;
|
|
1046
|
+
});
|
|
1047
|
+
};
|
|
1048
|
+
const over = Object.fromEntries(
|
|
1049
|
+
Object.entries(request.overHeaders ?? {}).filter(([name]) => name.toLowerCase() !== "content-type")
|
|
1050
|
+
);
|
|
1051
|
+
const firstHeaders = { ...headers, ...credentialHeaders, ...over };
|
|
1052
|
+
const idempotent = method === "GET" || method === "HEAD";
|
|
1053
|
+
const attempts = Math.max(1, request.retryAttempts ?? 1);
|
|
1054
|
+
const first = idempotent && attempts > 1 && !request.stream ? await withRetry(() => attempt(firstHeaders), {
|
|
1055
|
+
attempts,
|
|
1056
|
+
retryOn: isTransportFailure,
|
|
1057
|
+
...request.signal ? { signal: request.signal } : {}
|
|
1058
|
+
}) : await attempt(firstHeaders);
|
|
1059
|
+
if (first.response.status !== 401 || !auth.refreshCredentials) return first;
|
|
1060
|
+
if (!await auth.refreshCredentials()) return first;
|
|
1061
|
+
await first.response.body?.cancel().catch(() => void 0);
|
|
1062
|
+
const retryHeaders = { ...headers };
|
|
1063
|
+
Object.assign(retryHeaders, auth.credentials ? credentialToHeaders(await auth.credentials.get()) : {}, over);
|
|
1064
|
+
return attempt(retryHeaders);
|
|
1065
|
+
}
|
|
1066
|
+
|
|
1067
|
+
// src/api.ts
|
|
1068
|
+
var DEFAULT_CONNECT_TIMEOUT_MS2 = 15e3;
|
|
826
1069
|
function defaultRequestId() {
|
|
827
1070
|
const c = globalThis.crypto;
|
|
828
1071
|
if (c?.randomUUID) return c.randomUUID();
|
|
@@ -851,9 +1094,6 @@ function queryString(query) {
|
|
|
851
1094
|
}
|
|
852
1095
|
return parts.length ? `?${parts.join("&")}` : "";
|
|
853
1096
|
}
|
|
854
|
-
function isBodyInit(body) {
|
|
855
|
-
return typeof body === "string" || typeof Blob !== "undefined" && body instanceof Blob || typeof FormData !== "undefined" && body instanceof FormData || typeof URLSearchParams !== "undefined" && body instanceof URLSearchParams || body instanceof ArrayBuffer || ArrayBuffer.isView(body) || typeof ReadableStream !== "undefined" && body instanceof ReadableStream;
|
|
856
|
-
}
|
|
857
1097
|
function acceptFor(stream) {
|
|
858
1098
|
switch (stream) {
|
|
859
1099
|
case "ndjson":
|
|
@@ -919,43 +1159,27 @@ function createApi(options = {}) {
|
|
|
919
1159
|
Accept: acceptFor(op.s),
|
|
920
1160
|
[MATRX_HEADERS.requestId]: requestId
|
|
921
1161
|
};
|
|
922
|
-
let body;
|
|
923
|
-
if (args?.body !== void 0 && op.m !== "GET" && op.m !== "HEAD") {
|
|
924
|
-
if (isBodyInit(args.body)) {
|
|
925
|
-
body = args.body;
|
|
926
|
-
} else {
|
|
927
|
-
body = JSON.stringify(args.body);
|
|
928
|
-
headers["Content-Type"] = "application/json";
|
|
929
|
-
}
|
|
930
|
-
}
|
|
931
|
-
const credentialHeaders = credentialToHeaders(await credentials.get());
|
|
932
|
-
Object.assign(headers, credentialHeaders);
|
|
933
1162
|
if (orgId !== null) headers[MATRX_HEADERS.organization] = orgId;
|
|
934
1163
|
options.onRequest?.({ operation: op.n, method: op.m, url, requestId, deployment: op.d });
|
|
935
|
-
const
|
|
936
|
-
url,
|
|
937
|
-
{ method: op.m, headers: sendHeaders, ...body !== void 0 ? { body } : {} },
|
|
1164
|
+
const { response, controller } = await sendOnWire(
|
|
938
1165
|
{
|
|
1166
|
+
url,
|
|
1167
|
+
method: op.m,
|
|
1168
|
+
headers,
|
|
1169
|
+
body: args?.body,
|
|
939
1170
|
...call?.signal ? { signal: call.signal } : {},
|
|
940
|
-
connectTimeoutMs: call?.connectTimeoutMs ?? options.connectTimeoutMs ??
|
|
1171
|
+
connectTimeoutMs: call?.connectTimeoutMs ?? options.connectTimeoutMs ?? DEFAULT_CONNECT_TIMEOUT_MS2,
|
|
941
1172
|
totalTimeoutMs: call?.totalTimeoutMs !== void 0 ? call.totalTimeoutMs : options.totalTimeoutMs ?? null,
|
|
942
|
-
|
|
1173
|
+
stream: Boolean(op.s),
|
|
1174
|
+
retryAttempts,
|
|
1175
|
+
...call?.onUploadProgress ? { onUploadProgress: call.onUploadProgress } : {}
|
|
1176
|
+
},
|
|
1177
|
+
{
|
|
1178
|
+
credentials,
|
|
1179
|
+
...options.readyTimeoutMs !== void 0 ? { readyTimeoutMs: options.readyTimeoutMs } : {},
|
|
1180
|
+
...options.refreshCredentials ? { refreshCredentials: options.refreshCredentials } : {}
|
|
943
1181
|
}
|
|
944
1182
|
);
|
|
945
|
-
const idempotent = op.m === "GET" || op.m === "HEAD";
|
|
946
|
-
const { response, controller } = idempotent && retryAttempts > 1 && !op.s ? await withRetry(() => attempt(), {
|
|
947
|
-
attempts: retryAttempts,
|
|
948
|
-
retryOn: isTransportFailure,
|
|
949
|
-
...call?.signal ? { signal: call.signal } : {}
|
|
950
|
-
}) : await attempt();
|
|
951
|
-
if (response.status === 401 && options.refreshCredentials && await options.refreshCredentials()) {
|
|
952
|
-
const retryHeaders = { ...headers };
|
|
953
|
-
for (const name of Object.keys(credentialHeaders)) delete retryHeaders[name];
|
|
954
|
-
Object.assign(retryHeaders, credentialToHeaders(await credentials.get()));
|
|
955
|
-
const retried = await attempt(retryHeaders);
|
|
956
|
-
if (!retried.response.ok) throw await errorFrom(retried.response, interpolate(op.p, args?.path));
|
|
957
|
-
return { response: retried.response, requestId, controller: retried.controller };
|
|
958
|
-
}
|
|
959
1183
|
if (!response.ok) throw await errorFrom(response, interpolate(op.p, args?.path));
|
|
960
1184
|
return { response, requestId, controller };
|
|
961
1185
|
};
|
|
@@ -1022,4 +1246,4 @@ async function openJsonOrStream(api, op, args, options) {
|
|
|
1022
1246
|
return { kind: "stream", stream: toStream(op, response, requestId, controller) };
|
|
1023
1247
|
}
|
|
1024
1248
|
|
|
1025
|
-
export { BackendApiError, CONTRACT_SHA256, DEFAULT_MATRX_NDJSON_READ_AHEAD, DEPLOYMENTS, DOMAINS, MatrxApiError, OrganizationContextError, StreamTransportError, applyOrganizationContextHeader, assertOrganizationMatchesOperation, assertQueryOrganizationMatchesContext, createApi, createMatrxNdjsonFramer, createMatrxSseFramer, createOrganizationOperation, describeBackendFailure, extractMatrxErrorCode, extractMatrxErrorMessage, getUserMessage, isGenericUserMessage, isStreamTransportLost, normalizeMatrxStreamEnvelope, openJsonOrStream, openStream, parseCallApiError, parseHttpError, parseHttpErrorBody, parseMatrxSseFrame, parsePersistedBackendError, parseStreamError, readMatrxNdjsonStream, readMatrxSseStream, requireOrganizationContext, unwrapUpstreamError };
|
|
1249
|
+
export { BackendApiError, CONTRACT_SHA256, DEFAULT_MATRX_NDJSON_READ_AHEAD, DEPLOYMENTS, DOMAINS, MATRX_AI_API_VERSION_DEFAULT, MatrxApiError, OrganizationContextError, StreamTransportError, V2_COVERED_AI_PATH_TEMPLATES, aiVersionPathOverrides, applyAiApiVersion, applyOrganizationContextHeader, assertOrganizationMatchesOperation, assertQueryOrganizationMatchesContext, createApi, createMatrxNdjsonFramer, createMatrxSseFramer, createOrganizationOperation, describeBackendFailure, extractMatrxErrorCode, extractMatrxErrorMessage, fetchWithMatrxProtocolFallback, getUserMessage, isCoveredAiPath, isGenericUserMessage, isStreamTransportLost, isV2Path, normalizeMatrxStreamEnvelope, openJsonOrStream, openStream, parseCallApiError, parseHttpError, parseHttpErrorBody, parseMatrxSseFrame, parsePersistedBackendError, parseStreamError, readMatrxNdjsonStream, readMatrxSseStream, requireOrganizationContext, sendOnWire, toV1FallbackUrl, toV2Path, unwrapUpstreamError };
|
|
@@ -141,6 +141,58 @@ function toNetError(err) {
|
|
|
141
141
|
);
|
|
142
142
|
}
|
|
143
143
|
|
|
144
|
+
// src/net/retry.ts
|
|
145
|
+
function defaultRetryOn(err) {
|
|
146
|
+
return isNetError(err) && err.retryable;
|
|
147
|
+
}
|
|
148
|
+
function sleep(ms, signal) {
|
|
149
|
+
return new Promise((resolve, reject) => {
|
|
150
|
+
const timer = setTimeout(() => {
|
|
151
|
+
resolve();
|
|
152
|
+
if (signal) signal.removeEventListener("abort", onAbort);
|
|
153
|
+
}, ms);
|
|
154
|
+
const onAbort = () => {
|
|
155
|
+
clearTimeout(timer);
|
|
156
|
+
reject(signal?.reason ?? new Error("Aborted"));
|
|
157
|
+
};
|
|
158
|
+
if (signal) {
|
|
159
|
+
if (signal.aborted) {
|
|
160
|
+
clearTimeout(timer);
|
|
161
|
+
reject(signal.reason);
|
|
162
|
+
} else {
|
|
163
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
async function withRetry(fn, opts = {}) {
|
|
169
|
+
const attempts = Math.max(1, opts.attempts ?? 3);
|
|
170
|
+
const initialDelayMs = opts.initialDelayMs ?? 250;
|
|
171
|
+
const maxDelayMs = opts.maxDelayMs ?? 4e3;
|
|
172
|
+
const factor = opts.backoffFactor ?? 2;
|
|
173
|
+
const jitter = Math.max(0, Math.min(1, opts.jitter ?? 0.25));
|
|
174
|
+
const retryOn = opts.retryOn ?? defaultRetryOn;
|
|
175
|
+
let lastErr;
|
|
176
|
+
for (let attempt = 1; attempt <= attempts; attempt++) {
|
|
177
|
+
if (opts.signal?.aborted) throw opts.signal.reason;
|
|
178
|
+
try {
|
|
179
|
+
return await fn(attempt);
|
|
180
|
+
} catch (err) {
|
|
181
|
+
lastErr = err;
|
|
182
|
+
if (attempt === attempts || !retryOn(err)) throw err;
|
|
183
|
+
const base = Math.min(
|
|
184
|
+
maxDelayMs,
|
|
185
|
+
initialDelayMs * Math.pow(factor, attempt - 1)
|
|
186
|
+
);
|
|
187
|
+
const jitterAmount = base * jitter * (Math.random() * 2 - 1);
|
|
188
|
+
const delayMs = Math.max(0, Math.round(base + jitterAmount));
|
|
189
|
+
opts.onRetry?.(attempt, err, delayMs);
|
|
190
|
+
await sleep(delayMs, opts.signal);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
throw lastErr;
|
|
194
|
+
}
|
|
195
|
+
|
|
144
196
|
// src/net/resilient-fetch.ts
|
|
145
197
|
var DEFAULTS = {
|
|
146
198
|
connectTimeoutMs: 15e3,
|
|
@@ -209,56 +261,58 @@ async function resilientFetch(url, init = {}, opts = {}) {
|
|
|
209
261
|
}
|
|
210
262
|
}
|
|
211
263
|
|
|
212
|
-
// src/net/
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
if (
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
reject(signal.reason);
|
|
230
|
-
} else {
|
|
231
|
-
signal.addEventListener("abort", onAbort, { once: true });
|
|
232
|
-
}
|
|
264
|
+
// src/net/stream-monitor.ts
|
|
265
|
+
var DEFAULTS2 = {
|
|
266
|
+
heartbeatTimeoutMs: 3e4,
|
|
267
|
+
maxLifetimeMs: 6e5
|
|
268
|
+
};
|
|
269
|
+
async function* monitorStream(source, opts = {}) {
|
|
270
|
+
const heartbeatTimeoutMs = opts.heartbeatTimeoutMs ?? DEFAULTS2.heartbeatTimeoutMs;
|
|
271
|
+
const maxLifetimeMs = opts.maxLifetimeMs ?? DEFAULTS2.maxLifetimeMs;
|
|
272
|
+
const abort = opts.abortController;
|
|
273
|
+
const startedAt = Date.now();
|
|
274
|
+
const iter = source[Symbol.asyncIterator]();
|
|
275
|
+
while (true) {
|
|
276
|
+
const elapsed = Date.now() - startedAt;
|
|
277
|
+
const remainingLifetime = maxLifetimeMs - elapsed;
|
|
278
|
+
if (remainingLifetime <= 0) {
|
|
279
|
+
abort?.abort("total-timeout");
|
|
280
|
+
throw new TotalTimeoutError(maxLifetimeMs);
|
|
233
281
|
}
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
282
|
+
const deadline = Math.min(heartbeatTimeoutMs, remainingLifetime);
|
|
283
|
+
let timer = null;
|
|
284
|
+
let timedOutKind = null;
|
|
285
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
286
|
+
timer = setTimeout(() => {
|
|
287
|
+
timedOutKind = deadline === remainingLifetime ? "total" : "heartbeat";
|
|
288
|
+
abort?.abort(
|
|
289
|
+
timedOutKind === "total" ? "total-timeout" : "heartbeat-timeout"
|
|
290
|
+
);
|
|
291
|
+
reject(
|
|
292
|
+
timedOutKind === "total" ? new TotalTimeoutError(maxLifetimeMs) : new HeartbeatTimeoutError(heartbeatTimeoutMs)
|
|
293
|
+
);
|
|
294
|
+
}, deadline);
|
|
295
|
+
});
|
|
296
|
+
let result;
|
|
246
297
|
try {
|
|
247
|
-
|
|
298
|
+
result = await Promise.race([iter.next(), timeoutPromise]);
|
|
248
299
|
} catch (err) {
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
300
|
+
if (timer !== null) clearTimeout(timer);
|
|
301
|
+
try {
|
|
302
|
+
const cleanup = iter.return?.(void 0);
|
|
303
|
+
if (cleanup) {
|
|
304
|
+
void Promise.resolve(cleanup).catch(() => {
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
} catch {
|
|
308
|
+
}
|
|
309
|
+
throw err;
|
|
259
310
|
}
|
|
311
|
+
if (timer !== null) clearTimeout(timer);
|
|
312
|
+
if (result.done) return;
|
|
313
|
+
opts.onHeartbeat?.(Date.now());
|
|
314
|
+
yield result.value;
|
|
260
315
|
}
|
|
261
|
-
throw lastErr;
|
|
262
316
|
}
|
|
263
317
|
|
|
264
|
-
export { AbortedError, ConnectTimeoutError, HeartbeatTimeoutError, HttpError, NetError, NetworkError, OfflineError, TotalTimeoutError, extractErrorMessage, isNetError, isTransportFailure, resilientFetch, toNetError, withRetry };
|
|
318
|
+
export { AbortedError, ConnectTimeoutError, HeartbeatTimeoutError, HttpError, NetError, NetworkError, OfflineError, TotalTimeoutError, extractErrorMessage, isNetError, isTransportFailure, monitorStream, resilientFetch, toNetError, withRetry };
|
|
@@ -143,6 +143,58 @@ function toNetError(err) {
|
|
|
143
143
|
);
|
|
144
144
|
}
|
|
145
145
|
|
|
146
|
+
// src/net/retry.ts
|
|
147
|
+
function defaultRetryOn(err) {
|
|
148
|
+
return isNetError(err) && err.retryable;
|
|
149
|
+
}
|
|
150
|
+
function sleep(ms, signal) {
|
|
151
|
+
return new Promise((resolve, reject) => {
|
|
152
|
+
const timer = setTimeout(() => {
|
|
153
|
+
resolve();
|
|
154
|
+
if (signal) signal.removeEventListener("abort", onAbort);
|
|
155
|
+
}, ms);
|
|
156
|
+
const onAbort = () => {
|
|
157
|
+
clearTimeout(timer);
|
|
158
|
+
reject(signal?.reason ?? new Error("Aborted"));
|
|
159
|
+
};
|
|
160
|
+
if (signal) {
|
|
161
|
+
if (signal.aborted) {
|
|
162
|
+
clearTimeout(timer);
|
|
163
|
+
reject(signal.reason);
|
|
164
|
+
} else {
|
|
165
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
async function withRetry(fn, opts = {}) {
|
|
171
|
+
const attempts = Math.max(1, opts.attempts ?? 3);
|
|
172
|
+
const initialDelayMs = opts.initialDelayMs ?? 250;
|
|
173
|
+
const maxDelayMs = opts.maxDelayMs ?? 4e3;
|
|
174
|
+
const factor = opts.backoffFactor ?? 2;
|
|
175
|
+
const jitter = Math.max(0, Math.min(1, opts.jitter ?? 0.25));
|
|
176
|
+
const retryOn = opts.retryOn ?? defaultRetryOn;
|
|
177
|
+
let lastErr;
|
|
178
|
+
for (let attempt = 1; attempt <= attempts; attempt++) {
|
|
179
|
+
if (opts.signal?.aborted) throw opts.signal.reason;
|
|
180
|
+
try {
|
|
181
|
+
return await fn(attempt);
|
|
182
|
+
} catch (err) {
|
|
183
|
+
lastErr = err;
|
|
184
|
+
if (attempt === attempts || !retryOn(err)) throw err;
|
|
185
|
+
const base = Math.min(
|
|
186
|
+
maxDelayMs,
|
|
187
|
+
initialDelayMs * Math.pow(factor, attempt - 1)
|
|
188
|
+
);
|
|
189
|
+
const jitterAmount = base * jitter * (Math.random() * 2 - 1);
|
|
190
|
+
const delayMs = Math.max(0, Math.round(base + jitterAmount));
|
|
191
|
+
opts.onRetry?.(attempt, err, delayMs);
|
|
192
|
+
await sleep(delayMs, opts.signal);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
throw lastErr;
|
|
196
|
+
}
|
|
197
|
+
|
|
146
198
|
// src/net/resilient-fetch.ts
|
|
147
199
|
var DEFAULTS = {
|
|
148
200
|
connectTimeoutMs: 15e3,
|
|
@@ -211,56 +263,58 @@ async function resilientFetch(url, init = {}, opts = {}) {
|
|
|
211
263
|
}
|
|
212
264
|
}
|
|
213
265
|
|
|
214
|
-
// src/net/
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
if (
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
reject(signal.reason);
|
|
232
|
-
} else {
|
|
233
|
-
signal.addEventListener("abort", onAbort, { once: true });
|
|
234
|
-
}
|
|
266
|
+
// src/net/stream-monitor.ts
|
|
267
|
+
var DEFAULTS2 = {
|
|
268
|
+
heartbeatTimeoutMs: 3e4,
|
|
269
|
+
maxLifetimeMs: 6e5
|
|
270
|
+
};
|
|
271
|
+
async function* monitorStream(source, opts = {}) {
|
|
272
|
+
const heartbeatTimeoutMs = opts.heartbeatTimeoutMs ?? DEFAULTS2.heartbeatTimeoutMs;
|
|
273
|
+
const maxLifetimeMs = opts.maxLifetimeMs ?? DEFAULTS2.maxLifetimeMs;
|
|
274
|
+
const abort = opts.abortController;
|
|
275
|
+
const startedAt = Date.now();
|
|
276
|
+
const iter = source[Symbol.asyncIterator]();
|
|
277
|
+
while (true) {
|
|
278
|
+
const elapsed = Date.now() - startedAt;
|
|
279
|
+
const remainingLifetime = maxLifetimeMs - elapsed;
|
|
280
|
+
if (remainingLifetime <= 0) {
|
|
281
|
+
abort?.abort("total-timeout");
|
|
282
|
+
throw new TotalTimeoutError(maxLifetimeMs);
|
|
235
283
|
}
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
284
|
+
const deadline = Math.min(heartbeatTimeoutMs, remainingLifetime);
|
|
285
|
+
let timer = null;
|
|
286
|
+
let timedOutKind = null;
|
|
287
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
288
|
+
timer = setTimeout(() => {
|
|
289
|
+
timedOutKind = deadline === remainingLifetime ? "total" : "heartbeat";
|
|
290
|
+
abort?.abort(
|
|
291
|
+
timedOutKind === "total" ? "total-timeout" : "heartbeat-timeout"
|
|
292
|
+
);
|
|
293
|
+
reject(
|
|
294
|
+
timedOutKind === "total" ? new TotalTimeoutError(maxLifetimeMs) : new HeartbeatTimeoutError(heartbeatTimeoutMs)
|
|
295
|
+
);
|
|
296
|
+
}, deadline);
|
|
297
|
+
});
|
|
298
|
+
let result;
|
|
248
299
|
try {
|
|
249
|
-
|
|
300
|
+
result = await Promise.race([iter.next(), timeoutPromise]);
|
|
250
301
|
} catch (err) {
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
302
|
+
if (timer !== null) clearTimeout(timer);
|
|
303
|
+
try {
|
|
304
|
+
const cleanup = iter.return?.(void 0);
|
|
305
|
+
if (cleanup) {
|
|
306
|
+
void Promise.resolve(cleanup).catch(() => {
|
|
307
|
+
});
|
|
308
|
+
}
|
|
309
|
+
} catch {
|
|
310
|
+
}
|
|
311
|
+
throw err;
|
|
261
312
|
}
|
|
313
|
+
if (timer !== null) clearTimeout(timer);
|
|
314
|
+
if (result.done) return;
|
|
315
|
+
opts.onHeartbeat?.(Date.now());
|
|
316
|
+
yield result.value;
|
|
262
317
|
}
|
|
263
|
-
throw lastErr;
|
|
264
318
|
}
|
|
265
319
|
|
|
266
320
|
exports.AbortedError = AbortedError;
|
|
@@ -274,6 +328,7 @@ exports.TotalTimeoutError = TotalTimeoutError;
|
|
|
274
328
|
exports.extractErrorMessage = extractErrorMessage;
|
|
275
329
|
exports.isNetError = isNetError;
|
|
276
330
|
exports.isTransportFailure = isTransportFailure;
|
|
331
|
+
exports.monitorStream = monitorStream;
|
|
277
332
|
exports.resilientFetch = resilientFetch;
|
|
278
333
|
exports.toNetError = toNetError;
|
|
279
334
|
exports.withRetry = withRetry;
|