@lasso-ai/cli 2.1.1 → 2.1.3
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/cli/bridge.js
CHANGED
|
@@ -151,6 +151,22 @@ async function startBridge(cwd = process.cwd(), collabConfig = null, bridgePort
|
|
|
151
151
|
...readEnvFile(root, ".env.local"),
|
|
152
152
|
...readEnvFile(root, ".env.production"),
|
|
153
153
|
}), {});
|
|
154
|
+
// Resolve the user's own model-provider key (BYOK) for hosted runs: the
|
|
155
|
+
// server calls the provider with it and never stores it.
|
|
156
|
+
const PROVIDER_ENV_KEYS = {
|
|
157
|
+
anthropic: ["ANTHROPIC_API_KEY"],
|
|
158
|
+
openai: ["OPENAI_API_KEY"],
|
|
159
|
+
google: ["GOOGLE_GENERATIVE_AI_API_KEY", "GOOGLE_API_KEY"],
|
|
160
|
+
nvidia: ["NVIDIA_API_KEY"],
|
|
161
|
+
};
|
|
162
|
+
function providerApiKeyFor(provider) {
|
|
163
|
+
for (const envName of PROVIDER_ENV_KEYS[provider] || []) {
|
|
164
|
+
const value = (process.env[envName] || fileEnv[envName] || "").trim();
|
|
165
|
+
if (value)
|
|
166
|
+
return value;
|
|
167
|
+
}
|
|
168
|
+
return undefined;
|
|
169
|
+
}
|
|
154
170
|
const cliCredentials = (0, auth_1.loadCredentials)();
|
|
155
171
|
const resolvedLassoKey = cliCredentials?.apiKey ||
|
|
156
172
|
(0, project_1.resolveLassoApiKey)(fileEnv) ||
|
|
@@ -425,7 +441,7 @@ async function startBridge(cwd = process.cwd(), collabConfig = null, bridgePort
|
|
|
425
441
|
// already rolled back at that point).
|
|
426
442
|
await facade.runSession(session.id, cwd, (event) => {
|
|
427
443
|
handleRuntimeEvent(event, socket, taskId, session, `Runtime session: ${instruction}`, true);
|
|
428
|
-
}, controller.signal);
|
|
444
|
+
}, controller.signal, { providerApiKey: providerApiKeyFor(provider) });
|
|
429
445
|
}
|
|
430
446
|
catch (error) {
|
|
431
447
|
socket.send(JSON.stringify({
|
|
@@ -575,7 +591,7 @@ async function startBridge(cwd = process.cwd(), collabConfig = null, bridgePort
|
|
|
575
591
|
try {
|
|
576
592
|
await facade.runSession(session.id, cwd, (event) => {
|
|
577
593
|
handleRuntimeEvent(event, socket, taskId, session, "Corrective run", true);
|
|
578
|
-
}, controller.signal);
|
|
594
|
+
}, controller.signal, { providerApiKey: providerApiKeyFor(session.model?.provider || "") });
|
|
579
595
|
}
|
|
580
596
|
catch (error) {
|
|
581
597
|
socket.send(JSON.stringify({
|
|
@@ -734,7 +750,7 @@ async function startBridge(cwd = process.cwd(), collabConfig = null, bridgePort
|
|
|
734
750
|
message: "Oneshot completed",
|
|
735
751
|
}));
|
|
736
752
|
}
|
|
737
|
-
}, controller.signal);
|
|
753
|
+
}, controller.signal, { providerApiKey: providerApiKeyFor(provider) });
|
|
738
754
|
}
|
|
739
755
|
catch (error) {
|
|
740
756
|
socket.send(JSON.stringify({
|
|
@@ -14,7 +14,9 @@ export declare class LocalRuntime implements RuntimeFacade {
|
|
|
14
14
|
private abortControllers;
|
|
15
15
|
createSession(input: RuntimeSessionInput): Promise<RuntimeSession>;
|
|
16
16
|
getSession(sessionId: string): Promise<RuntimeSession>;
|
|
17
|
-
runSession(sessionId: string, projectPath: string, onEvent: RuntimeEventHandler, signal?: AbortSignal
|
|
17
|
+
runSession(sessionId: string, projectPath: string, onEvent: RuntimeEventHandler, signal?: AbortSignal, _opts?: {
|
|
18
|
+
providerApiKey?: string;
|
|
19
|
+
}): Promise<void>;
|
|
18
20
|
verifySession(sessionId: string, projectPath: string): Promise<SessionVerificationResult>;
|
|
19
21
|
switchModel(sessionId: string, model: {
|
|
20
22
|
provider: string;
|
|
@@ -63,7 +63,8 @@ class LocalRuntime {
|
|
|
63
63
|
throw new Error("Session not found");
|
|
64
64
|
return this.toSession(record);
|
|
65
65
|
}
|
|
66
|
-
async runSession(sessionId, projectPath, onEvent, signal
|
|
66
|
+
async runSession(sessionId, projectPath, onEvent, signal, _opts // local agents run in-process; no server/model key needed
|
|
67
|
+
) {
|
|
67
68
|
const record = this.sessions.get(sessionId);
|
|
68
69
|
if (!record)
|
|
69
70
|
throw new Error("Session not found");
|
package/dist/cli/project.js
CHANGED
|
@@ -394,8 +394,32 @@ async function resolveWorkspaceConfig(fileEnv) {
|
|
|
394
394
|
async function fetchModels(fileEnv) {
|
|
395
395
|
const serverUrl = (0, auth_1.serverUrlFrom)(fileEnv).replace(/\/$/, "");
|
|
396
396
|
const apiUrl = `${serverUrl}/api/v1`;
|
|
397
|
+
// Pass the user's own provider keys (BYOK) so the server can list live
|
|
398
|
+
// models per provider instead of falling back to empty/static lists.
|
|
399
|
+
const envKey = (...names) => {
|
|
400
|
+
for (const name of names) {
|
|
401
|
+
const value = (process.env[name] || fileEnv[name] || "").trim();
|
|
402
|
+
if (value)
|
|
403
|
+
return value;
|
|
404
|
+
}
|
|
405
|
+
return "";
|
|
406
|
+
};
|
|
407
|
+
const query = new URLSearchParams();
|
|
408
|
+
const anthropicKey = envKey("ANTHROPIC_API_KEY");
|
|
409
|
+
const openaiKey = envKey("OPENAI_API_KEY");
|
|
410
|
+
const googleKey = envKey("GOOGLE_GENERATIVE_AI_API_KEY", "GOOGLE_API_KEY");
|
|
411
|
+
const nvidiaKey = envKey("NVIDIA_API_KEY");
|
|
412
|
+
if (anthropicKey)
|
|
413
|
+
query.set("anthropicKey", anthropicKey);
|
|
414
|
+
if (openaiKey)
|
|
415
|
+
query.set("openaiKey", openaiKey);
|
|
416
|
+
if (googleKey)
|
|
417
|
+
query.set("googleKey", googleKey);
|
|
418
|
+
if (nvidiaKey)
|
|
419
|
+
query.set("nvidiaKey", nvidiaKey);
|
|
420
|
+
const qs = query.toString();
|
|
397
421
|
try {
|
|
398
|
-
const response = await (0, auth_1.fetchWithTimeout)(`${apiUrl}/models`, {
|
|
422
|
+
const response = await (0, auth_1.fetchWithTimeout)(`${apiUrl}/models${qs ? `?${qs}` : ""}`, {
|
|
399
423
|
method: "GET",
|
|
400
424
|
});
|
|
401
425
|
if (!response.ok) {
|
|
@@ -137,7 +137,9 @@ export interface SessionVerificationResult {
|
|
|
137
137
|
*/
|
|
138
138
|
export interface RuntimeFacade {
|
|
139
139
|
createSession(input: RuntimeSessionInput): Promise<RuntimeSession>;
|
|
140
|
-
runSession(sessionId: string, projectPath: string, onEvent: RuntimeEventHandler, signal?: AbortSignal
|
|
140
|
+
runSession(sessionId: string, projectPath: string, onEvent: RuntimeEventHandler, signal?: AbortSignal, opts?: {
|
|
141
|
+
providerApiKey?: string;
|
|
142
|
+
}): Promise<void>;
|
|
141
143
|
getSession(sessionId: string): Promise<RuntimeSession>;
|
|
142
144
|
verifySession(sessionId: string, projectPath: string): Promise<SessionVerificationResult>;
|
|
143
145
|
switchModel(sessionId: string, model: {
|
|
@@ -288,7 +290,9 @@ export declare class RuntimeClient {
|
|
|
288
290
|
* 3. On agent_completed: diff the workspace, roll it back, and cache the
|
|
289
291
|
* changes for the review panel. Only user approval re-applies them.
|
|
290
292
|
*/
|
|
291
|
-
runSession(sessionId: string, projectPath: string, onEvent: RuntimeEventHandler, signal?: AbortSignal
|
|
293
|
+
runSession(sessionId: string, projectPath: string, onEvent: RuntimeEventHandler, signal?: AbortSignal, opts?: {
|
|
294
|
+
providerApiKey?: string;
|
|
295
|
+
}): Promise<void>;
|
|
292
296
|
/** Execute a tool_call request locally against the real project. */
|
|
293
297
|
private executeToolCallLocally;
|
|
294
298
|
/** Post a tool result back to the server (resolves its pending request). */
|
|
@@ -77,7 +77,7 @@ class RuntimeClient {
|
|
|
77
77
|
* 3. On agent_completed: diff the workspace, roll it back, and cache the
|
|
78
78
|
* changes for the review panel. Only user approval re-applies them.
|
|
79
79
|
*/
|
|
80
|
-
async runSession(sessionId, projectPath, onEvent, signal) {
|
|
80
|
+
async runSession(sessionId, projectPath, onEvent, signal, opts) {
|
|
81
81
|
// CLI-side snapshot: nothing the agent does is left on disk before review.
|
|
82
82
|
let guard = null;
|
|
83
83
|
try {
|
|
@@ -127,7 +127,9 @@ class RuntimeClient {
|
|
|
127
127
|
"Content-Type": "application/json",
|
|
128
128
|
...(this.apiKey && { "Authorization": `Bearer ${this.apiKey}` }),
|
|
129
129
|
},
|
|
130
|
-
|
|
130
|
+
// providerApiKey is the user's own model-provider key (BYOK): the
|
|
131
|
+
// server calls the hosted model with it and never stores it.
|
|
132
|
+
body: JSON.stringify({ projectPath, apiKey: opts?.providerApiKey }),
|
|
131
133
|
signal,
|
|
132
134
|
});
|
|
133
135
|
if (!response.ok) {
|
package/package.json
CHANGED