@theokit/agents 7.6.0 → 8.0.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 (52) hide show
  1. package/dist/{agent-handle-BX4oFqfb.d.ts → agent-handle-Dgi4ZGbg.d.ts} +11 -1
  2. package/dist/ask.d.ts +190 -0
  3. package/dist/ask.js +167 -0
  4. package/dist/ask.js.map +1 -0
  5. package/dist/auth.d.ts +95 -1
  6. package/dist/auth.js +83 -0
  7. package/dist/auth.js.map +1 -1
  8. package/dist/{bridge-entry-CvmBrmc9.d.ts → bridge-entry-BEniSXWE.d.ts} +223 -700
  9. package/dist/bridge.d.ts +6 -3
  10. package/dist/bridge.js +16 -8
  11. package/dist/chunk-4VHCH6IZ.js +181 -0
  12. package/dist/chunk-4VHCH6IZ.js.map +1 -0
  13. package/dist/{chunk-22IPZFVT.js → chunk-C7UXZWVY.js} +167 -207
  14. package/dist/chunk-C7UXZWVY.js.map +1 -0
  15. package/dist/{chunk-2BAFKRXT.js → chunk-M6HMASZC.js} +9 -4
  16. package/dist/chunk-M6HMASZC.js.map +1 -0
  17. package/dist/client-react.d.ts +2 -1
  18. package/dist/client-react.js +1 -1
  19. package/dist/client.d.ts +3 -2
  20. package/dist/client.js +1 -1
  21. package/dist/commands.d.ts +120 -0
  22. package/dist/commands.js +145 -0
  23. package/dist/commands.js.map +1 -0
  24. package/dist/define-agent-3Kuf6iKM.d.ts +633 -0
  25. package/dist/doctor.d.ts +119 -0
  26. package/dist/doctor.js +84 -0
  27. package/dist/doctor.js.map +1 -0
  28. package/dist/hook-handlers-Cw2FsnE5.d.ts +56 -0
  29. package/dist/hooks.d.ts +225 -0
  30. package/dist/hooks.js +286 -0
  31. package/dist/hooks.js.map +1 -0
  32. package/dist/index.d.ts +170 -26
  33. package/dist/index.js +90 -22
  34. package/dist/index.js.map +1 -1
  35. package/dist/mcp-health.d.ts +69 -0
  36. package/dist/mcp-health.js +42 -0
  37. package/dist/mcp-health.js.map +1 -0
  38. package/dist/session.d.ts +238 -0
  39. package/dist/session.js +338 -0
  40. package/dist/session.js.map +1 -0
  41. package/dist/testing.d.ts +90 -1
  42. package/dist/testing.js +76 -1
  43. package/dist/testing.js.map +1 -1
  44. package/dist/tool-scope.d.ts +133 -0
  45. package/dist/tool-scope.js +61 -0
  46. package/dist/tool-scope.js.map +1 -0
  47. package/dist/usage.d.ts +98 -0
  48. package/dist/usage.js +55 -0
  49. package/dist/usage.js.map +1 -0
  50. package/package.json +34 -2
  51. package/dist/chunk-22IPZFVT.js.map +0 -1
  52. package/dist/chunk-2BAFKRXT.js.map +0 -1
@@ -1,4 +1,5 @@
1
1
  import { WireTransport, WireChunk, WireMessage } from '@theokit/presenter/wire';
2
+ import { TheokitAgentError } from '@theokit/sdk/errors';
2
3
 
3
4
  /**
4
5
  * M41 (ADR-0050 D2) — a HITL approval decision sent to settle a paused gated-tool call. Mirrors the
@@ -90,8 +91,17 @@ interface InProcessTransportOptions {
90
91
  * M92 — typed on purpose. Before, the promise simply **never** settled and the SDK tool call hung;
91
92
  * `resolve(false)` would be worse still, because it is indistinguishable from "the user denied".
92
93
  */
