@vellumai/credential-executor 0.5.12 → 0.5.13
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/node_modules/@vellumai/ces-contracts/src/index.ts +7 -0
- package/node_modules/@vellumai/ces-contracts/src/rpc.ts +5 -0
- package/package.json +1 -1
- package/src/__tests__/managed-lazy-getters.test.ts +61 -12
- package/src/managed-lazy-getters.ts +18 -6
- package/src/managed-main.ts +18 -10
- package/src/server.ts +8 -8
|
@@ -33,6 +33,13 @@ export const HandshakeRequestSchema = z.object({
|
|
|
33
33
|
* can use it for platform credential materialisation.
|
|
34
34
|
*/
|
|
35
35
|
assistantApiKey: z.string().optional(),
|
|
36
|
+
/**
|
|
37
|
+
* Optional platform assistant ID passed from the assistant runtime.
|
|
38
|
+
* In managed (sidecar) mode with warm pools, the PLATFORM_ASSISTANT_ID
|
|
39
|
+
* env var may not be set at CES startup. The assistant forwards it here
|
|
40
|
+
* so CES can use it for platform credential materialisation.
|
|
41
|
+
*/
|
|
42
|
+
assistantId: z.string().optional(),
|
|
36
43
|
});
|
|
37
44
|
export type HandshakeRequest = z.infer<typeof HandshakeRequestSchema>;
|
|
38
45
|
|
|
@@ -422,6 +422,11 @@ export type ListAuditRecordsResponse = z.infer<
|
|
|
422
422
|
export const UpdateManagedCredentialSchema = z.object({
|
|
423
423
|
/** The assistant API key to push to CES for platform credential materialization. */
|
|
424
424
|
assistantApiKey: z.string(), // nosemgrep: not-a-secret
|
|
425
|
+
/**
|
|
426
|
+
* Optional platform assistant ID. In warm-pool mode the ID may not be
|
|
427
|
+
* available at CES startup; the assistant pushes it here once provisioned.
|
|
428
|
+
*/
|
|
429
|
+
assistantId: z.string().optional(),
|
|
425
430
|
});
|
|
426
431
|
export type UpdateManagedCredential = z.infer<
|
|
427
432
|
typeof UpdateManagedCredentialSchema
|
package/package.json
CHANGED
|
@@ -11,6 +11,7 @@ import { describe, expect, test } from "bun:test";
|
|
|
11
11
|
import {
|
|
12
12
|
buildLazyGetters,
|
|
13
13
|
type ApiKeyRef,
|
|
14
|
+
type AssistantIdRef,
|
|
14
15
|
} from "../managed-lazy-getters.js";
|
|
15
16
|
|
|
16
17
|
// ---------------------------------------------------------------------------
|
|
@@ -20,9 +21,10 @@ import {
|
|
|
20
21
|
describe("managed lazy getters — before API key arrives", () => {
|
|
21
22
|
test("apiKeyRef starts empty and managed subject options are undefined", () => {
|
|
22
23
|
const apiKeyRef: ApiKeyRef = { current: "" };
|
|
24
|
+
const assistantIdRef: AssistantIdRef = { current: "ast_abc123" };
|
|
23
25
|
const { getManagedSubjectOptions } = buildLazyGetters({
|
|
24
26
|
platformBaseUrl: "https://api.vellum.ai",
|
|
25
|
-
|
|
27
|
+
assistantIdRef,
|
|
26
28
|
apiKeyRef,
|
|
27
29
|
});
|
|
28
30
|
|
|
@@ -32,9 +34,10 @@ describe("managed lazy getters — before API key arrives", () => {
|
|
|
32
34
|
|
|
33
35
|
test("apiKeyRef starts empty and managed materializer options are undefined", () => {
|
|
34
36
|
const apiKeyRef: ApiKeyRef = { current: "" };
|
|
37
|
+
const assistantIdRef: AssistantIdRef = { current: "ast_abc123" };
|
|
35
38
|
const { getManagedMaterializerOptions } = buildLazyGetters({
|
|
36
39
|
platformBaseUrl: "https://api.vellum.ai",
|
|
37
|
-
|
|
40
|
+
assistantIdRef,
|
|
38
41
|
apiKeyRef,
|
|
39
42
|
});
|
|
40
43
|
|
|
@@ -43,9 +46,10 @@ describe("managed lazy getters — before API key arrives", () => {
|
|
|
43
46
|
|
|
44
47
|
test("getAssistantApiKey returns empty string when ref is empty and no env var", () => {
|
|
45
48
|
const apiKeyRef: ApiKeyRef = { current: "" };
|
|
49
|
+
const assistantIdRef: AssistantIdRef = { current: "ast_abc123" };
|
|
46
50
|
const { getAssistantApiKey } = buildLazyGetters({
|
|
47
51
|
platformBaseUrl: "https://api.vellum.ai",
|
|
48
|
-
|
|
52
|
+
assistantIdRef,
|
|
49
53
|
apiKeyRef,
|
|
50
54
|
});
|
|
51
55
|
|
|
@@ -60,9 +64,10 @@ describe("managed lazy getters — before API key arrives", () => {
|
|
|
60
64
|
describe("managed lazy getters — after API key arrives via handshake", () => {
|
|
61
65
|
test("setting apiKeyRef.current enables managed subject options", () => {
|
|
62
66
|
const apiKeyRef: ApiKeyRef = { current: "" };
|
|
67
|
+
const assistantIdRef: AssistantIdRef = { current: "ast_abc123" };
|
|
63
68
|
const { getManagedSubjectOptions } = buildLazyGetters({
|
|
64
69
|
platformBaseUrl: "https://api.vellum.ai",
|
|
65
|
-
|
|
70
|
+
assistantIdRef,
|
|
66
71
|
apiKeyRef,
|
|
67
72
|
});
|
|
68
73
|
|
|
@@ -79,9 +84,10 @@ describe("managed lazy getters — after API key arrives via handshake", () => {
|
|
|
79
84
|
|
|
80
85
|
test("setting apiKeyRef.current enables managed materializer options", () => {
|
|
81
86
|
const apiKeyRef: ApiKeyRef = { current: "" };
|
|
87
|
+
const assistantIdRef: AssistantIdRef = { current: "ast_abc123" };
|
|
82
88
|
const { getManagedMaterializerOptions } = buildLazyGetters({
|
|
83
89
|
platformBaseUrl: "https://api.vellum.ai",
|
|
84
|
-
|
|
90
|
+
assistantIdRef,
|
|
85
91
|
apiKeyRef,
|
|
86
92
|
});
|
|
87
93
|
|
|
@@ -98,10 +104,11 @@ describe("managed lazy getters — after API key arrives via handshake", () => {
|
|
|
98
104
|
|
|
99
105
|
test("returned options contain the exact key from the ref (not a stale copy)", () => {
|
|
100
106
|
const apiKeyRef: ApiKeyRef = { current: "" };
|
|
107
|
+
const assistantIdRef: AssistantIdRef = { current: "ast_abc123" };
|
|
101
108
|
const { getManagedSubjectOptions, getManagedMaterializerOptions } =
|
|
102
109
|
buildLazyGetters({
|
|
103
110
|
platformBaseUrl: "https://api.vellum.ai",
|
|
104
|
-
|
|
111
|
+
assistantIdRef,
|
|
105
112
|
apiKeyRef,
|
|
106
113
|
});
|
|
107
114
|
|
|
@@ -122,11 +129,12 @@ describe("managed lazy getters — after API key arrives via handshake", () => {
|
|
|
122
129
|
describe("managed lazy getters — lazy resolution timing", () => {
|
|
123
130
|
test("handlers built before key arrives resolve the key at call time", () => {
|
|
124
131
|
const apiKeyRef: ApiKeyRef = { current: "" };
|
|
132
|
+
const assistantIdRef: AssistantIdRef = { current: "ast_abc123" };
|
|
125
133
|
|
|
126
134
|
const { getManagedSubjectOptions, getManagedMaterializerOptions } =
|
|
127
135
|
buildLazyGetters({
|
|
128
136
|
platformBaseUrl: "https://api.vellum.ai",
|
|
129
|
-
|
|
137
|
+
assistantIdRef,
|
|
130
138
|
apiKeyRef,
|
|
131
139
|
});
|
|
132
140
|
|
|
@@ -147,10 +155,11 @@ describe("managed lazy getters — lazy resolution timing", () => {
|
|
|
147
155
|
|
|
148
156
|
test("deps object with getter properties resolves lazily (mirrors httpDeps pattern)", () => {
|
|
149
157
|
const apiKeyRef: ApiKeyRef = { current: "" };
|
|
158
|
+
const assistantIdRef: AssistantIdRef = { current: "ast_abc123" };
|
|
150
159
|
const { getManagedSubjectOptions, getManagedMaterializerOptions } =
|
|
151
160
|
buildLazyGetters({
|
|
152
161
|
platformBaseUrl: "https://api.vellum.ai",
|
|
153
|
-
|
|
162
|
+
assistantIdRef,
|
|
154
163
|
apiKeyRef,
|
|
155
164
|
});
|
|
156
165
|
|
|
@@ -182,9 +191,10 @@ describe("managed lazy getters — lazy resolution timing", () => {
|
|
|
182
191
|
|
|
183
192
|
test("env var fallback is used when ref is empty", () => {
|
|
184
193
|
const apiKeyRef: ApiKeyRef = { current: "" };
|
|
194
|
+
const assistantIdRef: AssistantIdRef = { current: "ast_abc123" };
|
|
185
195
|
const { getAssistantApiKey, getManagedSubjectOptions } = buildLazyGetters({
|
|
186
196
|
platformBaseUrl: "https://api.vellum.ai",
|
|
187
|
-
|
|
197
|
+
assistantIdRef,
|
|
188
198
|
apiKeyRef,
|
|
189
199
|
envApiKey: "vak_env_fallback",
|
|
190
200
|
});
|
|
@@ -198,9 +208,10 @@ describe("managed lazy getters — lazy resolution timing", () => {
|
|
|
198
208
|
|
|
199
209
|
test("handshake-provided key takes precedence over env var", () => {
|
|
200
210
|
const apiKeyRef: ApiKeyRef = { current: "" };
|
|
211
|
+
const assistantIdRef: AssistantIdRef = { current: "ast_abc123" };
|
|
201
212
|
const { getAssistantApiKey } = buildLazyGetters({
|
|
202
213
|
platformBaseUrl: "https://api.vellum.ai",
|
|
203
|
-
|
|
214
|
+
assistantIdRef,
|
|
204
215
|
apiKeyRef,
|
|
205
216
|
envApiKey: "vak_env_key",
|
|
206
217
|
});
|
|
@@ -219,10 +230,11 @@ describe("managed lazy getters — lazy resolution timing", () => {
|
|
|
219
230
|
describe("managed lazy getters — missing platform config fields", () => {
|
|
220
231
|
test("missing platformBaseUrl returns undefined even with API key", () => {
|
|
221
232
|
const apiKeyRef: ApiKeyRef = { current: "vak_test_key" };
|
|
233
|
+
const assistantIdRef: AssistantIdRef = { current: "ast_abc123" };
|
|
222
234
|
const { getManagedSubjectOptions, getManagedMaterializerOptions } =
|
|
223
235
|
buildLazyGetters({
|
|
224
236
|
platformBaseUrl: "",
|
|
225
|
-
|
|
237
|
+
assistantIdRef,
|
|
226
238
|
apiKeyRef,
|
|
227
239
|
});
|
|
228
240
|
|
|
@@ -232,14 +244,51 @@ describe("managed lazy getters — missing platform config fields", () => {
|
|
|
232
244
|
|
|
233
245
|
test("missing assistantId returns undefined even with API key", () => {
|
|
234
246
|
const apiKeyRef: ApiKeyRef = { current: "vak_test_key" };
|
|
247
|
+
const assistantIdRef: AssistantIdRef = { current: "" };
|
|
235
248
|
const { getManagedSubjectOptions, getManagedMaterializerOptions } =
|
|
236
249
|
buildLazyGetters({
|
|
237
250
|
platformBaseUrl: "https://api.vellum.ai",
|
|
238
|
-
|
|
251
|
+
assistantIdRef,
|
|
239
252
|
apiKeyRef,
|
|
240
253
|
});
|
|
241
254
|
|
|
242
255
|
expect(getManagedSubjectOptions()).toBeUndefined();
|
|
243
256
|
expect(getManagedMaterializerOptions()).toBeUndefined();
|
|
244
257
|
});
|
|
258
|
+
|
|
259
|
+
test("assistantIdRef updated after build enables options (warm-pool scenario)", () => {
|
|
260
|
+
/**
|
|
261
|
+
* Verifies that updating assistantIdRef.current after buildLazyGetters
|
|
262
|
+
* makes previously-undefined options become defined — the core fix for
|
|
263
|
+
* warm-pool pods where PLATFORM_ASSISTANT_ID is empty at CES startup.
|
|
264
|
+
*/
|
|
265
|
+
|
|
266
|
+
// GIVEN an API key is available but assistant ID is empty (warm-pool startup)
|
|
267
|
+
const apiKeyRef: ApiKeyRef = { current: "vak_test_key" };
|
|
268
|
+
const assistantIdRef: AssistantIdRef = { current: "" };
|
|
269
|
+
const { getManagedSubjectOptions, getManagedMaterializerOptions } =
|
|
270
|
+
buildLazyGetters({
|
|
271
|
+
platformBaseUrl: "https://api.vellum.ai",
|
|
272
|
+
assistantIdRef,
|
|
273
|
+
apiKeyRef,
|
|
274
|
+
});
|
|
275
|
+
|
|
276
|
+
// WHEN options are checked before assistant ID arrives
|
|
277
|
+
// THEN they are undefined
|
|
278
|
+
expect(getManagedSubjectOptions()).toBeUndefined();
|
|
279
|
+
expect(getManagedMaterializerOptions()).toBeUndefined();
|
|
280
|
+
|
|
281
|
+
// WHEN the assistant ID arrives via handshake/RPC
|
|
282
|
+
assistantIdRef.current = "ast_provisioned_123";
|
|
283
|
+
|
|
284
|
+
// THEN the same getter functions now return valid options
|
|
285
|
+
const subOpts = getManagedSubjectOptions();
|
|
286
|
+
expect(subOpts).toBeDefined();
|
|
287
|
+
expect(subOpts!.assistantId).toBe("ast_provisioned_123");
|
|
288
|
+
expect(subOpts!.assistantApiKey).toBe("vak_test_key");
|
|
289
|
+
|
|
290
|
+
const matOpts = getManagedMaterializerOptions();
|
|
291
|
+
expect(matOpts).toBeDefined();
|
|
292
|
+
expect(matOpts!.assistantId).toBe("ast_provisioned_123");
|
|
293
|
+
});
|
|
245
294
|
});
|
|
@@ -22,9 +22,19 @@ export interface ApiKeyRef {
|
|
|
22
22
|
current: string;
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
+
/**
|
|
26
|
+
* Mutable reference to the platform assistant ID. For warm-pool pods the
|
|
27
|
+
* PLATFORM_ASSISTANT_ID env var is empty at startup; the assistant forwards
|
|
28
|
+
* the ID via the handshake or update_managed_credential RPC after
|
|
29
|
+
* provisioning, and `.current` is updated so lazy getters pick it up.
|
|
30
|
+
*/
|
|
31
|
+
export interface AssistantIdRef {
|
|
32
|
+
current: string;
|
|
33
|
+
}
|
|
34
|
+
|
|
25
35
|
export interface LazyGetterOptions {
|
|
26
36
|
platformBaseUrl: string;
|
|
27
|
-
|
|
37
|
+
assistantIdRef: AssistantIdRef;
|
|
28
38
|
apiKeyRef: ApiKeyRef;
|
|
29
39
|
envApiKey?: string;
|
|
30
40
|
}
|
|
@@ -43,22 +53,24 @@ export interface LazyGetters {
|
|
|
43
53
|
* (chicken-and-egg: key is provisioned after hatch).
|
|
44
54
|
*/
|
|
45
55
|
export function buildLazyGetters(opts: LazyGetterOptions): LazyGetters {
|
|
46
|
-
const { platformBaseUrl,
|
|
56
|
+
const { platformBaseUrl, assistantIdRef, apiKeyRef, envApiKey } = opts;
|
|
47
57
|
|
|
48
58
|
const getAssistantApiKey = (): string =>
|
|
49
59
|
apiKeyRef.current || envApiKey || "";
|
|
50
60
|
|
|
51
61
|
const getManagedSubjectOptions = (): ManagedSubjectResolverOptions | undefined => {
|
|
52
62
|
const key = getAssistantApiKey();
|
|
53
|
-
|
|
54
|
-
|
|
63
|
+
const id = assistantIdRef.current;
|
|
64
|
+
return platformBaseUrl && key && id
|
|
65
|
+
? { platformBaseUrl, assistantApiKey: key, assistantId: id }
|
|
55
66
|
: undefined;
|
|
56
67
|
};
|
|
57
68
|
|
|
58
69
|
const getManagedMaterializerOptions = (): ManagedMaterializerOptions | undefined => {
|
|
59
70
|
const key = getAssistantApiKey();
|
|
60
|
-
|
|
61
|
-
|
|
71
|
+
const id = assistantIdRef.current;
|
|
72
|
+
return platformBaseUrl && key && id
|
|
73
|
+
? { platformBaseUrl, assistantApiKey: key, assistantId: id }
|
|
62
74
|
: undefined;
|
|
63
75
|
};
|
|
64
76
|
|
package/src/managed-main.ts
CHANGED
|
@@ -55,7 +55,7 @@ import { buildCesEgressHooks } from "./commands/egress-hooks.js";
|
|
|
55
55
|
import { resolveManagedSubject } from "./subjects/managed.js";
|
|
56
56
|
import { materializeManagedToken } from "./materializers/managed-platform.js";
|
|
57
57
|
import { HandleType, parseHandle } from "@vellumai/ces-contracts";
|
|
58
|
-
import { buildLazyGetters, type ApiKeyRef } from "./managed-lazy-getters.js";
|
|
58
|
+
import { buildLazyGetters, type ApiKeyRef, type AssistantIdRef } from "./managed-lazy-getters.js";
|
|
59
59
|
import { MANAGED_LOCAL_STATIC_REJECTION_ERROR } from "./managed-errors.js";
|
|
60
60
|
import type { SecureKeyBackend } from "@vellumai/credential-storage";
|
|
61
61
|
import { createLocalSecureKeyBackend } from "./materializers/local-secure-key-backend.js";
|
|
@@ -91,7 +91,7 @@ function ensureDataDirs(): void {
|
|
|
91
91
|
// Build RPC handler registry (managed mode)
|
|
92
92
|
// ---------------------------------------------------------------------------
|
|
93
93
|
|
|
94
|
-
function buildHandlers(sessionIdRef: SessionIdRef, apiKeyRef: ApiKeyRef, secureKeyBackend: SecureKeyBackend): RpcHandlerRegistry {
|
|
94
|
+
function buildHandlers(sessionIdRef: SessionIdRef, apiKeyRef: ApiKeyRef, assistantIdRef: AssistantIdRef, secureKeyBackend: SecureKeyBackend): RpcHandlerRegistry {
|
|
95
95
|
// -- Grant stores ----------------------------------------------------------
|
|
96
96
|
const persistentGrantStore = new PersistentGrantStore(
|
|
97
97
|
getCesGrantsDir("managed"),
|
|
@@ -112,20 +112,19 @@ function buildHandlers(sessionIdRef: SessionIdRef, apiKeyRef: ApiKeyRef, secureK
|
|
|
112
112
|
// We use a lazy getter so the handshake-provided key takes effect even
|
|
113
113
|
// though handlers are built before the handshake completes.
|
|
114
114
|
const platformBaseUrl = process.env["VELLUM_PLATFORM_URL"] ?? "";
|
|
115
|
-
const assistantId = process.env["PLATFORM_ASSISTANT_ID"] ?? "";
|
|
116
115
|
|
|
117
116
|
const { getAssistantApiKey, getManagedSubjectOptions, getManagedMaterializerOptions } =
|
|
118
117
|
buildLazyGetters({
|
|
119
118
|
platformBaseUrl,
|
|
120
|
-
|
|
119
|
+
assistantIdRef,
|
|
121
120
|
apiKeyRef,
|
|
122
121
|
envApiKey: process.env["ASSISTANT_API_KEY"] || "",
|
|
123
122
|
});
|
|
124
123
|
|
|
125
|
-
if (!platformBaseUrl
|
|
124
|
+
if (!platformBaseUrl) {
|
|
126
125
|
warn(
|
|
127
|
-
"VELLUM_PLATFORM_URL
|
|
128
|
-
"Managed credential materialisation will depend on the handshake-provided
|
|
126
|
+
"VELLUM_PLATFORM_URL not set. " +
|
|
127
|
+
"Managed credential materialisation will depend on the handshake-provided values.",
|
|
129
128
|
);
|
|
130
129
|
}
|
|
131
130
|
|
|
@@ -570,7 +569,8 @@ async function main(): Promise<void> {
|
|
|
570
569
|
// are available to handlers at call time (after the handshake completes).
|
|
571
570
|
const sessionIdRef: SessionIdRef = { current: `ces-managed-${Date.now()}` };
|
|
572
571
|
const apiKeyRef: ApiKeyRef = { current: "" };
|
|
573
|
-
const
|
|
572
|
+
const assistantIdRef: AssistantIdRef = { current: process.env["PLATFORM_ASSISTANT_ID"] ?? "" };
|
|
573
|
+
const handlers = buildHandlers(sessionIdRef, apiKeyRef, assistantIdRef, secureKeyBackend);
|
|
574
574
|
|
|
575
575
|
const server = new CesRpcServer({
|
|
576
576
|
input: connection.readable,
|
|
@@ -585,16 +585,24 @@ async function main(): Promise<void> {
|
|
|
585
585
|
process.stderr.write(`[ces-managed] ERROR: ${msg} ${args.map(String).join(" ")}\n`),
|
|
586
586
|
},
|
|
587
587
|
signal: controller.signal,
|
|
588
|
-
onHandshakeComplete: (hsSessionId, hsApiKey) => {
|
|
588
|
+
onHandshakeComplete: (hsSessionId, hsApiKey, hsAssistantId) => {
|
|
589
589
|
sessionIdRef.current = hsSessionId;
|
|
590
590
|
if (hsApiKey) {
|
|
591
591
|
apiKeyRef.current = hsApiKey;
|
|
592
592
|
log(`Received assistant API key via handshake`);
|
|
593
593
|
}
|
|
594
|
+
if (hsAssistantId) {
|
|
595
|
+
assistantIdRef.current = hsAssistantId;
|
|
596
|
+
log(`Received assistant ID via handshake`);
|
|
597
|
+
}
|
|
594
598
|
},
|
|
595
|
-
onApiKeyUpdate: (newKey) => {
|
|
599
|
+
onApiKeyUpdate: (newKey, newAssistantId) => {
|
|
596
600
|
apiKeyRef.current = newKey;
|
|
597
601
|
log(`Assistant API key updated via RPC`);
|
|
602
|
+
if (newAssistantId) {
|
|
603
|
+
assistantIdRef.current = newAssistantId;
|
|
604
|
+
log(`Assistant ID updated via RPC`);
|
|
605
|
+
}
|
|
598
606
|
},
|
|
599
607
|
});
|
|
600
608
|
|
package/src/server.ts
CHANGED
|
@@ -88,10 +88,10 @@ export interface CesServerOptions {
|
|
|
88
88
|
logger?: Pick<Console, "log" | "warn" | "error">;
|
|
89
89
|
/** Optional abort signal to shut down the server. */
|
|
90
90
|
signal?: AbortSignal;
|
|
91
|
-
/** Callback invoked when the handshake completes with the negotiated session ID and optional API key. */
|
|
92
|
-
onHandshakeComplete?: (sessionId: string, assistantApiKey?: string) => void;
|
|
93
|
-
/** Callback invoked when the assistant pushes an updated API key after hatch. */
|
|
94
|
-
onApiKeyUpdate?: (assistantApiKey: string) => void;
|
|
91
|
+
/** Callback invoked when the handshake completes with the negotiated session ID and optional API key / assistant ID. */
|
|
92
|
+
onHandshakeComplete?: (sessionId: string, assistantApiKey?: string, assistantId?: string) => void;
|
|
93
|
+
/** Callback invoked when the assistant pushes an updated API key (and optionally assistant ID) after hatch. */
|
|
94
|
+
onApiKeyUpdate?: (assistantApiKey: string, assistantId?: string) => void;
|
|
95
95
|
}
|
|
96
96
|
|
|
97
97
|
// ---------------------------------------------------------------------------
|
|
@@ -104,7 +104,7 @@ export class CesRpcServer {
|
|
|
104
104
|
private readonly handlers: RpcHandlerRegistry;
|
|
105
105
|
private readonly logger: Pick<Console, "log" | "warn" | "error">;
|
|
106
106
|
private readonly signal?: AbortSignal;
|
|
107
|
-
private readonly onHandshakeComplete?: (sessionId: string, assistantApiKey?: string) => void;
|
|
107
|
+
private readonly onHandshakeComplete?: (sessionId: string, assistantApiKey?: string, assistantId?: string) => void;
|
|
108
108
|
|
|
109
109
|
private handshakeComplete = false;
|
|
110
110
|
private sessionId: string | null = null;
|
|
@@ -123,8 +123,8 @@ export class CesRpcServer {
|
|
|
123
123
|
if (options.onApiKeyUpdate) {
|
|
124
124
|
const onUpdate = options.onApiKeyUpdate;
|
|
125
125
|
this.handlers[CesRpcMethod.UpdateManagedCredential] = (request: unknown) => {
|
|
126
|
-
const { assistantApiKey } = request as { assistantApiKey: string };
|
|
127
|
-
onUpdate(assistantApiKey);
|
|
126
|
+
const { assistantApiKey, assistantId } = request as { assistantApiKey: string; assistantId?: string };
|
|
127
|
+
onUpdate(assistantApiKey, assistantId);
|
|
128
128
|
return { updated: true };
|
|
129
129
|
};
|
|
130
130
|
}
|
|
@@ -267,7 +267,7 @@ export class CesRpcServer {
|
|
|
267
267
|
this.handshakeComplete = true;
|
|
268
268
|
this.sessionId = req.sessionId;
|
|
269
269
|
this.logger.log(`[ces-server] Handshake accepted for session ${req.sessionId}`);
|
|
270
|
-
this.onHandshakeComplete?.(req.sessionId, req.assistantApiKey);
|
|
270
|
+
this.onHandshakeComplete?.(req.sessionId, req.assistantApiKey, req.assistantId);
|
|
271
271
|
} else {
|
|
272
272
|
this.logger.warn(
|
|
273
273
|
`[ces-server] Handshake rejected: version mismatch (got ${req.protocolVersion}, expected ${CES_PROTOCOL_VERSION})`,
|