@theokit/agents 7.5.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.
- package/dist/{agent-handle-BX4oFqfb.d.ts → agent-handle-Dgi4ZGbg.d.ts} +11 -1
- package/dist/ask.d.ts +190 -0
- package/dist/ask.js +167 -0
- package/dist/ask.js.map +1 -0
- package/dist/auth.d.ts +96 -2
- package/dist/auth.js +85 -1
- package/dist/auth.js.map +1 -1
- package/dist/{bridge-entry-Z8GjrwH4.d.ts → bridge-entry-BEniSXWE.d.ts} +228 -609
- package/dist/bridge.d.ts +6 -3
- package/dist/bridge.js +18 -6
- package/dist/chunk-4VHCH6IZ.js +181 -0
- package/dist/chunk-4VHCH6IZ.js.map +1 -0
- package/dist/{chunk-WKBZZQBO.js → chunk-C7UXZWVY.js} +168 -177
- package/dist/chunk-C7UXZWVY.js.map +1 -0
- package/dist/{chunk-2BAFKRXT.js → chunk-M6HMASZC.js} +9 -4
- package/dist/chunk-M6HMASZC.js.map +1 -0
- package/dist/client-react.d.ts +2 -1
- package/dist/client-react.js +1 -1
- package/dist/client.d.ts +3 -2
- package/dist/client.js +1 -1
- package/dist/commands.d.ts +120 -0
- package/dist/commands.js +145 -0
- package/dist/commands.js.map +1 -0
- package/dist/define-agent-3Kuf6iKM.d.ts +633 -0
- package/dist/doctor.d.ts +119 -0
- package/dist/doctor.js +84 -0
- package/dist/doctor.js.map +1 -0
- package/dist/hook-handlers-Cw2FsnE5.d.ts +56 -0
- package/dist/hooks.d.ts +225 -0
- package/dist/hooks.js +286 -0
- package/dist/hooks.js.map +1 -0
- package/dist/index.d.ts +170 -26
- package/dist/index.js +105 -20
- package/dist/index.js.map +1 -1
- package/dist/mcp-health.d.ts +69 -0
- package/dist/mcp-health.js +42 -0
- package/dist/mcp-health.js.map +1 -0
- package/dist/persistence.d.ts +1 -1
- package/dist/persistence.js +4 -0
- package/dist/persistence.js.map +1 -1
- package/dist/sandbox.d.ts +1 -1
- package/dist/sandbox.js +29 -2
- package/dist/sandbox.js.map +1 -1
- package/dist/session.d.ts +238 -0
- package/dist/session.js +338 -0
- package/dist/session.js.map +1 -0
- package/dist/testing.d.ts +90 -1
- package/dist/testing.js +76 -1
- package/dist/testing.js.map +1 -1
- package/dist/tool-scope.d.ts +133 -0
- package/dist/tool-scope.js +61 -0
- package/dist/tool-scope.js.map +1 -0
- package/dist/tools.js.map +1 -1
- package/dist/usage.d.ts +98 -0
- package/dist/usage.js +55 -0
- package/dist/usage.js.map +1 -0
- package/package.json +37 -12
- package/dist/chunk-2BAFKRXT.js.map +0 -1
- package/dist/chunk-WKBZZQBO.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
|
-
|
|
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
|
package/dist/ask.js.map
ADDED
|
@@ -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
|
-
export { CredentialError, CredentialStoreConfig, DeviceCodeGrant, DeviceDeps, DeviceOAuthConfig, OAuthProviderConfig, OAuthTokens, OpenAIDeviceConfig, ResolveCredentialOptions, ResolvedCredential, authFilePath, credentialHome, deviceLogin, ensureFreshCredential, extractAccountId, openaiDeviceLogin, persistOAuthTokens, pollDeviceToken, readAuthFile, readStoredOAuth, refreshOAuthTokens, requestDeviceCode, writeCredential } from '@theokit/sdk/auth';
|
|
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
|
-
|
|
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
|
@@ -123,7 +123,7 @@ var AuthProvider = class _AuthProvider {
|
|
|
123
123
|
};
|
|
124
124
|
|
|
125
125
|
// src/auth-entry.ts
|
|
126
|
-
import { authFilePath as authFilePath2, CredentialError, credentialHome, readAuthFile, readStoredOAuth as readStoredOAuth2, writeCredential } from "@theokit/sdk/auth";
|
|
126
|
+
import { assertSecureModes, authFilePath as authFilePath2, CredentialError, credentialHome, readAuthFile, readStoredOAuth as readStoredOAuth2, writeCredential } from "@theokit/sdk/auth";
|
|
127
127
|
import { deviceLogin, openaiDeviceLogin as openaiDeviceLogin3, pollDeviceToken, requestDeviceCode } from "@theokit/sdk/auth";
|
|
128
128
|
import { ensureFreshCredential as ensureFreshCredential2, extractAccountId, persistOAuthTokens as persistOAuthTokens2, refreshOAuthTokens } from "@theokit/sdk/auth";
|
|
129
129
|
|
|
@@ -196,11 +196,94 @@ 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,
|
|
286
|
+
assertSecureModes,
|
|
204
287
|
authFilePath2 as authFilePath,
|
|
205
288
|
credentialHome,
|
|
206
289
|
deviceLogin,
|
|
@@ -214,6 +297,7 @@ export {
|
|
|
214
297
|
readStoredOAuth2 as readStoredOAuth,
|
|
215
298
|
refreshOAuthTokens,
|
|
216
299
|
requestDeviceCode,
|
|
300
|
+
resolveCredential,
|
|
217
301
|
writeCredential
|
|
218
302
|
};
|
|
219
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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
|
|
1
|
+
{"version":3,"sources":["../src/auth/auth-provider.ts","../src/auth-entry.ts","../src/auth/device-provider.ts","../src/auth/resolve-credential.ts"],"mappings":";;;;;AAAA,SACEA,cACAC,uBACAC,mBACAC,oBACAC,uBACK;AAQP,SAASC,oBAAoB;AAkCtB,IAAMC,iBAAN,cAA6BC,MAAAA;EAhDpC,OAgDoCA;;;;EAClC,YACEC,SAESC,WACT;AACA,UAAMD,OAAAA,GAAAA,KAFGC,YAAAA;AAGT,SAAKC,OAAO;EACd;AACF;AAMA,IAAMC,oBAAoB;EACxB;EACA;EACA;EACA;EACA;EACA;;AAIK,SAASC,uBAAuBC,KAAY;AACjD,QAAMC,OAAOD,eAAeN,QAAQ,GAAGM,IAAIH,IAAI,KAAKG,IAAIL,OAAO,KAAKO,OAAOF,GAAAA;AAC3E,MAAI,qDAAqDG,KAAKF,IAAAA,GAAO;AACnE,WAAO,IAAIR,eACT,mGACA,KAAA;EAEJ;AACA,QAAMG,YACJE,kBAAkBM,KAAK,CAACC,MAAMJ,KAAKK,SAASD,CAAAA,CAAAA,KAAO,gCAAgCF,KAAKF,IAAAA;AAC1F,SAAO,IAAIR,eACTG,YAAY,gDAAgD,qCAC5DA,SAAAA;AAEJ;AAdgBG;AAiBT,SAASQ,eAAeC,SAAiBC,SAAS,KAAKC,SAASC,KAAKD,QAAM;AAChF,QAAME,OAAOH,SAAS,KAAKD;AAC3B,SAAOG,KAAKE,MAAMD,QAAQ,OAAOF,OAAAA,IAAW,IAAE;AAChD;AAHgBH;AAKT,IAAMO,eAAN,MAAMA,cAAAA;EA/Fb,OA+FaA;;;;;EACX,YACmBC,QACAC,OACjB;SAFiBD,SAAAA;SACAC,QAAAA;EAChB;;;;;;EAOH,MAAMC,YACJC,UACAC,MACAC,KAC6B;AAC7B,QAAIF,SAASG,SAAS,SAAS;AAI7B,aAAOC,sBAAsBJ,UAAU;QAAEH,QAAQ,KAAKA;QAAQC,OAAO,KAAKA;QAAOI;MAAI,GAAGD,IAAAA;IAC1F;AAEA,UAAMI,WAAmBC,aAAa,KAAKR,OAAOI,GAAAA;AAUlD,UAAMK,WAAWX,cAAaY,gBAAgBC,IAAIJ,QAAAA;AAClD,QAAIE,aAAaG,OAAW,QAAOH;AAEnC,UAAMI,UAAU,KAAKC,iBAAiBP,UAAUL,UAAUC,MAAMC,GAAAA;AAChEN,kBAAaY,gBAAgBK,IAAIR,UAAUM,OAAAA;AAC3C,QAAI;AACF,aAAO,MAAMA;IACf,UAAA;AACEf,oBAAaY,gBAAgBM,OAAOT,QAAAA;IACtC;EACF;;EAGA,OAAwBG,kBAAkB,oBAAIO,IAAAA;;;;;;;;;EAUtCH,iBACNP,UACAL,UACAC,MACAC,KAC6B;AAE7B,WAAOc,aAAaX,UAAU,YAAA;AAE5B,YAAMY,UAAUC,gBAAgB,KAAKpB,OAAOI,GAAAA;AAC5C,YAAMiB,UACJF,YAAYP,SACR;QAAE,GAAGV;QAAUoB,QAAQH,QAAQI;QAAQC,WAAWL,QAAQM;MAAQ,IAClEvB;AAQN,YAAMwB,eAAe;AACrB,eAASlC,UAAU,KAAKA,WAAW;AACjC,YAAI;AACF,iBAAO,MAAMc,sBACXe,SACA;YAAEtB,QAAQ,KAAKA;YAAQC,OAAO,KAAKA;YAAOI;UAAI,GAC9CD,IAAAA;QAEJ,SAASnB,KAAK;AACZ,gBAAM2C,UAAU5C,uBAAuBC,GAAAA;AACvC,cAAI,CAAC2C,QAAQ/C,aAAaY,WAAWkC,eAAe,EAAG,OAAMC;AAC7D,gBAAM,IAAIC,QAAQ,CAACC,YAAYC,WAAWD,SAAStC,eAAeC,OAAAA,CAAAA,CAAAA;QACpE;MACF;IACF,CAAA;EAEF;;;;;;EAOAuC,YACEC,cACA7B,MACA8B,OACsB;AACtB,WAAOC,kBAAkBF,cAAc7B,MAAM8B,KAAAA;EAC/C;;;;;EAMAE,QAAQC,UAAkBC,QAAqBjC,KAAkD;AAC/F,WAAOkC,mBAAmBF,UAAUC,QAAQ,KAAKrC,OAAOI,GAAAA;EAC1D;AACF;;;ACrLA,SACEmC,mBACAC,gBAAAA,eACAC,iBACAC,gBACAC,cACAC,mBAAAA,kBACAC,uBACK;AAsBP,SACEC,aACAC,qBAAAA,oBACAC,iBACAC,yBACK;AAwBP,SACEC,yBAAAA,wBACAC,kBACAC,sBAAAA,qBACAC,0BACK;;;ACtFP,SAASC,qBAAAA,0BAAyB;AA4ElC,IAAMC,kBAAkB;AACxB,IAAMC,eAAe;AAQd,IAAMC,0BAA0B;AAEvC,IAAMC,cAAmC;EACvCC,UAAU;EACVC,UAAUC,QAAQC,IAAIL,uBAAAA,KAA4BF;EAClDQ,mBAAmB,GAAGP,YAAAA;EACtBQ,eAAe,GAAGR,YAAAA;EAClBS,QAAQ;IAAC;IAAU;IAAW;IAAS;;EACvCC,aAAa,GAAGV,YAAAA;AAClB;AAMA,IAAMW,eAAmC;EACvC,GAAGT;EACHU,wBAAwB,GAAGZ,YAAAA;EAC3Ba,oBAAoB,GAAGb,YAAAA;EACvBc,iBAAiB,GAAGd,YAAAA;AACtB;AASO,IAAMe,iBAAqCC,OAAOC,OAAO;EAC9DC,MAAM;EACNC,OAAOH,OAAOC,OAAOf,WAAAA;EACrBkB,SAASJ,OAAOC,OAAO;IACrBD,OAAOC,OAAO;MACZI,OAAO;MACPC,MAAM;;;MAGNC,WAAW,wBAACC,MAAkBC,UAC5BC,mBAAkBf,cAAca,MAAMC,KAAAA,GAD7B;IAEb,CAAA;IACAT,OAAOC,OAAO;MACZI,OAAO;MACPC,MAAM;IACR,CAAA;GACD;AACH,CAAA;AAeA,SAASK,YAAYH,MAA0B;AAC7C,SAAO;IACLI,OAAOJ,MAAMI,SAASA;IACtBC,OAAOL,MAAMK,UAAU,CAACC,OAAe,IAAIC,QAAc,CAACC,YAAYC,WAAWD,SAASF,EAAAA,CAAAA;IAC1FI,KAAKV,MAAMU,OAAOC,KAAKD;EACzB;AACF;AANSP;AAqBT,eAAsBS,gBACpBjC,UACAkC,QACAC,OACAb,OACAc,OAA+B,CAAC,GAAC;AAKjC,MAAIpC,SAASiB,QAAQoB,WAAW,GAAG;AACjC,UAAM,IAAIC,UACR,aAAatC,SAASe,IAAI,uEAAkE;EAEhG;AACA,MAAI,CAACf,SAASiB,QAAQsB,SAASL,MAAAA,GAAS;AACtC,UAAM,IAAII,UAAU,WAAWJ,OAAOhB,KAAK,kCAAkClB,SAASe,IAAI,GAAG;EAC/F;AACA,MAAImB,OAAOf,SAAS,SAAS;AAC3B,UAAM,IAAImB,UACR,WAAWJ,OAAOhB,KAAK,yEAAoE;EAE/F;AAEA,QAAMsB,SAAS,MAAMN,OAAOd,UAAUI,YAAYY,KAAKf,IAAI,GAAGC,KAAAA;AAC9D,QAAMmB,OAAO,IAAIC,aAAa1C,SAASgB,OAAOmB,KAAAA,EAAOQ,QAAQ3C,SAASe,MAAMyB,QAAQJ,KAAKjC,GAAG;AAE5F,SAAOqC,OAAOI,cAAcC,SAAY;IAAEJ;EAAK,IAAI;IAAEA;IAAMG,WAAWJ,OAAOI;EAAU;AACzF;AA5BsBX;;;AC9KtB,SAASa,oBAAoB;AAC7B,SAASC,YAAY;AAErB,SAASC,yBAAyB;AAqE3B,IAAMC,8BAAN,cAA0CC,kBAAAA;EAxEjD,OAwEiDA;;;EAC7BC,OAAO;EACzB,YAAYC,UAAkBC,QAAgBC,OAAe;AAC3D,UACE,UAAUA,KAAAA,qBAA0BF,QAAAA,8CAC/BC,MAAAA,iLAC4F;EAErG;AACF;AAqBA,SAASE,cAAcC,MAAY;AACjC,MAAIC;AACJ,MAAI;AAGFA,UAAMC,aAAaF,MAAM,MAAA;EAC3B,QAAQ;AAEN,WAAO,oBAAIG,IAAAA;EACb;AAEA,QAAMC,QAAQ,oBAAID,IAAAA;AAClB,aAAWE,QAAQJ,IAAIK,MAAM,IAAA,GAAO;AAClC,UAAMC,UAAUF,KAAKG,KAAI;AAGzB,QAAID,YAAY,MAAMA,QAAQE,WAAW,GAAA,EAAM;AAE/C,UAAMC,gBAAgBH,QAAQE,WAAW,SAAA,IAAaF,QAAQI,MAAM,UAAUC,MAAM,IAAIL;AACxF,UAAMM,KAAKH,cAAcI,QAAQ,GAAA;AACjC,QAAID,MAAM,EAAG;AACbT,UAAMW,IAAIL,cAAcC,MAAM,GAAGE,EAAAA,EAAIL,KAAI,CAAA;EAC3C;AACA,SAAOJ;AACT;AAxBSL;AAkCF,SAASiB,kBAAkBC,OAA6B;AAC7D,QAAMC,aAAa;OAAID,MAAME;IAAWC,KAAK,CAACC,GAAGC,MAAMD,EAAEE,WAAWD,EAAEC,QAAQ;AAS9E,QAAMC,YAAYN,WAAWO,QAAQ,CAACC,eAAAA;AACpC,UAAMC,SAASV,MAAMW,IAAIF,WAAW7B,MAAM;AAC1C,WAAO8B,WAAWE,UAAaF,WAAW,KAAK,CAAA,IAAK;MAAC;QAAED;QAAYC;MAAO;;EAC5E,CAAA;AAEA,QAAMG,UAAUC,gBAAgBd,MAAMnB,OAAOoB,UAAAA;AAC7C,QAAMc,QACJF,YAAYD,SACRL,UAAU,CAAA,IACVA,UAAUS,KAAK,CAACC,cAAcA,UAAUR,eAAeI,OAAAA;AAE7D,MAAIA,YAAYD,UAAaG,UAAUH,QAAW;AAChD,UAAM,IAAIpC,4BAA4BqC,QAAQnC,MAAMmC,QAAQjC,QAAQoB,MAAMnB,SAAS,EAAA;EACrF;AACA,MAAIkC,UAAUH,OAAW,QAAOA;AAEhC,SAAO;IACLM,MAAM;IACNvC,UAAUoC,MAAMN,WAAW/B;IAC3BgC,QAAQK,MAAML;IACdS,QAAQC,SAASL,MAAMN,WAAW7B,QAAQoB,MAAMqB,IAAI;IACpDC,UAAUT,YAAYD;EACxB;AACF;AAjCgBb;AA0ChB,SAASe,gBACPjC,OACAqB,WAAwC;AAExC,MAAIrB,UAAU+B,OAAW,QAAOA;AAChC,SAAOV,UAAUc,KAAK,CAACO,MAAMA,EAAEC,gBAAgBZ,UAAa/B,MAAMW,WAAW+B,EAAEC,WAAW,CAAA;AAC5F;AANSV;AAST,SAASM,SAASK,SAAiBJ,MAAwB;AACzD,MAAIA,SAAST,OAAW,QAAO;IAAEM,MAAM;IAAOO;EAAQ;AACtD,QAAMC,SAASC,KAAKN,MAAM,MAAA;AAC1B,SAAOvC,cAAc4C,MAAAA,EAAQE,IAAIH,OAAAA,IAC7B;IAAEP,MAAM;IAAQnC,MAAM2C;EAAO,IAC7B;IAAER,MAAM;IAAOO;EAAQ;AAC7B;AANSL;","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"]}
|