@loomcycle/client 1.124.0 → 1.126.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/README.md +158 -0
- package/dist/cjs/client-tools.js +28 -5
- package/dist/cjs/client.js +310 -10
- package/dist/cjs/device-login.js +146 -0
- package/dist/cjs/errors.js +40 -1
- package/dist/cjs/fetch-helpers.js +31 -0
- package/dist/cjs/index.js +35 -1
- package/dist/cjs/oauth.js +400 -0
- package/dist/client-tools.d.ts +6 -2
- package/dist/client-tools.js +28 -5
- package/dist/client.d.ts +226 -4
- package/dist/client.js +311 -11
- package/dist/device-login.d.ts +12 -0
- package/dist/device-login.js +143 -0
- package/dist/errors.d.ts +36 -0
- package/dist/errors.js +37 -0
- package/dist/fetch-helpers.d.ts +8 -0
- package/dist/fetch-helpers.js +30 -0
- package/dist/index.d.ts +31 -2
- package/dist/index.js +29 -1
- package/dist/oauth.d.ts +131 -0
- package/dist/oauth.js +393 -0
- package/dist/types.d.ts +593 -12
- package/package.json +1 -1
package/dist/types.d.ts
CHANGED
|
@@ -187,6 +187,81 @@ export interface RunPromptResponse {
|
|
|
187
187
|
system: PromptBlock[];
|
|
188
188
|
input: PromptBlock[];
|
|
189
189
|
}
|
|
190
|
+
/** Input for {@link LoomcycleClient.runFile} — one File-tool op on the inbox of
|
|
191
|
+
* a run, from outside the run (`POST /v1/runs/{run_id}/file`). The run is the
|
|
192
|
+
* path's; the fields are the tool's own, snake_case as on the wire. download
|
|
193
|
+
* and upload are not offered here: they need a run's HTTP allowlist. */
|
|
194
|
+
export type RunFileInput = {
|
|
195
|
+
op: "stat" | "ls" | "extract" | "import" | "keep" | "rm" | "clear";
|
|
196
|
+
/** stat / ls / rm / extract / import: `volume:inbox:<path>`, or a bare path in the inbox. */
|
|
197
|
+
path?: string;
|
|
198
|
+
/** keep: the inbox file to copy. */
|
|
199
|
+
from?: string;
|
|
200
|
+
/** keep: `volume:<name>:<path>` in a read-write dynamic volume of your tenant. */
|
|
201
|
+
to?: string;
|
|
202
|
+
overwrite?: boolean;
|
|
203
|
+
recursive?: boolean;
|
|
204
|
+
/** clear: one folder of the inbox to empty instead of all of it. */
|
|
205
|
+
prefix?: string;
|
|
206
|
+
images?: boolean;
|
|
207
|
+
max_rows?: number;
|
|
208
|
+
excerpt_chars?: number;
|
|
209
|
+
title?: string;
|
|
210
|
+
doc_path?: string;
|
|
211
|
+
scope?: string;
|
|
212
|
+
tags?: string[];
|
|
213
|
+
/** import: where the document came from, kept on it as a link back. */
|
|
214
|
+
source?: RunFileImportSource;
|
|
215
|
+
/** import: headings to add by line number, so a file whose structure is only
|
|
216
|
+
* in its numbering imports as sections. The file is not changed, so the
|
|
217
|
+
* document keeps the record of where it came from. */
|
|
218
|
+
headings?: RunFileImportHeading[];
|
|
219
|
+
};
|
|
220
|
+
/** import's `source`: the item's web link (a SharePoint `webUrl`, an email's
|
|
221
|
+
* `webLink`), never a download or upload link. */
|
|
222
|
+
export interface RunFileImportSource {
|
|
223
|
+
/** An http(s) link, at most 2048 bytes; a signature in its query is masked. */
|
|
224
|
+
url?: string;
|
|
225
|
+
kind?: "sharepoint" | "email" | "attachment" | "web" | "other";
|
|
226
|
+
/** One line, at most 300 characters. */
|
|
227
|
+
title?: string;
|
|
228
|
+
}
|
|
229
|
+
/** One entry of import's `headings`. Lines count from 1 in the file as it is;
|
|
230
|
+
* give entries in increasing line order. */
|
|
231
|
+
export type RunFileImportHeading =
|
|
232
|
+
/** The line itself becomes a heading; `lines` (1–10) joins a wrapped title. */
|
|
233
|
+
{
|
|
234
|
+
line: number;
|
|
235
|
+
level: 2 | 3 | 4 | 5 | 6;
|
|
236
|
+
as: "heading";
|
|
237
|
+
lines?: number;
|
|
238
|
+
}
|
|
239
|
+
/** A heading with `title` is inserted before the line, which stays body text. */
|
|
240
|
+
| {
|
|
241
|
+
line: number;
|
|
242
|
+
level: 2 | 3 | 4 | 5 | 6;
|
|
243
|
+
as: "marker";
|
|
244
|
+
title: string;
|
|
245
|
+
};
|
|
246
|
+
/** What {@link LoomcycleClient.downloadRunInboxFile} returns: one inbox file's
|
|
247
|
+
* bytes and what the server says about them. */
|
|
248
|
+
export interface RunInboxDownload {
|
|
249
|
+
/** The bytes (empty for a HEAD request). */
|
|
250
|
+
bytes: Uint8Array;
|
|
251
|
+
/** 200, or 206 for a range. */
|
|
252
|
+
status: number;
|
|
253
|
+
/** The type the server served: the recorded type when it is one a browser
|
|
254
|
+
* cannot run, else `application/octet-stream`. */
|
|
255
|
+
contentType: string;
|
|
256
|
+
/** The file's name, from Content-Disposition. */
|
|
257
|
+
filename: string;
|
|
258
|
+
/** SHA-256 (hex) of the file's bytes as served — the whole file, also for a range. */
|
|
259
|
+
sha256: string;
|
|
260
|
+
/** The producer the runtime recorded (`mcp:<server>/<tool>`, `http`, …), or
|
|
261
|
+
* `unknown` when the file changed since it was kept. */
|
|
262
|
+
origin: string;
|
|
263
|
+
headers: Headers;
|
|
264
|
+
}
|
|
190
265
|
/** The reply from `GET /v1/runs/{run_id}/effective-config` — for every
|
|
191
266
|
* overridable field, the value this run will actually use and which layer
|
|
192
267
|
* decided it.
|
|
@@ -1361,6 +1436,11 @@ export interface ClientOptions {
|
|
|
1361
1436
|
* When present, attached as `Authorization: Bearer <token>` on
|
|
1362
1437
|
* every request. */
|
|
1363
1438
|
authToken?: string;
|
|
1439
|
+
/** A source of short-lived bearers, instead of `authToken` (pass one or
|
|
1440
|
+
* the other): every request asks it for the token, and a 401 is retried
|
|
1441
|
+
* once with the token it hands back. An app signed in through loomcycle
|
|
1442
|
+
* passes an `OAuthTokenProvider`, which refreshes before expiry. */
|
|
1443
|
+
tokenProvider?: TokenProvider;
|
|
1364
1444
|
/** Custom fetch implementation; defaults to global `fetch`.
|
|
1365
1445
|
* Useful for testing (vi.fn()) or for runtimes that ship their
|
|
1366
1446
|
* own fetch (e.g. node-fetch on older Node). */
|
|
@@ -2045,19 +2125,34 @@ export interface UserSummary {
|
|
|
2045
2125
|
registered?: boolean;
|
|
2046
2126
|
display_name?: string;
|
|
2047
2127
|
access_mode?: string;
|
|
2048
|
-
status
|
|
2128
|
+
/** The registered user's status; `""` for a subject seen only in runs. */
|
|
2129
|
+
status?: UserStatus | (string & {});
|
|
2049
2130
|
}
|
|
2050
2131
|
export interface ListUsersResponse {
|
|
2051
2132
|
users: UserSummary[];
|
|
2052
2133
|
}
|
|
2053
|
-
/**
|
|
2054
|
-
*
|
|
2134
|
+
/** A first-class user's status.
|
|
2135
|
+
*
|
|
2136
|
+
* - `active` — the user may do what its access mode and bindings allow.
|
|
2137
|
+
* - `disabled` — refused everywhere; its delegated tokens are retired.
|
|
2138
|
+
* - `pending` — provisioned by a sign-in gate whose new users await
|
|
2139
|
+
* approval: the person can sign in, but every request is refused until
|
|
2140
|
+
* {@link LoomcycleClient.approveUser} makes the user `active`. Only a gate
|
|
2141
|
+
* puts a user here and only the approval takes one out, so createUser and
|
|
2142
|
+
* updateUser refuse it.
|
|
2143
|
+
*
|
|
2144
|
+
* Fields typed `UserStatus | (string & {})` still accept a status a newer
|
|
2145
|
+
* server adds. */
|
|
2146
|
+
export type UserStatus = "active" | "disabled" | "pending";
|
|
2147
|
+
/** One first-class users-table row (POST/PATCH /v1/_users). The tenant is the
|
|
2148
|
+
* authenticated principal's, or the one an admin or `auth:manage` caller
|
|
2149
|
+
* names with `opts.tenant`; it is never in the body. */
|
|
2055
2150
|
export interface UserRecord {
|
|
2056
2151
|
tenant_id: string;
|
|
2057
2152
|
subject: string;
|
|
2058
2153
|
display_name: string;
|
|
2059
2154
|
access_mode: string;
|
|
2060
|
-
status: string;
|
|
2155
|
+
status: UserStatus | (string & {});
|
|
2061
2156
|
created_at: string;
|
|
2062
2157
|
created_by: string;
|
|
2063
2158
|
}
|
|
@@ -2067,14 +2162,18 @@ export interface CreateUserBody {
|
|
|
2067
2162
|
/** "tenant" (default) collaborates on the tenant's shared primitives;
|
|
2068
2163
|
* "isolated" confines the member to its own user scope. */
|
|
2069
2164
|
access_mode?: string;
|
|
2070
|
-
|
|
2165
|
+
/** Default `active`. `pending` is refused (400 `invalid_status`). */
|
|
2166
|
+
status?: "active" | "disabled" | (string & {});
|
|
2071
2167
|
}
|
|
2072
2168
|
/** PATCH body — an omitted key leaves the column unchanged; a present key
|
|
2073
2169
|
* (even the empty string) is applied. */
|
|
2074
2170
|
export interface UpdateUserBody {
|
|
2075
2171
|
display_name?: string;
|
|
2076
2172
|
access_mode?: string;
|
|
2077
|
-
|
|
2173
|
+
/** `disabled` also retires the user's delegated tokens. `pending` is
|
|
2174
|
+
* refused (400 `invalid_status`), and `active` on a pending user with 409
|
|
2175
|
+
* `use_approve`: call {@link LoomcycleClient.approveUser} instead. */
|
|
2176
|
+
status?: "active" | "disabled" | (string & {});
|
|
2078
2177
|
}
|
|
2079
2178
|
/** The show-once result of POST /v1/_users/{subject}/tokens. `token` is the
|
|
2080
2179
|
* plaintext bearer, returned exactly once and never retrievable again. */
|
|
@@ -2127,6 +2226,171 @@ export interface ListUserTokensResponse {
|
|
|
2127
2226
|
subject: string;
|
|
2128
2227
|
tokens: UserTokenMeta[];
|
|
2129
2228
|
}
|
|
2229
|
+
/** One identity-provider account a user signs in with, from
|
|
2230
|
+
* GET /v1/_users/{subject}/identities. Never a secret. */
|
|
2231
|
+
export interface UserIdentity {
|
|
2232
|
+
/** The configured sign-in gate. */
|
|
2233
|
+
gate: string;
|
|
2234
|
+
/** The provider's issuer, when it reports one. */
|
|
2235
|
+
issuer?: string;
|
|
2236
|
+
/** The account's subject at the provider. */
|
|
2237
|
+
external_subject: string;
|
|
2238
|
+
email?: string;
|
|
2239
|
+
email_verified: boolean;
|
|
2240
|
+
created_at: string;
|
|
2241
|
+
/** Absent until the account has been used to sign in. */
|
|
2242
|
+
last_login_at?: string;
|
|
2243
|
+
}
|
|
2244
|
+
export interface UserIdentitiesResponse {
|
|
2245
|
+
subject: string;
|
|
2246
|
+
identities: UserIdentity[];
|
|
2247
|
+
}
|
|
2248
|
+
/** A sign-in gate's kind. Fields typed with it still accept a kind a newer
|
|
2249
|
+
* server adds. */
|
|
2250
|
+
export type AuthGateKind = "token" | "password" | "oidc" | "oauth" | "external" | "device" | (string & {});
|
|
2251
|
+
/** One configured sign-in gate, from GET /v1/_authgate. Never key material. */
|
|
2252
|
+
export interface AuthGate {
|
|
2253
|
+
name: string;
|
|
2254
|
+
kind: AuthGateKind;
|
|
2255
|
+
label: string;
|
|
2256
|
+
/** Whether a browser can sign in through it. */
|
|
2257
|
+
interactive: boolean;
|
|
2258
|
+
/** The gate's identity map, when it has one: whether it may provision
|
|
2259
|
+
* beyond the new-user floor, the tenant it maps to (or the claim naming
|
|
2260
|
+
* it) and how it provisions users. */
|
|
2261
|
+
trusted?: boolean;
|
|
2262
|
+
tenant?: string;
|
|
2263
|
+
tenant_claim?: string;
|
|
2264
|
+
provision?: string;
|
|
2265
|
+
/** An external gate's signing key. */
|
|
2266
|
+
key?: AuthGateKey;
|
|
2267
|
+
callback_url?: string;
|
|
2268
|
+
discovery_url?: string;
|
|
2269
|
+
/** With `probe: true`: what the external gate's discovery document said. */
|
|
2270
|
+
probe?: AuthGateProbe;
|
|
2271
|
+
/** An external gate's removal timing. */
|
|
2272
|
+
on_removed?: AuthGateRemoval;
|
|
2273
|
+
}
|
|
2274
|
+
/** An external gate's key as configured: algorithm, key id and fingerprint,
|
|
2275
|
+
* or for an HMAC secret the NAME of the env var holding it — never a key. */
|
|
2276
|
+
export interface AuthGateKey {
|
|
2277
|
+
alg: string;
|
|
2278
|
+
kid?: string;
|
|
2279
|
+
fingerprint?: string;
|
|
2280
|
+
secret_env?: string;
|
|
2281
|
+
}
|
|
2282
|
+
/** Durations, e.g. `168h0m0s`; `erase_after` may be `never`. */
|
|
2283
|
+
export interface AuthGateRemoval {
|
|
2284
|
+
unbind_after: string;
|
|
2285
|
+
erase_after: string;
|
|
2286
|
+
}
|
|
2287
|
+
export interface AuthGateProbe {
|
|
2288
|
+
reachable: boolean;
|
|
2289
|
+
/** The discovery document's HTTP status. */
|
|
2290
|
+
status?: number;
|
|
2291
|
+
/** A failure class (`unreachable`, `status`, …), never the response. */
|
|
2292
|
+
error?: string;
|
|
2293
|
+
name_matches: boolean;
|
|
2294
|
+
key_matches: boolean;
|
|
2295
|
+
capabilities?: string[];
|
|
2296
|
+
}
|
|
2297
|
+
export interface AuthGateListResponse {
|
|
2298
|
+
gates: AuthGate[];
|
|
2299
|
+
}
|
|
2300
|
+
/** POST /v1/_authgate/{gate}/invites. The tenant is `opts.tenant`, not a
|
|
2301
|
+
* field here. */
|
|
2302
|
+
export interface CreateInviteBody {
|
|
2303
|
+
/** An existing user to give a login at this gate. It keeps its access mode
|
|
2304
|
+
* and groups: the invite may restate but never raise them. Omitted, the
|
|
2305
|
+
* invite makes a new user when it is redeemed. */
|
|
2306
|
+
subject?: string;
|
|
2307
|
+
/** A new user's access mode, `tenant` or `isolated`; default the gate's
|
|
2308
|
+
* new-user floor. Beyond the floor only on a trusted gate (403
|
|
2309
|
+
* `beyond_floor` otherwise). */
|
|
2310
|
+
access_mode?: string;
|
|
2311
|
+
/** Groups for the new user; each must exist in the tenant. */
|
|
2312
|
+
groups?: string[];
|
|
2313
|
+
/** Fix the login the invitee gets; otherwise the invitee picks one (409
|
|
2314
|
+
* `login_taken` if it is in use at the gate). */
|
|
2315
|
+
login?: string;
|
|
2316
|
+
email?: string;
|
|
2317
|
+
/** How long the link lives, as a Go duration (`72h`); default and maximum
|
|
2318
|
+
* are the gate's. */
|
|
2319
|
+
ttl?: string;
|
|
2320
|
+
/** Where the person lands after redeeming: a path on the server, or one
|
|
2321
|
+
* of the gate's `allowed_return_to`. */
|
|
2322
|
+
return_to?: string;
|
|
2323
|
+
}
|
|
2324
|
+
/** A one-time invite link. `url` carries the code in its fragment: hand it to
|
|
2325
|
+
* the person and do not log it. It is shown once — listing invites never
|
|
2326
|
+
* returns it. */
|
|
2327
|
+
export interface CreatedInvite {
|
|
2328
|
+
invite_id: string;
|
|
2329
|
+
url: string;
|
|
2330
|
+
expires_at: string;
|
|
2331
|
+
}
|
|
2332
|
+
export type AuthInviteState = "live" | "redeemed" | "revoked" | "expired";
|
|
2333
|
+
/** One invite from GET /v1/_authgate/{gate}/invites. Never its code. */
|
|
2334
|
+
export interface AuthInvite {
|
|
2335
|
+
invite_id: string;
|
|
2336
|
+
gate: string;
|
|
2337
|
+
tenant_id: string;
|
|
2338
|
+
/** Set for an invite to an existing user. */
|
|
2339
|
+
subject?: string;
|
|
2340
|
+
access_mode?: string;
|
|
2341
|
+
groups: string[];
|
|
2342
|
+
login?: string;
|
|
2343
|
+
email?: string;
|
|
2344
|
+
return_to?: string;
|
|
2345
|
+
/** The owner invite of a tenant that has never had a user. */
|
|
2346
|
+
bootstrap?: boolean;
|
|
2347
|
+
created_by?: string;
|
|
2348
|
+
created_at: string;
|
|
2349
|
+
expires_at: string;
|
|
2350
|
+
state: AuthInviteState;
|
|
2351
|
+
redeemed_at?: string;
|
|
2352
|
+
redeemed_subject?: string;
|
|
2353
|
+
revoked_at?: string;
|
|
2354
|
+
}
|
|
2355
|
+
export interface AuthInviteListResponse {
|
|
2356
|
+
invites: AuthInvite[];
|
|
2357
|
+
}
|
|
2358
|
+
/** A one-time password-reset link; like {@link CreatedInvite}, `url`
|
|
2359
|
+
* carries the code and is shown once. */
|
|
2360
|
+
export interface CreatedPasswordReset {
|
|
2361
|
+
reset_id: string;
|
|
2362
|
+
url: string;
|
|
2363
|
+
expires_at: string;
|
|
2364
|
+
}
|
|
2365
|
+
/** A user's login at one gate, from GET /v1/_authgate/{gate}/identities. */
|
|
2366
|
+
export interface GateIdentity {
|
|
2367
|
+
gate: string;
|
|
2368
|
+
login: string;
|
|
2369
|
+
email?: string;
|
|
2370
|
+
email_verified: boolean;
|
|
2371
|
+
created_at: string;
|
|
2372
|
+
last_login_at?: string;
|
|
2373
|
+
/** Whether the user has a password set. */
|
|
2374
|
+
has_password: boolean;
|
|
2375
|
+
/** Whether the user has a confirmed authenticator. */
|
|
2376
|
+
has_totp: boolean;
|
|
2377
|
+
}
|
|
2378
|
+
export interface GateIdentitiesResponse {
|
|
2379
|
+
tenant_id: string;
|
|
2380
|
+
subject: string;
|
|
2381
|
+
identities: GateIdentity[];
|
|
2382
|
+
}
|
|
2383
|
+
/** GET /v1/_authgate/{gate}/tenant-status: what a website needs to decide
|
|
2384
|
+
* on an owner (bootstrap) invite, and nothing about who the users are. */
|
|
2385
|
+
export interface GateTenantStatus {
|
|
2386
|
+
tenant_id: string;
|
|
2387
|
+
/** Whether the tenant has a user now. */
|
|
2388
|
+
has_users: boolean;
|
|
2389
|
+
/** Whether it has ever had one; once true, no owner invite or owner create
|
|
2390
|
+
* by an `auth:manage` credential is possible again. */
|
|
2391
|
+
bootstrapped: boolean;
|
|
2392
|
+
bootstrap_invite_live: boolean;
|
|
2393
|
+
}
|
|
2130
2394
|
/** One entry in the runnable-agent catalog — the name to run + its tier.
|
|
2131
2395
|
* Intentionally lean: no operator metadata (versions, retired, hashes). */
|
|
2132
2396
|
export interface RunnableAgent {
|
|
@@ -2161,6 +2425,8 @@ export interface WhoamiResponse {
|
|
|
2161
2425
|
/** How the caller signed in. Absent on a server that predates Web UI
|
|
2162
2426
|
* sessions. */
|
|
2163
2427
|
auth?: WhoamiAuth;
|
|
2428
|
+
/** What narrows the caller's token below its scopes, when anything does. */
|
|
2429
|
+
restrictions?: TokenRestrictions;
|
|
2164
2430
|
}
|
|
2165
2431
|
/** GET /v1/_me's sign-in block. `mode` is always present; the rest only when
|
|
2166
2432
|
* a Web UI session (not a bearer) authenticated the request. */
|
|
@@ -2175,6 +2441,10 @@ export interface WhoamiAuth {
|
|
|
2175
2441
|
auth_time?: string;
|
|
2176
2442
|
/** When the session stops authenticating unless renewed by activity. */
|
|
2177
2443
|
session_expires_at?: string;
|
|
2444
|
+
/** `pending` when the session's user awaits approval: every other request
|
|
2445
|
+
* the session makes is refused until the user is approved. Absent
|
|
2446
|
+
* otherwise. */
|
|
2447
|
+
status?: "pending";
|
|
2178
2448
|
}
|
|
2179
2449
|
/** GET /v1/_me's capability summary. Bounded and non-secret: a fixed list of
|
|
2180
2450
|
* Web UI pages, no per-instance data. */
|
|
@@ -2391,11 +2661,12 @@ export interface MemorySearchInput {
|
|
|
2391
2661
|
*
|
|
2392
2662
|
* The four document filters need a search that can return documents (no
|
|
2393
2663
|
* `sources`, or `sources` including `"documents"`; otherwise 400
|
|
2394
|
-
* `invalid_filter`)
|
|
2395
|
-
*
|
|
2396
|
-
*
|
|
2397
|
-
* MemorySearchResponse.filter}. For chunk-level
|
|
2398
|
-
*
|
|
2664
|
+
* `invalid_filter`) and SQL Memory on the server (400 `filter_unavailable`).
|
|
2665
|
+
* They resolve in the caller's own tenant. With a {@link documentsScope}
|
|
2666
|
+
* different from `scope` they aim at that scope's documents instead. The
|
|
2667
|
+
* response then carries {@link MemorySearchResponse.filter}. For chunk-level
|
|
2668
|
+
* filters (type, status, tags, a validity instant) use
|
|
2669
|
+
* `document({ op: "search" })`. */
|
|
2399
2670
|
underPaths?: string[];
|
|
2400
2671
|
/** Never return the chunks of documents named at or under these paths (sent as
|
|
2401
2672
|
* `exclude_under_paths`). Documents only, as {@link underPaths}. */
|
|
@@ -2406,6 +2677,23 @@ export interface MemorySearchInput {
|
|
|
2406
2677
|
/** Never return the chunks of these documents (sent as
|
|
2407
2678
|
* `exclude_document_ids`). Documents only, as {@link underPaths}. */
|
|
2408
2679
|
excludeDocumentIds?: string[];
|
|
2680
|
+
/** Also search the DOCUMENTS of this scope in the same call (sent as
|
|
2681
|
+
* `documents_scope`): for example a user's own notes together with the
|
|
2682
|
+
* tenant's reference documents. Both are ranked into one list under one
|
|
2683
|
+
* `topK`, and each entry then carries {@link MemorySearchEntry.scope}. Only
|
|
2684
|
+
* documents come from this scope; facts and notes still come from `scope`.
|
|
2685
|
+
* The four document filters aim at this scope's documents.
|
|
2686
|
+
*
|
|
2687
|
+
* Equal to `scope` (and {@link documentsScopeId} omitted or equal to
|
|
2688
|
+
* `scopeId`), it is the same as adding `"documents"` to `sources`. It cannot
|
|
2689
|
+
* be combined with `sources: ["traces"]` (400 `invalid_documents_scope`). A
|
|
2690
|
+
* caller whose access does not reach that scope's documents gets 403. */
|
|
2691
|
+
documentsScope?: "agent" | "user" | "tenant";
|
|
2692
|
+
/** The subject of {@link documentsScope} (sent as `documents_scope_id`): the
|
|
2693
|
+
* agent name or user id. Required when `documentsScope` is `"agent"` or
|
|
2694
|
+
* `"user"` and differs from `scope`; ignored for `"tenant"`. The tenant is
|
|
2695
|
+
* always the caller's own. */
|
|
2696
|
+
documentsScopeId?: string;
|
|
2409
2697
|
}
|
|
2410
2698
|
/** What a document filter on {@link LoomcycleClient.memorySearch} resolved to —
|
|
2411
2699
|
* present on the response ONLY when a filter was sent. */
|
|
@@ -2427,6 +2715,9 @@ export interface MemorySearchDocumentFilter {
|
|
|
2427
2715
|
* false while access-control rules can deny the caller reading part of the
|
|
2428
2716
|
* scope — the counts then cover only documents it may read. */
|
|
2429
2717
|
inverted: boolean;
|
|
2718
|
+
/** The scope the filter resolved in — present when it aimed at a
|
|
2719
|
+
* {@link MemorySearchInput.documentsScope} different from `scope`. */
|
|
2720
|
+
scope?: "agent" | "user" | "tenant";
|
|
2430
2721
|
}
|
|
2431
2722
|
/** The observed-time predicate on {@link MemorySearchInput}. Timestamps are
|
|
2432
2723
|
* RFC3339 instants — resolve phrases like "the first weekend of October"
|
|
@@ -2501,6 +2792,10 @@ export interface MemorySearchEntry {
|
|
|
2501
2792
|
kind: "description" | "claim" | "question";
|
|
2502
2793
|
text: string;
|
|
2503
2794
|
};
|
|
2795
|
+
/** The scope this hit came from — present on every entry when the request
|
|
2796
|
+
* set a {@link MemorySearchInput.documentsScope} different from `scope`, so
|
|
2797
|
+
* the caller's own memory can be told from the other scope's documents. */
|
|
2798
|
+
scope?: "agent" | "user" | "tenant";
|
|
2504
2799
|
}
|
|
2505
2800
|
export interface MemorySearchResponse {
|
|
2506
2801
|
scope: string;
|
|
@@ -2518,6 +2813,11 @@ export interface MemorySearchResponse {
|
|
|
2518
2813
|
/** What the document filter resolved to — present only when one was sent
|
|
2519
2814
|
* ({@link MemorySearchInput.underPaths} and its siblings). */
|
|
2520
2815
|
filter?: MemorySearchDocumentFilter;
|
|
2816
|
+
/** The second scope searched for documents and its store scope id ("" for
|
|
2817
|
+
* tenant) — present only when the request set a
|
|
2818
|
+
* {@link MemorySearchInput.documentsScope} different from `scope`. */
|
|
2819
|
+
documents_scope?: "agent" | "user" | "tenant";
|
|
2820
|
+
documents_scope_id?: string;
|
|
2521
2821
|
}
|
|
2522
2822
|
export interface MemoryTimeFilter {
|
|
2523
2823
|
mode: "prefer" | "require";
|
|
@@ -4342,6 +4642,16 @@ export interface AgentTranscription {
|
|
|
4342
4642
|
/** At most the operator's `transcription.stt.max_minutes_per_run`. */
|
|
4343
4643
|
max_minutes_per_run?: number;
|
|
4344
4644
|
}
|
|
4645
|
+
/** An agent's text-to-speech settings. It can switch speech off for the agent
|
|
4646
|
+
* and lower the operator's per-run character cap; it can never raise it or
|
|
4647
|
+
* pick an engine, a model or a voice list. */
|
|
4648
|
+
export interface AgentSpeech {
|
|
4649
|
+
/** Whether the agent may speak. Default `true` when the operator configured
|
|
4650
|
+
* an engine; `false` switches it off for this agent. */
|
|
4651
|
+
enabled?: boolean;
|
|
4652
|
+
/** At most the operator's `speech.max_chars_per_run`. */
|
|
4653
|
+
max_chars_per_run?: number;
|
|
4654
|
+
}
|
|
4345
4655
|
/** The `context` block of an {@link AgentDefOverlay}: {@link ContextOptions}
|
|
4346
4656
|
* in its wire spelling — see there for what each field does. A fork merges it
|
|
4347
4657
|
* per field, and the spawn tree inherits it. */
|
|
@@ -4538,6 +4848,8 @@ export interface AgentDefOverlay {
|
|
|
4538
4848
|
compaction?: AgentCompaction;
|
|
4539
4849
|
/** OCR and speech-to-text settings, merged per field. */
|
|
4540
4850
|
transcription?: AgentTranscription;
|
|
4851
|
+
/** Text-to-speech settings, merged per field. */
|
|
4852
|
+
speech?: AgentSpeech;
|
|
4541
4853
|
/** How history is distilled, merged per field. */
|
|
4542
4854
|
context?: AgentContext;
|
|
4543
4855
|
/** Volumes the file and exec tools may resolve paths against. None declared
|
|
@@ -5409,7 +5721,17 @@ export interface LLMEmbeddingsResponse {
|
|
|
5409
5721
|
usage: LLMEmbeddingsUsage;
|
|
5410
5722
|
}
|
|
5411
5723
|
/** A whitelisted grouping dimension for the usage report. */
|
|
5412
|
-
export type UsageDimension = "tenant" | "user" | "provider" | "model" | "source"
|
|
5724
|
+
export type UsageDimension = "tenant" | "user" | "provider" | "model" | "source"
|
|
5725
|
+
/** What the calls were for (see `UsageAggregate.purpose`). */
|
|
5726
|
+
| "purpose"
|
|
5727
|
+
/** The model tier the calls were resolved through; "pinned" for a named model. */
|
|
5728
|
+
| "tier" | "user_tier"
|
|
5729
|
+
/** The agent that made the calls — the per-call detail window only. */
|
|
5730
|
+
| "agent"
|
|
5731
|
+
/** foreground | background, derived from the purpose. */
|
|
5732
|
+
| "class";
|
|
5733
|
+
/** The period a usage report splits its window into (UTC; weeks start Monday). */
|
|
5734
|
+
export type UsageBucket = "hour" | "day" | "week" | "month";
|
|
5413
5735
|
/** One grouped row of a usage report; only the grouped dimensions are set. */
|
|
5414
5736
|
export interface UsageAggregate {
|
|
5415
5737
|
tenant_id?: string;
|
|
@@ -5418,6 +5740,21 @@ export interface UsageAggregate {
|
|
|
5418
5740
|
model?: string;
|
|
5419
5741
|
/** operator | tenant | user */
|
|
5420
5742
|
credential_source?: string;
|
|
5743
|
+
/** chat | gateway | consolidation | rerank | decision | compaction | recap |
|
|
5744
|
+
* unit_generation | image_description | embedding | ocr | stt | tts — set
|
|
5745
|
+
* when grouped by `purpose`. */
|
|
5746
|
+
purpose?: string;
|
|
5747
|
+
tier?: string;
|
|
5748
|
+
user_tier?: string;
|
|
5749
|
+
agent?: string;
|
|
5750
|
+
/** foreground | background — set when grouped by `class`. */
|
|
5751
|
+
class?: string;
|
|
5752
|
+
/** RFC 3339 start of the UTC period the row sums, when a bucket was asked for. */
|
|
5753
|
+
period?: string;
|
|
5754
|
+
/** The row folds every value of the first dimension outside `top`. */
|
|
5755
|
+
other?: boolean;
|
|
5756
|
+
/** Characters text-to-speech and embedding calls sent; absent when none. */
|
|
5757
|
+
input_chars?: number;
|
|
5421
5758
|
input_tokens: number;
|
|
5422
5759
|
output_tokens: number;
|
|
5423
5760
|
cache_creation_tokens: number;
|
|
@@ -5426,12 +5763,20 @@ export interface UsageAggregate {
|
|
|
5426
5763
|
currency?: string;
|
|
5427
5764
|
call_count: number;
|
|
5428
5765
|
unpriced_calls: number;
|
|
5766
|
+
/** Seconds of audio the group's speech calls transcribed (stt) or produced
|
|
5767
|
+
* (tts), the unit a per-minute price is computed from; absent when it has none. */
|
|
5768
|
+
audio_seconds?: number;
|
|
5429
5769
|
}
|
|
5430
5770
|
export interface UsageReportResponse {
|
|
5431
5771
|
group_by: string[];
|
|
5432
5772
|
from?: string;
|
|
5433
5773
|
to?: string;
|
|
5774
|
+
bucket?: UsageBucket;
|
|
5434
5775
|
rows: UsageAggregate[];
|
|
5776
|
+
/** The oldest instant the per-call ledger holds; before it only whole days
|
|
5777
|
+
* survive, so hour buckets and the agent dimension stop there. Absent when
|
|
5778
|
+
* nothing is archived. */
|
|
5779
|
+
detail_since?: string;
|
|
5435
5780
|
}
|
|
5436
5781
|
/** A per-scope token budget (RFC AW) plus its live month-to-date usage.
|
|
5437
5782
|
* `soft_limit` / `hard_limit` are absent when that tier is unset (no ceiling
|
|
@@ -6754,3 +7099,239 @@ export interface AuthzSimulateResponse {
|
|
|
6754
7099
|
/** Lists the draft's bindings name that no layer has. */
|
|
6755
7100
|
missing_acls: string[] | null;
|
|
6756
7101
|
}
|
|
7102
|
+
/** The authorization server's metadata (RFC 8414), from
|
|
7103
|
+
* `GET /.well-known/oauth-authorization-server`. Published only when the
|
|
7104
|
+
* server knows its public address (`LOOMCYCLE_PUBLIC_URL`). */
|
|
7105
|
+
export interface OAuthServerMetadata {
|
|
7106
|
+
issuer: string;
|
|
7107
|
+
authorization_endpoint: string;
|
|
7108
|
+
token_endpoint: string;
|
|
7109
|
+
revocation_endpoint: string;
|
|
7110
|
+
response_types_supported: string[];
|
|
7111
|
+
grant_types_supported: string[];
|
|
7112
|
+
code_challenge_methods_supported: string[];
|
|
7113
|
+
token_endpoint_auth_methods_supported: string[];
|
|
7114
|
+
revocation_endpoint_auth_methods_supported: string[];
|
|
7115
|
+
/** The server adds `iss` to every authorization response (RFC 9207). */
|
|
7116
|
+
authorization_response_iss_parameter_supported: boolean;
|
|
7117
|
+
}
|
|
7118
|
+
/** The token endpoint's answer (RFC 6749 §5.1). */
|
|
7119
|
+
export interface OAuthTokenResponse {
|
|
7120
|
+
access_token: string;
|
|
7121
|
+
/** Always `Bearer`. */
|
|
7122
|
+
token_type: string;
|
|
7123
|
+
/** Seconds the access token lives. */
|
|
7124
|
+
expires_in: number;
|
|
7125
|
+
/** Single use: each refresh returns a new one and spends the old one.
|
|
7126
|
+
* Presenting a spent one ends the whole sign-in. */
|
|
7127
|
+
refresh_token: string;
|
|
7128
|
+
}
|
|
7129
|
+
/** A token answer with the moment the access token expires — what a caller
|
|
7130
|
+
* persists. */
|
|
7131
|
+
export interface OAuthTokenSet extends OAuthTokenResponse {
|
|
7132
|
+
/** When the access token expires, in milliseconds since the epoch
|
|
7133
|
+
* (`Date.now()` at receipt plus `expires_in`). */
|
|
7134
|
+
expires_at: number;
|
|
7135
|
+
}
|
|
7136
|
+
/** Input to `LoomcycleOAuth.beginAuthorize`. */
|
|
7137
|
+
export interface BeginAuthorizeOptions {
|
|
7138
|
+
/** The app's registered client id. */
|
|
7139
|
+
clientId: string;
|
|
7140
|
+
/** One of the app's registered redirect URIs, exactly (a loopback one may
|
|
7141
|
+
* carry any port). */
|
|
7142
|
+
redirectUri: string;
|
|
7143
|
+
/** An opaque value to round-trip; a random one is generated when omitted.
|
|
7144
|
+
* 1 to 1024 characters. */
|
|
7145
|
+
state?: string;
|
|
7146
|
+
}
|
|
7147
|
+
/** What `LoomcycleOAuth.beginAuthorize` returns. Persist `verifier` and
|
|
7148
|
+
* `state` (session storage, never a URL) until the redirect comes back, then
|
|
7149
|
+
* send the person to `url`. */
|
|
7150
|
+
export interface AuthorizeRequest {
|
|
7151
|
+
url: string;
|
|
7152
|
+
/** The PKCE code verifier. A secret until the exchange: keep it out of
|
|
7153
|
+
* URLs and logs. */
|
|
7154
|
+
verifier: string;
|
|
7155
|
+
state: string;
|
|
7156
|
+
}
|
|
7157
|
+
/** The parameters the server puts on the redirect back to the app: `code`
|
|
7158
|
+
* on success, `error` (+ `error_description`) otherwise, `state` as sent,
|
|
7159
|
+
* and `iss` when the server knows its issuer (RFC 9207). */
|
|
7160
|
+
export interface AuthorizeResponseParams {
|
|
7161
|
+
code?: string;
|
|
7162
|
+
state?: string;
|
|
7163
|
+
iss?: string;
|
|
7164
|
+
error?: string;
|
|
7165
|
+
error_description?: string;
|
|
7166
|
+
}
|
|
7167
|
+
/** Input to `LoomcycleOAuth.completeAuthorize`: the redirect's parameters
|
|
7168
|
+
* plus what `beginAuthorize` returned. */
|
|
7169
|
+
export interface CompleteAuthorizeOptions extends AuthorizeResponseParams {
|
|
7170
|
+
/** The `state` beginAuthorize returned; a redirect carrying any other is
|
|
7171
|
+
* refused before the code is used. */
|
|
7172
|
+
expectedState: string;
|
|
7173
|
+
verifier: string;
|
|
7174
|
+
clientId: string;
|
|
7175
|
+
/** The same redirect URI the authorization request named. */
|
|
7176
|
+
redirectUri: string;
|
|
7177
|
+
signal?: AbortSignal;
|
|
7178
|
+
}
|
|
7179
|
+
/** Input to `LoomcycleOAuth.refresh`. */
|
|
7180
|
+
export interface RefreshTokenOptions {
|
|
7181
|
+
refreshToken: string;
|
|
7182
|
+
clientId: string;
|
|
7183
|
+
signal?: AbortSignal;
|
|
7184
|
+
}
|
|
7185
|
+
/** Input to `LoomcycleOAuth.revoke`. */
|
|
7186
|
+
export interface RevokeTokenOptions {
|
|
7187
|
+
/** A refresh token (ends the whole sign-in) or an access token (ends that
|
|
7188
|
+
* token only). */
|
|
7189
|
+
token: string;
|
|
7190
|
+
clientId: string;
|
|
7191
|
+
signal?: AbortSignal;
|
|
7192
|
+
}
|
|
7193
|
+
/** Supplies the bearer for every request of a `LoomcycleClient` built with
|
|
7194
|
+
* `tokenProvider` instead of `authToken`. `OAuthTokenProvider` implements it
|
|
7195
|
+
* for an app sign-in; any other source of short-lived tokens can too. */
|
|
7196
|
+
export interface TokenProvider {
|
|
7197
|
+
/** The token for the next request, refreshed ahead of expiry; undefined
|
|
7198
|
+
* sends none. A throw fails the request with that error. */
|
|
7199
|
+
getToken(): Promise<string | undefined>;
|
|
7200
|
+
/** Called at most once per request, after the server answered 401 to
|
|
7201
|
+
* `rejected`: a different token to retry with once, or undefined to let
|
|
7202
|
+
* the 401 stand. */
|
|
7203
|
+
onUnauthorized?(rejected: string | undefined): Promise<string | undefined>;
|
|
7204
|
+
}
|
|
7205
|
+
/** A client's refresh-token lifetimes: Go durations or whole days (`"7d"`). */
|
|
7206
|
+
export interface AppClientRefresh {
|
|
7207
|
+
idle?: string;
|
|
7208
|
+
absolute?: string;
|
|
7209
|
+
}
|
|
7210
|
+
/** An app client's definition: an entry of the config's `auth.clients`, and
|
|
7211
|
+
* the body of a ClientDef. */
|
|
7212
|
+
export interface AppClientConfig {
|
|
7213
|
+
/** `public`, the only kind: the app holds no secret and PKCE binds a code
|
|
7214
|
+
* to it. */
|
|
7215
|
+
kind: string;
|
|
7216
|
+
/** The name the login page shows. */
|
|
7217
|
+
label?: string;
|
|
7218
|
+
/** Exact https URIs, loopback URIs (any port, exact path) and private-use
|
|
7219
|
+
* scheme URIs (`myapp://callback`). */
|
|
7220
|
+
redirect_uris: string[];
|
|
7221
|
+
/** Origins allowed to call the token and revoke endpoints from a browser:
|
|
7222
|
+
* https, loopback, `chrome-extension://`, `moz-extension://`, `tauri://`. */
|
|
7223
|
+
allowed_origins?: string[];
|
|
7224
|
+
/** Go duration, 1m to 24h; default 1h. */
|
|
7225
|
+
access_token_ttl?: string;
|
|
7226
|
+
refresh?: AppClientRefresh;
|
|
7227
|
+
/** Narrows every token the client's sign-ins mint, as a token's
|
|
7228
|
+
* restrictions record does. */
|
|
7229
|
+
restrictions?: Record<string, unknown>;
|
|
7230
|
+
}
|
|
7231
|
+
/** The body of `POST /v1/_clientdef`. */
|
|
7232
|
+
export interface ClientDefInput {
|
|
7233
|
+
op: "create" | "update" | "get" | "list" | "retire" | "verify";
|
|
7234
|
+
/** The client id. Unique across the deployment, retired names included. */
|
|
7235
|
+
name?: string;
|
|
7236
|
+
def_id?: string;
|
|
7237
|
+
client?: AppClientConfig;
|
|
7238
|
+
description?: string;
|
|
7239
|
+
/** Admin only. On create: the tenant whose people the client signs in, ""
|
|
7240
|
+
* (the default) for every tenant. On list: focus one tenant. A tenant
|
|
7241
|
+
* operator's clients are always its own tenant's. */
|
|
7242
|
+
tenant?: string;
|
|
7243
|
+
/** verify: the content hash to compare with the deployed one. */
|
|
7244
|
+
content_sha256?: string;
|
|
7245
|
+
}
|
|
7246
|
+
/** A runtime-registered client (a ClientDef version). */
|
|
7247
|
+
export interface ClientDefRecord {
|
|
7248
|
+
name: string;
|
|
7249
|
+
source: "def";
|
|
7250
|
+
def_id: string;
|
|
7251
|
+
version: number;
|
|
7252
|
+
/** The tenant whose people it signs in; "" for every tenant. */
|
|
7253
|
+
tenant_id: string;
|
|
7254
|
+
all_tenants: boolean;
|
|
7255
|
+
label: string;
|
|
7256
|
+
redirect_uris: string[];
|
|
7257
|
+
/** The definition as stored. */
|
|
7258
|
+
client: AppClientConfig;
|
|
7259
|
+
description: string;
|
|
7260
|
+
content_sha256: string;
|
|
7261
|
+
created_at: string;
|
|
7262
|
+
created_by: string;
|
|
7263
|
+
created_by_tenant: string;
|
|
7264
|
+
read_only: false;
|
|
7265
|
+
}
|
|
7266
|
+
/** A client declared in the server's config: read only through the API. */
|
|
7267
|
+
export interface ConfigAppClient {
|
|
7268
|
+
name: string;
|
|
7269
|
+
source: "config";
|
|
7270
|
+
label: string;
|
|
7271
|
+
all_tenants: true;
|
|
7272
|
+
tenant_id: string;
|
|
7273
|
+
redirect_uris: string[];
|
|
7274
|
+
allowed_origins: string[];
|
|
7275
|
+
access_token_ttl: string;
|
|
7276
|
+
refresh_idle: string;
|
|
7277
|
+
refresh_absolute: string;
|
|
7278
|
+
read_only: true;
|
|
7279
|
+
}
|
|
7280
|
+
/** A client as `get` and `list` report it. */
|
|
7281
|
+
export type AppClientEntry = ClientDefRecord | ConfigAppClient;
|
|
7282
|
+
/** `op: "list"`: the clients the caller may see, config ones included. */
|
|
7283
|
+
export interface ClientDefListResponse {
|
|
7284
|
+
clients: AppClientEntry[];
|
|
7285
|
+
}
|
|
7286
|
+
/** `op: "verify"`: whether a client is deployed and matches a hash. An absent
|
|
7287
|
+
* client (or one the caller may not see) answers `deployed: false`. */
|
|
7288
|
+
export interface ClientDefVerifyResult {
|
|
7289
|
+
name: string;
|
|
7290
|
+
deployed: boolean;
|
|
7291
|
+
current_def_id?: string;
|
|
7292
|
+
current_sha256?: string;
|
|
7293
|
+
version?: number;
|
|
7294
|
+
matches: boolean;
|
|
7295
|
+
}
|
|
7296
|
+
/** `op: "retire"`. */
|
|
7297
|
+
export interface ClientDefRetireResult {
|
|
7298
|
+
name: string;
|
|
7299
|
+
retired: boolean;
|
|
7300
|
+
}
|
|
7301
|
+
/** One row of `GET /v1/_clientdef/names`. */
|
|
7302
|
+
export interface ClientDefNameSummary {
|
|
7303
|
+
name: string;
|
|
7304
|
+
source: "def" | "config";
|
|
7305
|
+
tenant_id: string;
|
|
7306
|
+
label: string;
|
|
7307
|
+
read_only: boolean;
|
|
7308
|
+
}
|
|
7309
|
+
export interface ClientDefNamesResponse {
|
|
7310
|
+
names: ClientDefNameSummary[];
|
|
7311
|
+
}
|
|
7312
|
+
/** What to show the person: open `verificationUri` and type `userCode`, or
|
|
7313
|
+
* open `verificationUriComplete`, which carries the code. */
|
|
7314
|
+
export interface DeviceLoginPrompt {
|
|
7315
|
+
userCode: string;
|
|
7316
|
+
verificationUri: string;
|
|
7317
|
+
verificationUriComplete?: string;
|
|
7318
|
+
/** Seconds until the code expires. */
|
|
7319
|
+
expiresIn: number;
|
|
7320
|
+
}
|
|
7321
|
+
export interface DeviceLoginOptions {
|
|
7322
|
+
/** How the client names itself on the approval page (default "loomcycle-ts"). */
|
|
7323
|
+
clientId?: string;
|
|
7324
|
+
/** Called once with the code to show; polling starts after it returns. */
|
|
7325
|
+
onPrompt: (prompt: DeviceLoginPrompt) => void | Promise<void>;
|
|
7326
|
+
signal?: AbortSignal;
|
|
7327
|
+
}
|
|
7328
|
+
/** The token issued to the person who approved the login: their own member
|
|
7329
|
+
* token, never wider than the session they approved from and never living
|
|
7330
|
+
* past it. Keep it in an OS credential store, never a plain file. */
|
|
7331
|
+
export interface DeviceLoginResult {
|
|
7332
|
+
accessToken: string;
|
|
7333
|
+
tokenType: string;
|
|
7334
|
+
/** Seconds until the token expires. */
|
|
7335
|
+
expiresIn?: number;
|
|
7336
|
+
scope?: string[];
|
|
7337
|
+
}
|