@awesomate/platform-sdk 0.1.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.
Files changed (45) hide show
  1. package/README.md +92 -0
  2. package/dist/cjs/client.d.ts +128 -0
  3. package/dist/cjs/client.js +257 -0
  4. package/dist/cjs/client.js.map +1 -0
  5. package/dist/cjs/http.d.ts +27 -0
  6. package/dist/cjs/http.js +127 -0
  7. package/dist/cjs/http.js.map +1 -0
  8. package/dist/cjs/index.d.ts +9 -0
  9. package/dist/cjs/index.js +35 -0
  10. package/dist/cjs/index.js.map +1 -0
  11. package/dist/cjs/package.json +1 -0
  12. package/dist/cjs/service.d.ts +140 -0
  13. package/dist/cjs/service.js +216 -0
  14. package/dist/cjs/service.js.map +1 -0
  15. package/dist/cjs/sign.d.ts +11 -0
  16. package/dist/cjs/sign.js +41 -0
  17. package/dist/cjs/sign.js.map +1 -0
  18. package/dist/cjs/sse.d.ts +27 -0
  19. package/dist/cjs/sse.js +130 -0
  20. package/dist/cjs/sse.js.map +1 -0
  21. package/dist/cjs/types.d.ts +517 -0
  22. package/dist/cjs/types.js +4 -0
  23. package/dist/cjs/types.js.map +1 -0
  24. package/dist/esm/client.d.ts +128 -0
  25. package/dist/esm/client.js +251 -0
  26. package/dist/esm/client.js.map +1 -0
  27. package/dist/esm/http.d.ts +27 -0
  28. package/dist/esm/http.js +116 -0
  29. package/dist/esm/http.js.map +1 -0
  30. package/dist/esm/index.d.ts +9 -0
  31. package/dist/esm/index.js +6 -0
  32. package/dist/esm/index.js.map +1 -0
  33. package/dist/esm/service.d.ts +140 -0
  34. package/dist/esm/service.js +210 -0
  35. package/dist/esm/service.js.map +1 -0
  36. package/dist/esm/sign.d.ts +11 -0
  37. package/dist/esm/sign.js +36 -0
  38. package/dist/esm/sign.js.map +1 -0
  39. package/dist/esm/sse.d.ts +27 -0
  40. package/dist/esm/sse.js +125 -0
  41. package/dist/esm/sse.js.map +1 -0
  42. package/dist/esm/types.d.ts +517 -0
  43. package/dist/esm/types.js +3 -0
  44. package/dist/esm/types.js.map +1 -0
  45. package/package.json +48 -0
