@lasso-ai/cli 1.4.5 → 1.5.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/cli/agent.d.ts +9 -89
- package/dist/cli/agent.js +66 -1412
- package/dist/cli/bridge-old.d.ts +259 -0
- package/dist/cli/bridge-old.js +1350 -0
- package/dist/cli/bridge.d.ts +19 -12
- package/dist/cli/bridge.js +625 -1181
- package/dist/cli/host/next-host-entry.js +0 -2
- package/dist/cli/host/vite-host-entry.js +1 -3
- package/dist/cli/oneshot.js +159 -961
- package/dist/cli/runtime-client.d.ts +229 -0
- package/dist/cli/runtime-client.js +143 -0
- package/dist/cli/snapshot.d.ts +3 -1
- package/dist/cli/snapshot.js +8 -1
- package/package.json +1 -1
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lasso Runtime Client
|
|
3
|
+
*
|
|
4
|
+
* Client for the new Lasso Agentic Runtime
|
|
5
|
+
* Uses SSE for real-time progress events
|
|
6
|
+
*/
|
|
7
|
+
export interface RuntimeSessionInput {
|
|
8
|
+
userPrompt: string;
|
|
9
|
+
project: {
|
|
10
|
+
projectId: string;
|
|
11
|
+
framework?: string;
|
|
12
|
+
hasTypeScript?: boolean;
|
|
13
|
+
hasReact?: boolean;
|
|
14
|
+
hasNext?: boolean;
|
|
15
|
+
hasVite?: boolean;
|
|
16
|
+
files?: string[];
|
|
17
|
+
currentRoute?: string;
|
|
18
|
+
};
|
|
19
|
+
model: {
|
|
20
|
+
provider: "anthropic" | "openai" | "google" | "nvidia" | "ollama";
|
|
21
|
+
id: string;
|
|
22
|
+
name?: string;
|
|
23
|
+
};
|
|
24
|
+
selection?: {
|
|
25
|
+
element?: {
|
|
26
|
+
tag?: string;
|
|
27
|
+
text?: string;
|
|
28
|
+
source?: string;
|
|
29
|
+
attributes?: Record<string, string>;
|
|
30
|
+
};
|
|
31
|
+
viewport?: {
|
|
32
|
+
width: number;
|
|
33
|
+
height: number;
|
|
34
|
+
scrollY?: number;
|
|
35
|
+
scrollHeight?: number;
|
|
36
|
+
};
|
|
37
|
+
route?: string;
|
|
38
|
+
screenshot?: string;
|
|
39
|
+
};
|
|
40
|
+
conversationUid?: string;
|
|
41
|
+
}
|
|
42
|
+
export interface RuntimeSession {
|
|
43
|
+
id: string;
|
|
44
|
+
phase: "understand" | "inspect" | "plan" | "execute" | "verify" | "recover" | "complete";
|
|
45
|
+
status: "running" | "waiting" | "completed" | "failed" | "cancelled";
|
|
46
|
+
iteration: number;
|
|
47
|
+
userPrompt: string;
|
|
48
|
+
conversation: Array<{
|
|
49
|
+
id: string;
|
|
50
|
+
role: "user" | "assistant" | "system" | "tool";
|
|
51
|
+
content: string;
|
|
52
|
+
timestamp: number;
|
|
53
|
+
metadata?: Record<string, unknown>;
|
|
54
|
+
}>;
|
|
55
|
+
observations: Array<{
|
|
56
|
+
id: string;
|
|
57
|
+
type: string;
|
|
58
|
+
summary: string;
|
|
59
|
+
data?: unknown;
|
|
60
|
+
timestamp: number;
|
|
61
|
+
phase?: string;
|
|
62
|
+
actionId?: string;
|
|
63
|
+
}>;
|
|
64
|
+
actions: Array<{
|
|
65
|
+
id: string;
|
|
66
|
+
type: string;
|
|
67
|
+
data: Record<string, unknown>;
|
|
68
|
+
}>;
|
|
69
|
+
completedActions: Array<{
|
|
70
|
+
id: string;
|
|
71
|
+
type: string;
|
|
72
|
+
data: Record<string, unknown>;
|
|
73
|
+
}>;
|
|
74
|
+
errors: Array<{
|
|
75
|
+
id: string;
|
|
76
|
+
type: string;
|
|
77
|
+
message: string;
|
|
78
|
+
phase: string;
|
|
79
|
+
actionId?: string;
|
|
80
|
+
timestamp: number;
|
|
81
|
+
recoverable: boolean;
|
|
82
|
+
}>;
|
|
83
|
+
plan?: {
|
|
84
|
+
id: string;
|
|
85
|
+
goal: string;
|
|
86
|
+
steps: Array<{
|
|
87
|
+
id: string;
|
|
88
|
+
description: string;
|
|
89
|
+
status: string;
|
|
90
|
+
actionCount?: number;
|
|
91
|
+
}>;
|
|
92
|
+
estimatedActions?: number;
|
|
93
|
+
};
|
|
94
|
+
selection?: RuntimeSessionInput["selection"];
|
|
95
|
+
project: RuntimeSessionInput["project"];
|
|
96
|
+
model: RuntimeSessionInput["model"];
|
|
97
|
+
conversationUid?: string;
|
|
98
|
+
createdAt: Date;
|
|
99
|
+
updatedAt: Date;
|
|
100
|
+
}
|
|
101
|
+
export type RuntimeEvent = {
|
|
102
|
+
type: "agent_started";
|
|
103
|
+
sessionId: string;
|
|
104
|
+
data: {};
|
|
105
|
+
timestamp: number;
|
|
106
|
+
} | {
|
|
107
|
+
type: "agent_reasoning";
|
|
108
|
+
sessionId: string;
|
|
109
|
+
data: {
|
|
110
|
+
summary: string;
|
|
111
|
+
};
|
|
112
|
+
timestamp: number;
|
|
113
|
+
} | {
|
|
114
|
+
type: "phase_changed";
|
|
115
|
+
sessionId: string;
|
|
116
|
+
data: {
|
|
117
|
+
from: string;
|
|
118
|
+
to: string;
|
|
119
|
+
};
|
|
120
|
+
timestamp: number;
|
|
121
|
+
} | {
|
|
122
|
+
type: "tool_started";
|
|
123
|
+
sessionId: string;
|
|
124
|
+
data: {
|
|
125
|
+
actionType: string;
|
|
126
|
+
};
|
|
127
|
+
timestamp: number;
|
|
128
|
+
} | {
|
|
129
|
+
type: "tool_completed";
|
|
130
|
+
sessionId: string;
|
|
131
|
+
data: {
|
|
132
|
+
actionType: string;
|
|
133
|
+
success: boolean;
|
|
134
|
+
};
|
|
135
|
+
timestamp: number;
|
|
136
|
+
} | {
|
|
137
|
+
type: "observation";
|
|
138
|
+
sessionId: string;
|
|
139
|
+
data: {
|
|
140
|
+
observationType: string;
|
|
141
|
+
summary: string;
|
|
142
|
+
};
|
|
143
|
+
timestamp: number;
|
|
144
|
+
} | {
|
|
145
|
+
type: "verification_started";
|
|
146
|
+
sessionId: string;
|
|
147
|
+
data: {
|
|
148
|
+
verificationType: string;
|
|
149
|
+
};
|
|
150
|
+
timestamp: number;
|
|
151
|
+
} | {
|
|
152
|
+
type: "verification_completed";
|
|
153
|
+
sessionId: string;
|
|
154
|
+
data: {
|
|
155
|
+
verificationType: string;
|
|
156
|
+
success: boolean;
|
|
157
|
+
};
|
|
158
|
+
timestamp: number;
|
|
159
|
+
} | {
|
|
160
|
+
type: "waiting_for_user";
|
|
161
|
+
sessionId: string;
|
|
162
|
+
data: {
|
|
163
|
+
question: string;
|
|
164
|
+
};
|
|
165
|
+
timestamp: number;
|
|
166
|
+
} | {
|
|
167
|
+
type: "error";
|
|
168
|
+
sessionId: string;
|
|
169
|
+
data: {
|
|
170
|
+
errorType: string;
|
|
171
|
+
message: string;
|
|
172
|
+
phase: string;
|
|
173
|
+
recoverable: boolean;
|
|
174
|
+
};
|
|
175
|
+
timestamp: number;
|
|
176
|
+
} | {
|
|
177
|
+
type: "model_changed";
|
|
178
|
+
sessionId: string;
|
|
179
|
+
data: {
|
|
180
|
+
from: any;
|
|
181
|
+
to: any;
|
|
182
|
+
};
|
|
183
|
+
timestamp: number;
|
|
184
|
+
} | {
|
|
185
|
+
type: "agent_completed";
|
|
186
|
+
sessionId: string;
|
|
187
|
+
data: {};
|
|
188
|
+
timestamp: number;
|
|
189
|
+
} | {
|
|
190
|
+
type: "started";
|
|
191
|
+
sessionId: string;
|
|
192
|
+
} | {
|
|
193
|
+
type: "completed";
|
|
194
|
+
sessionId: string;
|
|
195
|
+
};
|
|
196
|
+
export type RuntimeEventHandler = (event: RuntimeEvent) => void | Promise<void>;
|
|
197
|
+
export declare class RuntimeClient {
|
|
198
|
+
private serverUrl;
|
|
199
|
+
private apiKey?;
|
|
200
|
+
constructor(serverUrl: string, apiKey?: string);
|
|
201
|
+
/**
|
|
202
|
+
* Create a new runtime session
|
|
203
|
+
*/
|
|
204
|
+
createSession(input: RuntimeSessionInput): Promise<RuntimeSession>;
|
|
205
|
+
/**
|
|
206
|
+
* Get a session by ID
|
|
207
|
+
*/
|
|
208
|
+
getSession(sessionId: string): Promise<RuntimeSession>;
|
|
209
|
+
/**
|
|
210
|
+
* Run a session with SSE event streaming
|
|
211
|
+
*/
|
|
212
|
+
runSession(sessionId: string, projectPath: string, onEvent: RuntimeEventHandler, signal?: AbortSignal): Promise<void>;
|
|
213
|
+
/**
|
|
214
|
+
* Cancel a running session
|
|
215
|
+
*/
|
|
216
|
+
cancelSession(sessionId: string): Promise<void>;
|
|
217
|
+
/**
|
|
218
|
+
* Switch model for a session
|
|
219
|
+
*/
|
|
220
|
+
switchModel(sessionId: string, model: {
|
|
221
|
+
provider: string;
|
|
222
|
+
id: string;
|
|
223
|
+
name?: string;
|
|
224
|
+
}, apiKey?: string): Promise<void>;
|
|
225
|
+
/**
|
|
226
|
+
* Delete a session
|
|
227
|
+
*/
|
|
228
|
+
deleteSession(sessionId: string): Promise<void>;
|
|
229
|
+
}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Lasso Runtime Client
|
|
4
|
+
*
|
|
5
|
+
* Client for the new Lasso Agentic Runtime
|
|
6
|
+
* Uses SSE for real-time progress events
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.RuntimeClient = void 0;
|
|
10
|
+
class RuntimeClient {
|
|
11
|
+
serverUrl;
|
|
12
|
+
apiKey;
|
|
13
|
+
constructor(serverUrl, apiKey) {
|
|
14
|
+
this.serverUrl = serverUrl;
|
|
15
|
+
this.apiKey = apiKey;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Create a new runtime session
|
|
19
|
+
*/
|
|
20
|
+
async createSession(input) {
|
|
21
|
+
const response = await fetch(`${this.serverUrl}/api/v1/agent-runtime/sessions`, {
|
|
22
|
+
method: "POST",
|
|
23
|
+
headers: {
|
|
24
|
+
"Content-Type": "application/json",
|
|
25
|
+
...(this.apiKey && { "Authorization": `Bearer ${this.apiKey}` }),
|
|
26
|
+
},
|
|
27
|
+
body: JSON.stringify(input),
|
|
28
|
+
});
|
|
29
|
+
if (!response.ok) {
|
|
30
|
+
throw new Error(`Failed to create session: ${response.statusText}`);
|
|
31
|
+
}
|
|
32
|
+
const data = await response.json();
|
|
33
|
+
return data;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Get a session by ID
|
|
37
|
+
*/
|
|
38
|
+
async getSession(sessionId) {
|
|
39
|
+
const response = await fetch(`${this.serverUrl}/api/v1/agent-runtime/sessions/${sessionId}`, {
|
|
40
|
+
headers: {
|
|
41
|
+
...(this.apiKey && { "Authorization": `Bearer ${this.apiKey}` }),
|
|
42
|
+
},
|
|
43
|
+
});
|
|
44
|
+
if (!response.ok) {
|
|
45
|
+
throw new Error(`Failed to get session: ${response.statusText}`);
|
|
46
|
+
}
|
|
47
|
+
const data = await response.json();
|
|
48
|
+
return data;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Run a session with SSE event streaming
|
|
52
|
+
*/
|
|
53
|
+
async runSession(sessionId, projectPath, onEvent, signal) {
|
|
54
|
+
const response = await fetch(`${this.serverUrl}/api/v1/agent-runtime/sessions/${sessionId}/run`, {
|
|
55
|
+
method: "POST",
|
|
56
|
+
headers: {
|
|
57
|
+
"Content-Type": "application/json",
|
|
58
|
+
...(this.apiKey && { "Authorization": `Bearer ${this.apiKey}` }),
|
|
59
|
+
},
|
|
60
|
+
body: JSON.stringify({ projectPath }),
|
|
61
|
+
signal,
|
|
62
|
+
});
|
|
63
|
+
if (!response.ok) {
|
|
64
|
+
throw new Error(`Failed to run session: ${response.statusText}`);
|
|
65
|
+
}
|
|
66
|
+
const reader = response.body?.getReader();
|
|
67
|
+
if (!reader) {
|
|
68
|
+
throw new Error("No response body");
|
|
69
|
+
}
|
|
70
|
+
const decoder = new TextDecoder();
|
|
71
|
+
try {
|
|
72
|
+
while (true) {
|
|
73
|
+
const { done, value } = await reader.read();
|
|
74
|
+
if (done)
|
|
75
|
+
break;
|
|
76
|
+
const chunk = decoder.decode(value);
|
|
77
|
+
const lines = chunk.split("\n");
|
|
78
|
+
for (const line of lines) {
|
|
79
|
+
if (!line.trim() || !line.startsWith("data: "))
|
|
80
|
+
continue;
|
|
81
|
+
const data = line.slice(6);
|
|
82
|
+
if (data === "[DONE]")
|
|
83
|
+
continue;
|
|
84
|
+
try {
|
|
85
|
+
const event = JSON.parse(data);
|
|
86
|
+
await onEvent(event);
|
|
87
|
+
}
|
|
88
|
+
catch (error) {
|
|
89
|
+
console.error("Failed to parse SSE event:", error);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
finally {
|
|
95
|
+
reader.releaseLock();
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Cancel a running session
|
|
100
|
+
*/
|
|
101
|
+
async cancelSession(sessionId) {
|
|
102
|
+
const response = await fetch(`${this.serverUrl}/api/v1/agent-runtime/sessions/${sessionId}/cancel`, {
|
|
103
|
+
method: "POST",
|
|
104
|
+
headers: {
|
|
105
|
+
...(this.apiKey && { "Authorization": `Bearer ${this.apiKey}` }),
|
|
106
|
+
},
|
|
107
|
+
});
|
|
108
|
+
if (!response.ok) {
|
|
109
|
+
throw new Error(`Failed to cancel session: ${response.statusText}`);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Switch model for a session
|
|
114
|
+
*/
|
|
115
|
+
async switchModel(sessionId, model, apiKey) {
|
|
116
|
+
const response = await fetch(`${this.serverUrl}/api/v1/agent-runtime/sessions/${sessionId}/model`, {
|
|
117
|
+
method: "POST",
|
|
118
|
+
headers: {
|
|
119
|
+
"Content-Type": "application/json",
|
|
120
|
+
...(this.apiKey && { "Authorization": `Bearer ${this.apiKey}` }),
|
|
121
|
+
},
|
|
122
|
+
body: JSON.stringify({ ...model, apiKey }),
|
|
123
|
+
});
|
|
124
|
+
if (!response.ok) {
|
|
125
|
+
throw new Error(`Failed to switch model: ${response.statusText}`);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Delete a session
|
|
130
|
+
*/
|
|
131
|
+
async deleteSession(sessionId) {
|
|
132
|
+
const response = await fetch(`${this.serverUrl}/api/v1/agent-runtime/sessions/${sessionId}`, {
|
|
133
|
+
method: "DELETE",
|
|
134
|
+
headers: {
|
|
135
|
+
...(this.apiKey && { "Authorization": `Bearer ${this.apiKey}` }),
|
|
136
|
+
},
|
|
137
|
+
});
|
|
138
|
+
if (!response.ok) {
|
|
139
|
+
throw new Error(`Failed to delete session: ${response.statusText}`);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
exports.RuntimeClient = RuntimeClient;
|
package/dist/cli/snapshot.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ export type FileSnapshot = {
|
|
|
7
7
|
export type TimelineSnapshot = {
|
|
8
8
|
id: string;
|
|
9
9
|
taskId: string;
|
|
10
|
+
sessionId?: string;
|
|
10
11
|
summary: string;
|
|
11
12
|
files: FileSnapshot[];
|
|
12
13
|
createdAt: string;
|
|
@@ -19,7 +20,7 @@ export type ConflictInfo = {
|
|
|
19
20
|
originalContent: string;
|
|
20
21
|
currentContent: string;
|
|
21
22
|
};
|
|
22
|
-
export declare function createSnapshot(cwd: string, taskId: string, summary: string, filePaths: string[], parentSnapshotId?: string): TimelineSnapshot;
|
|
23
|
+
export declare function createSnapshot(cwd: string, taskId: string, summary: string, filePaths: string[], parentSnapshotId?: string, sessionId?: string): TimelineSnapshot;
|
|
23
24
|
export declare function restoreSnapshot(cwd: string, snapshotId: string): boolean;
|
|
24
25
|
export declare function detectConflicts(cwd: string, expectedFiles: Array<{
|
|
25
26
|
filePath: string;
|
|
@@ -30,4 +31,5 @@ export declare function getTimeline(cwd: string, limit?: number): TimelineSnapsh
|
|
|
30
31
|
export declare function deleteSnapshot(cwd: string, snapshotId: string): boolean;
|
|
31
32
|
export declare function clearSnapshots(cwd: string): void;
|
|
32
33
|
export declare function getSnapshotByTaskId(cwd: string, taskId: string): TimelineSnapshot | undefined;
|
|
34
|
+
export declare function getSnapshotBySessionId(cwd: string, sessionId: string): TimelineSnapshot | undefined;
|
|
33
35
|
export declare function getLatestSnapshot(cwd: string): TimelineSnapshot | undefined;
|
package/dist/cli/snapshot.js
CHANGED
|
@@ -10,6 +10,7 @@ exports.getTimeline = getTimeline;
|
|
|
10
10
|
exports.deleteSnapshot = deleteSnapshot;
|
|
11
11
|
exports.clearSnapshots = clearSnapshots;
|
|
12
12
|
exports.getSnapshotByTaskId = getSnapshotByTaskId;
|
|
13
|
+
exports.getSnapshotBySessionId = getSnapshotBySessionId;
|
|
13
14
|
exports.getLatestSnapshot = getLatestSnapshot;
|
|
14
15
|
// src/cli/snapshot.ts
|
|
15
16
|
// Local history snapshot system for safe concurrent edits
|
|
@@ -59,7 +60,7 @@ function saveTimeline(cwd, timeline) {
|
|
|
59
60
|
}
|
|
60
61
|
}
|
|
61
62
|
// Create a snapshot of current file states
|
|
62
|
-
function createSnapshot(cwd, taskId, summary, filePaths, parentSnapshotId) {
|
|
63
|
+
function createSnapshot(cwd, taskId, summary, filePaths, parentSnapshotId, sessionId) {
|
|
63
64
|
ensureSnapshotsDir(cwd);
|
|
64
65
|
const snapshotId = generateSnapshotId();
|
|
65
66
|
const files = [];
|
|
@@ -87,6 +88,7 @@ function createSnapshot(cwd, taskId, summary, filePaths, parentSnapshotId) {
|
|
|
87
88
|
const snapshot = {
|
|
88
89
|
id: snapshotId,
|
|
89
90
|
taskId,
|
|
91
|
+
sessionId,
|
|
90
92
|
summary,
|
|
91
93
|
files,
|
|
92
94
|
createdAt: timestamp,
|
|
@@ -218,6 +220,11 @@ function getSnapshotByTaskId(cwd, taskId) {
|
|
|
218
220
|
const timeline = loadTimeline(cwd);
|
|
219
221
|
return timeline.find((s) => s.taskId === taskId);
|
|
220
222
|
}
|
|
223
|
+
// Get snapshot by session ID
|
|
224
|
+
function getSnapshotBySessionId(cwd, sessionId) {
|
|
225
|
+
const timeline = loadTimeline(cwd);
|
|
226
|
+
return timeline.find((s) => s.sessionId === sessionId);
|
|
227
|
+
}
|
|
221
228
|
// Get latest snapshot
|
|
222
229
|
function getLatestSnapshot(cwd) {
|
|
223
230
|
const timeline = loadTimeline(cwd);
|
package/package.json
CHANGED