modelpact 2.0.2
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/LICENSE +21 -0
- package/README.md +372 -0
- package/dist/helpers/abort.d.ts +14 -0
- package/dist/helpers/abort.d.ts.map +1 -0
- package/dist/helpers/abort.js +22 -0
- package/dist/helpers/abort.js.map +1 -0
- package/dist/helpers/lifetime.d.ts +34 -0
- package/dist/helpers/lifetime.d.ts.map +1 -0
- package/dist/helpers/lifetime.js +71 -0
- package/dist/helpers/lifetime.js.map +1 -0
- package/dist/helpers/monitor.d.ts +52 -0
- package/dist/helpers/monitor.d.ts.map +1 -0
- package/dist/helpers/monitor.js +69 -0
- package/dist/helpers/monitor.js.map +1 -0
- package/dist/helpers/ndjson.d.ts +19 -0
- package/dist/helpers/ndjson.d.ts.map +1 -0
- package/dist/helpers/ndjson.js +39 -0
- package/dist/helpers/ndjson.js.map +1 -0
- package/dist/helpers/overflow.d.ts +50 -0
- package/dist/helpers/overflow.d.ts.map +1 -0
- package/dist/helpers/overflow.js +72 -0
- package/dist/helpers/overflow.js.map +1 -0
- package/dist/helpers/transcript.d.ts +22 -0
- package/dist/helpers/transcript.d.ts.map +1 -0
- package/dist/helpers/transcript.js +26 -0
- package/dist/helpers/transcript.js.map +1 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -0
- package/dist/lifecycle/01_access.d.ts +13 -0
- package/dist/lifecycle/01_access.d.ts.map +1 -0
- package/dist/lifecycle/01_access.js +45 -0
- package/dist/lifecycle/01_access.js.map +1 -0
- package/dist/lifecycle/02_download.d.ts +8 -0
- package/dist/lifecycle/02_download.d.ts.map +1 -0
- package/dist/lifecycle/02_download.js +12 -0
- package/dist/lifecycle/02_download.js.map +1 -0
- package/dist/lifecycle/03_open.d.ts +22 -0
- package/dist/lifecycle/03_open.d.ts.map +1 -0
- package/dist/lifecycle/03_open.js +39 -0
- package/dist/lifecycle/03_open.js.map +1 -0
- package/dist/lifecycle/04_generate.d.ts +15 -0
- package/dist/lifecycle/04_generate.d.ts.map +1 -0
- package/dist/lifecycle/04_generate.js +154 -0
- package/dist/lifecycle/04_generate.js.map +1 -0
- package/dist/lifecycle/05_close.d.ts +4 -0
- package/dist/lifecycle/05_close.d.ts.map +1 -0
- package/dist/lifecycle/05_close.js +8 -0
- package/dist/lifecycle/05_close.js.map +1 -0
- package/dist/providers/create.d.ts +5 -0
- package/dist/providers/create.d.ts.map +1 -0
- package/dist/providers/create.js +7 -0
- package/dist/providers/create.js.map +1 -0
- package/dist/providers/mock.d.ts +36 -0
- package/dist/providers/mock.d.ts.map +1 -0
- package/dist/providers/mock.js +128 -0
- package/dist/providers/mock.js.map +1 -0
- package/dist/providers/ollama.d.ts +33 -0
- package/dist/providers/ollama.d.ts.map +1 -0
- package/dist/providers/ollama.js +275 -0
- package/dist/providers/ollama.js.map +1 -0
- package/dist/providers/prompt-api.d.ts +23 -0
- package/dist/providers/prompt-api.d.ts.map +1 -0
- package/dist/providers/prompt-api.js +203 -0
- package/dist/providers/prompt-api.js.map +1 -0
- package/dist/providers/registry.d.ts +22 -0
- package/dist/providers/registry.d.ts.map +1 -0
- package/dist/providers/registry.js +30 -0
- package/dist/providers/registry.js.map +1 -0
- package/dist/testing/contract.d.ts +47 -0
- package/dist/testing/contract.d.ts.map +1 -0
- package/dist/testing/contract.js +518 -0
- package/dist/testing/contract.js.map +1 -0
- package/dist/testing/index.d.ts +9 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +9 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/types/backend.d.ts +63 -0
- package/dist/types/backend.d.ts.map +1 -0
- package/dist/types/backend.js +11 -0
- package/dist/types/backend.js.map +1 -0
- package/dist/types/failures.d.ts +115 -0
- package/dist/types/failures.d.ts.map +1 -0
- package/dist/types/failures.js +68 -0
- package/dist/types/failures.js.map +1 -0
- package/dist/types/foundations.d.ts +35 -0
- package/dist/types/foundations.d.ts.map +1 -0
- package/dist/types/foundations.js +30 -0
- package/dist/types/foundations.js.map +1 -0
- package/dist/types/messages.d.ts +30 -0
- package/dist/types/messages.d.ts.map +1 -0
- package/dist/types/messages.js +2 -0
- package/dist/types/messages.js.map +1 -0
- package/dist/types/provider.d.ts +22 -0
- package/dist/types/provider.d.ts.map +1 -0
- package/dist/types/provider.js +2 -0
- package/dist/types/provider.js.map +1 -0
- package/dist/types/session.d.ts +156 -0
- package/dist/types/session.d.ts.map +1 -0
- package/dist/types/session.js +2 -0
- package/dist/types/session.js.map +1 -0
- package/dist/types/usage.d.ts +25 -0
- package/dist/types/usage.d.ts.map +1 -0
- package/dist/types/usage.js +16 -0
- package/dist/types/usage.js.map +1 -0
- package/package.json +85 -0
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What a backend supplies; `../lifecycle` turns it into an `AiProvider`.
|
|
3
|
+
*
|
|
4
|
+
* The contract's runtime guarantees — one generation at a time, an abort that
|
|
5
|
+
* leaves the session open, a close that refuses everything after it, an
|
|
6
|
+
* overflow that fires once — are implemented once, in `../lifecycle/01_access.ts`
|
|
7
|
+
* through `05_close.ts`. A backend never sees them: it says what the model is
|
|
8
|
+
* and how to talk to it, and the order of calls is the lifecycle's business.
|
|
9
|
+
*/
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=backend.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"backend.js","sourceRoot":"","sources":["../../src/types/backend.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG"}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import type { Modality } from "./messages.js";
|
|
2
|
+
import type { ContextUsage } from "./usage.js";
|
|
3
|
+
/**
|
|
4
|
+
* The contract's failure vocabulary: any refusal from any provider — browser,
|
|
5
|
+
* Ollama, mock — is one of these kinds.
|
|
6
|
+
*
|
|
7
|
+
* The set is cut by the caller's next move, not by exception name: kinds merge
|
|
8
|
+
* where the reaction would be the same and split where it differs, even when
|
|
9
|
+
* the spec throws one exception for both (`unsupported-config` vs
|
|
10
|
+
* `unsupported-input`). The mechanical name-to-kind mapping lives in
|
|
11
|
+
* `failureFromError`; the kinds with no spec exception behind them (`unsupported`,
|
|
12
|
+
* `busy`, `unknown`) say so in their own docs below.
|
|
13
|
+
*
|
|
14
|
+
* Each failure carries exactly the data its kind implies. `cause` is factored
|
|
15
|
+
* into an intersection to avoid repeating it; narrowing on `kind` still works
|
|
16
|
+
* through that, which `src/types.test-d.ts` checks.
|
|
17
|
+
*/
|
|
18
|
+
export type AiFailure = {
|
|
19
|
+
readonly cause?: unknown;
|
|
20
|
+
} & (
|
|
21
|
+
/** No such API in this runtime. */
|
|
22
|
+
{
|
|
23
|
+
readonly kind: "unsupported";
|
|
24
|
+
}
|
|
25
|
+
/** Blocked by the `language-model` Permissions-Policy (`NotAllowedError`). */
|
|
26
|
+
| {
|
|
27
|
+
readonly kind: "not-allowed";
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* The environment has a model, but not for this request. Both lists name the
|
|
31
|
+
* parts that did not fit; empty or absent means the provider did not narrow
|
|
32
|
+
* it down.
|
|
33
|
+
*/
|
|
34
|
+
| {
|
|
35
|
+
readonly kind: "unsupported-config";
|
|
36
|
+
readonly languages: readonly string[];
|
|
37
|
+
readonly modalities?: readonly Modality[];
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* The message the caller built is not accepted. Kept apart from
|
|
41
|
+
* `unsupported-config` because it is a bug in the caller, not the
|
|
42
|
+
* environment — the spec throws one `NotSupportedError` for both.
|
|
43
|
+
*/
|
|
44
|
+
| {
|
|
45
|
+
readonly kind: "unsupported-input";
|
|
46
|
+
readonly detail: string;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* `QuotaExceededError`: usage passed the window. Retrying without trimming
|
|
50
|
+
* history will fail again, hence the measurement travels along.
|
|
51
|
+
*/
|
|
52
|
+
| {
|
|
53
|
+
readonly kind: "context-overflow";
|
|
54
|
+
readonly usage: ContextUsage;
|
|
55
|
+
}
|
|
56
|
+
/** Explicit abort, or a call on a closed session — the spec throws `AbortError` for both. */
|
|
57
|
+
| {
|
|
58
|
+
readonly kind: "aborted";
|
|
59
|
+
readonly reason: string;
|
|
60
|
+
}
|
|
61
|
+
/** Malformed request: empty message list, misplaced system turn, conflicting options. */
|
|
62
|
+
| {
|
|
63
|
+
readonly kind: "invalid-input";
|
|
64
|
+
readonly detail: string;
|
|
65
|
+
}
|
|
66
|
+
/** Document not fully active. */
|
|
67
|
+
| {
|
|
68
|
+
readonly kind: "invalid-state";
|
|
69
|
+
readonly detail: string;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* A generation is already running on this session; `detail` names the call
|
|
73
|
+
* holding it. Its own kind rather than a shade of `invalid-state`: the spec
|
|
74
|
+
* spends that one on a single condition (the document is not fully active),
|
|
75
|
+
* and the caller's move differs — wait, or open a second session.
|
|
76
|
+
*
|
|
77
|
+
* Not a spec exception: the spec says nothing about two `prompt()` calls at
|
|
78
|
+
* once, and points at `clone()` for work meant to run in parallel. A
|
|
79
|
+
* provider here has to serialize instead.
|
|
80
|
+
*/
|
|
81
|
+
| {
|
|
82
|
+
readonly kind: "busy";
|
|
83
|
+
readonly detail: string;
|
|
84
|
+
}
|
|
85
|
+
/** The browser's own catch-all (`OperationError`). */
|
|
86
|
+
| {
|
|
87
|
+
readonly kind: "failed";
|
|
88
|
+
readonly detail: string;
|
|
89
|
+
} | {
|
|
90
|
+
readonly kind: "unknown";
|
|
91
|
+
});
|
|
92
|
+
/** Every kind in the vocabulary, under a name; derived, and a type rather than an enum — see `AccessKind` in `./session.ts`. */
|
|
93
|
+
export type FailureKind = AiFailure["kind"];
|
|
94
|
+
/**
|
|
95
|
+
* Where thrown exceptions enter the vocabulary: whatever a provider caught
|
|
96
|
+
* becomes an `AiFailure`, mapped by DOMException name. This is the generic
|
|
97
|
+
* half of the mapping — a provider that knows the call site refines what a
|
|
98
|
+
* name alone cannot say (see the `NotSupportedError` and
|
|
99
|
+
* `QuotaExceededError` branches).
|
|
100
|
+
*
|
|
101
|
+
* Matches on `error.name` rather than `instanceof DOMException`, because the
|
|
102
|
+
* spec throws a plain `TypeError` that the latter would miss. The trade-off is
|
|
103
|
+
* that a genuine `TypeError` from a bug in the adapter also lands in
|
|
104
|
+
* `invalid-input`.
|
|
105
|
+
*/
|
|
106
|
+
export declare function failureFromError(error: unknown): AiFailure;
|
|
107
|
+
/**
|
|
108
|
+
* For the boundaries where throwing is unavoidable — React error boundaries,
|
|
109
|
+
* tests. Inside the adapter, failures travel as values.
|
|
110
|
+
*/
|
|
111
|
+
export declare class AiError extends Error {
|
|
112
|
+
readonly failure: AiFailure;
|
|
113
|
+
constructor(failure: AiFailure);
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=failures.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"failures.d.ts","sourceRoot":"","sources":["../../src/types/failures.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAK/C;;;;;;;;;;;;;;GAcG;AACH,MAAM,MAAM,SAAS,GAAG;IAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG;AACrD,mCAAmC;AACjC;IAAE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAA;CAAE;AAClC,8EAA8E;GAC5E;IAAE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAA;CAAE;AAClC;;;;GAIG;GACD;IACE,QAAQ,CAAC,IAAI,EAAE,oBAAoB,CAAC;IACpC,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,QAAQ,CAAC,UAAU,CAAC,EAAE,SAAS,QAAQ,EAAE,CAAC;CAC3C;AACH;;;;GAIG;GACD;IAAE,QAAQ,CAAC,IAAI,EAAE,mBAAmB,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE;AACjE;;;GAGG;GACD;IAAE,QAAQ,CAAC,IAAI,EAAE,kBAAkB,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAA;CAAE;AACrE,6FAA6F;GAC3F;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE;AACvD,yFAAyF;GACvF;IAAE,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE;AAC7D,iCAAiC;GAC/B;IAAE,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE;AAC7D;;;;;;;;;GASG;GACD;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE;AACpD,sDAAsD;GACpD;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACpD;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAA;CAAE,CAC/B,CAAC;AAEF,gIAAgI;AAChI,MAAM,MAAM,WAAW,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;AAE5C;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,SAAS,CA0C1D;AAED;;;GAGG;AACH,qBAAa,OAAQ,SAAQ,KAAK;IACpB,QAAQ,CAAC,OAAO,EAAE,SAAS;gBAAlB,OAAO,EAAE,SAAS;CAMxC"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where thrown exceptions enter the vocabulary: whatever a provider caught
|
|
3
|
+
* becomes an `AiFailure`, mapped by DOMException name. This is the generic
|
|
4
|
+
* half of the mapping — a provider that knows the call site refines what a
|
|
5
|
+
* name alone cannot say (see the `NotSupportedError` and
|
|
6
|
+
* `QuotaExceededError` branches).
|
|
7
|
+
*
|
|
8
|
+
* Matches on `error.name` rather than `instanceof DOMException`, because the
|
|
9
|
+
* spec throws a plain `TypeError` that the latter would miss. The trade-off is
|
|
10
|
+
* that a genuine `TypeError` from a bug in the adapter also lands in
|
|
11
|
+
* `invalid-input`.
|
|
12
|
+
*/
|
|
13
|
+
export function failureFromError(error) {
|
|
14
|
+
const errorName = error instanceof Error ? error.name : "";
|
|
15
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
16
|
+
const isDomException = typeof DOMException !== "undefined" && error instanceof DOMException;
|
|
17
|
+
switch (errorName) {
|
|
18
|
+
case "AbortError":
|
|
19
|
+
return { kind: "aborted", reason: detail, cause: error };
|
|
20
|
+
case "InvalidStateError":
|
|
21
|
+
return { kind: "invalid-state", detail, cause: error };
|
|
22
|
+
case "NotAllowedError":
|
|
23
|
+
return { kind: "not-allowed", cause: error };
|
|
24
|
+
case "NotSupportedError":
|
|
25
|
+
// The name covers both "wrong environment" and "wrong message" and
|
|
26
|
+
// cannot tell them apart; a provider that knows the call site must build
|
|
27
|
+
// `unsupported-input` itself. Empty list means "not narrowed down".
|
|
28
|
+
return { kind: "unsupported-config", languages: [], cause: error };
|
|
29
|
+
case "OperationError":
|
|
30
|
+
return { kind: "failed", detail, cause: error };
|
|
31
|
+
case "QuotaExceededError":
|
|
32
|
+
// The exception carries no measurement; a provider holding the session
|
|
33
|
+
// can refine this.
|
|
34
|
+
return {
|
|
35
|
+
kind: "context-overflow",
|
|
36
|
+
usage: { kind: "unknown" },
|
|
37
|
+
cause: error,
|
|
38
|
+
};
|
|
39
|
+
case "SyntaxError":
|
|
40
|
+
// The spec's SyntaxError is a DOMException; JSON.parse on a truncated
|
|
41
|
+
// frame throws a native one under the same name. Only the former means
|
|
42
|
+
// "the caller sent nonsense". A provider should still convert its own
|
|
43
|
+
// parse errors where they happen rather than let them reach here.
|
|
44
|
+
return isDomException
|
|
45
|
+
? { kind: "invalid-input", detail, cause: error }
|
|
46
|
+
: { kind: "failed", detail, cause: error };
|
|
47
|
+
case "TypeError":
|
|
48
|
+
// No such split available: the spec throws a native TypeError too.
|
|
49
|
+
return { kind: "invalid-input", detail, cause: error };
|
|
50
|
+
default:
|
|
51
|
+
return { kind: "unknown", cause: error };
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* For the boundaries where throwing is unavoidable — React error boundaries,
|
|
56
|
+
* tests. Inside the adapter, failures travel as values.
|
|
57
|
+
*/
|
|
58
|
+
export class AiError extends Error {
|
|
59
|
+
failure;
|
|
60
|
+
constructor(failure) {
|
|
61
|
+
// Only the kind: the details are in `failure`, and restating them as a
|
|
62
|
+
// string would create a second version of the truth.
|
|
63
|
+
super(failure.kind, { cause: failure.cause });
|
|
64
|
+
this.failure = failure;
|
|
65
|
+
this.name = "AiError";
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=failures.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"failures.js","sourceRoot":"","sources":["../../src/types/failures.ts"],"names":[],"mappings":"AAwEA;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAc;IAC7C,MAAM,SAAS,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;IAC3D,MAAM,MAAM,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACtE,MAAM,cAAc,GAClB,OAAO,YAAY,KAAK,WAAW,IAAI,KAAK,YAAY,YAAY,CAAC;IAEvE,QAAQ,SAAS,EAAE,CAAC;QAClB,KAAK,YAAY;YACf,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;QAC3D,KAAK,mBAAmB;YACtB,OAAO,EAAE,IAAI,EAAE,eAAe,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;QACzD,KAAK,iBAAiB;YACpB,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;QAC/C,KAAK,mBAAmB;YACtB,mEAAmE;YACnE,yEAAyE;YACzE,oEAAoE;YACpE,OAAO,EAAE,IAAI,EAAE,oBAAoB,EAAE,SAAS,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;QACrE,KAAK,gBAAgB;YACnB,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;QAClD,KAAK,oBAAoB;YACvB,uEAAuE;YACvE,mBAAmB;YACnB,OAAO;gBACL,IAAI,EAAE,kBAAkB;gBACxB,KAAK,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE;gBAC1B,KAAK,EAAE,KAAK;aACb,CAAC;QACJ,KAAK,aAAa;YAChB,sEAAsE;YACtE,uEAAuE;YACvE,sEAAsE;YACtE,kEAAkE;YAClE,OAAO,cAAc;gBACnB,CAAC,CAAC,EAAE,IAAI,EAAE,eAAe,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE;gBACjD,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;QAC/C,KAAK,WAAW;YACd,mEAAmE;YACnE,OAAO,EAAE,IAAI,EAAE,eAAe,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;QACzD;YACE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;IAC7C,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,OAAO,OAAQ,SAAQ,KAAK;IACX;IAArB,YAAqB,OAAkB;QACrC,uEAAuE;QACvE,qDAAqD;QACrD,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;QAH3B,YAAO,GAAP,OAAO,CAAW;QAIrC,IAAI,CAAC,IAAI,GAAG,SAAS,CAAC;IACxB,CAAC;CACF"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
declare const brand: unique symbol;
|
|
2
|
+
type Brand<T, Name extends string> = T & {
|
|
3
|
+
readonly [brand]: Name;
|
|
4
|
+
};
|
|
5
|
+
/** Non-negative integer count of context tokens. */
|
|
6
|
+
export type Tokens = Brand<number, "Tokens">;
|
|
7
|
+
export declare function tokens(value: number): Tokens | null;
|
|
8
|
+
/**
|
|
9
|
+
* 0..1, for download progress. A brand of its own, not `Tokens`: a ratio and a
|
|
10
|
+
* percentage (0.5 against 50) are both numbers, and swapping them is silent.
|
|
11
|
+
*/
|
|
12
|
+
export type Fraction = Brand<number, "Fraction">;
|
|
13
|
+
export declare function fraction(value: number): Fraction | null;
|
|
14
|
+
/** A plain object: not an array, `Date` or function. */
|
|
15
|
+
export type JsonSchema = Brand<Record<string, unknown>, "JsonSchema">;
|
|
16
|
+
export declare function jsonSchema(value: unknown): JsonSchema | null;
|
|
17
|
+
/**
|
|
18
|
+
* Success or failure as one value.
|
|
19
|
+
*
|
|
20
|
+
* The failure path is visible in the signature and cannot be skipped: until
|
|
21
|
+
* `ok` is checked, `value` is not in the type. The cost is that `Result`
|
|
22
|
+
* spreads, so keep it at the adapter boundary — inside a provider's
|
|
23
|
+
* implementation, exceptions are fine.
|
|
24
|
+
*/
|
|
25
|
+
export type Result<T, E> = {
|
|
26
|
+
readonly ok: true;
|
|
27
|
+
readonly value: T;
|
|
28
|
+
} | {
|
|
29
|
+
readonly ok: false;
|
|
30
|
+
readonly error: E;
|
|
31
|
+
};
|
|
32
|
+
export declare const ok: <T>(value: T) => Result<T, never>;
|
|
33
|
+
export declare const err: <E>(error: E) => Result<never, E>;
|
|
34
|
+
export {};
|
|
35
|
+
//# sourceMappingURL=foundations.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"foundations.d.ts","sourceRoot":"","sources":["../../src/types/foundations.ts"],"names":[],"mappings":"AAGA,OAAO,CAAC,MAAM,KAAK,EAAE,OAAO,MAAM,CAAC;AACnC,KAAK,KAAK,CAAC,CAAC,EAAE,IAAI,SAAS,MAAM,IAAI,CAAC,GAAG;IAAE,QAAQ,CAAC,CAAC,KAAK,CAAC,EAAE,IAAI,CAAA;CAAE,CAAC;AAEpE,oDAAoD;AACpD,MAAM,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;AAI7C,wBAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAInD;AAED;;;GAGG;AACH,MAAM,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;AAEjD,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI,CAEvD;AAED,wDAAwD;AACxD,MAAM,MAAM,UAAU,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,CAAC,CAAC;AAKtE,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,UAAU,GAAG,IAAI,CAU5D;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,MAAM,CAAC,CAAC,EAAE,CAAC,IACnB;IAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAA;CAAE,GACxC;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAA;CAAE,CAAC;AAI9C,eAAO,MAAM,EAAE,GAAI,CAAC,EAAE,OAAO,CAAC,KAAG,MAAM,CAAC,CAAC,EAAE,KAAK,CAA0B,CAAC;AAC3E,eAAO,MAAM,GAAG,GAAI,CAAC,EAAE,OAAO,CAAC,KAAG,MAAM,CAAC,KAAK,EAAE,CAAC,CAA2B,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// Returns null rather than throwing: the input comes from someone else's API,
|
|
2
|
+
// and the provider has to decide what to do with junk.
|
|
3
|
+
export function tokens(value) {
|
|
4
|
+
// The condition to its left is what makes this `as` honest, and the same
|
|
5
|
+
// holds for every other cast in this file.
|
|
6
|
+
return Number.isInteger(value) && value >= 0 ? value : null;
|
|
7
|
+
}
|
|
8
|
+
export function fraction(value) {
|
|
9
|
+
return value >= 0 && value <= 1 ? value : null;
|
|
10
|
+
}
|
|
11
|
+
// Narrower than `object`, which in TypeScript covers arrays, `Date` and
|
|
12
|
+
// functions — all of which reach `responseConstraint` and fail deep inside the
|
|
13
|
+
// browser. `unknown` in: a schema almost always arrives from JSON.parse.
|
|
14
|
+
export function jsonSchema(value) {
|
|
15
|
+
if (typeof value !== "object" || value === null)
|
|
16
|
+
return null;
|
|
17
|
+
// The prototype, not `Array.isArray`: `Date`, `Map` and `RegExp` are objects
|
|
18
|
+
// that pass every shape check and only fail once the browser tries to read
|
|
19
|
+
// them as a schema. What JSON.parse builds carries `Object.prototype`, and
|
|
20
|
+
// `Object.create(null)` carries none.
|
|
21
|
+
const prototype = Object.getPrototypeOf(value);
|
|
22
|
+
return prototype === Object.prototype || prototype === null
|
|
23
|
+
? value
|
|
24
|
+
: null;
|
|
25
|
+
}
|
|
26
|
+
// `never` for the other side means "cannot happen here", which lets the value
|
|
27
|
+
// slot into any Result<T, E> without naming E at the call site.
|
|
28
|
+
export const ok = (value) => ({ ok: true, value });
|
|
29
|
+
export const err = (error) => ({ ok: false, error });
|
|
30
|
+
//# sourceMappingURL=foundations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"foundations.js","sourceRoot":"","sources":["../../src/types/foundations.ts"],"names":[],"mappings":"AASA,8EAA8E;AAC9E,uDAAuD;AACvD,MAAM,UAAU,MAAM,CAAC,KAAa;IAClC,yEAAyE;IACzE,2CAA2C;IAC3C,OAAO,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,CAAE,KAAgB,CAAC,CAAC,CAAC,IAAI,CAAC;AAC1E,CAAC;AAQD,MAAM,UAAU,QAAQ,CAAC,KAAa;IACpC,OAAO,KAAK,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,CAAE,KAAkB,CAAC,CAAC,CAAC,IAAI,CAAC;AAC/D,CAAC;AAKD,wEAAwE;AACxE,+EAA+E;AAC/E,yEAAyE;AACzE,MAAM,UAAU,UAAU,CAAC,KAAc;IACvC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAC7D,6EAA6E;IAC7E,2EAA2E;IAC3E,2EAA2E;IAC3E,sCAAsC;IACtC,MAAM,SAAS,GAAY,MAAM,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;IACxD,OAAO,SAAS,KAAK,MAAM,CAAC,SAAS,IAAI,SAAS,KAAK,IAAI;QACzD,CAAC,CAAE,KAAoB;QACvB,CAAC,CAAC,IAAI,CAAC;AACX,CAAC;AAcD,8EAA8E;AAC9E,gEAAgE;AAChE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAI,KAAQ,EAAoB,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;AAC3E,MAAM,CAAC,MAAM,GAAG,GAAG,CAAI,KAAQ,EAAoB,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `system` is missing on purpose. The spec accepts a system instruction only
|
|
3
|
+
* as the very first message and throws `TypeError` otherwise; here the system
|
|
4
|
+
* text is a session option instead, so a misplaced one cannot be written.
|
|
5
|
+
*/
|
|
6
|
+
export type AiRole = "user" | "assistant";
|
|
7
|
+
export interface AiMessage {
|
|
8
|
+
readonly role: AiRole;
|
|
9
|
+
readonly content: string;
|
|
10
|
+
}
|
|
11
|
+
/** Text only for now; the other two gate model selection, not message content. */
|
|
12
|
+
export type Modality = "text" | "image" | "audio";
|
|
13
|
+
export interface ModalityExpectation {
|
|
14
|
+
readonly type: Modality;
|
|
15
|
+
/** BCP-47 tags. */
|
|
16
|
+
readonly languages?: readonly string[];
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* What the caller needs from the model. Availability depends on the request,
|
|
20
|
+
* not only on the environment — an image input or an unsupported language can
|
|
21
|
+
* make an otherwise present model unavailable — so it is asked for up front.
|
|
22
|
+
*
|
|
23
|
+
* Tools are absent because the contract has no tool support; when they arrive
|
|
24
|
+
* they belong here too, since they take part in choosing the model.
|
|
25
|
+
*/
|
|
26
|
+
export interface ModelRequest {
|
|
27
|
+
readonly inputs?: readonly ModalityExpectation[];
|
|
28
|
+
readonly outputs?: readonly ModalityExpectation[];
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=messages.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../src/types/messages.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,MAAM,MAAM,GAAG,MAAM,GAAG,WAAW,CAAC;AAE1C,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAGtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,kFAAkF;AAClF,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC;AAElD,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,mBAAmB;IACnB,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACxC;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,mBAAmB,EAAE,CAAC;IACjD,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,mBAAmB,EAAE,CAAC;CACnD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"messages.js","sourceRoot":"","sources":["../../src/types/messages.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { ModelRequest } from "./messages.js";
|
|
2
|
+
import type { ModelAccess } from "./session.js";
|
|
3
|
+
/**
|
|
4
|
+
* Free-form, because a backend written outside this package names itself and
|
|
5
|
+
* the package cannot know that name in advance.
|
|
6
|
+
*
|
|
7
|
+
* The exhaustive switch a persisted choice needs did not disappear, it moved:
|
|
8
|
+
* an app's registry is the only place the full set is known, and
|
|
9
|
+
* `src/providers/registry.ts` derives the union from it. `src/types.test-d.ts`
|
|
10
|
+
* holds one — add a member without a branch and the build breaks.
|
|
11
|
+
*/
|
|
12
|
+
export type ProviderName = string;
|
|
13
|
+
export interface AiProvider {
|
|
14
|
+
readonly name: ProviderName;
|
|
15
|
+
/**
|
|
16
|
+
* The single entry point; everything else hangs off the returned access.
|
|
17
|
+
* The request travels with it because it decides the answer: asking whether
|
|
18
|
+
* a model is available without saying what for is meaningless.
|
|
19
|
+
*/
|
|
20
|
+
readonly access: (request?: ModelRequest) => Promise<ModelAccess>;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../src/types/provider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEhD;;;;;;;;GAQG;AACH,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC;AAElC,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAC5B;;;;OAIG;IACH,QAAQ,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,EAAE,YAAY,KAAK,OAAO,CAAC,WAAW,CAAC,CAAC;CACnE"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider.js","sourceRoot":"","sources":["../../src/types/provider.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import type { JsonSchema, Result } from "./foundations.js";
|
|
2
|
+
import type { AiMessage } from "./messages.js";
|
|
3
|
+
import type { ContextUsage } from "./usage.js";
|
|
4
|
+
import type { AiFailure } from "./failures.js";
|
|
5
|
+
/**
|
|
6
|
+
* Per-session options. Modalities and tools are deliberately not here: they
|
|
7
|
+
* belong to `ModelRequest`, because they decide which model gets loaded rather
|
|
8
|
+
* than how one session behaves.
|
|
9
|
+
*/
|
|
10
|
+
export interface SessionOptions {
|
|
11
|
+
/** A field rather than a leading history entry, which is what makes a misplaced system turn unwritable. */
|
|
12
|
+
readonly system?: string;
|
|
13
|
+
readonly history?: readonly AiMessage[];
|
|
14
|
+
/** Aborts the create, including a model download in progress. */
|
|
15
|
+
readonly signal?: AbortSignal;
|
|
16
|
+
}
|
|
17
|
+
export interface GenerateOptions {
|
|
18
|
+
readonly signal?: AbortSignal;
|
|
19
|
+
/**
|
|
20
|
+
* `responseConstraint`: it constrains decoding, so the model cannot emit
|
|
21
|
+
* another shape.
|
|
22
|
+
*
|
|
23
|
+
* Honoured or refused, never ignored. A provider that cannot constrain
|
|
24
|
+
* decoding fails the call; answering anyway would hand back prose where the
|
|
25
|
+
* caller is about to run `JSON.parse`, and nothing in the Result says the
|
|
26
|
+
* constraint was dropped.
|
|
27
|
+
*/
|
|
28
|
+
readonly schema?: JsonSchema;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* One generation at a time: while a `prompt` or a `promptStream` is running,
|
|
32
|
+
* both calls fail with `busy`. A session is one transcript, and interleaving
|
|
33
|
+
* two turns into it produces a history no caller can repair; the refusal
|
|
34
|
+
* itself is `src/helpers/lifetime.ts`. Like the guarantee on `close`, this one is
|
|
35
|
+
* runtime: a type cannot say "not while that promise is pending".
|
|
36
|
+
*
|
|
37
|
+
* Callbacks are fields, not methods: `strictFunctionTypes` checks argument
|
|
38
|
+
* types strictly only on function-typed properties, while method syntax stays
|
|
39
|
+
* bivariant and would let an implementation narrow an argument.
|
|
40
|
+
*/
|
|
41
|
+
export interface AiSession extends EventTarget {
|
|
42
|
+
/**
|
|
43
|
+
* The transcript has outgrown the window, and the oldest turns are being
|
|
44
|
+
* dropped to fit the newest — silently, wherever the backend does it. Fires
|
|
45
|
+
* once: the window does not un-overflow, and every turn after the first is
|
|
46
|
+
* over the same line.
|
|
47
|
+
*
|
|
48
|
+
* An `onevent` property rather than a typed `addEventListener`, for the
|
|
49
|
+
* reason spelled out on `DownloadMonitor`. The event carries nothing: what a
|
|
50
|
+
* listener wants next is `usage()`, which is current by the time this fires.
|
|
51
|
+
*/
|
|
52
|
+
oncontextoverflow: ((event: Event) => void) | null;
|
|
53
|
+
readonly prompt: (input: string, options?: GenerateOptions) => Promise<Result<string, AiFailure>>;
|
|
54
|
+
/**
|
|
55
|
+
* A `ReadableStream`, not a bare async iterable, so the caller keeps `tee()`,
|
|
56
|
+
* `pipeThrough()` and `cancel()`.
|
|
57
|
+
*
|
|
58
|
+
* Consume it with a reader loop: async iteration of a stream is missing in
|
|
59
|
+
* Safari, and `dom.asynciterable` is deliberately left out of `lib` so the
|
|
60
|
+
* compiler rejects `for await` here. It also hides a trap — leaving such a
|
|
61
|
+
* loop with `break` cancels generation unless you iterate
|
|
62
|
+
* `stream.values({ preventCancel: true })`.
|
|
63
|
+
*
|
|
64
|
+
* Only a failure to start lands in Result; a break after the first chunk
|
|
65
|
+
* surfaces as a stream error, and that error is an `AiError` — a reader has
|
|
66
|
+
* nowhere to put a Result, so this is the one place a failure is thrown.
|
|
67
|
+
*/
|
|
68
|
+
readonly promptStream: (input: string, options?: GenerateOptions) => Promise<Result<ReadableStream<string>, AiFailure>>;
|
|
69
|
+
readonly usage: () => ContextUsage;
|
|
70
|
+
/**
|
|
71
|
+
* The conversation so far: what was handed at open, then every completed
|
|
72
|
+
* turn. An aborted or cancelled turn adds nothing, and nothing is ever
|
|
73
|
+
* dropped — `src/helpers/transcript.ts` holds both rules.
|
|
74
|
+
*
|
|
75
|
+
* It lives as long as the session does, which is one tab. Storing it is the
|
|
76
|
+
* app's, and handing it back to `open` continues the conversation where it
|
|
77
|
+
* was — that round trip is how a reload is survived, not this array. Each
|
|
78
|
+
* call is a snapshot: later turns do not write into one already handed out.
|
|
79
|
+
*/
|
|
80
|
+
readonly history: () => readonly AiMessage[];
|
|
81
|
+
/**
|
|
82
|
+
* In-flight and later calls fail with `aborted`, matching `destroy()`.
|
|
83
|
+
*
|
|
84
|
+
* Types cannot carry that guarantee — a value cannot be spent in TypeScript,
|
|
85
|
+
* so the old reference stays valid. Stating it as a runtime guarantee is
|
|
86
|
+
* honest; pretending the types hold it would not be.
|
|
87
|
+
*/
|
|
88
|
+
readonly close: () => void;
|
|
89
|
+
}
|
|
90
|
+
type OpenSession = (options?: SessionOptions) => Promise<Result<AiSession, AiFailure>>;
|
|
91
|
+
/**
|
|
92
|
+
* The download monitor, shaped after the spec's `CreateMonitor`: an
|
|
93
|
+
* `EventTarget` firing `downloadprogress` with a `ProgressEvent`. The browser's
|
|
94
|
+
* own monitor satisfies this too, so a Prompt API provider can hand its one
|
|
95
|
+
* through — `src/types.test-d.ts` checks that against the ambient declaration.
|
|
96
|
+
* `src/helpers/monitor.ts` is the implementation for a provider with no browser
|
|
97
|
+
* behind it.
|
|
98
|
+
*
|
|
99
|
+
* `ondownloadprogress` is the whole surface because it is the only typed way
|
|
100
|
+
* in. An `addEventListener` overload narrowed to `downloadprogress` does not
|
|
101
|
+
* survive extending `EventTarget`: the inherited listener parameter is
|
|
102
|
+
* `EventListener`, a listener taking a `ProgressEvent` is not one, and neither
|
|
103
|
+
* this interface's implementations nor the ambient `CreateMonitor` then satisfy
|
|
104
|
+
* it (TS2420 and TS2322, measured). A caller wanting several listeners uses
|
|
105
|
+
* `addEventListener` and casts the event.
|
|
106
|
+
*
|
|
107
|
+
* What a provider owes a listener: `loaded` is 0..1, never decreasing, and
|
|
108
|
+
* `total` is 1 — see `DownloadProgressEvent` for where that normalization
|
|
109
|
+
* comes from, and `Fraction` for what carries it.
|
|
110
|
+
*/
|
|
111
|
+
export interface DownloadMonitor extends EventTarget {
|
|
112
|
+
ondownloadprogress: ((event: ProgressEvent) => void) | null;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Availability and session creation are one value, not two calls. `open`
|
|
116
|
+
* exists only on the variants where opening can work, so "create a session
|
|
117
|
+
* from an unavailable model" is not a mistake to guard against — it is
|
|
118
|
+
* unwritable.
|
|
119
|
+
*/
|
|
120
|
+
export type ModelAccess = {
|
|
121
|
+
readonly kind: "unavailable";
|
|
122
|
+
readonly reason: AiFailure;
|
|
123
|
+
} | {
|
|
124
|
+
readonly kind: "ready";
|
|
125
|
+
readonly open: OpenSession;
|
|
126
|
+
} | {
|
|
127
|
+
readonly kind: "needs-download";
|
|
128
|
+
/** True when another caller already started the fetch (`downloading` in the spec). */
|
|
129
|
+
readonly started: boolean;
|
|
130
|
+
/**
|
|
131
|
+
* The monitor is the first argument and required: this is the one branch
|
|
132
|
+
* where weights are certainly being fetched, and a silent download of
|
|
133
|
+
* hundreds of megabytes reads as a frozen UI.
|
|
134
|
+
*
|
|
135
|
+
* A callback handed the monitor, not a monitor handed back, and it runs
|
|
136
|
+
* before `open` awaits anything — subscribing after the promise settles
|
|
137
|
+
* is subscribing after the download. The spec's `monitor` option works
|
|
138
|
+
* the same way and for the same reason.
|
|
139
|
+
*/
|
|
140
|
+
readonly open: (monitor: (monitor: DownloadMonitor) => void, options?: SessionOptions) => Promise<Result<AiSession, AiFailure>>;
|
|
141
|
+
};
|
|
142
|
+
/**
|
|
143
|
+
* The three answers, under a name — for a `Record` keyed by them, or a
|
|
144
|
+
* signature that takes the answer without the payload. Derived, so a fourth
|
|
145
|
+
* variant extends it rather than being forgotten here.
|
|
146
|
+
*
|
|
147
|
+
* A type and not an enum, which is the point: `"ready"` still passes wherever
|
|
148
|
+
* one of these is asked for, so a caller keeps writing literals and importing
|
|
149
|
+
* nothing, and none of it reaches their bundle. An enum would be a value, and
|
|
150
|
+
* a nominal one — a caller's own `"ready"` would stop being assignable.
|
|
151
|
+
* `FailureKind` and `UsageKind` are the same for the other two unions worth
|
|
152
|
+
* switching on.
|
|
153
|
+
*/
|
|
154
|
+
export type AccessKind = ModelAccess["kind"];
|
|
155
|
+
export {};
|
|
156
|
+
//# sourceMappingURL=session.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/types/session.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE/C;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC7B,2GAA2G;IAC3G,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAGzB,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,SAAS,EAAE,CAAC;IACxC,iEAAiE;IACjE,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;CAC/B;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;IAC9B;;;;;;;;OAQG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,UAAU,CAAC;CAC9B;AAED;;;;;;;;;;GAUG;AACH,MAAM,WAAW,SAAU,SAAQ,WAAW;IAC5C;;;;;;;;;OASG;IACH,iBAAiB,EAAE,CAAC,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC;IACnD,QAAQ,CAAC,MAAM,EAAE,CACf,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE,eAAe,KACtB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC;IACxC;;;;;;;;;;;;;OAaG;IACH,QAAQ,CAAC,YAAY,EAAE,CACrB,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE,eAAe,KACtB,OAAO,CAAC,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC;IACxD,QAAQ,CAAC,KAAK,EAAE,MAAM,YAAY,CAAC;IACnC;;;;;;;;;OASG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,SAAS,SAAS,EAAE,CAAC;IAC7C;;;;;;OAMG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,IAAI,CAAC;CAC5B;AAED,KAAK,WAAW,GAAG,CACjB,OAAO,CAAC,EAAE,cAAc,KACrB,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC;AAE3C;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,WAAW,eAAgB,SAAQ,WAAW;IAClD,kBAAkB,EAAE,CAAC,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC;CAC7D;AAED;;;;;GAKG;AACH,MAAM,MAAM,WAAW,GAGnB;IAAE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAA;CAAE,GAC5D;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAA;CAAE,GACtD;IACE,QAAQ,CAAC,IAAI,EAAE,gBAAgB,CAAC;IAChC,sFAAsF;IACtF,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B;;;;;;;;;OASG;IACH,QAAQ,CAAC,IAAI,EAAE,CACb,OAAO,EAAE,CAAC,OAAO,EAAE,eAAe,KAAK,IAAI,EAC3C,OAAO,CAAC,EAAE,cAAc,KACrB,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC;CAC5C,CAAC;AAEN;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,UAAU,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/types/session.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { type Tokens } from "./foundations.js";
|
|
2
|
+
/**
|
|
3
|
+
* Context accounting in tokens.
|
|
4
|
+
*
|
|
5
|
+
* `unbounded` is a separate variant because the Prompt API reports `Infinity`
|
|
6
|
+
* there; as a plain number it would flow into `total - used` and produce a
|
|
7
|
+
* `remaining` that looks meaningful. `unknown` covers providers that expose no
|
|
8
|
+
* budget at all, which is cheaper than a `null` case at every call site.
|
|
9
|
+
*/
|
|
10
|
+
export type ContextUsage = {
|
|
11
|
+
readonly kind: "unknown";
|
|
12
|
+
} | {
|
|
13
|
+
readonly kind: "unbounded";
|
|
14
|
+
readonly used: Tokens;
|
|
15
|
+
} | {
|
|
16
|
+
readonly kind: "bounded";
|
|
17
|
+
readonly used: Tokens;
|
|
18
|
+
readonly total: Tokens;
|
|
19
|
+
readonly remaining: Tokens;
|
|
20
|
+
};
|
|
21
|
+
/** Which of the three a measurement is, under a name; as `AccessKind` in `./session.ts`. */
|
|
22
|
+
export type UsageKind = ContextUsage["kind"];
|
|
23
|
+
/** The checked way to build one: no fractional total, no negative `remaining`. */
|
|
24
|
+
export declare function contextUsage(used: Tokens, total: number): ContextUsage;
|
|
25
|
+
//# sourceMappingURL=usage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"usage.d.ts","sourceRoot":"","sources":["../../src/types/usage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,KAAK,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAEvD;;;;;;;GAOG;AACH,MAAM,MAAM,YAAY,GACpB;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAA;CAAE,GAC5B;IAAE,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACrD;IACE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B,CAAC;AAEN,4FAA4F;AAC5F,MAAM,MAAM,SAAS,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;AAE7C,kFAAkF;AAClF,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,YAAY,CAUtE"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { tokens } from "./foundations.js";
|
|
2
|
+
/** The checked way to build one: no fractional total, no negative `remaining`. */
|
|
3
|
+
export function contextUsage(used, total) {
|
|
4
|
+
if (total === Infinity)
|
|
5
|
+
return { kind: "unbounded", used };
|
|
6
|
+
// Usage is allowed to pass the window — that is what fires `contextoverflow`
|
|
7
|
+
// — but "minus three tokens left" is not a value worth carrying.
|
|
8
|
+
const remaining = tokens(Math.max(0, total - used));
|
|
9
|
+
const totalTokens = tokens(total);
|
|
10
|
+
// A fractional or negative total means the API returned something
|
|
11
|
+
// unexpected; saying "unknown" beats inventing a number.
|
|
12
|
+
if (totalTokens === null || remaining === null)
|
|
13
|
+
return { kind: "unknown" };
|
|
14
|
+
return { kind: "bounded", used, total: totalTokens, remaining };
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=usage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"usage.js","sourceRoot":"","sources":["../../src/types/usage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAe,MAAM,kBAAkB,CAAC;AAuBvD,kFAAkF;AAClF,MAAM,UAAU,YAAY,CAAC,IAAY,EAAE,KAAa;IACtD,IAAI,KAAK,KAAK,QAAQ;QAAE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC;IAC3D,6EAA6E;IAC7E,iEAAiE;IACjE,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC;IACpD,MAAM,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAClC,kEAAkE;IAClE,yDAAyD;IACzD,IAAI,WAAW,KAAK,IAAI,IAAI,SAAS,KAAK,IAAI;QAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;IAC3E,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,CAAC;AAClE,CAAC"}
|