@@ -0,0 +1,251 @@
1
+ import { deadline, defaultFetch, enc, failureOf, queryString, resultOf, trimSlash, UNAVAILABLE, untilEnd } from "./http.js";
2
+ import { answerEvents, collectAnswer } from "./sse.js";
3
+ const KEY_RE = /^amk_([qpiasu])_[0-9A-Za-z]{40}$/;
4
+ /** Class of a platform key, or null when the string is not a well-formed key. */
5
+ export function keyClass(key) {
6
+ const m = KEY_RE.exec(key);
7
+ return m ? m[1] : null;
8
+ }
9
+ /**
10
+ * Client for the tenant API (`/v1/*`). One instance = one key = one tenant; the platform
11
+ * scopes every call server-side. Never throws on the request path — see PlatformResult.
12
+ */
13
+ export class PlatformClient {
14
+ baseUrl;
15
+ apiKey;
16
+ timeoutMs;
17
+ answerTimeoutMs;
18
+ uploadTimeoutMs;
19
+ fetchImpl;
20
+ constructor(config) {
21
+ this.baseUrl = trimSlash(config.baseUrl ?? "");
22
+ this.apiKey = config.apiKey ?? "";
23
+ this.timeoutMs = config.timeoutMs ?? 10_000;
24
+ this.answerTimeoutMs = config.answerTimeoutMs ?? 5 * 60_000;
25
+ this.uploadTimeoutMs = config.uploadTimeoutMs ?? 10 * 60_000;
26
+ this.fetchImpl = config.fetchImpl ?? defaultFetch();
27
+ }
28
+ isConfigured() {
29
+ return Boolean(this.baseUrl && this.apiKey);
30
+ }
31
+ headers(extra = {}) {
32
+ return { Authorization: `Bearer ${this.apiKey}`, ...extra };
33
+ }
34
+ async request(method, path, opts = {}) {
35
+ if (!this.isConfigured())
36
+ return UNAVAILABLE;
37
+ const headers = this.headers(opts.headers);
38
+ const rawBody = opts.body === undefined ? undefined : JSON.stringify(opts.body);
39
+ if (rawBody !== undefined)
40
+ headers["Content-Type"] = "application/json";
41
+ const d = deadline(opts.timeoutMs ?? this.timeoutMs, opts.signal);
42
+ try {
43
+ const res = await this.fetchImpl(`${this.baseUrl}${path}`, { method, headers, body: rawBody, signal: d.signal });
44
+ return await resultOf(res);
45
+ }
46
+ catch {
47
+ return UNAVAILABLE;
48
+ }
49
+ finally {
50
+ d.done();
51
+ }
52
+ }
53
+ // --- answers ---------------------------------------------------------------------------
54
+ /** `POST /v1/answer`, JSON: the validated answer with numbered sources. */
55
+ answer(body, opts = {}) {
56
+ return this.request("POST", "/v1/answer", {
57
+ body,
58
+ headers: { Accept: "application/json" },
59
+ signal: opts.signal,
60
+ timeoutMs: this.answerTimeoutMs,
61
+ });
62
+ }
63
+ /** `POST /v1/answer` with `Accept: text/event-stream`: sources first, then gated sentences, then meta. */
64
+ async answerStream(body, opts = {}) {
65
+ return this.stream("/v1/answer", body, opts.signal);
66
+ }
67
+ /** v2 `POST /v1/agents/:agent_id/chat` streamed (Phase 1; `404 not_found` until it lands). */
68
+ async agentChatStream(agentId, body, opts = {}) {
69
+ return this.stream(`/v1/agents/${enc(agentId)}/chat`, body, opts.signal);
70
+ }
71
+ async stream(path, body, signal) {
72
+ if (!this.isConfigured())
73
+ return UNAVAILABLE;
74
+ // The budget covers the headers (time to first byte). Once the stream is open the caller's
75
+ // own signal governs it, so the timer stops at headers while the abort link stays wired
76
+ // until the body ends or is cancelled.
77
+ const d = deadline(this.answerTimeoutMs, signal);
78
+ let res;
79
+ try {
80
+ res = await this.fetchImpl(`${this.baseUrl}${path}`, {
81
+ method: "POST",
82
+ headers: this.headers({ "Content-Type": "application/json", Accept: "text/event-stream" }),
83
+ body: JSON.stringify(body),
84
+ signal: d.signal,
85
+ });
86
+ }
87
+ catch {
88
+ d.done();
89
+ return UNAVAILABLE;
90
+ }
91
+ if (!res.ok) {
92
+ d.done();
93
+ return failureOf(res);
94
+ }
95
+ d.clearTimer();
96
+ const stream = res.body ? untilEnd(res.body, d.done) : emptyBody(d.done);
97
+ return {
98
+ ok: true,
99
+ status: res.status,
100
+ contentType: res.headers?.get?.("content-type") ?? "text/event-stream",
101
+ body: stream,
102
+ events: () => answerEvents(stream),
103
+ collect: () => collectAnswer(stream),
104
+ };
105
+ }
106
+ // --- search / identity -----------------------------------------------------------------
107
+ /** `GET /v1/query` — raw hybrid-search passages (bypass the citation gate). */
108
+ query(params, opts = {}) {
109
+ return this.request("GET", `/v1/query${queryString(params)}`, { signal: opts.signal });
110
+ }
111
+ whoami() {
112
+ return this.request("GET", "/v1/whoami");
113
+ }
114
+ status() {
115
+ return this.request("GET", "/v1/status");
116
+ }
117
+ feedback(body) {
118
+ return this.request("POST", "/v1/feedback", { body });
119
+ }
120
+ // --- media -----------------------------------------------------------------------------
121
+ /**
122
+ * `GET /v1/media/<key>`: the platform 302s to a 10-minute presigned URL. `fetch` follows
123
+ * it, so the Response carries the bytes. Prefer presigned URLs from answer sources where
124
+ * the platform supplies them; use this when you hold only a media key.
125
+ */
126
+ async media(key, init = {}) {
127
+ if (!this.isConfigured())
128
+ return UNAVAILABLE;
129
+ const path = key
130
+ .replace(/^\/+/, "")
131
+ .split("/")
132
+ .map(enc)
133
+ .join("/");
134
+ const d = deadline(this.uploadTimeoutMs, init.signal);
135
+ let res;
136
+ try {
137
+ res = await this.fetchImpl(`${this.baseUrl}/v1/media/${path}`, {
138
+ method: "GET",
139
+ headers: this.headers(init.range ? { Range: init.range } : {}),
140
+ redirect: "follow",
141
+ signal: d.signal,
142
+ });
143
+ }
144
+ catch {
145
+ d.done();
146
+ return UNAVAILABLE;
147
+ }
148
+ if (!res.ok) {
149
+ d.done();
150
+ return failureOf(res);
151
+ }
152
+ if (!res.body) {
153
+ d.done();
154
+ return { ok: true, status: res.status, data: res };
155
+ }
156
+ // Same shape as the platform's Response, with the body wrapped so the caller's abort
157
+ // stays wired while bytes flow and the link is dropped when they stop.
158
+ d.clearTimer();
159
+ return { ok: true, status: res.status, data: new Response(untilEnd(res.body, d.done), res) };
160
+ }
161
+ // --- ingestion (amk_i_ keys) -----------------------------------------------------------
162
+ createUpload(body) {
163
+ return this.request("POST", "/v1/ingest/uploads", { body });
164
+ }
165
+ completeUpload(uploadId, body = {}) {
166
+ return this.request("POST", `/v1/ingest/uploads/${enc(uploadId)}/complete`, { body });
167
+ }
168
+ /**
169
+ * PUT the staged bytes to `put_url` EXACTLY as the platform returned it. A presigned S3 URL
170
+ * is its own credential and gets no headers of ours. On FsStore deployments the platform
171
+ * hands back its own `/v1/ingest/uploads/:id/content` route instead, which sits behind the
172
+ * same ingest-key auth as every `/v1/ingest/*` call, so that one carries the Bearer key.
173
+ * A relative `put_url` resolves against `baseUrl`.
174
+ */
175
+ async uploadBytes(putUrl, body, sizeBytes) {
176
+ const url = putUrl.startsWith("/") ? `${this.baseUrl}${putUrl}` : putUrl;
177
+ const platformRoute = url.startsWith(`${this.baseUrl}/v1/ingest/`);
178
+ return uploadTo(this.fetchImpl, url, body, sizeBytes, this.uploadTimeoutMs, platformRoute ? this.headers() : {});
179
+ }
180
+ /** `POST /v1/ingest/jobs`; pass `idempotencyKey` so a retry returns the same job. */
181
+ createJob(body, opts = {}) {
182
+ return this.request("POST", "/v1/ingest/jobs", {
183
+ body,
184
+ headers: opts.idempotencyKey ? { "Idempotency-Key": opts.idempotencyKey } : {},
185
+ });
186
+ }
187
+ getJob(jobId) {
188
+ return this.request("GET", `/v1/ingest/jobs/${enc(jobId)}`);
189
+ }
190
+ listJobs(params = {}) {
191
+ return this.request("GET", `/v1/ingest/jobs${queryString(params)}`);
192
+ }
193
+ cancelJob(jobId) {
194
+ return this.request("POST", `/v1/ingest/jobs/${enc(jobId)}/cancel`, { body: {} });
195
+ }
196
+ retryJob(jobId) {
197
+ return this.request("POST", `/v1/ingest/jobs/${enc(jobId)}/retry`, { body: {} });
198
+ }
199
+ // --- business data ---------------------------------------------------------------------
200
+ listDatasets() {
201
+ return this.request("GET", "/v1/data/datasets");
202
+ }
203
+ getDataset(datasetId) {
204
+ return this.request("GET", `/v1/data/datasets/${enc(datasetId)}`);
205
+ }
206
+ queryData(dsl, opts = {}) {
207
+ return this.request("POST", "/v1/data/query", { body: dsl, signal: opts.signal });
208
+ }
209
+ createImport(body, opts = {}) {
210
+ return this.request("POST", "/v1/data/imports", {
211
+ body,
212
+ headers: opts.idempotencyKey ? { "Idempotency-Key": opts.idempotencyKey } : {},
213
+ });
214
+ }
215
+ getImport(id) {
216
+ return this.request("GET", `/v1/data/imports/${enc(id)}`);
217
+ }
218
+ }
219
+ const emptyBody = (onEnd) => new ReadableStream({
220
+ start(c) {
221
+ onEnd();
222
+ c.close();
223
+ },
224
+ });
225
+ /**
226
+ * Shared by the tenant and service clients: a PUT of raw bytes to the platform's `put_url`.
227
+ * `headers` is empty for presigned URLs (the URL is the credential) and carries the Bearer
228
+ * key only for the platform's own auth-gated upload route.
229
+ */
230
+ export async function uploadTo(fetchImpl, url, body, sizeBytes, timeoutMs, headers = {}) {
231
+ const init = {
232
+ method: "PUT",
233
+ headers: sizeBytes === undefined ? headers : { ...headers, "Content-Length": String(sizeBytes) },
234
+ body: body,
235
+ signal: AbortSignal.timeout(timeoutMs),
236
+ };
237
+ // Streaming request bodies need half-duplex in undici (Node) and are rejected otherwise.
238
+ if (typeof ReadableStream !== "undefined" && body instanceof ReadableStream)
239
+ init.duplex = "half";
240
+ let res;
241
+ try {
242
+ res = await fetchImpl(url, init);
243
+ }
244
+ catch {
245
+ return UNAVAILABLE;
246
+ }
247
+ if (!res.ok)
248
+ return failureOf(res);
249
+ return { ok: true, status: res.status, data: undefined };
250
+ }
251
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ import type { PlatformFailure, PlatformResult } from "./types.js";
2
+ export type FetchLike = (input: string, init?: RequestInit) => Promise<Response>;
3
+ export declare const UNAVAILABLE: PlatformFailure;
4
+ export declare const trimSlash: (url: string) => string;
5
+ export declare function defaultFetch(): FetchLike;
6
+ export interface Deadline {
7
+ signal: AbortSignal;
8
+ /** Headers arrived within budget: stop the timer but keep the caller's abort wired to the body. */
9
+ clearTimer: () => void;
10
+ /** The request is over (settled, or its body ended/cancelled): timer off, caller listener detached. */
11
+ done: () => void;
12
+ }
13
+ /**
14
+ * One AbortSignal from an optional caller signal plus a timeout budget. `AbortSignal.any`
15
+ * is not on Node 20.0, so this composes by hand. `done()` must run when the request is over,
16
+ * or the timer and the listener on the caller's (often long-lived) signal outlive it; for a
17
+ * streamed body call `clearTimer()` at headers and `done()` when the body finishes.
18
+ */
19
+ export declare function deadline(timeoutMs: number, signal?: AbortSignal): Deadline;
20
+ /** Passes a body through untouched and runs `onEnd` once, when it closes, errors or is cancelled. */
21
+ export declare function untilEnd(body: ReadableStream<Uint8Array>, onEnd: () => void): ReadableStream<Uint8Array>;
22
+ /** Reads the platform error envelope `{error, message, request_id}`; non-JSON bodies keep the http_<status> code. */
23
+ export declare function failureOf(res: Response): Promise<PlatformFailure>;
24
+ /** Resolves a fetch Response into the result envelope; 204 carries `undefined` data. */
25
+ export declare function resultOf<T>(res: Response): Promise<PlatformResult<T>>;
26
+ export declare function queryString(params: object): string;
27
+ export declare const enc: (v: string) => string;
@@ -0,0 +1,116 @@
1
+ export const UNAVAILABLE = { ok: false, reason: "unavailable" };
2
+ export const trimSlash = (url) => url.replace(/\/+$/, "");
3
+ export function defaultFetch() {
4
+ const f = globalThis.fetch;
5
+ if (typeof f !== "function")
6
+ throw new Error("@awesomate/platform-sdk: no global fetch; pass fetchImpl");
7
+ return (input, init) => f(input, init);
8
+ }
9
+ /**
10
+ * One AbortSignal from an optional caller signal plus a timeout budget. `AbortSignal.any`
11
+ * is not on Node 20.0, so this composes by hand. `done()` must run when the request is over,
12
+ * or the timer and the listener on the caller's (often long-lived) signal outlive it; for a
13
+ * streamed body call `clearTimer()` at headers and `done()` when the body finishes.
14
+ */
15
+ export function deadline(timeoutMs, signal) {
16
+ const ctrl = new AbortController();
17
+ const timer = setTimeout(() => ctrl.abort(new DOMException("timeout", "TimeoutError")), timeoutMs);
18
+ const onAbort = () => ctrl.abort(signal?.reason);
19
+ if (signal?.aborted)
20
+ onAbort();
21
+ else
22
+ signal?.addEventListener("abort", onAbort, { once: true });
23
+ const clearTimer = () => clearTimeout(timer);
24
+ return {
25
+ signal: ctrl.signal,
26
+ clearTimer,
27
+ done: () => {
28
+ clearTimer();
29
+ signal?.removeEventListener("abort", onAbort);
30
+ },
31
+ };
32
+ }
33
+ /** Passes a body through untouched and runs `onEnd` once, when it closes, errors or is cancelled. */
34
+ export function untilEnd(body, onEnd) {
35
+ const reader = body.getReader();
36
+ let ended = false;
37
+ const end = () => {
38
+ if (ended)
39
+ return;
40
+ ended = true;
41
+ onEnd();
42
+ };
43
+ return new ReadableStream({
44
+ async pull(ctrl) {
45
+ try {
46
+ const { value, done } = await reader.read();
47
+ if (done) {
48
+ end();
49
+ ctrl.close();
50
+ return;
51
+ }
52
+ ctrl.enqueue(value);
53
+ }
54
+ catch (err) {
55
+ end();
56
+ ctrl.error(err);
57
+ }
58
+ },
59
+ cancel(reason) {
60
+ end();
61
+ return reader.cancel(reason);
62
+ },
63
+ });
64
+ }
65
+ const header = (res, name) => {
66
+ const v = res.headers?.get?.(name);
67
+ return v === null || v === undefined ? undefined : v;
68
+ };
69
+ /** Reads the platform error envelope `{error, message, request_id}`; non-JSON bodies keep the http_<status> code. */
70
+ export async function failureOf(res) {
71
+ if (res.status >= 500)
72
+ return UNAVAILABLE;
73
+ let envelope = {};
74
+ try {
75
+ envelope = (await res.json());
76
+ }
77
+ catch {
78
+ // keep the fallback code
79
+ }
80
+ const out = { ok: false, status: res.status, error: envelope.error ?? `http_${res.status}` };
81
+ if (envelope.message !== undefined)
82
+ out.message = envelope.message;
83
+ if (envelope.request_id !== undefined)
84
+ out.requestId = envelope.request_id;
85
+ const retryAfter = header(res, "retry-after");
86
+ if (retryAfter !== undefined)
87
+ out.retryAfter = retryAfter;
88
+ return out;
89
+ }
90
+ /** Resolves a fetch Response into the result envelope; 204 carries `undefined` data. */
91
+ export async function resultOf(res) {
92
+ if (!res.ok)
93
+ return failureOf(res);
94
+ if (res.status === 204)
95
+ return { ok: true, status: 204, data: undefined };
96
+ try {
97
+ return { ok: true, status: res.status, data: (await res.json()) };
98
+ }
99
+ catch {
100
+ return UNAVAILABLE;
101
+ }
102
+ }
103
+ export function queryString(params) {
104
+ const q = new URLSearchParams();
105
+ for (const [k, v] of Object.entries(params)) {
106
+ if (v === undefined || v === null || v === "")
107
+ continue;
108
+ if (typeof v !== "string" && typeof v !== "number" && typeof v !== "boolean")
109
+ continue;
110
+ q.set(k, String(v));
111
+ }
112
+ const s = q.toString();
113
+ return s ? `?${s}` : "";
114
+ }
115
+ export const enc = (v) => encodeURIComponent(v);
116
+ //# sourceMappingURL=http.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http.js","sourceRoot":"","sources":["../../src/http.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ export { PlatformClient, keyClass, uploadTo } from "./client.js";
2
+ export type { PlatformClientConfig, AnswerStreamResult } from "./client.js";
3
+ export { ServiceClient, countTenantSources, liveSourceTotals } from "./service.js";
4
+ export type { ServiceClientConfig } from "./service.js";
5
+ export { parseSSE, answerEvents, collectAnswer } from "./sse.js";
6
+ export type { SSEMessage, CollectedAnswer } from "./sse.js";
7
+ export { signServiceRequest, serviceHeaders, hmacSha256Hex } from "./sign.js";
8
+ export type { FetchLike } from "./http.js";
9
+ export * from "./types.js";
@@ -0,0 +1,6 @@
1
+ export { PlatformClient, keyClass, uploadTo } from "./client.js";
2
+ export { ServiceClient, countTenantSources, liveSourceTotals } from "./service.js";
3
+ export { parseSSE, answerEvents, collectAnswer } from "./sse.js";
4
+ export { signServiceRequest, serviceHeaders, hmacSha256Hex } from "./sign.js";
5
+ export * from "./types.js";
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEjE,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEnF,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEjE,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAE9E,cAAc,YAAY,CAAC"}
@@ -0,0 +1,140 @@
1
+ import type { FetchLike } from "./http.js";
2
+ import type { AdminJobsPage, AliasDecisionBody, AliasesPage, CompleteUploadBody, CreateSourceBody, CreateUploadBody, Enqueued, EntityKind, LiveSourceTotals, MergeResult, MintKeyBody, MintedKey, PeoplePage, PersonDetail, PersonMeta, PersonPatchBody, PersonStatus, PlatformResult, PurgeJob, SourceSummary, SourcesPage, Tenant, TenantDetail, UploadTicket, UpsertTenantBody, UsageRow } from "./types.js";
3
+ export interface ServiceClientConfig {
4
+ /** Service-channel base, e.g. `https://knowledge-admin.awesomate.ai`. */
5
+ adminUrl: string;
6
+ /** `amk_s_…` — held by the hub's api and worker only, never handed to a client. */
7
+ serviceKey: string;
8
+ hmacSecret: string;
9
+ timeoutMs?: number;
10
+ uploadTimeoutMs?: number;
11
+ fetchImpl?: FetchLike;
12
+ /** Clock for the signed timestamp (tests). */
13
+ now?: () => number;
14
+ }
15
+ /**
16
+ * Client for the hub-only service channel (`/v1/admin/*`). Every request carries
17
+ * `Authorization: Bearer amk_s_…`, `X-Awm-Timestamp`, `X-Awm-Signature` (HMAC over
18
+ * `<ts>.<rawBody>`) and, on mutations, `X-Awm-Idempotency-Key` (replays return the stored
19
+ * response). Same error contract as PlatformClient: never throws on the request path.
20
+ */
21
+ export declare class ServiceClient {
22
+ private readonly adminUrl;
23
+ private readonly serviceKey;
24
+ private readonly hmacSecret;
25
+ private readonly timeoutMs;
26
+ private readonly uploadTimeoutMs;
27
+ private readonly fetchImpl;
28
+ private readonly now;
29
+ constructor(config: ServiceClientConfig);
30
+ isConfigured(): boolean;
31
+ private request;
32
+ private tenantPath;
33
+ /** `PUT /v1/admin/tenants/:id` — idempotent upsert. */
34
+ upsertTenant(tenantId: string, body: UpsertTenantBody, idempotencyKey: string): Promise<PlatformResult<{
35
+ tenant: Tenant;
36
+ }>>;
37
+ getTenant(tenantId: string): Promise<PlatformResult<TenantDetail>>;
38
+ mintKey(tenantId: string, body: MintKeyBody, idempotencyKey: string): Promise<PlatformResult<MintedKey>>;
39
+ revokeKey(tenantId: string, keyId: string, idempotencyKey: string): Promise<PlatformResult<void>>;
40
+ suspend(tenantId: string, idempotencyKey: string): Promise<PlatformResult<{
41
+ status: string;
42
+ }>>;
43
+ resume(tenantId: string, idempotencyKey: string): Promise<PlatformResult<{
44
+ status: string;
45
+ }>>;
46
+ patchConfig(tenantId: string, config: Record<string, unknown>, idempotencyKey: string): Promise<PlatformResult<{
47
+ tenant: Tenant;
48
+ }>>;
49
+ /** Short-lived `q` key for a test-chat pane — never persisted. Default TTL 15 min. */
50
+ mintTestChatKey(tenantId: string, opts?: {
51
+ name?: string;
52
+ ttlSeconds?: number;
53
+ }): Promise<PlatformResult<MintedKey>>;
54
+ purge(tenantId: string, idempotencyKey: string): Promise<PlatformResult<{
55
+ purge_job_id: string;
56
+ }>>;
57
+ getPurgeJob(purgeJobId: string): Promise<PlatformResult<PurgeJob>>;
58
+ /** Absolute daily counters; the range is capped at 62 days. */
59
+ listUsage(params: {
60
+ sinceDay: string;
61
+ untilDay?: string;
62
+ }): Promise<PlatformResult<UsageRow[]>>;
63
+ listJobs(tenantId: string, params?: {
64
+ status?: string;
65
+ limit?: number;
66
+ cursor?: string;
67
+ }): Promise<PlatformResult<AdminJobsPage>>;
68
+ retryJob(tenantId: string, jobId: string, idempotencyKey: string): Promise<PlatformResult<Enqueued>>;
69
+ listSources(tenantId: string, params?: {
70
+ limit?: number;
71
+ cursor?: string;
72
+ kind?: string;
73
+ tag?: string;
74
+ }): Promise<PlatformResult<SourcesPage>>;
75
+ /** Whole-library counts in one call — for "how much is in here", not for browsing.
76
+ * 404 on a platform that predates the route; `liveSourceTotals()` falls back to paging. */
77
+ sourceSummary(tenantId: string): Promise<PlatformResult<SourceSummary>>;
78
+ createSource(tenantId: string, body: CreateSourceBody, idempotencyKey: string): Promise<PlatformResult<Enqueued>>;
79
+ deleteSource(tenantId: string, sourceId: string, idempotencyKey: string): Promise<PlatformResult<{
80
+ job_id: string;
81
+ }>>;
82
+ createUpload(tenantId: string, body: CreateUploadBody, idempotencyKey: string): Promise<PlatformResult<UploadTicket>>;
83
+ completeUpload(tenantId: string, uploadId: string, body: CompleteUploadBody, idempotencyKey: string): Promise<PlatformResult<{
84
+ upload_id: string;
85
+ status: string;
86
+ }>>;
87
+ /**
88
+ * PUT the staged bytes to `put_url` EXACTLY as the platform returned it — presigned S3 or
89
+ * the platform's query-signed dev route. No service headers: the URL is the credential.
90
+ * A relative `put_url` (FsStore deployments) resolves against `adminUrl`.
91
+ */
92
+ uploadBytes(putUrl: string, body: BodyInit | ReadableStream<Uint8Array>, sizeBytes?: number): Promise<PlatformResult<void>>;
93
+ listPeople(tenantId: string, params?: {
94
+ status?: PersonStatus | "all";
95
+ limit?: number;
96
+ cursor?: string;
97
+ }): Promise<PlatformResult<PeoplePage>>;
98
+ getPerson(tenantId: string, personId: string): Promise<PlatformResult<PersonDetail>>;
99
+ /** Rename (`display_name`, 1–80 chars) or hide/unhide (`status`). The platform propagates a
100
+ * rename into its facets and enqueues a resolve. */
101
+ patchPerson(tenantId: string, personId: string, body: PersonPatchBody, idempotencyKey: string): Promise<PlatformResult<{
102
+ person: PersonMeta;
103
+ relabelled: number;
104
+ job_id: string | null;
105
+ }>>;
106
+ mergePeople(tenantId: string, personId: string, body: {
107
+ into_person_id: string;
108
+ }, idempotencyKey: string): Promise<PlatformResult<MergeResult>>;
109
+ listAliasSuggestions(tenantId: string, params?: {
110
+ status?: "pending" | "accepted" | "rejected";
111
+ kind?: EntityKind;
112
+ limit?: number;
113
+ cursor?: string;
114
+ }): Promise<PlatformResult<AliasesPage>>;
115
+ decideAlias(tenantId: string, body: AliasDecisionBody, idempotencyKey: string): Promise<PlatformResult<{
116
+ alias: string;
117
+ entity_id: string | null;
118
+ job_id: string | null;
119
+ }>>;
120
+ /** 202 `{job_id, status:'queued', position}` when a resolve is enqueued; 200 `{job_id, status}`
121
+ * when one is already queued|running for the tenant. */
122
+ resolveEntities(tenantId: string, idempotencyKey: string, body?: {
123
+ full?: boolean;
124
+ stub?: boolean;
125
+ }): Promise<PlatformResult<Enqueued>>;
126
+ }
127
+ /**
128
+ * The truthful "what is in this tenant" figure: the platform's summary route (one GROUP BY,
129
+ * exact at any size); on a platform that predates it, the paged count — capped, and flagged.
130
+ */
131
+ export declare function liveSourceTotals(client: Pick<ServiceClient, "listSources" | "sourceSummary">, tenantId: string): Promise<PlatformResult<LiveSourceTotals>>;
132
+ /**
133
+ * Live source count by paging the metadata list. Prefer `liveSourceTotals`, which uses the
134
+ * summary route when the platform serves it and falls back to this.
135
+ */
136
+ export declare function countTenantSources(client: Pick<ServiceClient, "listSources">, tenantId: string): Promise<PlatformResult<{
137
+ total: number;
138
+ failed: number;
139
+ truncated: boolean;
140
+ }>>;