@vymalo/opencode-lightbridge 0.16.1 → 0.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +101 -38
- package/dist/config.d.ts +70 -4
- package/dist/config.js +76 -3
- package/dist/config.js.map +1 -1
- package/dist/lib.d.ts +4 -3
- package/dist/lib.js +4 -3
- package/dist/lib.js.map +1 -1
- package/dist/logging.d.ts +44 -0
- package/dist/logging.js +100 -0
- package/dist/logging.js.map +1 -0
- package/dist/migration.d.ts +31 -0
- package/dist/migration.js +91 -0
- package/dist/migration.js.map +1 -0
- package/dist/opencode.d.ts +33 -15
- package/dist/opencode.js +390 -194
- package/dist/opencode.js.map +1 -1
- package/dist/otel-adapter.d.ts +68 -0
- package/dist/otel-adapter.js +315 -0
- package/dist/otel-adapter.js.map +1 -0
- package/dist/plugin.d.ts +77 -23
- package/dist/plugin.js +157 -33
- package/dist/plugin.js.map +1 -1
- package/package.json +15 -9
package/dist/opencode.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"mappings":"AAAA,SAAS,gBAAgB;
|
|
1
|
+
{"mappings":"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","names":[],"sources":["../src/opencode.ts"],"version":3,"file":"opencode.js","sourceRoot":""}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import type { ChatMessageInput, ChatMessageOutput, ChatParamsInput, ChatParamsOutput, PermissionAskInput, PermissionAskOutput, RecorderEvent, ToolAfterInput, ToolBeforeInput, ToolResultOutput } from "@vymalo/opencode-core-otel/lib";
|
|
2
|
+
/**
|
|
3
|
+
* v2 -> `core-otel` adapter (ADR-0019). `TelemetryRecorder` is an engine with
|
|
4
|
+
* its own input vocabulary (`recorder-input.ts`); OpenCode v2 reports the same
|
|
5
|
+
* facts under different event names and a `{ type, data }` shape. This file is
|
|
6
|
+
* the whole translation, kept pure (no Effect, no host types) so it is testable
|
|
7
|
+
* without a host: the plugin only subscribes and forwards.
|
|
8
|
+
*
|
|
9
|
+
* The host payloads are read defensively (`unknown` in, narrowed per field) —
|
|
10
|
+
* a malformed or future-shaped event is skipped, never thrown: telemetry must
|
|
11
|
+
* not break the host.
|
|
12
|
+
*/
|
|
13
|
+
/** A host event, as delivered by `ctx.event.subscribe()`. */
|
|
14
|
+
export interface HostEvent {
|
|
15
|
+
readonly type: string;
|
|
16
|
+
/** Event time (epoch ms), when the host provides it. */
|
|
17
|
+
readonly created?: number;
|
|
18
|
+
readonly data?: unknown;
|
|
19
|
+
}
|
|
20
|
+
/** The recorder surface the adapter drives. */
|
|
21
|
+
export interface RecorderSink {
|
|
22
|
+
onEvent(event: RecorderEvent): void;
|
|
23
|
+
onTextComplete(messageID: string, text: string): void;
|
|
24
|
+
}
|
|
25
|
+
/** Stateful only for the step bookkeeping (model + start time) the end event lacks. */
|
|
26
|
+
export declare class OtelEventAdapter {
|
|
27
|
+
private readonly sink;
|
|
28
|
+
private readonly now;
|
|
29
|
+
private readonly steps;
|
|
30
|
+
constructor(sink: RecorderSink, now?: () => number);
|
|
31
|
+
/** Translate one host event; unknown types are ignored. */
|
|
32
|
+
handle(event: HostEvent): void;
|
|
33
|
+
private stepStarted;
|
|
34
|
+
private stepFinished;
|
|
35
|
+
}
|
|
36
|
+
/** `session.hook("prompt")`: flatten `Prompt { text, files }` to recorder parts. */
|
|
37
|
+
export declare function adaptPrompt(event: {
|
|
38
|
+
sessionID: string;
|
|
39
|
+
prompt: unknown;
|
|
40
|
+
agent?: unknown;
|
|
41
|
+
model?: unknown;
|
|
42
|
+
}): [ChatMessageInput, ChatMessageOutput];
|
|
43
|
+
/** `session.hook("context")`: sampling parameters from `options`. */
|
|
44
|
+
export declare function adaptContext(event: {
|
|
45
|
+
sessionID: string;
|
|
46
|
+
agent?: unknown;
|
|
47
|
+
model?: unknown;
|
|
48
|
+
options?: unknown;
|
|
49
|
+
}): [ChatParamsInput, ChatParamsOutput];
|
|
50
|
+
export declare function adaptToolBefore(event: {
|
|
51
|
+
tool: string;
|
|
52
|
+
sessionID: string;
|
|
53
|
+
id: string;
|
|
54
|
+
}): ToolBeforeInput;
|
|
55
|
+
/** `tool.hook("execute.after")`: the result's text content only, never read for meaning. */
|
|
56
|
+
export declare function adaptToolAfter(event: {
|
|
57
|
+
tool: string;
|
|
58
|
+
sessionID: string;
|
|
59
|
+
id: string;
|
|
60
|
+
status: "completed" | "error";
|
|
61
|
+
result?: unknown;
|
|
62
|
+
}): [ToolAfterInput, ToolResultOutput | undefined];
|
|
63
|
+
/** `permission.hook("evaluate")`: `action` becomes `type`, `effect` becomes `status`. */
|
|
64
|
+
export declare function adaptPermission(event: {
|
|
65
|
+
sessionID: string;
|
|
66
|
+
action: string;
|
|
67
|
+
effect: string;
|
|
68
|
+
}): [PermissionAskInput, PermissionAskOutput];
|
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
function record(value) {
|
|
2
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : undefined;
|
|
3
|
+
}
|
|
4
|
+
function str(value) {
|
|
5
|
+
return typeof value === "string" && value.length > 0 ? value : undefined;
|
|
6
|
+
}
|
|
7
|
+
function num(value) {
|
|
8
|
+
return typeof value === "number" && Number.isFinite(value) ? value : undefined;
|
|
9
|
+
}
|
|
10
|
+
function tokenCounts(value) {
|
|
11
|
+
const tokens = record(value);
|
|
12
|
+
const cache = record(tokens?.cache);
|
|
13
|
+
if (!tokens) {
|
|
14
|
+
return undefined;
|
|
15
|
+
}
|
|
16
|
+
return {
|
|
17
|
+
input: num(tokens.input) ?? 0,
|
|
18
|
+
output: num(tokens.output) ?? 0,
|
|
19
|
+
reasoning: num(tokens.reasoning) ?? 0,
|
|
20
|
+
cache: {
|
|
21
|
+
read: num(cache?.read) ?? 0,
|
|
22
|
+
write: num(cache?.write) ?? 0
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
/** Stateful only for the step bookkeeping (model + start time) the end event lacks. */
|
|
27
|
+
export class OtelEventAdapter {
|
|
28
|
+
sink;
|
|
29
|
+
now;
|
|
30
|
+
steps = new Map();
|
|
31
|
+
constructor(sink, now = Date.now) {
|
|
32
|
+
this.sink = sink;
|
|
33
|
+
this.now = now;
|
|
34
|
+
}
|
|
35
|
+
/** Translate one host event; unknown types are ignored. */
|
|
36
|
+
handle(event) {
|
|
37
|
+
const data = record(event.data);
|
|
38
|
+
switch (event.type) {
|
|
39
|
+
case "session.created": {
|
|
40
|
+
const sessionID = str(data?.sessionID);
|
|
41
|
+
if (!sessionID) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
this.sink.onEvent({
|
|
45
|
+
type: "session.created",
|
|
46
|
+
properties: { info: {
|
|
47
|
+
id: sessionID,
|
|
48
|
+
parentID: str(data?.parentID),
|
|
49
|
+
directory: str(record(data?.location)?.directory)
|
|
50
|
+
} }
|
|
51
|
+
});
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
case "session.deleted": {
|
|
55
|
+
const sessionID = str(data?.sessionID);
|
|
56
|
+
if (sessionID) {
|
|
57
|
+
this.sink.onEvent({
|
|
58
|
+
type: "session.deleted",
|
|
59
|
+
properties: { info: { id: sessionID } }
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
case "session.step.started":
|
|
65
|
+
this.stepStarted(data, event.created);
|
|
66
|
+
return;
|
|
67
|
+
case "session.step.ended":
|
|
68
|
+
this.stepFinished(data, event.created, false);
|
|
69
|
+
return;
|
|
70
|
+
case "session.step.failed":
|
|
71
|
+
this.stepFinished(data, event.created, true);
|
|
72
|
+
return;
|
|
73
|
+
case "session.text.ended": {
|
|
74
|
+
const id = str(data?.assistantMessageID);
|
|
75
|
+
const text = typeof data?.text === "string" ? data.text : undefined;
|
|
76
|
+
if (id && text !== undefined) {
|
|
77
|
+
this.sink.onTextComplete(id, text);
|
|
78
|
+
}
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
case "session.retry.scheduled": {
|
|
82
|
+
const sessionID = str(data?.sessionID);
|
|
83
|
+
if (sessionID) {
|
|
84
|
+
this.sink.onEvent({
|
|
85
|
+
type: "session.status",
|
|
86
|
+
properties: {
|
|
87
|
+
sessionID,
|
|
88
|
+
status: {
|
|
89
|
+
type: "retry",
|
|
90
|
+
attempt: num(data?.attempt)
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
case "session.compaction.ended": {
|
|
98
|
+
const sessionID = str(data?.sessionID);
|
|
99
|
+
if (sessionID) {
|
|
100
|
+
this.sink.onEvent({
|
|
101
|
+
type: "session.compacted",
|
|
102
|
+
properties: { sessionID }
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
case "session.execution.failed": {
|
|
108
|
+
const sessionID = str(data?.sessionID);
|
|
109
|
+
if (!sessionID) {
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
const error = record(data?.error);
|
|
113
|
+
this.sink.onEvent({
|
|
114
|
+
type: "session.error",
|
|
115
|
+
properties: {
|
|
116
|
+
sessionID,
|
|
117
|
+
error: {
|
|
118
|
+
name: str(error?.type),
|
|
119
|
+
data: { statusCode: num(error?.status) }
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
this.sink.onEvent({
|
|
124
|
+
type: "session.idle",
|
|
125
|
+
properties: { sessionID }
|
|
126
|
+
});
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
case "session.execution.succeeded":
|
|
130
|
+
case "session.execution.interrupted": {
|
|
131
|
+
// The turn boundary: v1's `session.idle` (the recorder flushes here).
|
|
132
|
+
const sessionID = str(data?.sessionID);
|
|
133
|
+
if (sessionID) {
|
|
134
|
+
this.sink.onEvent({
|
|
135
|
+
type: "session.idle",
|
|
136
|
+
properties: { sessionID }
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
case "permission.asked": {
|
|
142
|
+
const id = str(data?.id);
|
|
143
|
+
const sessionID = str(data?.sessionID);
|
|
144
|
+
const type = str(data?.action);
|
|
145
|
+
if (id && sessionID && type) {
|
|
146
|
+
this.sink.onEvent({
|
|
147
|
+
type: "permission.updated",
|
|
148
|
+
properties: {
|
|
149
|
+
id,
|
|
150
|
+
type,
|
|
151
|
+
sessionID
|
|
152
|
+
}
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
case "permission.replied": {
|
|
158
|
+
const sessionID = str(data?.sessionID);
|
|
159
|
+
const permissionID = str(data?.requestID);
|
|
160
|
+
const response = str(data?.reply);
|
|
161
|
+
if (sessionID && permissionID && response) {
|
|
162
|
+
this.sink.onEvent({
|
|
163
|
+
type: "permission.replied",
|
|
164
|
+
properties: {
|
|
165
|
+
sessionID,
|
|
166
|
+
permissionID,
|
|
167
|
+
response
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
case "vcs.branch.updated":
|
|
174
|
+
this.sink.onEvent({
|
|
175
|
+
type: "vcs.branch.updated",
|
|
176
|
+
properties: { branch: str(data?.branch) }
|
|
177
|
+
});
|
|
178
|
+
return;
|
|
179
|
+
case "installation.updated": {
|
|
180
|
+
const version = str(data?.version);
|
|
181
|
+
if (version) {
|
|
182
|
+
this.sink.onEvent({
|
|
183
|
+
type: "installation.updated",
|
|
184
|
+
properties: { version }
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
default: return;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
stepStarted(data, created) {
|
|
193
|
+
const id = str(data?.assistantMessageID);
|
|
194
|
+
const sessionID = str(data?.sessionID);
|
|
195
|
+
if (!id || !sessionID) {
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
const model = record(data?.model);
|
|
199
|
+
const state = {
|
|
200
|
+
modelID: str(model?.id),
|
|
201
|
+
providerID: str(model?.providerID),
|
|
202
|
+
agent: str(data?.agent),
|
|
203
|
+
created: num(data?.started) ?? created ?? this.now()
|
|
204
|
+
};
|
|
205
|
+
this.steps.set(id, state);
|
|
206
|
+
this.sink.onEvent({
|
|
207
|
+
type: "message.updated",
|
|
208
|
+
properties: { info: {
|
|
209
|
+
id,
|
|
210
|
+
sessionID,
|
|
211
|
+
role: "assistant",
|
|
212
|
+
modelID: state.modelID,
|
|
213
|
+
providerID: state.providerID,
|
|
214
|
+
mode: state.agent,
|
|
215
|
+
time: { created: state.created }
|
|
216
|
+
} }
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
stepFinished(data, created, failed) {
|
|
220
|
+
const id = str(data?.assistantMessageID);
|
|
221
|
+
const sessionID = str(data?.sessionID);
|
|
222
|
+
if (!id || !sessionID) {
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
const state = this.steps.get(id);
|
|
226
|
+
this.steps.delete(id);
|
|
227
|
+
const completed = created ?? this.now();
|
|
228
|
+
const error = failed ? record(data?.error) : undefined;
|
|
229
|
+
this.sink.onEvent({
|
|
230
|
+
type: "message.updated",
|
|
231
|
+
properties: { info: {
|
|
232
|
+
id,
|
|
233
|
+
sessionID,
|
|
234
|
+
role: "assistant",
|
|
235
|
+
modelID: state?.modelID,
|
|
236
|
+
providerID: state?.providerID,
|
|
237
|
+
mode: state?.agent,
|
|
238
|
+
cost: num(data?.cost),
|
|
239
|
+
tokens: tokenCounts(data?.tokens),
|
|
240
|
+
finish: failed ? "error" : str(data?.finish),
|
|
241
|
+
error: error ? {
|
|
242
|
+
name: str(error.type),
|
|
243
|
+
data: { statusCode: num(error.status) }
|
|
244
|
+
} : undefined,
|
|
245
|
+
time: {
|
|
246
|
+
created: state?.created ?? completed,
|
|
247
|
+
completed
|
|
248
|
+
}
|
|
249
|
+
} }
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
// ----------------------------------------------------------------- hooks
|
|
254
|
+
function modelRef(value) {
|
|
255
|
+
const model = record(value);
|
|
256
|
+
return model ? {
|
|
257
|
+
id: str(model.id),
|
|
258
|
+
providerID: str(model.providerID)
|
|
259
|
+
} : undefined;
|
|
260
|
+
}
|
|
261
|
+
/** `session.hook("prompt")`: flatten `Prompt { text, files }` to recorder parts. */
|
|
262
|
+
export function adaptPrompt(event) {
|
|
263
|
+
const prompt = record(event.prompt);
|
|
264
|
+
const files = Array.isArray(prompt?.files) ? prompt.files : [];
|
|
265
|
+
return [{
|
|
266
|
+
sessionID: event.sessionID,
|
|
267
|
+
agent: str(event.agent),
|
|
268
|
+
model: modelRef(event.model)
|
|
269
|
+
}, { parts: [{
|
|
270
|
+
type: "text",
|
|
271
|
+
text: typeof prompt?.text === "string" ? prompt.text : ""
|
|
272
|
+
}, ...files.map(() => ({ type: "file" }))] }];
|
|
273
|
+
}
|
|
274
|
+
/** `session.hook("context")`: sampling parameters from `options`. */
|
|
275
|
+
export function adaptContext(event) {
|
|
276
|
+
const options = record(event.options);
|
|
277
|
+
return [{
|
|
278
|
+
sessionID: event.sessionID,
|
|
279
|
+
agent: str(event.agent),
|
|
280
|
+
model: modelRef(event.model)
|
|
281
|
+
}, {
|
|
282
|
+
temperature: num(options?.temperature),
|
|
283
|
+
topP: num(options?.topP),
|
|
284
|
+
topK: num(options?.topK),
|
|
285
|
+
maxTokens: num(options?.maxTokens)
|
|
286
|
+
}];
|
|
287
|
+
}
|
|
288
|
+
export function adaptToolBefore(event) {
|
|
289
|
+
return {
|
|
290
|
+
tool: event.tool,
|
|
291
|
+
sessionID: event.sessionID,
|
|
292
|
+
id: event.id
|
|
293
|
+
};
|
|
294
|
+
}
|
|
295
|
+
/** `tool.hook("execute.after")`: the result's text content only, never read for meaning. */
|
|
296
|
+
export function adaptToolAfter(event) {
|
|
297
|
+
const result = record(event.result);
|
|
298
|
+
const content = result?.content;
|
|
299
|
+
const output = typeof content === "string" || Array.isArray(content) ? { content } : undefined;
|
|
300
|
+
return [{
|
|
301
|
+
tool: event.tool,
|
|
302
|
+
sessionID: event.sessionID,
|
|
303
|
+
id: event.id,
|
|
304
|
+
status: event.status
|
|
305
|
+
}, output];
|
|
306
|
+
}
|
|
307
|
+
/** `permission.hook("evaluate")`: `action` becomes `type`, `effect` becomes `status`. */
|
|
308
|
+
export function adaptPermission(event) {
|
|
309
|
+
return [{
|
|
310
|
+
sessionID: event.sessionID,
|
|
311
|
+
type: event.action
|
|
312
|
+
}, { status: event.effect }];
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
//# sourceMappingURL=otel-adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"mappings":"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","names":[],"sources":["../src/otel-adapter.ts"],"version":3,"file":"otel-adapter.js","sourceRoot":""}
|
package/dist/plugin.d.ts
CHANGED
|
@@ -1,12 +1,28 @@
|
|
|
1
1
|
import { type AuthServerConfig, type Logger, type TokenSet } from "@vymalo/opencode-auth-core/lib";
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
3
|
+
* Legacy identity for the exchanged project-token store (UNCHANGED by
|
|
4
|
+
* ADR-0017 — see `migration.ts`'s module doc for why only the ROOT token
|
|
5
|
+
* relocated). Kept as a constant, not `auth.id`, because the exchanged-token
|
|
6
|
+
* cache key has always been derived from this literal, independent of the
|
|
7
|
+
* configured IdP's `id`.
|
|
5
8
|
*/
|
|
6
9
|
export declare const LIGHTBRIDGE_IDENTITY = "lightbridge";
|
|
7
|
-
/** Own cache namespace — separate from oauth2/repo-auth/otel's
|
|
10
|
+
/** Own cache namespace for the exchanged-token store — separate from oauth2/repo-auth/otel's. */
|
|
8
11
|
export declare const DEFAULT_CACHE_NAMESPACE = "opencode-lightbridge";
|
|
9
12
|
/**
|
|
13
|
+
* ADR-0017: the human ROOT token now lives in the SAME cache file
|
|
14
|
+
* `@vymalo/opencode-oauth2` uses for a server of this id —
|
|
15
|
+
* `<cacheRoot>/opencode-oauth2/opencode-oauth2-model-sync/<id>.json`, a fused
|
|
16
|
+
* `CachedServerState` (token + discovered models). This is what lets a
|
|
17
|
+
* developer who configures the same IdP (`auth.id` == an oauth2 `servers[].id`,
|
|
18
|
+
* same issuer/clientId) log in ONCE and have both plugins read/write the same
|
|
19
|
+
* on-disk state. The literals are pinned here (not imported from
|
|
20
|
+
* `@vymalo/opencode-oauth2`, which lightbridge does not depend on) — see
|
|
21
|
+
* `docs/adr/0017-lightbridge-all-in-one.md` for the shared-contract rationale.
|
|
22
|
+
*/
|
|
23
|
+
export declare const ROOT_CACHE_SEGMENT = "opencode-oauth2";
|
|
24
|
+
export declare const ROOT_CACHE_NAMESPACE = "opencode-oauth2-model-sync";
|
|
25
|
+
/**
|
|
10
26
|
* Cache key for the default-project token — used when no `projectId` is
|
|
11
27
|
* configured, so the exchange sends no `project_id` and the backend mints a
|
|
12
28
|
* token for the caller's default project (ADR-0012). Distinct from any real
|
|
@@ -17,9 +33,16 @@ export interface LightbridgeRuntimeOptions {
|
|
|
17
33
|
logger?: Logger;
|
|
18
34
|
fetchImpl?: typeof fetch;
|
|
19
35
|
onAuthorizationUrl?: (url: string) => Promise<void> | void;
|
|
20
|
-
/** Override the cache
|
|
36
|
+
/** Override the cache ROOT (defaults to the OS cache dir convention) — both
|
|
37
|
+
* the shared root-token store and the exchange-only store are joined from
|
|
38
|
+
* this. Test seam; production callers omit it. */
|
|
21
39
|
cacheDir?: string;
|
|
22
40
|
tokenExpirySkewMs?: number;
|
|
41
|
+
/**
|
|
42
|
+
* Whether to perform the RFC 8693 exchange (ADR-0012) rather than use the
|
|
43
|
+
* IdP access token directly as the bearer. Defaults to `false` (ADR-0017).
|
|
44
|
+
*/
|
|
45
|
+
exchange?: boolean;
|
|
23
46
|
}
|
|
24
47
|
/**
|
|
25
48
|
* The minimal surface `opencode.ts` needs from the shared runtime — narrow on
|
|
@@ -38,50 +61,81 @@ export interface LightbridgeRuntimeLike {
|
|
|
38
61
|
*/
|
|
39
62
|
export type LightbridgeRuntimeFactory = (auth: AuthServerConfig, projectId: string | undefined, options: LightbridgeRuntimeOptions) => LightbridgeRuntimeLike;
|
|
40
63
|
/**
|
|
41
|
-
* The ONE shared
|
|
42
|
-
* single human login, reused as the subject token for a
|
|
43
|
-
* 8693 exchange
|
|
44
|
-
*
|
|
45
|
-
* the
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
64
|
+
* The ONE shared runtime the umbrella plugin builds (ADR-0012, amended by
|
|
65
|
+
* ADR-0017): a single human login, reused as the subject token for a
|
|
66
|
+
* project-scoped RFC 8693 exchange (when `gateway.exchange` is `true`) or
|
|
67
|
+
* used directly as the gateway/OTEL bearer (the new default) — consumed by
|
|
68
|
+
* BOTH the gateway (`chat.headers`) and OTEL (`TokenSource.headers()`).
|
|
69
|
+
*
|
|
70
|
+
* The human root token itself is no longer lightbridge-exclusive storage: it
|
|
71
|
+
* lives in the SAME cache file `@vymalo/opencode-oauth2` writes for a server
|
|
72
|
+
* of this id (`ROOT_CACHE_SEGMENT`/`ROOT_CACHE_NAMESPACE`), so configuring
|
|
73
|
+
* both plugins against the same IdP (`auth.id` matching an oauth2
|
|
74
|
+
* `servers[].id`, same issuer/clientId) means logging in once. An upgrading
|
|
75
|
+
* install's pre-existing root token is migrated in automatically — see
|
|
76
|
+
* `migration.ts`.
|
|
49
77
|
*/
|
|
50
78
|
export declare class LightbridgeRuntime implements LightbridgeRuntimeLike {
|
|
51
79
|
private readonly projectId;
|
|
52
|
-
private readonly
|
|
80
|
+
private readonly rootRuntime;
|
|
81
|
+
private readonly sharedStore;
|
|
82
|
+
private readonly exchangeRuntime;
|
|
53
83
|
private readonly logger;
|
|
54
84
|
private readonly tokenExpirySkewMs;
|
|
85
|
+
private readonly exchange;
|
|
86
|
+
private readonly cacheRoot;
|
|
87
|
+
private readonly serverId;
|
|
55
88
|
/** Token-cache key: the project id, or `DEFAULT_PROJECT_KEY` when unset. */
|
|
56
89
|
private readonly projectKey;
|
|
57
90
|
private inFlightExchange?;
|
|
91
|
+
private migration?;
|
|
58
92
|
constructor(auth: AuthServerConfig, projectId: string | undefined, options?: LightbridgeRuntimeOptions);
|
|
93
|
+
/**
|
|
94
|
+
* One-time (per instance) migration of a pre-ADR-0017 root token into the
|
|
95
|
+
* shared cache file — see `migration.ts`. Idempotent and cheap on every
|
|
96
|
+
* call after the first (the underlying function also short-circuits once
|
|
97
|
+
* the new location has ANY state).
|
|
98
|
+
*/
|
|
99
|
+
private ensureMigrated;
|
|
59
100
|
/** Non-network read of the cached project token, if any. */
|
|
60
101
|
getCachedProjectToken(): Promise<TokenSet | undefined>;
|
|
61
102
|
/**
|
|
62
|
-
* Resolve a usable
|
|
63
|
-
* `chat.headers`, OTEL `TokenSource.headers()`)
|
|
103
|
+
* Resolve a usable gateway/OTEL bearer, shared by every caller (gateway
|
|
104
|
+
* `chat.headers`, OTEL `TokenSource.headers()`).
|
|
105
|
+
*
|
|
106
|
+
* `gateway.exchange: false` (default, ADR-0017): the IdP access token IS
|
|
107
|
+
* the bearer — just `ensure()` the shared root token (refresh-only unless
|
|
108
|
+
* `interactive`).
|
|
109
|
+
*
|
|
110
|
+
* `gateway.exchange: true` (ADR-0012, unchanged):
|
|
64
111
|
*
|
|
65
|
-
* cached usable? ──yes──▶ return it
|
|
112
|
+
* cached exchanged token usable? ──yes──▶ return it
|
|
66
113
|
* │ no
|
|
67
114
|
* ▼
|
|
68
|
-
* ensure human root (refresh-only unless `interactive`)
|
|
115
|
+
* ensure shared human root (refresh-only unless `interactive`)
|
|
69
116
|
* ▼
|
|
70
117
|
* exchangeTo(projectKey, humanToken, projectId ? { project_id } : {})
|
|
71
118
|
* ▼ (no projectId → backend picks the default project)
|
|
72
119
|
* cache + return
|
|
73
120
|
*
|
|
74
|
-
* Concurrent callers
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
-
* which is expected to fail closed (no header / empty `headers()`).
|
|
121
|
+
* Concurrent callers share the in-flight exchange in either mode. Never
|
|
122
|
+
* invents a token: a failure propagates to the caller, which is expected to
|
|
123
|
+
* fail closed (no header / empty `headers()`).
|
|
78
124
|
*/
|
|
79
125
|
getProjectToken(options?: {
|
|
80
126
|
interactive?: boolean;
|
|
81
127
|
}): Promise<TokenSet>;
|
|
82
128
|
private performExchange;
|
|
83
|
-
/**
|
|
129
|
+
/**
|
|
130
|
+
* Drop the cached tokens for this identity: the exchanged project token
|
|
131
|
+
* entirely (its own exclusive store), and the shared root token's `token`
|
|
132
|
+
* field only — NOT the whole shared cache file, which may also hold
|
|
133
|
+
* `@vymalo/opencode-oauth2`'s discovered models for this server id and must
|
|
134
|
+
* survive a lightbridge-side logout.
|
|
135
|
+
*/
|
|
84
136
|
reset(): Promise<void>;
|
|
85
137
|
}
|
|
86
|
-
/** Absolute path to the lightbridge cache directory
|
|
138
|
+
/** Absolute path to the lightbridge-exclusive (exchanged-token) cache directory. */
|
|
87
139
|
export declare function lightbridgeCacheDir(cacheRoot: string): string;
|
|
140
|
+
/** Absolute path to the SHARED root-token cache directory (ADR-0017). */
|
|
141
|
+
export declare function rootCacheDir(cacheRoot: string): string;
|