93
- declare class ApprovalAbortedError extends Error {
94
+ /**
95
+ * M80 — extends {@link TheokitAgentError}, not plain `Error`.
96
+ *
97
+ * `isTransientError` is defined over `TheokitAgentError`, so a class outside that hierarchy is
98
+ * INVISIBLE to it and the only recourse left to a consumer is matching on message text. `code` is
99
+ * stable across a rename; `isRetryable` is DECLARED, because a default would be a retry policy
100
+ * nobody chose.
101
+ */
102
+ declare class ApprovalAbortedError extends TheokitAgentError {
94
103
  readonly approvalId: string;
104
+ readonly name = "ApprovalAbortedError";
95
105
  constructor(approvalId: string, reason: string);
96
106
  }
97
107
  declare class InProcessTransport implements AgentTransport {
package/dist/ask.d.ts ADDED
@@ -0,0 +1,190 @@
1
+ import { TheokitAgentError } from '@theokit/sdk/errors';
2
+
3
+ /**
4
+ * M77 — the ask channel: the agent asks, a human answers, the turn waits.
5
+ *
6
+ * ## The asymmetry this closes
7
+ *
8
+ * "Pause the turn for a human" existed only for tool APPROVAL. Its sibling — the agent asking a
9
+ * question mid-turn — had a tool and no channel: the SDK's `createQuestionTool` takes an `askUser`
10
+ * callback (preferring `ctx.context.askUser`), and nothing in this layer ever supplied one. A tool
11
+ * that cannot reach a human is a tool that times out, five minutes later, with no diagnosis.
12
+ *
13
+ * ## Why this is framework and not runtime
14
+ *
15
+ * It makes no model call, dispatches no tool and stores no conversation. It is a rendezvous between
16
+ * a paused turn and a surface — the "home the agent lives in" (ADR 0038 / ADR-0040 § D2), the same
17
+ * category as the approval gate this is modelled on.
18
+ *
19
+ * ## Modelled on `ApprovalRegistry`, deliberately
20
+ *
21
+ * That registry already solved this exact problem for approvals: hold the live resolver in memory,
22
+ * settle it from outside, and keep ONE instance per process because the promise being awaited and
23
+ * the promise being settled must be the same object. Inventing a second shape for the same problem
24
+ * would be the duplication G12 forbids. What differs is the key — a thread, not an approval id —
25
+ * because a question belongs to a conversation and a surface renders one at a time.
26
+ *
27
+ * ## What it refuses, and why refusing beats resolving
28
+ *
29
+ * Two questions on one thread have no coherent UI: the answer cannot be attributed to either. Two
30
+ * listeners on one thread means the prompt is rendered twice and answered by whoever wins. Both are
31
+ * refused with a typed error rather than resolved by picking a winner — silently replacing a
32
+ * listener makes the first surface go deaf with no signal at all.
33
+ */
34
+ /** Raised when a thread already has a question in flight. */
35
+ declare class ConcurrentQuestionError extends TheokitAgentError {
36
+ readonly name = "ConcurrentQuestionError";
37
+ constructor(threadId: string);
38
+ }
39
+ /** Raised when a thread already has a listener attached. */
40
+ declare class ConcurrentListenerError extends TheokitAgentError {
41
+ readonly name = "ConcurrentListenerError";
42
+ constructor(threadId: string);
43
+ }
44
+ /**
45
+ * Raised when a pending question will never be answered — the run was cancelled, the surface
46
+ * detached, or nobody was listening in the first place.
47
+ */
48
+ declare class QuestionAbandonedError extends TheokitAgentError {
49
+ readonly name = "QuestionAbandonedError";
50
+ constructor(threadId: string, why: string);
51
+ }
52
+ /** A question as it reaches the surface. */
53
+ interface PendingQuestion {
54
+ /** Correlates {@link AskBridge.answer} with the promise the tool is awaiting. */
55
+ readonly id: string;
56
+ /** The thread the question belongs to. */
57
+ readonly threadId: string;
58
+ /** What to show the human. */
59
+ readonly question: string;
60
+ }
61
+ /** Extra hooks a surface may attach alongside its listener. */
62
+ interface ListenerOptions {
63
+ /**
64
+ * Called when a pending question is abandoned, so the surface can release its slot.
65
+ *
66
+ * Without it, cancelling a run leaves the prompt on screen waiting for an answer nobody awaits —
67
+ * and the next question fails with "one already pending" against a question that is gone.
68
+ */
69
+ readonly onAbandon?: (threadId: string) => void;
70
+ }
71
+ /** Detaches a listener. Calling it twice is harmless. */
72
+ type DisposeListener = () => void;
73
+ interface AskBridge {
74
+ /**
75
+ * Ask, and resolve when a human answers.
76
+ *
77
+ * Rejects — never hangs — when there is no listener, when the thread is already asking, or when
78
+ * the question is abandoned. Hanging is the failure this module exists to remove.
79
+ */
80
+ ask(threadId: string, question: string): Promise<string>;
81
+ /** Settle a pending question. `false` when the id is unknown or already settled. */
82
+ answer(id: string, answer: string): boolean;
83
+ /** Reject whatever is pending on a thread. `false` when nothing was pending. */
84
+ abandon(threadId: string): boolean;
85
+ /** Attach the surface that renders questions for a thread. */
86
+ setListener(threadId: string, listener: (question: PendingQuestion) => void, options?: ListenerOptions): DisposeListener;
87
+ }
88
+ /**
89
+ * Build a bridge.
90
+ *
91
+ * A factory rather than a class with a process singleton baked in: tests get a fresh instance, and
92
+ * the surface that owns the process decides where the shared one lives — exactly the shape
93
+ * `createInProcessApprovalRegistry` established.
94
+ */
95
+ declare function createAskBridge(): AskBridge;
96
+
97
+ /**
98
+ * M77 — the client-side ledger of pending human decisions.
99
+ *
100
+ * ## Why a surface needs this at all
101
+ *
102
+ * The framework's own lookup is STATELESS. `ApprovalRegistry.list()` answers "what is pending right
103
+ * now", and nothing remembers what a surface already showed or already answered. Two defects fall
104
+ * straight out of that, and the consumer that prompted this milestone hit both:
105
+ *
106
+ * - **the dismissed card comes back** — the surface polls again, the same approval is still in the
107
+ * list, and it renders a second time;
108
+ * - **a second answer is sent for an already-answered request** — the user clicks twice, or two
109
+ * surfaces answer, and the second send is a decision nobody made.
110
+ *
111
+ * Both are memory problems, and memory is the surface's to keep. Making the registry remember what
112
+ * each surface has seen would put per-client state inside a process-wide primitive.
113
+ *
114
+ * ## What this deliberately is not
115
+ *
116
+ * No policy. It never decides whether to approve, never talks to the registry, never knows what an
117
+ * approval means. It is bookkeeping over ids — which is why it is a pure function of its own state
118
+ * and tested without a mock.
119
+ */
120
+ /** A decision waiting for a human, as the surface knows it. */
121
+ interface PendingItem {
122
+ /** The framework's id for the decision (an approval id, a question id). */
123
+ readonly id: string;
124
+ /**
125
+ * Where in the conversation it belongs.
126
+ *
127
+ * Ordering key AND pruning key: a surface shows the oldest first, and a rewind invalidates
128
+ * everything attached to messages that no longer exist.
129
+ */
130
+ readonly messageIndex: number;
131
+ }
132
+ interface PendingLedger {
133
+ /**
134
+ * Record what the framework reports as pending.
135
+ *
136
+ * Additive and idempotent: the same list arrives on every poll. An id already settled is NOT
137
+ * re-added — that single rule is what stops the dismissed card from coming back.
138
+ */
139
+ ingest(items: readonly PendingItem[]): void;
140
+ /**
141
+ * Mark one as answered. `false` when it was unknown or already settled.
142
+ *
143
+ * The caller uses that boolean to decide whether to SEND: returning `true` twice would send a
144
+ * decision the user made once, twice.
145
+ */
146
+ settle(id: string): boolean;
147
+ /** The oldest unsettled item, or `undefined`. A surface shows one at a time. */
148
+ findNext(): PendingItem | undefined;
149
+ /**
150
+ * Forget everything attached to a message before `messageIndex`, settled or not. Returns how many
151
+ * unsettled items were dropped.
152
+ *
153
+ * The cutoff is the first index that STILL EXISTS, so an item sitting exactly on it survives.
154
+ */
155
+ pruneBefore(messageIndex: number): number;
156
+ }
157
+ declare function createPendingLedger(): PendingLedger;
158
+
159
+ /**
160
+ * M77 — adapt an {@link AskBridge} to the `askUser` shape the question tool expects.
161
+ *
162
+ * ## Why an adapter and not a re-export
163
+ *
164
+ * The two signatures genuinely differ, and not cosmetically:
165
+ *
166
+ * | | question tool | {@link AskBridge} |
167
+ * |---|---|---|
168
+ * | shape | `(question, threadId?) => Promise<string>` | `(threadId, question) => Promise<string>` |
169
+ * | thread | optional | required — it is the routing key |
170
+ *
171
+ * The tool's `threadId` is optional because the tool cannot know whether the surface tracks threads.
172
+ * The bridge's is required because a question with no thread has no listener to reach: the channel
173
+ * routes BY thread, and "ask whoever" is not a destination.
174
+ *
175
+ * That mismatch is the whole reason this function exists. Writing the flip at each call site is how
176
+ * the argument order eventually gets swapped somewhere and a question is asked with the thread id as
177
+ * its text.
178
+ *
179
+ * ## What it does with a missing thread
180
+ *
181
+ * Rejects, naming the cause. The alternative — pick a default thread, or ask the most recent
182
+ * listener — routes a human question to a conversation it does not belong to, which is worse than
183
+ * failing: the answer comes back attributed to the wrong turn.
184
+ *
185
+ * Pass it as `askUser` when building the question tool, or put it on the run context as
186
+ * `ctx.context.askUser`, which the tool prefers.
187
+ */
188
+ declare function askUserVia(bridge: AskBridge): (question: string, threadId?: string) => Promise<string>;
189
+
190
+ export { type AskBridge, ConcurrentListenerError, ConcurrentQuestionError, type DisposeListener, type ListenerOptions, type PendingItem, type PendingLedger, type PendingQuestion, QuestionAbandonedError, askUserVia, createAskBridge, createPendingLedger };
package/dist/ask.js ADDED
@@ -0,0 +1,167 @@
1
+ import {
2
+ __name
3
+ } from "./chunk-Z4QWC7IK.js";
4
+
5
+ // src/ask/ask-bridge.ts
6
+ import { TheokitAgentError } from "@theokit/sdk/errors";
7
+ var ConcurrentQuestionError = class extends TheokitAgentError {
8
+ static {
9
+ __name(this, "ConcurrentQuestionError");
10
+ }
11
+ name = "ConcurrentQuestionError";
12
+ constructor(threadId) {
13
+ super(`thread "${threadId}" already has a question awaiting an answer. A surface renders one question at a time, and a second one in flight cannot be attributed to an answer. Answer or abandon the first.`);
14
+ }
15
+ };
16
+ var ConcurrentListenerError = class extends TheokitAgentError {
17
+ static {
18
+ __name(this, "ConcurrentListenerError");
19
+ }
20
+ name = "ConcurrentListenerError";
21
+ constructor(threadId) {
22
+ super(`thread "${threadId}" already has a question listener. Two listeners render the prompt twice and race to answer it. Dispose the first (call the function \`setListener\` returned) before attaching another.`);
23
+ }
24
+ };
25
+ var QuestionAbandonedError = class extends TheokitAgentError {
26
+ static {
27
+ __name(this, "QuestionAbandonedError");
28
+ }
29
+ name = "QuestionAbandonedError";
30
+ constructor(threadId, why) {
31
+ super(`question on thread "${threadId}" was abandoned: ${why}`);
32
+ }
33
+ };
34
+ function createAskBridge() {
35
+ const pendingByThread = /* @__PURE__ */ new Map();
36
+ const pendingById = /* @__PURE__ */ new Map();
37
+ const listeners = /* @__PURE__ */ new Map();
38
+ const forget = /* @__PURE__ */ __name((threadId, id) => {
39
+ pendingByThread.delete(threadId);
40
+ pendingById.delete(id);
41
+ }, "forget");
42
+ return {
43
+ ask(threadId, question) {
44
+ if (pendingByThread.has(threadId)) {
45
+ return Promise.reject(new ConcurrentQuestionError(threadId));
46
+ }
47
+ const listener = listeners.get(threadId);
48
+ if (listener === void 0) {
49
+ return Promise.reject(new QuestionAbandonedError(threadId, "no surface is listening on this thread"));
50
+ }
51
+ const id = crypto.randomUUID();
52
+ const promise = new Promise((resolve, reject) => {
53
+ const entry = {
54
+ id,
55
+ settle: /* @__PURE__ */ __name((answer) => {
56
+ forget(threadId, id);
57
+ resolve(answer);
58
+ }, "settle"),
59
+ fail: /* @__PURE__ */ __name((error) => {
60
+ forget(threadId, id);
61
+ reject(error);
62
+ }, "fail")
63
+ };
64
+ pendingByThread.set(threadId, entry);
65
+ pendingById.set(id, {
66
+ ...entry,
67
+ threadId
68
+ });
69
+ });
70
+ listener.notify({
71
+ id,
72
+ threadId,
73
+ question
74
+ });
75
+ return promise;
76
+ },
77
+ answer(id, answer) {
78
+ const entry = pendingById.get(id);
79
+ if (entry === void 0) return false;
80
+ entry.settle(answer);
81
+ return true;
82
+ },
83
+ abandon(threadId) {
84
+ const entry = pendingByThread.get(threadId);
85
+ if (entry === void 0) return false;
86
+ entry.fail(new QuestionAbandonedError(threadId, "the run was cancelled or the surface detached"));
87
+ listeners.get(threadId)?.onAbandon?.(threadId);
88
+ return true;
89
+ },
90
+ setListener(threadId, listener, options) {
91
+ if (listeners.has(threadId)) throw new ConcurrentListenerError(threadId);
92
+ const entry = {
93
+ notify: listener,
94
+ ...options?.onAbandon !== void 0 && {
95
+ onAbandon: options.onAbandon
96
+ }
97
+ };
98
+ listeners.set(threadId, entry);
99
+ return () => {
100
+ if (listeners.get(threadId) === entry) listeners.delete(threadId);
101
+ };
102
+ }
103
+ };
104
+ }
105
+ __name(createAskBridge, "createAskBridge");
106
+
107
+ // src/ask/pending-ledger.ts
108
+ function createPendingLedger() {
109
+ const open = /* @__PURE__ */ new Map();
110
+ const settled = /* @__PURE__ */ new Map();
111
+ return {
112
+ ingest(items) {
113
+ for (const item of items) {
114
+ if (settled.has(item.id) || open.has(item.id)) continue;
115
+ open.set(item.id, item);
116
+ }
117
+ },
118
+ settle(id) {
119
+ const item = open.get(id);
120
+ if (item === void 0) return false;
121
+ open.delete(id);
122
+ settled.set(id, item.messageIndex);
123
+ return true;
124
+ },
125
+ findNext() {
126
+ let oldest;
127
+ for (const item of open.values()) {
128
+ if (oldest === void 0 || item.messageIndex < oldest.messageIndex) oldest = item;
129
+ }
130
+ return oldest;
131
+ },
132
+ pruneBefore(messageIndex) {
133
+ let dropped = 0;
134
+ for (const [id, item] of open) {
135
+ if (item.messageIndex < messageIndex) {
136
+ open.delete(id);
137
+ dropped += 1;
138
+ }
139
+ }
140
+ for (const [id, at] of settled) {
141
+ if (at < messageIndex) settled.delete(id);
142
+ }
143
+ return dropped;
144
+ }
145
+ };
146
+ }
147
+ __name(createPendingLedger, "createPendingLedger");
148
+
149
+ // src/ask/ask-user-via.ts
150
+ function askUserVia(bridge) {
151
+ return (question, threadId) => {
152
+ if (threadId === void 0 || threadId === "") {
153
+ return Promise.reject(new QuestionAbandonedError("(none)", "the question tool was invoked without a thread id, and the ask channel routes by thread \u2014 there is no surface to reach. Pass the thread id through the run context."));
154
+ }
155
+ return bridge.ask(threadId, question);
156
+ };
157
+ }
158
+ __name(askUserVia, "askUserVia");
159
+ export {
160
+ ConcurrentListenerError,
161
+ ConcurrentQuestionError,
162
+ QuestionAbandonedError,
163
+ askUserVia,
164
+ createAskBridge,
165
+ createPendingLedger
166
+ };
167
+ //# sourceMappingURL=ask.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/ask/ask-bridge.ts","../src/ask/pending-ledger.ts","../src/ask/ask-user-via.ts"],"mappings":"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","names":["TheokitAgentError","ConcurrentQuestionError","TheokitAgentError","name","threadId","ConcurrentListenerError","QuestionAbandonedError","why","createAskBridge","pendingByThread","Map","pendingById","listeners","forget","id","delete","ask","question","has","Promise","reject","listener","get","undefined","crypto","randomUUID","promise","resolve","entry","settle","answer","fail","error","set","notify","abandon","onAbandon","setListener","options","createPendingLedger","open","Map","settled","ingest","items","item","has","id","set","settle","get","undefined","delete","messageIndex","findNext","oldest","values","pruneBefore","dropped","at","askUserVia","bridge","question","threadId","undefined","Promise","reject","QuestionAbandonedError","ask"]}
package/dist/auth.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { OAuthProviderConfig, CredentialStoreConfig, ResolvedCredential, ensureFreshCredential, OpenAIDeviceConfig, openaiDeviceLogin, OAuthTokens, DeviceDeps } from '@theokit/sdk/auth';
2
2
  export { CredentialError, CredentialStoreConfig, DeviceCodeGrant, DeviceDeps, DeviceOAuthConfig, OAuthProviderConfig, OAuthTokens, OpenAIDeviceConfig, ResolveCredentialOptions, ResolvedCredential, assertSecureModes, authFilePath, credentialHome, deviceLogin, ensureFreshCredential, extractAccountId, openaiDeviceLogin, persistOAuthTokens, pollDeviceToken, readAuthFile, readStoredOAuth, refreshOAuthTokens, requestDeviceCode, writeCredential } from '@theokit/sdk/auth';
3
+ import { TheokitAgentError } from '@theokit/sdk/errors';
3
4
 
4
5
  /**
5
6
  * M60 — `AuthProvider`, the OO contract that unifies the SDK's free OAuth-lifecycle functions
@@ -168,4 +169,97 @@ declare function loginWithDevice(provider: DeviceAuthProvider, method: AuthMetho
168
169
  accountId?: string;
169
170
  }>;
170
171
 
171
- export { type AuthMethod, AuthProvider, CODEX_CLIENT_ID_ENV_VAR, CODEX_PROVIDER, type DeviceAuthProvider, type PromptHooks, loginWithDevice };
172
+ /**
173
+ * M79 — "given an env, a home and a model, WHICH credential do I use, and WHERE did it come from?"
174
+ *
175
+ * ## The gap this closes
176
+ *
177
+ * The genuinely hard half was already supplied: RFC 8628 device flow, refresh under a cross-process
178
+ * lock, persistence, account-id extraction. The half every consumer meets FIRST was answered twice
179
+ * inside the framework and exposed neither time — `resolveProvider()` locked behind
180
+ * `internal-api.ts`, and `resolveCredential` deliberately withheld from `@theokit/agents/auth`.
181
+ *
182
+ * The "app policy" framing defends **which** providers exist. It does not defend the precedence
183
+ * chain, the prefix↔provider consistency check, or the provenance record: those are mechanism. A
184
+ * consumer forced to rewrite mechanism wrote a 70-line dotenv parser for the single question "shell
185
+ * or `.env`?".
186
+ *
187
+ * ## Why the descriptors are a PARAMETER, and why this name is safe here
188
+ *
189
+ * Two functions already share the name `resolveCredential` with divergent semantics — sync vs async,
190
+ * throws vs `undefined`, reads env vs does not, infers the provider vs refuses — which is exactly
191
+ * why `auth-entry.ts` withholds the SDK's. A third under the same name in the same scope would
192
+ * invite importing the wrong one.
193
+ *
194
+ * Taking the descriptor list as an ARGUMENT is what makes this one distinguishable at the call site
195
+ * rather than by luck: it is the only one whose signature says which providers it is talking about.
196
+ * The SDK's symbol stays unexported from this subpath, so only one is reachable.
197
+ */
198
+ /** Where a credential came from — data, so provenance is formatting rather than parsing. */
199
+ type SourceOrigin = {
200
+ readonly kind: 'env';
201
+ readonly varName: string;
202
+ } | {
203
+ readonly kind: 'file';
204
+ readonly path: string;
205
+ } | {
206
+ readonly kind: 'oauth';
207
+ readonly provider: string;
208
+ };
209
+ /** One provider the app is willing to use. WHICH providers exist stays app policy. */
210
+ interface ProviderDescriptor {
211
+ /** Name used in provenance, telemetry and messages. */
212
+ readonly name: string;
213
+ /** Environment variable carrying the API key. */
214
+ readonly envKey: string;
215
+ /** Lower wins. Declared, so the caller's array order is not a hidden second policy. */
216
+ readonly priority: number;
217
+ /** Model-id prefix this provider claims (`openai/`). Absent ⇒ it claims none. */
218
+ readonly modelPrefix?: string;
219
+ }
220
+ /**
221
+ * The answer, with its provenance attached.
222
+ *
223
+ * NOT called `ResolvedCredential`: the SDK already publishes a type under that name from this same
224
+ * subpath, and the collision surfaced the moment this shipped. Two shapes sharing one name in one
225
+ * scope is the failure this whole milestone is about — so the name says what it is, a resolution.
226
+ */
227
+ interface CredentialResolution {
228
+ readonly kind: 'api-key' | 'oauth';
229
+ readonly provider: string;
230
+ readonly apiKey: string;
231
+ readonly source: SourceOrigin;
232
+ /**
233
+ * Whether the resolver PICKED the provider rather than the caller naming it.
234
+ *
235
+ * Without this, "why is it calling Anthropic?" has no answer in the data — the caller cannot tell
236
+ * a user's explicit choice from a precedence fallback.
237
+ */
238
+ readonly inferred: boolean;
239
+ }
240
+ /** Raised when the model's prefix names a provider that has no credential. */
241
+ declare class ProviderPrefixMismatchError extends TheokitAgentError {
242
+ readonly name = "ProviderPrefixMismatchError";
243
+ constructor(provider: string, envKey: string, model: string);
244
+ }
245
+ interface ResolveCredentialInput {
246
+ /** The environment as the process sees it — already loaded, already interpolated. */
247
+ readonly env: Readonly<Record<string, string | undefined>>;
248
+ /** Directory whose `.env` is consulted for PROVENANCE only. Omitted ⇒ everything reads as shell. */
249
+ readonly home?: string;
250
+ /** The providers this app accepts. App policy, hence a parameter. */
251
+ readonly providers: readonly ProviderDescriptor[];
252
+ /** Model id, when known. Its prefix is checked against the resolved provider. */
253
+ readonly model?: string;
254
+ }
255
+ /**
256
+ * Resolve which credential to use, and record where it came from.
257
+ *
258
+ * Returns `undefined` when nothing is configured: a missing key is the ordinary first-run state, and
259
+ * the caller's next move is to print "run `theokit auth login`" — which a thrown error makes harder,
260
+ * not easier. A prefix that names a provider with no credential DOES throw, because that is a
261
+ * contradiction rather than an absence.
262
+ */
263
+ declare function resolveCredential(input: ResolveCredentialInput): CredentialResolution | undefined;
264
+
265
+ export { type AuthMethod, AuthProvider, CODEX_CLIENT_ID_ENV_VAR, CODEX_PROVIDER, type ProviderDescriptor as CredentialProviderDescriptor, type CredentialResolution, type DeviceAuthProvider, type PromptHooks, ProviderPrefixMismatchError, type ResolveCredentialInput, type SourceOrigin, loginWithDevice, resolveCredential };
package/dist/auth.js CHANGED
@@ -196,11 +196,93 @@ async function loginWithDevice(provider, method, store, hooks, opts = {}) {
196
196
  };
197
197
  }
198
198
  __name(loginWithDevice, "loginWithDevice");
199
+
200
+ // src/auth/resolve-credential.ts
201
+ import { readFileSync } from "fs";
202
+ import { join } from "path";
203
+ import { TheokitAgentError } from "@theokit/sdk/errors";
204
+ var ProviderPrefixMismatchError = class extends TheokitAgentError {
205
+ static {
206
+ __name(this, "ProviderPrefixMismatchError");
207
+ }
208
+ name = "ProviderPrefixMismatchError";
209
+ constructor(provider, envKey, model) {
210
+ super(`model "${model}" names provider "${provider}", but no credential for it was found. Set ${envKey}, or drop the prefix to let the resolver pick by precedence. Falling back to another provider would send the request to a model you did not ask for \u2014 and bill you for it.`);
211
+ }
212
+ };
213
+ function declaredNames(path) {
214
+ let raw;
215
+ try {
216
+ raw = readFileSync(path, "utf8");
217
+ } catch {
218
+ return /* @__PURE__ */ new Set();
219
+ }
220
+ const names = /* @__PURE__ */ new Set();
221
+ for (const line of raw.split("\n")) {
222
+ const trimmed = line.trim();
223
+ if (trimmed === "" || trimmed.startsWith("#")) continue;
224
+ const withoutExport = trimmed.startsWith("export ") ? trimmed.slice("export ".length) : trimmed;
225
+ const eq = withoutExport.indexOf("=");
226
+ if (eq <= 0) continue;
227
+ names.add(withoutExport.slice(0, eq).trim());
228
+ }
229
+ return names;
230
+ }
231
+ __name(declaredNames, "declaredNames");
232
+ function resolveCredential(input) {
233
+ const byPriority = [
234
+ ...input.providers
235
+ ].sort((a, b) => a.priority - b.priority);
236
+ const available = byPriority.flatMap((descriptor) => {
237
+ const apiKey = input.env[descriptor.envKey];
238
+ return apiKey === void 0 || apiKey === "" ? [] : [
239
+ {
240
+ descriptor,
241
+ apiKey
242
+ }
243
+ ];
244
+ });
245
+ const claimed = claimedProvider(input.model, byPriority);
246
+ const found = claimed === void 0 ? available[0] : available.find((candidate) => candidate.descriptor === claimed);
247
+ if (claimed !== void 0 && found === void 0) {
248
+ throw new ProviderPrefixMismatchError(claimed.name, claimed.envKey, input.model ?? "");
249
+ }
250
+ if (found === void 0) return void 0;
251
+ return {
252
+ kind: "api-key",
253
+ provider: found.descriptor.name,
254
+ apiKey: found.apiKey,
255
+ source: originOf(found.descriptor.envKey, input.home),
256
+ inferred: claimed === void 0
257
+ };
258
+ }
259
+ __name(resolveCredential, "resolveCredential");
260
+ function claimedProvider(model, providers) {
261
+ if (model === void 0) return void 0;
262
+ return providers.find((p) => p.modelPrefix !== void 0 && model.startsWith(p.modelPrefix));
263
+ }
264
+ __name(claimedProvider, "claimedProvider");
265
+ function originOf(varName, home) {
266
+ if (home === void 0) return {
267
+ kind: "env",
268
+ varName
269
+ };
270
+ const dotenv = join(home, ".env");
271
+ return declaredNames(dotenv).has(varName) ? {
272
+ kind: "file",
273
+ path: dotenv
274
+ } : {
275
+ kind: "env",
276
+ varName
277
+ };
278
+ }
279
+ __name(originOf, "originOf");
199
280
  export {
200
281
  AuthProvider,
201
282
  CODEX_CLIENT_ID_ENV_VAR,
202
283
  CODEX_PROVIDER,
203
284
  CredentialError,
285
+ ProviderPrefixMismatchError,
204
286
  assertSecureModes,
205
287
  authFilePath2 as authFilePath,
206
288
  credentialHome,
@@ -215,6 +297,7 @@ export {
215
297
  readStoredOAuth2 as readStoredOAuth,
216
298
  refreshOAuthTokens,
217
299
  requestDeviceCode,
300
+ resolveCredential,
218
301
  writeCredential
219
302
  };
220
303
  //# sourceMappingURL=auth.js.map
package/dist/auth.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/auth/auth-provider.ts","../src/auth-entry.ts","../src/auth/device-provider.ts"],"mappings":"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","names":["authFilePath","ensureFreshCredential","openaiDeviceLogin","persistOAuthTokens","readStoredOAuth","withFileLock","RefreshFailure","Error","message","transient","name","TRANSIENT_REASONS","classifyRefreshFailure","err","text","String","test","some","m","includes","waitWithJitter","attempt","baseMs","random","Math","base","round","AuthProvider","config","store","ensureFresh","resolved","deps","env","kind","ensureFreshCredential","filePath","authFilePath","inFlight","refreshInFlight","get","undefined","promise","refreshUnderLock","set","delete","Map","withFileLock","doDisco","readStoredOAuth","current","apiKey","access","expiresAt","expires","MAX_ATTEMPTS","failure","Promise","resolve","setTimeout","deviceLogin","deviceConfig","hooks","openaiDeviceLogin","persist","provider","tokens","persistOAuthTokens","assertSecureModes","authFilePath","CredentialError","credentialHome","readAuthFile","readStoredOAuth","writeCredential","deviceLogin","openaiDeviceLogin","pollDeviceToken","requestDeviceCode","ensureFreshCredential","extractAccountId","persistOAuthTokens","refreshOAuthTokens","openaiDeviceLogin","CODEX_CLIENT_ID","CODEX_ISSUER","CODEX_CLIENT_ID_ENV_VAR","CODEX_OAUTH","provider","clientId","process","env","authorizeEndpoint","tokenEndpoint","scopes","redirectUri","CODEX_DEVICE","deviceUsercodeEndpoint","devicePollEndpoint","verificationUri","CODEX_PROVIDER","Object","freeze","name","oauth","methods","label","type","authorize","deps","hooks","openaiDeviceLogin","comDefaults","fetch","sleep","ms","Promise","resolve","setTimeout","now","Date","loginWithDevice","method","store","opts","length","TypeError","includes","tokens","path","AuthProvider","persist","accountId","undefined"]}
1
+ {"version":3,"sources":["../src/auth/auth-provider.ts","../src/auth-entry.ts","../src/auth/device-provider.ts","../src/auth/resolve-credential.ts"],"mappings":"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","names":["authFilePath","ensureFreshCredential","openaiDeviceLogin","persistOAuthTokens","readStoredOAuth","withFileLock","RefreshFailure","Error","message","transient","name","TRANSIENT_REASONS","classifyRefreshFailure","err","text","String","test","some","m","includes","waitWithJitter","attempt","baseMs","random","Math","base","round","AuthProvider","config","store","ensureFresh","resolved","deps","env","kind","ensureFreshCredential","filePath","authFilePath","inFlight","refreshInFlight","get","undefined","promise","refreshUnderLock","set","delete","Map","withFileLock","doDisco","readStoredOAuth","current","apiKey","access","expiresAt","expires","MAX_ATTEMPTS","failure","Promise","resolve","setTimeout","deviceLogin","deviceConfig","hooks","openaiDeviceLogin","persist","provider","tokens","persistOAuthTokens","assertSecureModes","authFilePath","CredentialError","credentialHome","readAuthFile","readStoredOAuth","writeCredential","deviceLogin","openaiDeviceLogin","pollDeviceToken","requestDeviceCode","ensureFreshCredential","extractAccountId","persistOAuthTokens","refreshOAuthTokens","openaiDeviceLogin","CODEX_CLIENT_ID","CODEX_ISSUER","CODEX_CLIENT_ID_ENV_VAR","CODEX_OAUTH","provider","clientId","process","env","authorizeEndpoint","tokenEndpoint","scopes","redirectUri","CODEX_DEVICE","deviceUsercodeEndpoint","devicePollEndpoint","verificationUri","CODEX_PROVIDER","Object","freeze","name","oauth","methods","label","type","authorize","deps","hooks","openaiDeviceLogin","comDefaults","fetch","sleep","ms","Promise","resolve","setTimeout","now","Date","loginWithDevice","method","store","opts","length","TypeError","includes","tokens","path","AuthProvider","persist","accountId","undefined","readFileSync","join","TheokitAgentError","ProviderPrefixMismatchError","TheokitAgentError","name","provider","envKey","model","declaredNames","path","raw","readFileSync","Set","names","line","split","trimmed","trim","startsWith","withoutExport","slice","length","eq","indexOf","add","resolveCredential","input","byPriority","providers","sort","a","b","priority","available","flatMap","descriptor","apiKey","env","undefined","claimed","claimedProvider","found","find","candidate","kind","source","originOf","home","inferred","p","modelPrefix","varName","dotenv","join","has"]}