@volter/supercode-frontend-vscode 0.1.47 → 0.1.48
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/extension.js +38 -0
- package/dist/session.d.ts +16 -0
- package/dist/session.js +17 -0
- package/package.json +2 -2
- package/vendor/supercode-frontend/contract.json +3 -0
- package/vendor/supercode-frontend/generated-client.d.mts +2 -1
- package/vendor/supercode-frontend/generated-client.mjs +1 -0
- package/vendor/supercode-frontend/generated.d.mts +8 -2
- package/vendor/supercode-frontend/generated.mjs +1 -0
- package/vendor/supercode-frontend/package.json +1 -1
package/dist/extension.js
CHANGED
|
@@ -994,6 +994,22 @@ export async function activate(context) {
|
|
|
994
994
|
watchApprovals: (connection, stream, token) => watchApprovals(connection, stream, token, () => approvalFor(connection.id)),
|
|
995
995
|
};
|
|
996
996
|
context.subscriptions.push(vscode.commands.registerCommand('supercode.frontend.activateSession', async (resource) => { await connectionFor(vscode.Uri.parse(resource)); }));
|
|
997
|
+
// A background task the chat named (sayTasks in runTurnInto), stopped through the harness's own control.
|
|
998
|
+
context.subscriptions.push(vscode.commands.registerCommand('supercode.frontend.stopBackgroundTask', async (connectionId, taskId) => {
|
|
999
|
+
const connection = frontends.get(connectionId);
|
|
1000
|
+
const task = connection?.session.backgroundTasks.find(candidate => candidate.id === taskId);
|
|
1001
|
+
if (!connection || !task) {
|
|
1002
|
+
void vscode.window.showInformationMessage('That background task is no longer running.');
|
|
1003
|
+
return;
|
|
1004
|
+
}
|
|
1005
|
+
try {
|
|
1006
|
+
const stopped = await connection.session.stopTask(taskId);
|
|
1007
|
+
void vscode.window.showInformationMessage(stopped ? `Stopped ${task.description || taskId}.` : `The harness did not stop ${task.description || taskId}.`);
|
|
1008
|
+
}
|
|
1009
|
+
catch (error) {
|
|
1010
|
+
void vscode.window.showErrorMessage(`Could not stop ${task.description || taskId}: ${String(error?.message ?? error)}`);
|
|
1011
|
+
}
|
|
1012
|
+
}));
|
|
997
1013
|
// The host's native focus event is authoritative even when a cached model
|
|
998
1014
|
// skips content resolution. Untitled/non-harness focus never starts a runtime.
|
|
999
1015
|
context.subscriptions.push(vscode.commands.registerCommand('supercode.frontend.focusSession', (resource) => {
|
|
@@ -1210,6 +1226,27 @@ export async function activate(context) {
|
|
|
1210
1226
|
});
|
|
1211
1227
|
const watch = watchApprovals(connection, stream, token, approval);
|
|
1212
1228
|
state.quiet = watch.answers;
|
|
1229
|
+
// The harness's own background tasks (a Monitor, a background shell): each event one reports is a turn of its own,
|
|
1230
|
+
// which this message waits behind, and nothing here would show it. Said once per change of the set, each with a
|
|
1231
|
+
// way to stop it.
|
|
1232
|
+
let saidTasks = '';
|
|
1233
|
+
const sayTasks = () => {
|
|
1234
|
+
const tasks = connection.session.backgroundTasks;
|
|
1235
|
+
const key = tasks.map(task => task.id).join(',');
|
|
1236
|
+
if (key === saidTasks)
|
|
1237
|
+
return;
|
|
1238
|
+
saidTasks = key;
|
|
1239
|
+
if (!tasks.length) {
|
|
1240
|
+
stream.markdown('\n\n_No background task is running any more._\n\n');
|
|
1241
|
+
return;
|
|
1242
|
+
}
|
|
1243
|
+
stream.markdown(`\n\n_${tasks.length === 1 ? 'A background task is' : `${tasks.length} background tasks are`} still running in this session. The harness answers each of its events as a turn of its own, so this message can wait behind them:_\n\n`);
|
|
1244
|
+
for (const task of tasks) {
|
|
1245
|
+
stream.button({ command: 'supercode.frontend.stopBackgroundTask', title: `Stop ${opaqueText(task.description || task.id, 80)}`, arguments: [connection.id, task.id] });
|
|
1246
|
+
}
|
|
1247
|
+
};
|
|
1248
|
+
sayTasks();
|
|
1249
|
+
const unwatchTasks = connection.session.onChange(sayTasks);
|
|
1213
1250
|
let completed = false;
|
|
1214
1251
|
try {
|
|
1215
1252
|
await connection.session.runTurn(prompt, (event) => {
|
|
@@ -1219,6 +1256,7 @@ export async function activate(context) {
|
|
|
1219
1256
|
completed = true;
|
|
1220
1257
|
}
|
|
1221
1258
|
finally {
|
|
1259
|
+
unwatchTasks();
|
|
1222
1260
|
watch.dispose();
|
|
1223
1261
|
cancellation.dispose();
|
|
1224
1262
|
if (controls && !attachedIds.has(connection.id)) {
|
package/dist/session.d.ts
CHANGED
|
@@ -15,6 +15,9 @@ export interface VscodeRuntimeClient {
|
|
|
15
15
|
steer(prompt: string): Promise<{
|
|
16
16
|
queued: boolean;
|
|
17
17
|
}>;
|
|
18
|
+
stopTask(taskId: string): Promise<{
|
|
19
|
+
stopped: boolean;
|
|
20
|
+
}>;
|
|
18
21
|
interrupt(): Promise<{
|
|
19
22
|
interrupted: boolean;
|
|
20
23
|
}>;
|
|
@@ -62,6 +65,12 @@ export declare const TURN_TERMINAL_KINDS: readonly ["turn_succeeded", "turn_fail
|
|
|
62
65
|
* the view reports.
|
|
63
66
|
*/
|
|
64
67
|
export declare const LEASE_ERROR_NAMES: readonly string[];
|
|
68
|
+
/** One of the harness's own background tasks (a Monitor, a background shell), as it last listed them. */
|
|
69
|
+
export interface BackgroundTask {
|
|
70
|
+
id: string;
|
|
71
|
+
kind: string;
|
|
72
|
+
description: string;
|
|
73
|
+
}
|
|
65
74
|
/**
|
|
66
75
|
* One attachment to one already-running Volter Harness SDK runtime: cursor-safe
|
|
67
76
|
* event projection, permission narrowing, and the semantic actions the runtime
|
|
@@ -86,6 +95,11 @@ export declare class VscodeFrontendSession {
|
|
|
86
95
|
*/
|
|
87
96
|
replay: FrontendEvent[];
|
|
88
97
|
pendingRequests: Map<number, FrontendRequest>;
|
|
98
|
+
/**
|
|
99
|
+
* The harness's own background tasks as it last listed them (`background_tasks`). Each event one reports starts a
|
|
100
|
+
* turn of its own, so while any runs the session can be busy with turns no one here submitted.
|
|
101
|
+
*/
|
|
102
|
+
backgroundTasks: BackgroundTask[];
|
|
89
103
|
/**
|
|
90
104
|
* Requests this attachment has seen resolved. `request_resolved` deletes the
|
|
91
105
|
* pending entry while it is being projected, so without this the resolution
|
|
@@ -136,6 +150,8 @@ export declare class VscodeFrontendSession {
|
|
|
136
150
|
submit(prompt: string): Promise<void>;
|
|
137
151
|
steer(prompt: string): Promise<void>;
|
|
138
152
|
interrupt(): Promise<void>;
|
|
153
|
+
/** Stop one of the harness's own background tasks, by the id it listed it with. */
|
|
154
|
+
stopTask(taskId: string): Promise<boolean>;
|
|
139
155
|
respond(response: FrontendResponse): Promise<void>;
|
|
140
156
|
detach(): Promise<void>;
|
|
141
157
|
close(): Promise<void>;
|
package/dist/session.js
CHANGED
|
@@ -56,6 +56,11 @@ export class VscodeFrontendSession {
|
|
|
56
56
|
*/
|
|
57
57
|
replay = [];
|
|
58
58
|
pendingRequests = new Map();
|
|
59
|
+
/**
|
|
60
|
+
* The harness's own background tasks as it last listed them (`background_tasks`). Each event one reports starts a
|
|
61
|
+
* turn of its own, so while any runs the session can be busy with turns no one here submitted.
|
|
62
|
+
*/
|
|
63
|
+
backgroundTasks = [];
|
|
59
64
|
/**
|
|
60
65
|
* Requests this attachment has seen resolved. `request_resolved` deletes the
|
|
61
66
|
* pending entry while it is being projected, so without this the resolution
|
|
@@ -105,6 +110,7 @@ export class VscodeFrontendSession {
|
|
|
105
110
|
const staged = {
|
|
106
111
|
descriptor: structuredClone(snapshot.descriptor),
|
|
107
112
|
pendingRequests: new Map([...this.pendingRequests].map(([id, request]) => [id, structuredClone(request)])),
|
|
113
|
+
backgroundTasks: structuredClone(this.backgroundTasks),
|
|
108
114
|
cursor: Math.max(this.cursor, snapshot.history_cursor),
|
|
109
115
|
};
|
|
110
116
|
// Validate and project the whole attachment before any observable field
|
|
@@ -129,6 +135,7 @@ export class VscodeFrontendSession {
|
|
|
129
135
|
this.historyCursor = snapshot.history_cursor;
|
|
130
136
|
this.appendTranscript(structuredClone(snapshot.replay));
|
|
131
137
|
this.pendingRequests = staged.pendingRequests;
|
|
138
|
+
this.backgroundTasks = staged.backgroundTasks;
|
|
132
139
|
this.cursor = staged.cursor;
|
|
133
140
|
this.connection = 'connected';
|
|
134
141
|
this.attachedAtMs ??= Date.now();
|
|
@@ -263,6 +270,11 @@ export class VscodeFrontendSession {
|
|
|
263
270
|
if (request && typeof request.id === 'number')
|
|
264
271
|
state.pendingRequests.set(request.id, structuredClone(request));
|
|
265
272
|
}
|
|
273
|
+
if (event.kind === 'background_tasks' && Array.isArray(payload.tasks)) {
|
|
274
|
+
state.backgroundTasks = payload.tasks
|
|
275
|
+
.filter(task => task && typeof task.id === 'string')
|
|
276
|
+
.map(task => ({ id: task.id, kind: String(task.kind ?? 'task'), description: String(task.description ?? '') }));
|
|
277
|
+
}
|
|
266
278
|
if (event.kind === 'request_resolved' && typeof payload.request_id === 'number') {
|
|
267
279
|
const resolved = state.pendingRequests.get(payload.request_id);
|
|
268
280
|
if (resolved) {
|
|
@@ -337,6 +349,11 @@ export class VscodeFrontendSession {
|
|
|
337
349
|
this.require('interrupt');
|
|
338
350
|
await this.withControl(() => this.client.interrupt());
|
|
339
351
|
}
|
|
352
|
+
/** Stop one of the harness's own background tasks, by the id it listed it with. */
|
|
353
|
+
async stopTask(taskId) {
|
|
354
|
+
const result = await this.withControl(() => this.client.stopTask(taskId));
|
|
355
|
+
return result?.stopped === true;
|
|
356
|
+
}
|
|
340
357
|
async respond(response) {
|
|
341
358
|
this.require('respond');
|
|
342
359
|
if (!this.pendingRequests.has(response.request_id))
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@volter/supercode-frontend-vscode",
|
|
3
3
|
"displayName": "Volter Harness",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.48",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "VS Code chat-view frontend for an existing Volter Harness SDK runtime",
|
|
7
7
|
"publisher": "volter-ai-dev",
|
|
@@ -190,7 +190,7 @@
|
|
|
190
190
|
},
|
|
191
191
|
"supercodeFrontendContract": {
|
|
192
192
|
"name": "@volter/supercode-frontend",
|
|
193
|
-
"version": "0.2.
|
|
193
|
+
"version": "0.2.9",
|
|
194
194
|
"mode": "generated-artifact"
|
|
195
195
|
},
|
|
196
196
|
"license": "MIT OR Apache-2.0"
|
|
@@ -251,6 +251,8 @@
|
|
|
251
251
|
"Reply": {"kind": "object", "fields": {"reply": {"type": "string"}}},
|
|
252
252
|
"Interrupted": {"kind": "object", "fields": {"interrupted": {"type": "boolean"}}},
|
|
253
253
|
"Queued": {"kind": "object", "fields": {"queued": {"type": "boolean"}}},
|
|
254
|
+
"TaskParams": {"kind": "object", "fields": {"task_id": {"type": "string"}}},
|
|
255
|
+
"Stopped": {"kind": "object", "fields": {"stopped": {"type": "boolean"}}},
|
|
254
256
|
"Closed": {"kind": "object", "fields": {"closed": {"type": "boolean"}}}
|
|
255
257
|
},
|
|
256
258
|
"methods": [
|
|
@@ -260,6 +262,7 @@
|
|
|
260
262
|
{"id": "submit", "wire": "frontend.v2.submit", "sdk_action": "input", "params": "MultimodalPromptParams", "result": "Reply", "compatibility": "completion_waiting_alias", "transports": ["local", "http", "websocket", "acp"]},
|
|
261
263
|
{"id": "interrupt", "wire": "frontend.v2.interrupt", "sdk_action": "interrupt", "params": "Empty", "result": "Interrupted", "transports": ["local", "http", "websocket", "acp"]},
|
|
262
264
|
{"id": "steer", "wire": "frontend.v2.steer", "sdk_action": "steer", "params": "PromptParams", "result": "Queued", "transports": ["local", "http", "websocket", "acp"]},
|
|
265
|
+
{"id": "stop_task", "wire": "frontend.v2.stop_task", "sdk_action": "stop_task", "params": "TaskParams", "result": "Stopped", "transports": ["local", "http", "websocket", "acp"]},
|
|
263
266
|
{"id": "respond", "wire": "frontend.v2.respond", "sdk_action": "respond", "params": "RespondParams", "result": "Accepted", "transports": ["local", "http", "websocket", "acp"]},
|
|
264
267
|
{"id": "invoke", "wire": "frontend.v2.invoke", "sdk_action": "input", "params": "InvokeParams", "result": "FrontendOperationResult", "transports": ["local", "http", "websocket", "acp"]},
|
|
265
268
|
{"id": "lease", "wire": "frontend.v2.lease", "sdk_action": "events", "params": "Empty", "result": "RuntimeLeaseSnapshot", "transports": ["local", "http", "websocket", "acp"]},
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// @generated by sdk/frontend/generate.mjs from contract.json. Do not edit.
|
|
2
|
-
import type { Accepted, Closed, FrontendAttachSnapshot, FrontendOperationInvocation, FrontendOperationResult, FrontendResponse, FrontendRuntimeDescriptor, FrontendWireMethod, Interrupted, Queued, Reply, RuntimeLeaseSnapshot } from './generated.mjs';
|
|
2
|
+
import type { Accepted, Closed, FrontendAttachSnapshot, FrontendOperationInvocation, FrontendOperationResult, FrontendResponse, FrontendRuntimeDescriptor, FrontendWireMethod, Interrupted, Queued, Reply, RuntimeLeaseSnapshot, Stopped } from './generated.mjs';
|
|
3
3
|
export abstract class GeneratedFrontendClient<Options = unknown> {
|
|
4
4
|
abstract rpc(method: FrontendWireMethod, params?: Record<string, unknown>, options?: Options): Promise<unknown>;
|
|
5
5
|
describe(options?: Options): Promise<FrontendRuntimeDescriptor>;
|
|
@@ -8,6 +8,7 @@ export abstract class GeneratedFrontendClient<Options = unknown> {
|
|
|
8
8
|
submit(prompt: string, options?: Options & {imageUrls?: string[]}): Promise<Reply>;
|
|
9
9
|
interrupt(options?: Options): Promise<Interrupted>;
|
|
10
10
|
steer(prompt: string, options?: Options): Promise<Queued>;
|
|
11
|
+
stopTask(taskId: string, options?: Options): Promise<Stopped>;
|
|
11
12
|
respond(response: FrontendResponse, options?: Options): Promise<Accepted>;
|
|
12
13
|
invoke(operation: FrontendOperationInvocation, options?: Options): Promise<FrontendOperationResult>;
|
|
13
14
|
lease(options?: Options): Promise<RuntimeLeaseSnapshot>;
|
|
@@ -9,6 +9,7 @@ export class GeneratedFrontendClient {
|
|
|
9
9
|
submit(prompt, { imageUrls, ...options } = {}) { return this.rpc(FRONTEND_METHODS.submit, { prompt, ...(imageUrls?.length ? {image_urls:imageUrls} : {}) }, options); }
|
|
10
10
|
interrupt(options) { return this.rpc(FRONTEND_METHODS.interrupt, {}, options); }
|
|
11
11
|
steer(prompt, options) { return this.rpc(FRONTEND_METHODS.steer, { prompt }, options); }
|
|
12
|
+
stopTask(taskId, options) { return this.rpc(FRONTEND_METHODS.stop_task, { task_id: taskId }, options); }
|
|
12
13
|
respond(response, options) { return this.rpc(FRONTEND_METHODS.respond, { response }, options); }
|
|
13
14
|
invoke(operation, options) { return this.rpc(FRONTEND_METHODS.invoke, { operation }, options); }
|
|
14
15
|
lease(options) { return this.rpc(FRONTEND_METHODS.lease, {}, options); }
|
|
@@ -139,8 +139,14 @@ export interface Interrupted {
|
|
|
139
139
|
export interface Queued {
|
|
140
140
|
queued: boolean;
|
|
141
141
|
}
|
|
142
|
+
export interface TaskParams {
|
|
143
|
+
task_id: string;
|
|
144
|
+
}
|
|
145
|
+
export interface Stopped {
|
|
146
|
+
stopped: boolean;
|
|
147
|
+
}
|
|
142
148
|
export interface Closed {
|
|
143
149
|
closed: boolean;
|
|
144
150
|
}
|
|
145
|
-
export type FrontendMethodId = 'describe' | 'attach' | 'send_input' | 'submit' | 'interrupt' | 'steer' | 'respond' | 'invoke' | 'lease' | 'acquire_control' | 'take_control' | 'heartbeat' | 'detach' | 'close';
|
|
146
|
-
export type FrontendWireMethod = 'frontend.v2.describe' | 'frontend.v2.attach' | 'frontend.v2.send_input' | 'frontend.v2.submit' | 'frontend.v2.interrupt' | 'frontend.v2.steer' | 'frontend.v2.respond' | 'frontend.v2.invoke' | 'frontend.v2.lease' | 'frontend.v2.acquire_control' | 'frontend.v2.take_control' | 'frontend.v2.heartbeat' | 'frontend.v2.detach' | 'frontend.v2.close';
|
|
151
|
+
export type FrontendMethodId = 'describe' | 'attach' | 'send_input' | 'submit' | 'interrupt' | 'steer' | 'stop_task' | 'respond' | 'invoke' | 'lease' | 'acquire_control' | 'take_control' | 'heartbeat' | 'detach' | 'close';
|
|
152
|
+
export type FrontendWireMethod = 'frontend.v2.describe' | 'frontend.v2.attach' | 'frontend.v2.send_input' | 'frontend.v2.submit' | 'frontend.v2.interrupt' | 'frontend.v2.steer' | 'frontend.v2.stop_task' | 'frontend.v2.respond' | 'frontend.v2.invoke' | 'frontend.v2.lease' | 'frontend.v2.acquire_control' | 'frontend.v2.take_control' | 'frontend.v2.heartbeat' | 'frontend.v2.detach' | 'frontend.v2.close';
|
|
@@ -7,6 +7,7 @@ export const FRONTEND_METHODS = Object.freeze({
|
|
|
7
7
|
"submit": "frontend.v2.submit",
|
|
8
8
|
"interrupt": "frontend.v2.interrupt",
|
|
9
9
|
"steer": "frontend.v2.steer",
|
|
10
|
+
"stop_task": "frontend.v2.stop_task",
|
|
10
11
|
"respond": "frontend.v2.respond",
|
|
11
12
|
"invoke": "frontend.v2.invoke",
|
|
12
13
|
"lease": "frontend.v2.lease",
|