@kindgi/client 0.1.4-rc.5 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -1
- package/dist/index.cjs +163 -129
- package/dist/index.d.cts +79 -1
- package/dist/index.d.ts +79 -1
- package/dist/index.js +163 -129
- package/package.json +7 -7
package/README.md
CHANGED
|
@@ -72,7 +72,7 @@ try {
|
|
|
72
72
|
|
|
73
73
|
## Exports
|
|
74
74
|
|
|
75
|
-
- **`createClient(options: ClientOptions)`** — returns a `KindgiClient` with one resource client per property (see [Resources](#resources)). `ClientOptions`: `apiUrl` (no trailing slash), `auth` (`{ kind: 'apiToken', token }` or `{ kind: 'oauth', accessToken, refresh? }`), and an optional `
|
|
75
|
+
- **`createClient(options: ClientOptions)`** — returns a `KindgiClient` with one resource client per property (see [Resources](#resources)). `ClientOptions`: `apiUrl` (no trailing slash), `auth` (`{ kind: 'apiToken', token }` or `{ kind: 'oauth', accessToken, refresh? }`), an optional `fetch`, and an optional `timeoutMs` (below). Creating a client opens no connections.
|
|
76
76
|
- **Errors** — every method throws **`KindgiApiError`**, whose `error` is a **`KindgiError`** discriminated on `code`: `network`, `auth`, `rate-limited`, `not-found`, `conflict`, `invalid-request`, `guardrail-violation`, `server`, `not-implemented-in-preview`, `not-yet-wired`. **`fromWire(body)`** maps an API error (`{ code, message, details? }`) onto that union; wire codes it does not recognize become `server`, with the original code in `serverCode`. **`notYetWired`** and **`notImplementedInPreview`** build the two preview variants.
|
|
77
77
|
- **Streaming** — **`readSse`** and **`unwrapSseData`** read a `text/event-stream` response as an `AsyncIterable`, reconnecting with exponential backoff and `Last-Event-Id`. `runs.stream`, `evalRuns.events`, `adapters.prepare` and the `secrets` rotation event stream are built on them.
|
|
78
78
|
- **Types** — the input, filter, page and record types of every resource; branded ids and `Filter` / `Page` re-exported from [`@kindgi/types`](../../packages/types/); `DefineAgentSpec` and `RunStatus`.
|
|
@@ -80,6 +80,8 @@ try {
|
|
|
80
80
|
|
|
81
81
|
The transport makes one attempt per call and does not retry. Mutating calls accept an `idempotencyKey`, sent as the `Idempotency-Key` header, so a caller's own retries are safe (see [`docs/API-ROUTE-CONVENTIONS.md`](../../docs/API-ROUTE-CONVENTIONS.md)).
|
|
82
82
|
|
|
83
|
+
**Timeouts.** One request may take `timeoutMs` (30 000 ms unless `ClientOptions.timeoutMs` says otherwise); then it fails with a `network` error whose `timeoutMs` is set. Streams aren't bound by it. A waited `runs.start` answers only when the run ends, so it's bound by it too, and takes its own `timeoutMs`. When the timeout runs out there, the run may still be going and its id never arrived. Start a run that can take longer with `options: { wait: false }`, whose answer carries the run's id at once, and follow it with `runs.stream(runId)`.
|
|
84
|
+
|
|
83
85
|
## JSDoc tags
|
|
84
86
|
|
|
85
87
|
- `@wire` — the method or type mirrors a route or schema in the API's `openapi.json`.
|
package/dist/index.cjs
CHANGED
|
@@ -2894,7 +2894,157 @@ function subscribeToRun(options) {
|
|
|
2894
2894
|
});
|
|
2895
2895
|
}
|
|
2896
2896
|
|
|
2897
|
+
// src/transport.ts
|
|
2898
|
+
var DEFAULT_TIMEOUT_MS = 3e4;
|
|
2899
|
+
var MUTATING = /* @__PURE__ */ new Set([
|
|
2900
|
+
"POST",
|
|
2901
|
+
"PUT",
|
|
2902
|
+
"PATCH",
|
|
2903
|
+
"DELETE"
|
|
2904
|
+
]);
|
|
2905
|
+
function createTransport(options) {
|
|
2906
|
+
const apiUrl = options.apiUrl.replace(/\/+$/u, "");
|
|
2907
|
+
const fetchImpl = options.fetch ?? fetch;
|
|
2908
|
+
const clientTimeoutMs = checkedTimeoutMs(
|
|
2909
|
+
options.timeoutMs ?? DEFAULT_TIMEOUT_MS,
|
|
2910
|
+
"ClientOptions.timeoutMs"
|
|
2911
|
+
);
|
|
2912
|
+
return {
|
|
2913
|
+
apiUrl,
|
|
2914
|
+
fetchImpl,
|
|
2915
|
+
authHeaders() {
|
|
2916
|
+
return { Authorization: `Bearer ${authTokenFor(options.auth)}` };
|
|
2917
|
+
},
|
|
2918
|
+
async request(input) {
|
|
2919
|
+
const url = buildUrl(apiUrl, input.path, input.query);
|
|
2920
|
+
const headers = buildHeaders(input, options.auth);
|
|
2921
|
+
const timeoutMs = input.timeoutMs === void 0 ? clientTimeoutMs : checkedTimeoutMs(input.timeoutMs, "timeoutMs");
|
|
2922
|
+
const ac = new AbortController();
|
|
2923
|
+
let timedOut = false;
|
|
2924
|
+
const timer = setTimeout(() => {
|
|
2925
|
+
timedOut = true;
|
|
2926
|
+
ac.abort(new Error("timeout"));
|
|
2927
|
+
}, timeoutMs);
|
|
2928
|
+
let response;
|
|
2929
|
+
try {
|
|
2930
|
+
response = await fetchImpl(url, {
|
|
2931
|
+
method: input.method,
|
|
2932
|
+
headers,
|
|
2933
|
+
...input.body !== void 0 && { body: JSON.stringify(input.body) },
|
|
2934
|
+
signal: ac.signal
|
|
2935
|
+
});
|
|
2936
|
+
} catch (cause) {
|
|
2937
|
+
clearTimeout(timer);
|
|
2938
|
+
const err = timedOut ? {
|
|
2939
|
+
code: "network",
|
|
2940
|
+
message: `No answer within ${seconds(timeoutMs)}, the client's timeout (timeoutMs).`,
|
|
2941
|
+
cause,
|
|
2942
|
+
timeoutMs
|
|
2943
|
+
} : {
|
|
2944
|
+
code: "network",
|
|
2945
|
+
message: cause instanceof Error ? cause.message : "network request failed",
|
|
2946
|
+
cause
|
|
2947
|
+
};
|
|
2948
|
+
throw new KindgiApiError(err);
|
|
2949
|
+
}
|
|
2950
|
+
clearTimeout(timer);
|
|
2951
|
+
if (response.ok) {
|
|
2952
|
+
if (input.discardResponse === true || response.status === 204) {
|
|
2953
|
+
try {
|
|
2954
|
+
await response.arrayBuffer();
|
|
2955
|
+
} catch {
|
|
2956
|
+
}
|
|
2957
|
+
return void 0;
|
|
2958
|
+
}
|
|
2959
|
+
try {
|
|
2960
|
+
return await response.json();
|
|
2961
|
+
} catch (cause) {
|
|
2962
|
+
const err = {
|
|
2963
|
+
code: "network",
|
|
2964
|
+
message: "Response body was not valid JSON",
|
|
2965
|
+
cause
|
|
2966
|
+
};
|
|
2967
|
+
throw new KindgiApiError(err);
|
|
2968
|
+
}
|
|
2969
|
+
}
|
|
2970
|
+
let body;
|
|
2971
|
+
try {
|
|
2972
|
+
body = await response.json();
|
|
2973
|
+
} catch {
|
|
2974
|
+
body = void 0;
|
|
2975
|
+
}
|
|
2976
|
+
throw new KindgiApiError(
|
|
2977
|
+
fromWire(unwrapErrorEnvelope(body, response.status), response.status)
|
|
2978
|
+
);
|
|
2979
|
+
}
|
|
2980
|
+
};
|
|
2981
|
+
}
|
|
2982
|
+
function checkedTimeoutMs(value, name) {
|
|
2983
|
+
if (!Number.isFinite(value) || value <= 0) {
|
|
2984
|
+
throw new TypeError(`${name} must be a positive number of milliseconds. Got ${String(value)}.`);
|
|
2985
|
+
}
|
|
2986
|
+
return value;
|
|
2987
|
+
}
|
|
2988
|
+
function seconds(ms) {
|
|
2989
|
+
return `${ms / 1e3} s`;
|
|
2990
|
+
}
|
|
2991
|
+
function buildUrl(apiUrl, path, query) {
|
|
2992
|
+
const normalizedPath = path.startsWith("/") ? path : `/${path}`;
|
|
2993
|
+
const base = `${apiUrl}${normalizedPath}`;
|
|
2994
|
+
if (query === void 0) return base;
|
|
2995
|
+
const params = [];
|
|
2996
|
+
for (const key of Object.keys(query)) {
|
|
2997
|
+
const value = query[key];
|
|
2998
|
+
if (value === void 0) continue;
|
|
2999
|
+
const values = typeof value === "object" ? value : [String(value)];
|
|
3000
|
+
for (const v of values) params.push(`${encodeURIComponent(key)}=${encodeURIComponent(v)}`);
|
|
3001
|
+
}
|
|
3002
|
+
return params.length === 0 ? base : `${base}?${params.join("&")}`;
|
|
3003
|
+
}
|
|
3004
|
+
function buildHeaders(input, auth) {
|
|
3005
|
+
const headers = {
|
|
3006
|
+
Accept: "application/json",
|
|
3007
|
+
Authorization: `Bearer ${authTokenFor(auth)}`
|
|
3008
|
+
};
|
|
3009
|
+
if (input.body !== void 0) {
|
|
3010
|
+
headers["Content-Type"] = "application/json; charset=utf-8";
|
|
3011
|
+
}
|
|
3012
|
+
if (input.idempotencyKey !== void 0 && MUTATING.has(input.method)) {
|
|
3013
|
+
headers["Idempotency-Key"] = input.idempotencyKey;
|
|
3014
|
+
}
|
|
3015
|
+
if (input.headers !== void 0) {
|
|
3016
|
+
for (const key of Object.keys(input.headers)) {
|
|
3017
|
+
headers[key] = input.headers[key];
|
|
3018
|
+
}
|
|
3019
|
+
}
|
|
3020
|
+
return headers;
|
|
3021
|
+
}
|
|
3022
|
+
function authTokenFor(auth) {
|
|
3023
|
+
if (auth.kind === "apiToken") return auth.token;
|
|
3024
|
+
return auth.accessToken;
|
|
3025
|
+
}
|
|
3026
|
+
function unwrapErrorEnvelope(body, status) {
|
|
3027
|
+
if (body !== null && typeof body === "object" && !Array.isArray(body)) {
|
|
3028
|
+
const inner = body.error;
|
|
3029
|
+
if (inner !== null && typeof inner === "object" && !Array.isArray(inner)) {
|
|
3030
|
+
return inner;
|
|
3031
|
+
}
|
|
3032
|
+
}
|
|
3033
|
+
return { code: "unknown", message: `HTTP ${status} without recognizable error envelope` };
|
|
3034
|
+
}
|
|
3035
|
+
|
|
2897
3036
|
// src/resources/runs.ts
|
|
3037
|
+
function waitedStartTimeout(e) {
|
|
3038
|
+
if (!(e instanceof KindgiApiError) || e.error.code !== "network") return e;
|
|
3039
|
+
const { timeoutMs } = e.error;
|
|
3040
|
+
if (timeoutMs === void 0) return e;
|
|
3041
|
+
return new KindgiApiError({
|
|
3042
|
+
code: "network",
|
|
3043
|
+
message: `The run didn't end within ${seconds(timeoutMs)}, the client's timeout (timeoutMs). A waited start answers only when the run ends, so the run may still be going, and its id didn't arrive. Start a run that can take longer with \`options: { wait: false }\`: the answer carries its id at once. Then follow it with \`runs.stream(runId)\` or \`runs.get(runId)\`. Or raise \`timeoutMs\`.`,
|
|
3044
|
+
cause: e.error.cause,
|
|
3045
|
+
timeoutMs
|
|
3046
|
+
});
|
|
3047
|
+
}
|
|
2898
3048
|
function makeRunsClient(transport) {
|
|
2899
3049
|
return {
|
|
2900
3050
|
async start(input) {
|
|
@@ -2913,14 +3063,19 @@ function makeRunsClient(transport) {
|
|
|
2913
3063
|
input: input.input,
|
|
2914
3064
|
...input.options !== void 0 && { options: input.options }
|
|
2915
3065
|
};
|
|
2916
|
-
|
|
2917
|
-
|
|
2918
|
-
|
|
2919
|
-
|
|
2920
|
-
|
|
2921
|
-
|
|
2922
|
-
|
|
2923
|
-
|
|
3066
|
+
try {
|
|
3067
|
+
return await transport.request({
|
|
3068
|
+
method: "POST",
|
|
3069
|
+
path: "/v1/runs",
|
|
3070
|
+
body,
|
|
3071
|
+
...input.idempotencyKey !== void 0 && {
|
|
3072
|
+
idempotencyKey: input.idempotencyKey
|
|
3073
|
+
},
|
|
3074
|
+
...input.timeoutMs !== void 0 && { timeoutMs: input.timeoutMs }
|
|
3075
|
+
});
|
|
3076
|
+
} catch (e) {
|
|
3077
|
+
throw input.options?.wait === false ? e : waitedStartTimeout(e);
|
|
3078
|
+
}
|
|
2924
3079
|
},
|
|
2925
3080
|
async dryRun(_input) {
|
|
2926
3081
|
throw new KindgiApiError(
|
|
@@ -4050,127 +4205,6 @@ function makeWebhooksClient(transport) {
|
|
|
4050
4205
|
};
|
|
4051
4206
|
}
|
|
4052
4207
|
|
|
4053
|
-
// src/transport.ts
|
|
4054
|
-
var DEFAULT_TIMEOUT_MS = 3e4;
|
|
4055
|
-
var MUTATING = /* @__PURE__ */ new Set([
|
|
4056
|
-
"POST",
|
|
4057
|
-
"PUT",
|
|
4058
|
-
"PATCH",
|
|
4059
|
-
"DELETE"
|
|
4060
|
-
]);
|
|
4061
|
-
function createTransport(options) {
|
|
4062
|
-
const apiUrl = options.apiUrl.replace(/\/+$/u, "");
|
|
4063
|
-
const fetchImpl = options.fetch ?? fetch;
|
|
4064
|
-
const clientTimeoutMs = DEFAULT_TIMEOUT_MS;
|
|
4065
|
-
return {
|
|
4066
|
-
apiUrl,
|
|
4067
|
-
fetchImpl,
|
|
4068
|
-
authHeaders() {
|
|
4069
|
-
return { Authorization: `Bearer ${authTokenFor(options.auth)}` };
|
|
4070
|
-
},
|
|
4071
|
-
async request(input) {
|
|
4072
|
-
const url = buildUrl(apiUrl, input.path, input.query);
|
|
4073
|
-
const headers = buildHeaders(input, options.auth);
|
|
4074
|
-
const timeoutMs = input.timeoutMs ?? clientTimeoutMs;
|
|
4075
|
-
const ac = new AbortController();
|
|
4076
|
-
const timer = setTimeout(
|
|
4077
|
-
() => ac.abort(new Error("timeout")),
|
|
4078
|
-
timeoutMs
|
|
4079
|
-
);
|
|
4080
|
-
let response;
|
|
4081
|
-
try {
|
|
4082
|
-
response = await fetchImpl(url, {
|
|
4083
|
-
method: input.method,
|
|
4084
|
-
headers,
|
|
4085
|
-
...input.body !== void 0 && { body: JSON.stringify(input.body) },
|
|
4086
|
-
signal: ac.signal
|
|
4087
|
-
});
|
|
4088
|
-
} catch (cause) {
|
|
4089
|
-
clearTimeout(timer);
|
|
4090
|
-
const err = {
|
|
4091
|
-
code: "network",
|
|
4092
|
-
message: cause instanceof Error ? cause.message : "network request failed",
|
|
4093
|
-
cause
|
|
4094
|
-
};
|
|
4095
|
-
throw new KindgiApiError(err);
|
|
4096
|
-
}
|
|
4097
|
-
clearTimeout(timer);
|
|
4098
|
-
if (response.ok) {
|
|
4099
|
-
if (input.discardResponse === true || response.status === 204) {
|
|
4100
|
-
try {
|
|
4101
|
-
await response.arrayBuffer();
|
|
4102
|
-
} catch {
|
|
4103
|
-
}
|
|
4104
|
-
return void 0;
|
|
4105
|
-
}
|
|
4106
|
-
try {
|
|
4107
|
-
return await response.json();
|
|
4108
|
-
} catch (cause) {
|
|
4109
|
-
const err = {
|
|
4110
|
-
code: "network",
|
|
4111
|
-
message: "Response body was not valid JSON",
|
|
4112
|
-
cause
|
|
4113
|
-
};
|
|
4114
|
-
throw new KindgiApiError(err);
|
|
4115
|
-
}
|
|
4116
|
-
}
|
|
4117
|
-
let body;
|
|
4118
|
-
try {
|
|
4119
|
-
body = await response.json();
|
|
4120
|
-
} catch {
|
|
4121
|
-
body = void 0;
|
|
4122
|
-
}
|
|
4123
|
-
throw new KindgiApiError(
|
|
4124
|
-
fromWire(unwrapErrorEnvelope(body, response.status), response.status)
|
|
4125
|
-
);
|
|
4126
|
-
}
|
|
4127
|
-
};
|
|
4128
|
-
}
|
|
4129
|
-
function buildUrl(apiUrl, path, query) {
|
|
4130
|
-
const normalizedPath = path.startsWith("/") ? path : `/${path}`;
|
|
4131
|
-
const base = `${apiUrl}${normalizedPath}`;
|
|
4132
|
-
if (query === void 0) return base;
|
|
4133
|
-
const params = [];
|
|
4134
|
-
for (const key of Object.keys(query)) {
|
|
4135
|
-
const value = query[key];
|
|
4136
|
-
if (value === void 0) continue;
|
|
4137
|
-
const values = typeof value === "object" ? value : [String(value)];
|
|
4138
|
-
for (const v of values) params.push(`${encodeURIComponent(key)}=${encodeURIComponent(v)}`);
|
|
4139
|
-
}
|
|
4140
|
-
return params.length === 0 ? base : `${base}?${params.join("&")}`;
|
|
4141
|
-
}
|
|
4142
|
-
function buildHeaders(input, auth) {
|
|
4143
|
-
const headers = {
|
|
4144
|
-
Accept: "application/json",
|
|
4145
|
-
Authorization: `Bearer ${authTokenFor(auth)}`
|
|
4146
|
-
};
|
|
4147
|
-
if (input.body !== void 0) {
|
|
4148
|
-
headers["Content-Type"] = "application/json; charset=utf-8";
|
|
4149
|
-
}
|
|
4150
|
-
if (input.idempotencyKey !== void 0 && MUTATING.has(input.method)) {
|
|
4151
|
-
headers["Idempotency-Key"] = input.idempotencyKey;
|
|
4152
|
-
}
|
|
4153
|
-
if (input.headers !== void 0) {
|
|
4154
|
-
for (const key of Object.keys(input.headers)) {
|
|
4155
|
-
headers[key] = input.headers[key];
|
|
4156
|
-
}
|
|
4157
|
-
}
|
|
4158
|
-
return headers;
|
|
4159
|
-
}
|
|
4160
|
-
function authTokenFor(auth) {
|
|
4161
|
-
if (auth.kind === "apiToken") return auth.token;
|
|
4162
|
-
return auth.accessToken;
|
|
4163
|
-
}
|
|
4164
|
-
function unwrapErrorEnvelope(body, status) {
|
|
4165
|
-
if (body !== null && typeof body === "object" && !Array.isArray(body)) {
|
|
4166
|
-
const inner = body.error;
|
|
4167
|
-
if (inner !== null && typeof inner === "object" && !Array.isArray(inner)) {
|
|
4168
|
-
return inner;
|
|
4169
|
-
}
|
|
4170
|
-
}
|
|
4171
|
-
return { code: "unknown", message: `HTTP ${status} without recognizable error envelope` };
|
|
4172
|
-
}
|
|
4173
|
-
|
|
4174
4208
|
// src/client.ts
|
|
4175
4209
|
function createClient(options) {
|
|
4176
4210
|
const transport = createTransport(options);
|
package/dist/index.d.cts
CHANGED
|
@@ -1775,7 +1775,9 @@ export interface DefineAgentSpec {
|
|
|
1775
1775
|
* Required capabilities the agent needs from a `ModelProvider`.
|
|
1776
1776
|
* Typically one entry: `[{ needs: [{ feature: 'tool-use' }] }]`
|
|
1777
1777
|
* for a tool-calling agent, `[{ needs: [{ feature: 'structured-output' }] }]`
|
|
1778
|
-
* for an agent that
|
|
1778
|
+
* for an agent that should run on a model that can follow a JSON schema
|
|
1779
|
+
* natively (its typed `output` is still checked by parse and repair, on
|
|
1780
|
+
* every model). The router uses
|
|
1779
1781
|
* the first entry to pick a compatible provider from the tenant's
|
|
1780
1782
|
* `ProviderRegistry`.
|
|
1781
1783
|
*/
|
|
@@ -3997,6 +3999,12 @@ export interface ClientOptions {
|
|
|
3997
3999
|
readonly auth: AuthConfig;
|
|
3998
4000
|
/** Overridable fetch impl for testing. Defaults to global `fetch`. */
|
|
3999
4001
|
readonly fetch?: typeof fetch;
|
|
4002
|
+
/**
|
|
4003
|
+
* How long one request may take, in milliseconds, before it fails with
|
|
4004
|
+
* a `network` error. Default 30 000. Streams (`runs.stream` and the
|
|
4005
|
+
* like) aren't bound by it. `runs.start` also takes its own.
|
|
4006
|
+
*/
|
|
4007
|
+
readonly timeoutMs?: number;
|
|
4000
4008
|
}
|
|
4001
4009
|
/** The verdict of a judgment. */
|
|
4002
4010
|
export type Verdict = "yes" | "no";
|
|
@@ -6909,6 +6917,19 @@ declare namespace Schemas {
|
|
|
6909
6917
|
nextCursor?: string;
|
|
6910
6918
|
hasMore: boolean;
|
|
6911
6919
|
};
|
|
6920
|
+
/**
|
|
6921
|
+
* How the model thinks before it answers, so a call that wants as little as it allows (a judge's) gets it. Absent: it doesn't think, or nothing is known.
|
|
6922
|
+
*/
|
|
6923
|
+
export type ModelThinking = {
|
|
6924
|
+
/**
|
|
6925
|
+
* `adaptive`: on unless turned down. `always`: on, and it can only be lowered.
|
|
6926
|
+
*/
|
|
6927
|
+
mode: "adaptive" | "always";
|
|
6928
|
+
/**
|
|
6929
|
+
* The vendor's own setting for the least thinking: for Anthropic `disabled`, `between_tools` or an effort (`low`); for Gemini a thinking level (`low`, `minimal`); for OpenAI a reasoning effort (`low`, `none`).
|
|
6930
|
+
*/
|
|
6931
|
+
lowest: string;
|
|
6932
|
+
};
|
|
6912
6933
|
/**
|
|
6913
6934
|
* USD per 1K tokens. An adapter may take more rate fields (see the adapter's README).
|
|
6914
6935
|
*/
|
|
@@ -6938,6 +6959,11 @@ declare namespace Schemas {
|
|
|
6938
6959
|
* Fallback cap on output tokens. Adapters that require `max_tokens` on every request (e.g. Anthropic) use this when `ModelCallInput.maxOutputTokens` is unset.
|
|
6939
6960
|
*/
|
|
6940
6961
|
maxOutputTokens?: number;
|
|
6962
|
+
/**
|
|
6963
|
+
* Whether the model takes sampling settings (`temperature`). `false`: its API rejects a non-default value, so the call goes without one and the answer's `warnings` say so (`sampling-unsupported`). Absent: it takes them.
|
|
6964
|
+
*/
|
|
6965
|
+
sampling?: boolean;
|
|
6966
|
+
thinking?: ModelThinking;
|
|
6941
6967
|
/**
|
|
6942
6968
|
* Short per-model description surfaced in logs.
|
|
6943
6969
|
*/
|
|
@@ -6953,6 +6979,10 @@ declare namespace Schemas {
|
|
|
6953
6979
|
* Models this connection exposes. Non-empty. `models[i].name` must be unique within the list.
|
|
6954
6980
|
*/
|
|
6955
6981
|
models: Array<ModelInfo>;
|
|
6982
|
+
/**
|
|
6983
|
+
* The model to use when an agent doesn't choose: one of `models[].name`. When candidates rank equally, it comes before the provider's other models; without it, ties break by model name. A preset sets it. A runtime before 0.1.4 ignores it.
|
|
6984
|
+
*/
|
|
6985
|
+
defaultModel?: string;
|
|
6956
6986
|
/**
|
|
6957
6987
|
* Soft attributes for preference-ranking (`local`, `lower-cost`, `higher-accuracy`, ...). Matched by string equality against `Preference.feature`.
|
|
6958
6988
|
*/
|
|
@@ -10091,8 +10121,17 @@ declare const ProviderMetadata: z.ZodObject<{
|
|
|
10091
10121
|
}, z.core.$catchall<z.ZodUnknown>>;
|
|
10092
10122
|
p95LatencyMs: z.ZodOptional<z.ZodNumber>;
|
|
10093
10123
|
maxOutputTokens: z.ZodOptional<z.ZodNumber>;
|
|
10124
|
+
sampling: z.ZodOptional<z.ZodBoolean>;
|
|
10125
|
+
thinking: z.ZodOptional<z.ZodObject<{
|
|
10126
|
+
mode: z.ZodEnum<{
|
|
10127
|
+
always: "always";
|
|
10128
|
+
adaptive: "adaptive";
|
|
10129
|
+
}>;
|
|
10130
|
+
lowest: z.ZodString;
|
|
10131
|
+
}, z.core.$strict>>;
|
|
10094
10132
|
description: z.ZodOptional<z.ZodString>;
|
|
10095
10133
|
}, z.core.$strict>>;
|
|
10134
|
+
defaultModel: z.ZodOptional<z.ZodString>;
|
|
10096
10135
|
attributes: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
10097
10136
|
description: z.ZodOptional<z.ZodString>;
|
|
10098
10137
|
capabilityKind: z.ZodOptional<z.ZodString>;
|
|
@@ -10128,8 +10167,17 @@ declare const ProviderCollectionPage: z.ZodObject<{
|
|
|
10128
10167
|
}, z.core.$catchall<z.ZodUnknown>>;
|
|
10129
10168
|
p95LatencyMs: z.ZodOptional<z.ZodNumber>;
|
|
10130
10169
|
maxOutputTokens: z.ZodOptional<z.ZodNumber>;
|
|
10170
|
+
sampling: z.ZodOptional<z.ZodBoolean>;
|
|
10171
|
+
thinking: z.ZodOptional<z.ZodObject<{
|
|
10172
|
+
mode: z.ZodEnum<{
|
|
10173
|
+
always: "always";
|
|
10174
|
+
adaptive: "adaptive";
|
|
10175
|
+
}>;
|
|
10176
|
+
lowest: z.ZodString;
|
|
10177
|
+
}, z.core.$strict>>;
|
|
10131
10178
|
description: z.ZodOptional<z.ZodString>;
|
|
10132
10179
|
}, z.core.$strict>>;
|
|
10180
|
+
defaultModel: z.ZodOptional<z.ZodString>;
|
|
10133
10181
|
attributes: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
10134
10182
|
description: z.ZodOptional<z.ZodString>;
|
|
10135
10183
|
capabilityKind: z.ZodOptional<z.ZodString>;
|
|
@@ -10168,8 +10216,17 @@ declare const RegisterProviderBody: z.ZodObject<{
|
|
|
10168
10216
|
}, z.core.$catchall<z.ZodUnknown>>;
|
|
10169
10217
|
p95LatencyMs: z.ZodOptional<z.ZodNumber>;
|
|
10170
10218
|
maxOutputTokens: z.ZodOptional<z.ZodNumber>;
|
|
10219
|
+
sampling: z.ZodOptional<z.ZodBoolean>;
|
|
10220
|
+
thinking: z.ZodOptional<z.ZodObject<{
|
|
10221
|
+
mode: z.ZodEnum<{
|
|
10222
|
+
always: "always";
|
|
10223
|
+
adaptive: "adaptive";
|
|
10224
|
+
}>;
|
|
10225
|
+
lowest: z.ZodString;
|
|
10226
|
+
}, z.core.$strict>>;
|
|
10171
10227
|
description: z.ZodOptional<z.ZodString>;
|
|
10172
10228
|
}, z.core.$strict>>;
|
|
10229
|
+
defaultModel: z.ZodOptional<z.ZodString>;
|
|
10173
10230
|
attributes: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
10174
10231
|
description: z.ZodOptional<z.ZodString>;
|
|
10175
10232
|
capabilityKind: z.ZodOptional<z.ZodString>;
|
|
@@ -14696,6 +14753,11 @@ export interface RunsClient {
|
|
|
14696
14753
|
* with `options.wait: false` as soon as it exists (202) — poll
|
|
14697
14754
|
* `get(runId)` until it finishes.
|
|
14698
14755
|
*
|
|
14756
|
+
* A waited start is bound by the client's timeout (`timeoutMs`, 30 s by
|
|
14757
|
+
* default; this call can set its own). When it runs out, the run may
|
|
14758
|
+
* still be going and its id never arrived: the `network` error says so.
|
|
14759
|
+
* Start a run that can take longer with `options.wait: false`.
|
|
14760
|
+
*
|
|
14699
14761
|
* `idempotencyKey` makes retries safe: two calls with the same key
|
|
14700
14762
|
* within the server's retention window return the same `Run`.
|
|
14701
14763
|
*
|
|
@@ -14860,6 +14922,13 @@ export type StartRunInput = {
|
|
|
14860
14922
|
readonly input: unknown;
|
|
14861
14923
|
readonly options?: StartRunOptions;
|
|
14862
14924
|
readonly idempotencyKey?: string;
|
|
14925
|
+
/**
|
|
14926
|
+
* How long to wait for the answer, in milliseconds: this call's
|
|
14927
|
+
* `ClientOptions.timeoutMs`. A waited start answers only when the run
|
|
14928
|
+
* ends, so a run that can take longer is better started with
|
|
14929
|
+
* `options: { wait: false }` and followed.
|
|
14930
|
+
*/
|
|
14931
|
+
readonly timeoutMs?: number;
|
|
14863
14932
|
} | {
|
|
14864
14933
|
readonly flow: FlowId | string;
|
|
14865
14934
|
readonly flowVersion?: string;
|
|
@@ -14870,6 +14939,13 @@ export type StartRunInput = {
|
|
|
14870
14939
|
readonly input: unknown;
|
|
14871
14940
|
readonly options?: StartRunOptions;
|
|
14872
14941
|
readonly idempotencyKey?: string;
|
|
14942
|
+
/**
|
|
14943
|
+
* How long to wait for the answer, in milliseconds: this call's
|
|
14944
|
+
* `ClientOptions.timeoutMs`. A waited start answers only when the run
|
|
14945
|
+
* ends, so a run that can take longer is better started with
|
|
14946
|
+
* `options: { wait: false }` and followed.
|
|
14947
|
+
*/
|
|
14948
|
+
readonly timeoutMs?: number;
|
|
14873
14949
|
};
|
|
14874
14950
|
export interface StartRunOptions {
|
|
14875
14951
|
/** Run with side-effects mocked; the row is marked `dryRun: true`. */
|
|
@@ -16054,6 +16130,8 @@ export interface NetworkError {
|
|
|
16054
16130
|
readonly code: "network";
|
|
16055
16131
|
readonly message: string;
|
|
16056
16132
|
readonly cause?: unknown;
|
|
16133
|
+
/** Set when the client's own timeout ended the request: that timeout, in milliseconds. */
|
|
16134
|
+
readonly timeoutMs?: number;
|
|
16057
16135
|
}
|
|
16058
16136
|
export interface AuthError {
|
|
16059
16137
|
readonly code: "auth";
|
package/dist/index.d.ts
CHANGED
|
@@ -1775,7 +1775,9 @@ export interface DefineAgentSpec {
|
|
|
1775
1775
|
* Required capabilities the agent needs from a `ModelProvider`.
|
|
1776
1776
|
* Typically one entry: `[{ needs: [{ feature: 'tool-use' }] }]`
|
|
1777
1777
|
* for a tool-calling agent, `[{ needs: [{ feature: 'structured-output' }] }]`
|
|
1778
|
-
* for an agent that
|
|
1778
|
+
* for an agent that should run on a model that can follow a JSON schema
|
|
1779
|
+
* natively (its typed `output` is still checked by parse and repair, on
|
|
1780
|
+
* every model). The router uses
|
|
1779
1781
|
* the first entry to pick a compatible provider from the tenant's
|
|
1780
1782
|
* `ProviderRegistry`.
|
|
1781
1783
|
*/
|
|
@@ -3997,6 +3999,12 @@ export interface ClientOptions {
|
|
|
3997
3999
|
readonly auth: AuthConfig;
|
|
3998
4000
|
/** Overridable fetch impl for testing. Defaults to global `fetch`. */
|
|
3999
4001
|
readonly fetch?: typeof fetch;
|
|
4002
|
+
/**
|
|
4003
|
+
* How long one request may take, in milliseconds, before it fails with
|
|
4004
|
+
* a `network` error. Default 30 000. Streams (`runs.stream` and the
|
|
4005
|
+
* like) aren't bound by it. `runs.start` also takes its own.
|
|
4006
|
+
*/
|
|
4007
|
+
readonly timeoutMs?: number;
|
|
4000
4008
|
}
|
|
4001
4009
|
/** The verdict of a judgment. */
|
|
4002
4010
|
export type Verdict = "yes" | "no";
|
|
@@ -6909,6 +6917,19 @@ declare namespace Schemas {
|
|
|
6909
6917
|
nextCursor?: string;
|
|
6910
6918
|
hasMore: boolean;
|
|
6911
6919
|
};
|
|
6920
|
+
/**
|
|
6921
|
+
* How the model thinks before it answers, so a call that wants as little as it allows (a judge's) gets it. Absent: it doesn't think, or nothing is known.
|
|
6922
|
+
*/
|
|
6923
|
+
export type ModelThinking = {
|
|
6924
|
+
/**
|
|
6925
|
+
* `adaptive`: on unless turned down. `always`: on, and it can only be lowered.
|
|
6926
|
+
*/
|
|
6927
|
+
mode: "adaptive" | "always";
|
|
6928
|
+
/**
|
|
6929
|
+
* The vendor's own setting for the least thinking: for Anthropic `disabled`, `between_tools` or an effort (`low`); for Gemini a thinking level (`low`, `minimal`); for OpenAI a reasoning effort (`low`, `none`).
|
|
6930
|
+
*/
|
|
6931
|
+
lowest: string;
|
|
6932
|
+
};
|
|
6912
6933
|
/**
|
|
6913
6934
|
* USD per 1K tokens. An adapter may take more rate fields (see the adapter's README).
|
|
6914
6935
|
*/
|
|
@@ -6938,6 +6959,11 @@ declare namespace Schemas {
|
|
|
6938
6959
|
* Fallback cap on output tokens. Adapters that require `max_tokens` on every request (e.g. Anthropic) use this when `ModelCallInput.maxOutputTokens` is unset.
|
|
6939
6960
|
*/
|
|
6940
6961
|
maxOutputTokens?: number;
|
|
6962
|
+
/**
|
|
6963
|
+
* Whether the model takes sampling settings (`temperature`). `false`: its API rejects a non-default value, so the call goes without one and the answer's `warnings` say so (`sampling-unsupported`). Absent: it takes them.
|
|
6964
|
+
*/
|
|
6965
|
+
sampling?: boolean;
|
|
6966
|
+
thinking?: ModelThinking;
|
|
6941
6967
|
/**
|
|
6942
6968
|
* Short per-model description surfaced in logs.
|
|
6943
6969
|
*/
|
|
@@ -6953,6 +6979,10 @@ declare namespace Schemas {
|
|
|
6953
6979
|
* Models this connection exposes. Non-empty. `models[i].name` must be unique within the list.
|
|
6954
6980
|
*/
|
|
6955
6981
|
models: Array<ModelInfo>;
|
|
6982
|
+
/**
|
|
6983
|
+
* The model to use when an agent doesn't choose: one of `models[].name`. When candidates rank equally, it comes before the provider's other models; without it, ties break by model name. A preset sets it. A runtime before 0.1.4 ignores it.
|
|
6984
|
+
*/
|
|
6985
|
+
defaultModel?: string;
|
|
6956
6986
|
/**
|
|
6957
6987
|
* Soft attributes for preference-ranking (`local`, `lower-cost`, `higher-accuracy`, ...). Matched by string equality against `Preference.feature`.
|
|
6958
6988
|
*/
|
|
@@ -10091,8 +10121,17 @@ declare const ProviderMetadata: z.ZodObject<{
|
|
|
10091
10121
|
}, z.core.$catchall<z.ZodUnknown>>;
|
|
10092
10122
|
p95LatencyMs: z.ZodOptional<z.ZodNumber>;
|
|
10093
10123
|
maxOutputTokens: z.ZodOptional<z.ZodNumber>;
|
|
10124
|
+
sampling: z.ZodOptional<z.ZodBoolean>;
|
|
10125
|
+
thinking: z.ZodOptional<z.ZodObject<{
|
|
10126
|
+
mode: z.ZodEnum<{
|
|
10127
|
+
always: "always";
|
|
10128
|
+
adaptive: "adaptive";
|
|
10129
|
+
}>;
|
|
10130
|
+
lowest: z.ZodString;
|
|
10131
|
+
}, z.core.$strict>>;
|
|
10094
10132
|
description: z.ZodOptional<z.ZodString>;
|
|
10095
10133
|
}, z.core.$strict>>;
|
|
10134
|
+
defaultModel: z.ZodOptional<z.ZodString>;
|
|
10096
10135
|
attributes: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
10097
10136
|
description: z.ZodOptional<z.ZodString>;
|
|
10098
10137
|
capabilityKind: z.ZodOptional<z.ZodString>;
|
|
@@ -10128,8 +10167,17 @@ declare const ProviderCollectionPage: z.ZodObject<{
|
|
|
10128
10167
|
}, z.core.$catchall<z.ZodUnknown>>;
|
|
10129
10168
|
p95LatencyMs: z.ZodOptional<z.ZodNumber>;
|
|
10130
10169
|
maxOutputTokens: z.ZodOptional<z.ZodNumber>;
|
|
10170
|
+
sampling: z.ZodOptional<z.ZodBoolean>;
|
|
10171
|
+
thinking: z.ZodOptional<z.ZodObject<{
|
|
10172
|
+
mode: z.ZodEnum<{
|
|
10173
|
+
always: "always";
|
|
10174
|
+
adaptive: "adaptive";
|
|
10175
|
+
}>;
|
|
10176
|
+
lowest: z.ZodString;
|
|
10177
|
+
}, z.core.$strict>>;
|
|
10131
10178
|
description: z.ZodOptional<z.ZodString>;
|
|
10132
10179
|
}, z.core.$strict>>;
|
|
10180
|
+
defaultModel: z.ZodOptional<z.ZodString>;
|
|
10133
10181
|
attributes: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
10134
10182
|
description: z.ZodOptional<z.ZodString>;
|
|
10135
10183
|
capabilityKind: z.ZodOptional<z.ZodString>;
|
|
@@ -10168,8 +10216,17 @@ declare const RegisterProviderBody: z.ZodObject<{
|
|
|
10168
10216
|
}, z.core.$catchall<z.ZodUnknown>>;
|
|
10169
10217
|
p95LatencyMs: z.ZodOptional<z.ZodNumber>;
|
|
10170
10218
|
maxOutputTokens: z.ZodOptional<z.ZodNumber>;
|
|
10219
|
+
sampling: z.ZodOptional<z.ZodBoolean>;
|
|
10220
|
+
thinking: z.ZodOptional<z.ZodObject<{
|
|
10221
|
+
mode: z.ZodEnum<{
|
|
10222
|
+
always: "always";
|
|
10223
|
+
adaptive: "adaptive";
|
|
10224
|
+
}>;
|
|
10225
|
+
lowest: z.ZodString;
|
|
10226
|
+
}, z.core.$strict>>;
|
|
10171
10227
|
description: z.ZodOptional<z.ZodString>;
|
|
10172
10228
|
}, z.core.$strict>>;
|
|
10229
|
+
defaultModel: z.ZodOptional<z.ZodString>;
|
|
10173
10230
|
attributes: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
10174
10231
|
description: z.ZodOptional<z.ZodString>;
|
|
10175
10232
|
capabilityKind: z.ZodOptional<z.ZodString>;
|
|
@@ -14696,6 +14753,11 @@ export interface RunsClient {
|
|
|
14696
14753
|
* with `options.wait: false` as soon as it exists (202) — poll
|
|
14697
14754
|
* `get(runId)` until it finishes.
|
|
14698
14755
|
*
|
|
14756
|
+
* A waited start is bound by the client's timeout (`timeoutMs`, 30 s by
|
|
14757
|
+
* default; this call can set its own). When it runs out, the run may
|
|
14758
|
+
* still be going and its id never arrived: the `network` error says so.
|
|
14759
|
+
* Start a run that can take longer with `options.wait: false`.
|
|
14760
|
+
*
|
|
14699
14761
|
* `idempotencyKey` makes retries safe: two calls with the same key
|
|
14700
14762
|
* within the server's retention window return the same `Run`.
|
|
14701
14763
|
*
|
|
@@ -14860,6 +14922,13 @@ export type StartRunInput = {
|
|
|
14860
14922
|
readonly input: unknown;
|
|
14861
14923
|
readonly options?: StartRunOptions;
|
|
14862
14924
|
readonly idempotencyKey?: string;
|
|
14925
|
+
/**
|
|
14926
|
+
* How long to wait for the answer, in milliseconds: this call's
|
|
14927
|
+
* `ClientOptions.timeoutMs`. A waited start answers only when the run
|
|
14928
|
+
* ends, so a run that can take longer is better started with
|
|
14929
|
+
* `options: { wait: false }` and followed.
|
|
14930
|
+
*/
|
|
14931
|
+
readonly timeoutMs?: number;
|
|
14863
14932
|
} | {
|
|
14864
14933
|
readonly flow: FlowId | string;
|
|
14865
14934
|
readonly flowVersion?: string;
|
|
@@ -14870,6 +14939,13 @@ export type StartRunInput = {
|
|
|
14870
14939
|
readonly input: unknown;
|
|
14871
14940
|
readonly options?: StartRunOptions;
|
|
14872
14941
|
readonly idempotencyKey?: string;
|
|
14942
|
+
/**
|
|
14943
|
+
* How long to wait for the answer, in milliseconds: this call's
|
|
14944
|
+
* `ClientOptions.timeoutMs`. A waited start answers only when the run
|
|
14945
|
+
* ends, so a run that can take longer is better started with
|
|
14946
|
+
* `options: { wait: false }` and followed.
|
|
14947
|
+
*/
|
|
14948
|
+
readonly timeoutMs?: number;
|
|
14873
14949
|
};
|
|
14874
14950
|
export interface StartRunOptions {
|
|
14875
14951
|
/** Run with side-effects mocked; the row is marked `dryRun: true`. */
|
|
@@ -16054,6 +16130,8 @@ export interface NetworkError {
|
|
|
16054
16130
|
readonly code: "network";
|
|
16055
16131
|
readonly message: string;
|
|
16056
16132
|
readonly cause?: unknown;
|
|
16133
|
+
/** Set when the client's own timeout ended the request: that timeout, in milliseconds. */
|
|
16134
|
+
readonly timeoutMs?: number;
|
|
16057
16135
|
}
|
|
16058
16136
|
export interface AuthError {
|
|
16059
16137
|
readonly code: "auth";
|
package/dist/index.js
CHANGED
|
@@ -2892,7 +2892,157 @@ function subscribeToRun(options) {
|
|
|
2892
2892
|
});
|
|
2893
2893
|
}
|
|
2894
2894
|
|
|
2895
|
+
// src/transport.ts
|
|
2896
|
+
var DEFAULT_TIMEOUT_MS = 3e4;
|
|
2897
|
+
var MUTATING = /* @__PURE__ */ new Set([
|
|
2898
|
+
"POST",
|
|
2899
|
+
"PUT",
|
|
2900
|
+
"PATCH",
|
|
2901
|
+
"DELETE"
|
|
2902
|
+
]);
|
|
2903
|
+
function createTransport(options) {
|
|
2904
|
+
const apiUrl = options.apiUrl.replace(/\/+$/u, "");
|
|
2905
|
+
const fetchImpl = options.fetch ?? fetch;
|
|
2906
|
+
const clientTimeoutMs = checkedTimeoutMs(
|
|
2907
|
+
options.timeoutMs ?? DEFAULT_TIMEOUT_MS,
|
|
2908
|
+
"ClientOptions.timeoutMs"
|
|
2909
|
+
);
|
|
2910
|
+
return {
|
|
2911
|
+
apiUrl,
|
|
2912
|
+
fetchImpl,
|
|
2913
|
+
authHeaders() {
|
|
2914
|
+
return { Authorization: `Bearer ${authTokenFor(options.auth)}` };
|
|
2915
|
+
},
|
|
2916
|
+
async request(input) {
|
|
2917
|
+
const url = buildUrl(apiUrl, input.path, input.query);
|
|
2918
|
+
const headers = buildHeaders(input, options.auth);
|
|
2919
|
+
const timeoutMs = input.timeoutMs === void 0 ? clientTimeoutMs : checkedTimeoutMs(input.timeoutMs, "timeoutMs");
|
|
2920
|
+
const ac = new AbortController();
|
|
2921
|
+
let timedOut = false;
|
|
2922
|
+
const timer = setTimeout(() => {
|
|
2923
|
+
timedOut = true;
|
|
2924
|
+
ac.abort(new Error("timeout"));
|
|
2925
|
+
}, timeoutMs);
|
|
2926
|
+
let response;
|
|
2927
|
+
try {
|
|
2928
|
+
response = await fetchImpl(url, {
|
|
2929
|
+
method: input.method,
|
|
2930
|
+
headers,
|
|
2931
|
+
...input.body !== void 0 && { body: JSON.stringify(input.body) },
|
|
2932
|
+
signal: ac.signal
|
|
2933
|
+
});
|
|
2934
|
+
} catch (cause) {
|
|
2935
|
+
clearTimeout(timer);
|
|
2936
|
+
const err = timedOut ? {
|
|
2937
|
+
code: "network",
|
|
2938
|
+
message: `No answer within ${seconds(timeoutMs)}, the client's timeout (timeoutMs).`,
|
|
2939
|
+
cause,
|
|
2940
|
+
timeoutMs
|
|
2941
|
+
} : {
|
|
2942
|
+
code: "network",
|
|
2943
|
+
message: cause instanceof Error ? cause.message : "network request failed",
|
|
2944
|
+
cause
|
|
2945
|
+
};
|
|
2946
|
+
throw new KindgiApiError(err);
|
|
2947
|
+
}
|
|
2948
|
+
clearTimeout(timer);
|
|
2949
|
+
if (response.ok) {
|
|
2950
|
+
if (input.discardResponse === true || response.status === 204) {
|
|
2951
|
+
try {
|
|
2952
|
+
await response.arrayBuffer();
|
|
2953
|
+
} catch {
|
|
2954
|
+
}
|
|
2955
|
+
return void 0;
|
|
2956
|
+
}
|
|
2957
|
+
try {
|
|
2958
|
+
return await response.json();
|
|
2959
|
+
} catch (cause) {
|
|
2960
|
+
const err = {
|
|
2961
|
+
code: "network",
|
|
2962
|
+
message: "Response body was not valid JSON",
|
|
2963
|
+
cause
|
|
2964
|
+
};
|
|
2965
|
+
throw new KindgiApiError(err);
|
|
2966
|
+
}
|
|
2967
|
+
}
|
|
2968
|
+
let body;
|
|
2969
|
+
try {
|
|
2970
|
+
body = await response.json();
|
|
2971
|
+
} catch {
|
|
2972
|
+
body = void 0;
|
|
2973
|
+
}
|
|
2974
|
+
throw new KindgiApiError(
|
|
2975
|
+
fromWire(unwrapErrorEnvelope(body, response.status), response.status)
|
|
2976
|
+
);
|
|
2977
|
+
}
|
|
2978
|
+
};
|
|
2979
|
+
}
|
|
2980
|
+
function checkedTimeoutMs(value, name) {
|
|
2981
|
+
if (!Number.isFinite(value) || value <= 0) {
|
|
2982
|
+
throw new TypeError(`${name} must be a positive number of milliseconds. Got ${String(value)}.`);
|
|
2983
|
+
}
|
|
2984
|
+
return value;
|
|
2985
|
+
}
|
|
2986
|
+
function seconds(ms) {
|
|
2987
|
+
return `${ms / 1e3} s`;
|
|
2988
|
+
}
|
|
2989
|
+
function buildUrl(apiUrl, path, query) {
|
|
2990
|
+
const normalizedPath = path.startsWith("/") ? path : `/${path}`;
|
|
2991
|
+
const base = `${apiUrl}${normalizedPath}`;
|
|
2992
|
+
if (query === void 0) return base;
|
|
2993
|
+
const params = [];
|
|
2994
|
+
for (const key of Object.keys(query)) {
|
|
2995
|
+
const value = query[key];
|
|
2996
|
+
if (value === void 0) continue;
|
|
2997
|
+
const values = typeof value === "object" ? value : [String(value)];
|
|
2998
|
+
for (const v of values) params.push(`${encodeURIComponent(key)}=${encodeURIComponent(v)}`);
|
|
2999
|
+
}
|
|
3000
|
+
return params.length === 0 ? base : `${base}?${params.join("&")}`;
|
|
3001
|
+
}
|
|
3002
|
+
function buildHeaders(input, auth) {
|
|
3003
|
+
const headers = {
|
|
3004
|
+
Accept: "application/json",
|
|
3005
|
+
Authorization: `Bearer ${authTokenFor(auth)}`
|
|
3006
|
+
};
|
|
3007
|
+
if (input.body !== void 0) {
|
|
3008
|
+
headers["Content-Type"] = "application/json; charset=utf-8";
|
|
3009
|
+
}
|
|
3010
|
+
if (input.idempotencyKey !== void 0 && MUTATING.has(input.method)) {
|
|
3011
|
+
headers["Idempotency-Key"] = input.idempotencyKey;
|
|
3012
|
+
}
|
|
3013
|
+
if (input.headers !== void 0) {
|
|
3014
|
+
for (const key of Object.keys(input.headers)) {
|
|
3015
|
+
headers[key] = input.headers[key];
|
|
3016
|
+
}
|
|
3017
|
+
}
|
|
3018
|
+
return headers;
|
|
3019
|
+
}
|
|
3020
|
+
function authTokenFor(auth) {
|
|
3021
|
+
if (auth.kind === "apiToken") return auth.token;
|
|
3022
|
+
return auth.accessToken;
|
|
3023
|
+
}
|
|
3024
|
+
function unwrapErrorEnvelope(body, status) {
|
|
3025
|
+
if (body !== null && typeof body === "object" && !Array.isArray(body)) {
|
|
3026
|
+
const inner = body.error;
|
|
3027
|
+
if (inner !== null && typeof inner === "object" && !Array.isArray(inner)) {
|
|
3028
|
+
return inner;
|
|
3029
|
+
}
|
|
3030
|
+
}
|
|
3031
|
+
return { code: "unknown", message: `HTTP ${status} without recognizable error envelope` };
|
|
3032
|
+
}
|
|
3033
|
+
|
|
2895
3034
|
// src/resources/runs.ts
|
|
3035
|
+
function waitedStartTimeout(e) {
|
|
3036
|
+
if (!(e instanceof KindgiApiError) || e.error.code !== "network") return e;
|
|
3037
|
+
const { timeoutMs } = e.error;
|
|
3038
|
+
if (timeoutMs === void 0) return e;
|
|
3039
|
+
return new KindgiApiError({
|
|
3040
|
+
code: "network",
|
|
3041
|
+
message: `The run didn't end within ${seconds(timeoutMs)}, the client's timeout (timeoutMs). A waited start answers only when the run ends, so the run may still be going, and its id didn't arrive. Start a run that can take longer with \`options: { wait: false }\`: the answer carries its id at once. Then follow it with \`runs.stream(runId)\` or \`runs.get(runId)\`. Or raise \`timeoutMs\`.`,
|
|
3042
|
+
cause: e.error.cause,
|
|
3043
|
+
timeoutMs
|
|
3044
|
+
});
|
|
3045
|
+
}
|
|
2896
3046
|
function makeRunsClient(transport) {
|
|
2897
3047
|
return {
|
|
2898
3048
|
async start(input) {
|
|
@@ -2911,14 +3061,19 @@ function makeRunsClient(transport) {
|
|
|
2911
3061
|
input: input.input,
|
|
2912
3062
|
...input.options !== void 0 && { options: input.options }
|
|
2913
3063
|
};
|
|
2914
|
-
|
|
2915
|
-
|
|
2916
|
-
|
|
2917
|
-
|
|
2918
|
-
|
|
2919
|
-
|
|
2920
|
-
|
|
2921
|
-
|
|
3064
|
+
try {
|
|
3065
|
+
return await transport.request({
|
|
3066
|
+
method: "POST",
|
|
3067
|
+
path: "/v1/runs",
|
|
3068
|
+
body,
|
|
3069
|
+
...input.idempotencyKey !== void 0 && {
|
|
3070
|
+
idempotencyKey: input.idempotencyKey
|
|
3071
|
+
},
|
|
3072
|
+
...input.timeoutMs !== void 0 && { timeoutMs: input.timeoutMs }
|
|
3073
|
+
});
|
|
3074
|
+
} catch (e) {
|
|
3075
|
+
throw input.options?.wait === false ? e : waitedStartTimeout(e);
|
|
3076
|
+
}
|
|
2922
3077
|
},
|
|
2923
3078
|
async dryRun(_input) {
|
|
2924
3079
|
throw new KindgiApiError(
|
|
@@ -4048,127 +4203,6 @@ function makeWebhooksClient(transport) {
|
|
|
4048
4203
|
};
|
|
4049
4204
|
}
|
|
4050
4205
|
|
|
4051
|
-
// src/transport.ts
|
|
4052
|
-
var DEFAULT_TIMEOUT_MS = 3e4;
|
|
4053
|
-
var MUTATING = /* @__PURE__ */ new Set([
|
|
4054
|
-
"POST",
|
|
4055
|
-
"PUT",
|
|
4056
|
-
"PATCH",
|
|
4057
|
-
"DELETE"
|
|
4058
|
-
]);
|
|
4059
|
-
function createTransport(options) {
|
|
4060
|
-
const apiUrl = options.apiUrl.replace(/\/+$/u, "");
|
|
4061
|
-
const fetchImpl = options.fetch ?? fetch;
|
|
4062
|
-
const clientTimeoutMs = DEFAULT_TIMEOUT_MS;
|
|
4063
|
-
return {
|
|
4064
|
-
apiUrl,
|
|
4065
|
-
fetchImpl,
|
|
4066
|
-
authHeaders() {
|
|
4067
|
-
return { Authorization: `Bearer ${authTokenFor(options.auth)}` };
|
|
4068
|
-
},
|
|
4069
|
-
async request(input) {
|
|
4070
|
-
const url = buildUrl(apiUrl, input.path, input.query);
|
|
4071
|
-
const headers = buildHeaders(input, options.auth);
|
|
4072
|
-
const timeoutMs = input.timeoutMs ?? clientTimeoutMs;
|
|
4073
|
-
const ac = new AbortController();
|
|
4074
|
-
const timer = setTimeout(
|
|
4075
|
-
() => ac.abort(new Error("timeout")),
|
|
4076
|
-
timeoutMs
|
|
4077
|
-
);
|
|
4078
|
-
let response;
|
|
4079
|
-
try {
|
|
4080
|
-
response = await fetchImpl(url, {
|
|
4081
|
-
method: input.method,
|
|
4082
|
-
headers,
|
|
4083
|
-
...input.body !== void 0 && { body: JSON.stringify(input.body) },
|
|
4084
|
-
signal: ac.signal
|
|
4085
|
-
});
|
|
4086
|
-
} catch (cause) {
|
|
4087
|
-
clearTimeout(timer);
|
|
4088
|
-
const err = {
|
|
4089
|
-
code: "network",
|
|
4090
|
-
message: cause instanceof Error ? cause.message : "network request failed",
|
|
4091
|
-
cause
|
|
4092
|
-
};
|
|
4093
|
-
throw new KindgiApiError(err);
|
|
4094
|
-
}
|
|
4095
|
-
clearTimeout(timer);
|
|
4096
|
-
if (response.ok) {
|
|
4097
|
-
if (input.discardResponse === true || response.status === 204) {
|
|
4098
|
-
try {
|
|
4099
|
-
await response.arrayBuffer();
|
|
4100
|
-
} catch {
|
|
4101
|
-
}
|
|
4102
|
-
return void 0;
|
|
4103
|
-
}
|
|
4104
|
-
try {
|
|
4105
|
-
return await response.json();
|
|
4106
|
-
} catch (cause) {
|
|
4107
|
-
const err = {
|
|
4108
|
-
code: "network",
|
|
4109
|
-
message: "Response body was not valid JSON",
|
|
4110
|
-
cause
|
|
4111
|
-
};
|
|
4112
|
-
throw new KindgiApiError(err);
|
|
4113
|
-
}
|
|
4114
|
-
}
|
|
4115
|
-
let body;
|
|
4116
|
-
try {
|
|
4117
|
-
body = await response.json();
|
|
4118
|
-
} catch {
|
|
4119
|
-
body = void 0;
|
|
4120
|
-
}
|
|
4121
|
-
throw new KindgiApiError(
|
|
4122
|
-
fromWire(unwrapErrorEnvelope(body, response.status), response.status)
|
|
4123
|
-
);
|
|
4124
|
-
}
|
|
4125
|
-
};
|
|
4126
|
-
}
|
|
4127
|
-
function buildUrl(apiUrl, path, query) {
|
|
4128
|
-
const normalizedPath = path.startsWith("/") ? path : `/${path}`;
|
|
4129
|
-
const base = `${apiUrl}${normalizedPath}`;
|
|
4130
|
-
if (query === void 0) return base;
|
|
4131
|
-
const params = [];
|
|
4132
|
-
for (const key of Object.keys(query)) {
|
|
4133
|
-
const value = query[key];
|
|
4134
|
-
if (value === void 0) continue;
|
|
4135
|
-
const values = typeof value === "object" ? value : [String(value)];
|
|
4136
|
-
for (const v of values) params.push(`${encodeURIComponent(key)}=${encodeURIComponent(v)}`);
|
|
4137
|
-
}
|
|
4138
|
-
return params.length === 0 ? base : `${base}?${params.join("&")}`;
|
|
4139
|
-
}
|
|
4140
|
-
function buildHeaders(input, auth) {
|
|
4141
|
-
const headers = {
|
|
4142
|
-
Accept: "application/json",
|
|
4143
|
-
Authorization: `Bearer ${authTokenFor(auth)}`
|
|
4144
|
-
};
|
|
4145
|
-
if (input.body !== void 0) {
|
|
4146
|
-
headers["Content-Type"] = "application/json; charset=utf-8";
|
|
4147
|
-
}
|
|
4148
|
-
if (input.idempotencyKey !== void 0 && MUTATING.has(input.method)) {
|
|
4149
|
-
headers["Idempotency-Key"] = input.idempotencyKey;
|
|
4150
|
-
}
|
|
4151
|
-
if (input.headers !== void 0) {
|
|
4152
|
-
for (const key of Object.keys(input.headers)) {
|
|
4153
|
-
headers[key] = input.headers[key];
|
|
4154
|
-
}
|
|
4155
|
-
}
|
|
4156
|
-
return headers;
|
|
4157
|
-
}
|
|
4158
|
-
function authTokenFor(auth) {
|
|
4159
|
-
if (auth.kind === "apiToken") return auth.token;
|
|
4160
|
-
return auth.accessToken;
|
|
4161
|
-
}
|
|
4162
|
-
function unwrapErrorEnvelope(body, status) {
|
|
4163
|
-
if (body !== null && typeof body === "object" && !Array.isArray(body)) {
|
|
4164
|
-
const inner = body.error;
|
|
4165
|
-
if (inner !== null && typeof inner === "object" && !Array.isArray(inner)) {
|
|
4166
|
-
return inner;
|
|
4167
|
-
}
|
|
4168
|
-
}
|
|
4169
|
-
return { code: "unknown", message: `HTTP ${status} without recognizable error envelope` };
|
|
4170
|
-
}
|
|
4171
|
-
|
|
4172
4206
|
// src/client.ts
|
|
4173
4207
|
function createClient(options) {
|
|
4174
4208
|
const transport = createTransport(options);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kindgi/client",
|
|
3
|
-
"version": "0.1.4
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"description": "TypeScript client SDK for Kindgi™ — the sovereign AI OS. Preview: wire-generated from openapi.json via typed-openapi, ergonomic hand-authored resource clients (Transport, KindgiApiError, SSE with Last-Event-Id resume).",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -45,12 +45,12 @@
|
|
|
45
45
|
"zod": "^4.6.5"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
|
-
"@kindgi/agents": "0.1.4
|
|
49
|
-
"@kindgi/api": "0.1.4
|
|
50
|
-
"@kindgi/flow": "0.1.4
|
|
51
|
-
"@kindgi/platform": "0.1.4
|
|
52
|
-
"@kindgi/runtime": "0.1.4
|
|
53
|
-
"@kindgi/types": "0.1.4
|
|
48
|
+
"@kindgi/agents": "0.1.4",
|
|
49
|
+
"@kindgi/api": "0.1.4",
|
|
50
|
+
"@kindgi/flow": "0.1.4",
|
|
51
|
+
"@kindgi/platform": "0.1.4",
|
|
52
|
+
"@kindgi/runtime": "0.1.4",
|
|
53
|
+
"@kindgi/types": "0.1.4",
|
|
54
54
|
"@types/node": "^22.10.5",
|
|
55
55
|
"dts-bundle-generator": "^9.5.1",
|
|
56
56
|
"tsup": "^8.5.1",
|