@getpaseo/server 0.1.91-beta.2 → 0.1.91
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/scripts/supervisor.js +21 -0
- package/dist/server/server/agent/agent-manager.d.ts +1 -1
- package/dist/server/server/agent/agent-manager.js +23 -48
- package/dist/server/server/agent/prompt-attachments.js +8 -0
- package/dist/server/server/agent/provider-registry.d.ts +0 -1
- package/dist/server/server/agent/provider-registry.js +21 -3
- package/dist/server/server/agent/providers/codex-app-server-agent.js +9 -5
- package/dist/server/server/agent/providers/opencode/test-utils/test-opencode-runtime.d.ts +1 -0
- package/dist/server/server/agent/providers/opencode/test-utils/test-opencode-runtime.js +4 -0
- package/dist/server/server/agent/providers/opencode-agent.d.ts +16 -2
- package/dist/server/server/agent/providers/opencode-agent.js +75 -4
- package/dist/server/server/agent/providers/pi/agent.d.ts +23 -1
- package/dist/server/server/agent/providers/pi/agent.js +219 -13
- package/dist/server/server/agent/providers/pi/cli-runtime.js +9 -0
- package/dist/server/server/agent/providers/pi/rpc-types.d.ts +9 -0
- package/dist/server/server/agent/providers/pi/runtime.d.ts +2 -0
- package/dist/server/server/agent/providers/pi/session-descriptor.d.ts +12 -0
- package/dist/server/server/agent/providers/pi/session-descriptor.js +304 -0
- package/dist/server/server/agent/providers/pi/test-utils/fake-pi.d.ts +8 -0
- package/dist/server/server/agent/providers/pi/test-utils/fake-pi.js +22 -0
- package/dist/server/server/agent/runtime-mcp-config.d.ts +8 -0
- package/dist/server/server/agent/runtime-mcp-config.js +50 -0
- package/dist/server/server/auto-archive-on-merge/archive-if-safe.js +2 -2
- package/dist/server/server/daemon-worker.js +84 -1
- package/dist/server/server/file-upload/index.d.ts +27 -0
- package/dist/server/server/file-upload/index.js +158 -0
- package/dist/server/server/loop-service.d.ts +12 -12
- package/dist/server/server/persisted-config.d.ts +8 -0
- package/dist/server/server/persisted-config.js +1 -1
- package/dist/server/server/persistence-hooks.js +6 -4
- package/dist/server/server/session.d.ts +5 -2
- package/dist/server/server/session.js +20 -2
- package/dist/server/server/speech/providers/local/runtime.js +1 -0
- package/dist/server/server/speech/providers/local/worker-client.d.ts +14 -1
- package/dist/server/server/speech/providers/local/worker-client.js +169 -7
- package/dist/server/server/websocket-server.d.ts +2 -0
- package/dist/server/server/websocket-server.js +20 -7
- package/dist/server/server/workspace-registry.d.ts +4 -4
- package/dist/src/server/persisted-config.js +1 -1
- package/package.json +5 -5
|
@@ -8,6 +8,8 @@ import { bufferToWorkerBytes, workerBytesToBuffer } from "./worker-bytes.js";
|
|
|
8
8
|
const DEFAULT_REQUEST_TIMEOUT_MS = 30000;
|
|
9
9
|
const DEFAULT_IDLE_TTL_MS = 5 * 60 * 1000;
|
|
10
10
|
const DEFAULT_LOCAL_SAMPLE_RATE = 16000;
|
|
11
|
+
const STDERR_TAIL_MAX_CHARS = 8000;
|
|
12
|
+
const USER_ERROR_STDERR_MAX_CHARS = 1000;
|
|
11
13
|
function resolveWorkerUrl() {
|
|
12
14
|
const currentUrl = import.meta.url;
|
|
13
15
|
if (currentUrl.endsWith(".ts")) {
|
|
@@ -38,21 +40,81 @@ function forkLocalSpeechWorker() {
|
|
|
38
40
|
env,
|
|
39
41
|
execArgv: resolveWorkerExecArgv(),
|
|
40
42
|
serialization: "advanced",
|
|
41
|
-
stdio: ["ignore", "ignore", "
|
|
43
|
+
stdio: ["ignore", "ignore", "pipe", "ipc"],
|
|
42
44
|
});
|
|
43
45
|
}
|
|
44
46
|
function isResponse(message) {
|
|
45
47
|
return message.type === "response";
|
|
46
48
|
}
|
|
49
|
+
function truncateStart(value, maxChars) {
|
|
50
|
+
if (value.length <= maxChars) {
|
|
51
|
+
return value;
|
|
52
|
+
}
|
|
53
|
+
return value.slice(value.length - maxChars);
|
|
54
|
+
}
|
|
55
|
+
function summarizeWorkerRequest(message) {
|
|
56
|
+
switch (message.type) {
|
|
57
|
+
case "session.create":
|
|
58
|
+
return { kind: message.kind, sessionId: message.sessionId };
|
|
59
|
+
case "session.append":
|
|
60
|
+
return { sessionId: message.sessionId, audioBytes: message.audio.byteLength };
|
|
61
|
+
case "session.commit":
|
|
62
|
+
case "session.clear":
|
|
63
|
+
case "session.flush":
|
|
64
|
+
case "session.reset":
|
|
65
|
+
case "session.close":
|
|
66
|
+
return { sessionId: message.sessionId };
|
|
67
|
+
case "stt.transcribe":
|
|
68
|
+
return {
|
|
69
|
+
model: message.model,
|
|
70
|
+
audioBytes: message.audio.byteLength,
|
|
71
|
+
format: message.format,
|
|
72
|
+
};
|
|
73
|
+
case "tts.synthesize":
|
|
74
|
+
return { textLength: message.text.length };
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
function formatExitStatus(code, signal) {
|
|
78
|
+
const parts = [];
|
|
79
|
+
if (code !== null) {
|
|
80
|
+
parts.push(`code ${code}`);
|
|
81
|
+
}
|
|
82
|
+
if (signal) {
|
|
83
|
+
parts.push(`signal ${signal}`);
|
|
84
|
+
}
|
|
85
|
+
return parts.length > 0 ? parts.join(", ") : "unknown exit status";
|
|
86
|
+
}
|
|
87
|
+
function formatPendingRequestForMessage(request) {
|
|
88
|
+
const type = typeof request.type === "string" ? request.type : "unknown request";
|
|
89
|
+
const kind = typeof request.kind === "string" ? ` (${request.kind})` : "";
|
|
90
|
+
return `${type}${kind}`;
|
|
91
|
+
}
|
|
92
|
+
function buildWorkerExitMessage(params) {
|
|
93
|
+
const pending = params.pendingRequests.length > 0
|
|
94
|
+
? ` while handling ${params.pendingRequests
|
|
95
|
+
.slice(0, 3)
|
|
96
|
+
.map(formatPendingRequestForMessage)
|
|
97
|
+
.join(", ")}`
|
|
98
|
+
: "";
|
|
99
|
+
const stderr = params.stderrTail
|
|
100
|
+
? ` Last stderr: ${truncateStart(params.stderrTail, USER_ERROR_STDERR_MAX_CHARS)}`
|
|
101
|
+
: " Check daemon.log and macOS DiagnosticReports for Paseo Voice crash details.";
|
|
102
|
+
return `Local speech worker exited (${formatExitStatus(params.code, params.signal)})${pending}.${stderr}`;
|
|
103
|
+
}
|
|
47
104
|
export class LocalSpeechWorkerClient {
|
|
48
105
|
constructor(options) {
|
|
49
106
|
this.pendingRequests = new Map();
|
|
50
107
|
this.activeSessionIds = new Set();
|
|
51
108
|
this.sessionEmitters = new Map();
|
|
52
109
|
this.worker = null;
|
|
110
|
+
this.workerPid = null;
|
|
111
|
+
this.stderrTail = "";
|
|
112
|
+
this.stderrLineBuffer = "";
|
|
53
113
|
this.inFlightRequests = 0;
|
|
54
114
|
this.idleTimer = null;
|
|
115
|
+
this.intentionalWorkerCloses = new WeakSet();
|
|
55
116
|
this.config = options.config;
|
|
117
|
+
this.logger = options.logger.child({ component: "local-speech-worker-client" });
|
|
56
118
|
this.requestTimeoutMs = options.requestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;
|
|
57
119
|
this.idleTtlMs = options.idleTtlMs ?? DEFAULT_IDLE_TTL_MS;
|
|
58
120
|
this.forkWorker = options.forkWorker ?? forkLocalSpeechWorker;
|
|
@@ -141,7 +203,9 @@ export class LocalSpeechWorkerClient {
|
|
|
141
203
|
this.sessionEmitters.clear();
|
|
142
204
|
const worker = this.worker;
|
|
143
205
|
this.worker = null;
|
|
206
|
+
this.workerPid = null;
|
|
144
207
|
if (worker && !worker.killed) {
|
|
208
|
+
this.intentionalWorkerCloses.add(worker);
|
|
145
209
|
try {
|
|
146
210
|
worker.disconnect();
|
|
147
211
|
}
|
|
@@ -160,6 +224,7 @@ export class LocalSpeechWorkerClient {
|
|
|
160
224
|
const worker = this.ensureWorker();
|
|
161
225
|
const requestId = randomUUID();
|
|
162
226
|
const message = { ...input, requestId };
|
|
227
|
+
const requestSummary = summarizeWorkerRequest(message);
|
|
163
228
|
this.inFlightRequests++;
|
|
164
229
|
this.clearIdleTimer();
|
|
165
230
|
return new Promise((resolve, reject) => {
|
|
@@ -173,6 +238,9 @@ export class LocalSpeechWorkerClient {
|
|
|
173
238
|
resolve: (value) => resolve(value),
|
|
174
239
|
reject,
|
|
175
240
|
timeout,
|
|
241
|
+
type: message.type,
|
|
242
|
+
summary: requestSummary,
|
|
243
|
+
startedAt: Date.now(),
|
|
176
244
|
});
|
|
177
245
|
worker.send(message, (error) => {
|
|
178
246
|
if (!error) {
|
|
@@ -196,10 +264,35 @@ export class LocalSpeechWorkerClient {
|
|
|
196
264
|
}
|
|
197
265
|
const worker = this.forkWorker();
|
|
198
266
|
this.worker = worker;
|
|
267
|
+
this.workerPid = worker.pid ?? null;
|
|
268
|
+
this.stderrTail = "";
|
|
269
|
+
this.stderrLineBuffer = "";
|
|
270
|
+
this.logger.info({
|
|
271
|
+
workerPid: this.workerPid,
|
|
272
|
+
modelsDir: this.config.modelsDir,
|
|
273
|
+
voiceSttModel: this.config.voiceSttModel,
|
|
274
|
+
dictationSttModel: this.config.dictationSttModel,
|
|
275
|
+
voiceTtsModel: this.config.voiceTtsModel,
|
|
276
|
+
}, "Local speech worker spawned");
|
|
277
|
+
worker.stderr?.on("data", (chunk) => this.handleWorkerStderr(chunk));
|
|
199
278
|
worker.on("message", (message) => this.handleWorkerMessage(message));
|
|
200
|
-
worker.on("
|
|
279
|
+
worker.on("close", (code, signal) => this.handleWorkerExit(worker, code, signal));
|
|
201
280
|
return worker;
|
|
202
281
|
}
|
|
282
|
+
handleWorkerStderr(chunk) {
|
|
283
|
+
const text = Buffer.isBuffer(chunk) ? chunk.toString("utf8") : chunk;
|
|
284
|
+
this.stderrTail = truncateStart(this.stderrTail + text, STDERR_TAIL_MAX_CHARS);
|
|
285
|
+
this.stderrLineBuffer += text;
|
|
286
|
+
const lines = this.stderrLineBuffer.split(/\r?\n/);
|
|
287
|
+
this.stderrLineBuffer = lines.pop() ?? "";
|
|
288
|
+
for (const line of lines) {
|
|
289
|
+
const trimmed = line.trim();
|
|
290
|
+
if (!trimmed) {
|
|
291
|
+
continue;
|
|
292
|
+
}
|
|
293
|
+
this.logger.warn({ workerPid: this.workerPid, stderr: trimmed }, "Local speech worker stderr");
|
|
294
|
+
}
|
|
295
|
+
}
|
|
203
296
|
handleWorkerMessage(message) {
|
|
204
297
|
if (isResponse(message)) {
|
|
205
298
|
const pending = this.pendingRequests.get(message.requestId);
|
|
@@ -240,19 +333,81 @@ export class LocalSpeechWorkerClient {
|
|
|
240
333
|
return;
|
|
241
334
|
}
|
|
242
335
|
}
|
|
243
|
-
handleWorkerExit() {
|
|
244
|
-
this.worker
|
|
336
|
+
handleWorkerExit(worker, code, signal) {
|
|
337
|
+
const wasCurrentWorker = this.worker === worker;
|
|
338
|
+
const wasIntentionalClose = this.intentionalWorkerCloses.has(worker);
|
|
339
|
+
this.intentionalWorkerCloses.delete(worker);
|
|
340
|
+
const workerPid = worker.pid ?? (wasCurrentWorker ? this.workerPid : null);
|
|
341
|
+
const pendingRequests = this.describePendingRequests();
|
|
342
|
+
const activeSessionCount = this.activeSessionIds.size;
|
|
343
|
+
const stderrTail = this.getStderrTail();
|
|
344
|
+
if (wasIntentionalClose) {
|
|
345
|
+
this.logger.info({
|
|
346
|
+
workerPid,
|
|
347
|
+
code,
|
|
348
|
+
signal,
|
|
349
|
+
pendingRequests,
|
|
350
|
+
activeSessionCount,
|
|
351
|
+
stderrTail: stderrTail || null,
|
|
352
|
+
}, "Local speech worker closed after shutdown");
|
|
353
|
+
if (wasCurrentWorker) {
|
|
354
|
+
this.worker = null;
|
|
355
|
+
this.workerPid = null;
|
|
356
|
+
}
|
|
357
|
+
return;
|
|
358
|
+
}
|
|
359
|
+
if (!wasCurrentWorker) {
|
|
360
|
+
this.logger.warn({
|
|
361
|
+
workerPid,
|
|
362
|
+
code,
|
|
363
|
+
signal,
|
|
364
|
+
pendingRequests,
|
|
365
|
+
activeSessionCount,
|
|
366
|
+
stderrTail: stderrTail || null,
|
|
367
|
+
}, "Stale local speech worker closed");
|
|
368
|
+
return;
|
|
369
|
+
}
|
|
370
|
+
const error = new Error(buildWorkerExitMessage({
|
|
371
|
+
code,
|
|
372
|
+
signal,
|
|
373
|
+
pendingRequests,
|
|
374
|
+
stderrTail,
|
|
375
|
+
}));
|
|
376
|
+
this.logger.error({
|
|
377
|
+
err: error,
|
|
378
|
+
workerPid,
|
|
379
|
+
code,
|
|
380
|
+
signal,
|
|
381
|
+
pendingRequests,
|
|
382
|
+
activeSessionCount,
|
|
383
|
+
stderrTail: stderrTail || null,
|
|
384
|
+
}, "Local speech worker exited");
|
|
385
|
+
if (wasCurrentWorker) {
|
|
386
|
+
this.worker = null;
|
|
387
|
+
this.workerPid = null;
|
|
388
|
+
}
|
|
245
389
|
this.clearIdleTimer();
|
|
246
|
-
this.rejectAllPending(
|
|
390
|
+
this.rejectAllPending(error);
|
|
247
391
|
for (const [sessionId, emitter] of this.sessionEmitters) {
|
|
248
392
|
if (this.activeSessionIds.has(sessionId)) {
|
|
249
|
-
|
|
393
|
+
this.emitErrorIfObserved(sessionId, emitter, error, workerPid);
|
|
250
394
|
}
|
|
251
395
|
}
|
|
252
396
|
this.activeSessionIds.clear();
|
|
253
397
|
this.sessionEmitters.clear();
|
|
254
398
|
this.inFlightRequests = 0;
|
|
255
399
|
}
|
|
400
|
+
describePendingRequests() {
|
|
401
|
+
const now = Date.now();
|
|
402
|
+
return Array.from(this.pendingRequests.entries()).map(([requestId, request]) => Object.assign({
|
|
403
|
+
requestId,
|
|
404
|
+
type: request.type,
|
|
405
|
+
ageMs: Math.max(0, now - request.startedAt),
|
|
406
|
+
}, request.summary));
|
|
407
|
+
}
|
|
408
|
+
getStderrTail() {
|
|
409
|
+
return truncateStart(this.stderrTail.trim(), STDERR_TAIL_MAX_CHARS);
|
|
410
|
+
}
|
|
256
411
|
rejectAllPending(error) {
|
|
257
412
|
for (const [requestId, pending] of this.pendingRequests) {
|
|
258
413
|
clearTimeout(pending.timeout);
|
|
@@ -265,7 +420,14 @@ export class LocalSpeechWorkerClient {
|
|
|
265
420
|
if (!emitter) {
|
|
266
421
|
return;
|
|
267
422
|
}
|
|
268
|
-
|
|
423
|
+
this.emitErrorIfObserved(sessionId, emitter, error instanceof Error ? error : new Error(String(error)));
|
|
424
|
+
}
|
|
425
|
+
emitErrorIfObserved(sessionId, emitter, error, workerPid = this.workerPid) {
|
|
426
|
+
if (emitter.listenerCount("error") > 0) {
|
|
427
|
+
emitter.emit("error", error);
|
|
428
|
+
return;
|
|
429
|
+
}
|
|
430
|
+
this.logger.warn({ err: error, workerPid, sessionId }, "Local speech worker session error had no listener");
|
|
269
431
|
}
|
|
270
432
|
scheduleIdleShutdownIfReady() {
|
|
271
433
|
if (!this.worker || this.inFlightRequests > 0 || this.activeSessionIds.size > 0) {
|
|
@@ -51,6 +51,7 @@ export declare class VoiceAssistantWebSocketServer {
|
|
|
51
51
|
private readonly pendingConnections;
|
|
52
52
|
private readonly sessions;
|
|
53
53
|
private readonly externalSessionsByKey;
|
|
54
|
+
private readonly socketMessageQueues;
|
|
54
55
|
private readonly serverId;
|
|
55
56
|
private readonly daemonVersion;
|
|
56
57
|
private readonly daemonRuntimeConfig;
|
|
@@ -129,6 +130,7 @@ export declare class VoiceAssistantWebSocketServer {
|
|
|
129
130
|
private broadcastCapabilitiesUpdate;
|
|
130
131
|
private broadcastDaemonConfigChanged;
|
|
131
132
|
private bindSocketHandlers;
|
|
133
|
+
private enqueueRawMessage;
|
|
132
134
|
resolveVoiceSpeakHandler(callerAgentId: string): VoiceSpeakHandler | null;
|
|
133
135
|
resolveVoiceCallerContext(callerAgentId: string): VoiceCallerContext | null;
|
|
134
136
|
private detachSocket;
|
|
@@ -2,7 +2,7 @@ import { WebSocketServer } from "ws";
|
|
|
2
2
|
import { basename, join } from "path";
|
|
3
3
|
import { hostname as getHostname } from "node:os";
|
|
4
4
|
import { WSInboundMessageSchema, wrapSessionMessage, } from "./messages.js";
|
|
5
|
-
import { asUint8Array,
|
|
5
|
+
import { asUint8Array, decodeBinaryFrame } from "@getpaseo/protocol/binary-frames/index";
|
|
6
6
|
import { isHostnameAllowed } from "./hostnames.js";
|
|
7
7
|
import { Session } from "./session.js";
|
|
8
8
|
import { buildWorkspaceGitMetadataFromSnapshot } from "./workspace-git-metadata.js";
|
|
@@ -206,6 +206,7 @@ export class VoiceAssistantWebSocketServer {
|
|
|
206
206
|
this.pendingConnections = new Map();
|
|
207
207
|
this.sessions = new Map();
|
|
208
208
|
this.externalSessionsByKey = new Map();
|
|
209
|
+
this.socketMessageQueues = new Map();
|
|
209
210
|
this.voiceSpeakHandlers = new Map();
|
|
210
211
|
this.voiceCallerContexts = new Map();
|
|
211
212
|
this.workspaceSetupSnapshots = new Map();
|
|
@@ -756,7 +757,7 @@ export class VoiceAssistantWebSocketServer {
|
|
|
756
757
|
bindSocketHandlers(ws) {
|
|
757
758
|
ws.on("message", (...args) => {
|
|
758
759
|
const data = args[0];
|
|
759
|
-
|
|
760
|
+
this.enqueueRawMessage(ws, data);
|
|
760
761
|
});
|
|
761
762
|
ws.on("close", async (...args) => {
|
|
762
763
|
const code = args[0];
|
|
@@ -776,6 +777,18 @@ export class VoiceAssistantWebSocketServer {
|
|
|
776
777
|
await this.detachSocket(ws, { error: err });
|
|
777
778
|
});
|
|
778
779
|
}
|
|
780
|
+
enqueueRawMessage(ws, data) {
|
|
781
|
+
const previous = this.socketMessageQueues.get(ws) ?? Promise.resolve();
|
|
782
|
+
const next = previous.then(() => this.handleRawMessage(ws, data), () => this.handleRawMessage(ws, data));
|
|
783
|
+
this.socketMessageQueues.set(ws, next);
|
|
784
|
+
void next
|
|
785
|
+
.catch(() => undefined)
|
|
786
|
+
.finally(() => {
|
|
787
|
+
if (this.socketMessageQueues.get(ws) === next) {
|
|
788
|
+
this.socketMessageQueues.delete(ws);
|
|
789
|
+
}
|
|
790
|
+
});
|
|
791
|
+
}
|
|
779
792
|
resolveVoiceSpeakHandler(callerAgentId) {
|
|
780
793
|
return this.voiceSpeakHandlers.get(callerAgentId) ?? null;
|
|
781
794
|
}
|
|
@@ -897,14 +910,14 @@ export class VoiceAssistantWebSocketServer {
|
|
|
897
910
|
},
|
|
898
911
|
}));
|
|
899
912
|
}
|
|
900
|
-
maybeHandleBinaryFrame(params) {
|
|
913
|
+
async maybeHandleBinaryFrame(params) {
|
|
901
914
|
const { ws, buffer, activeConnection, log } = params;
|
|
902
915
|
const asBytes = asUint8Array(buffer);
|
|
903
916
|
if (!asBytes) {
|
|
904
917
|
return false;
|
|
905
918
|
}
|
|
906
|
-
const
|
|
907
|
-
if (!
|
|
919
|
+
const decodedFrame = decodeBinaryFrame(asBytes);
|
|
920
|
+
if (!decodedFrame) {
|
|
908
921
|
return false;
|
|
909
922
|
}
|
|
910
923
|
if (!activeConnection) {
|
|
@@ -919,7 +932,7 @@ export class VoiceAssistantWebSocketServer {
|
|
|
919
932
|
}
|
|
920
933
|
return true;
|
|
921
934
|
}
|
|
922
|
-
activeConnection.session.handleBinaryFrame(
|
|
935
|
+
await activeConnection.session.handleBinaryFrame(decodedFrame);
|
|
923
936
|
return true;
|
|
924
937
|
}
|
|
925
938
|
handlePendingConnectionMessage(params) {
|
|
@@ -950,7 +963,7 @@ export class VoiceAssistantWebSocketServer {
|
|
|
950
963
|
const log = activeConnection?.connectionLogger ?? pendingConnection?.connectionLogger ?? this.logger;
|
|
951
964
|
try {
|
|
952
965
|
const buffer = bufferFromWsData(data);
|
|
953
|
-
const binaryHandled = this.maybeHandleBinaryFrame({
|
|
966
|
+
const binaryHandled = await this.maybeHandleBinaryFrame({
|
|
954
967
|
ws,
|
|
955
968
|
buffer,
|
|
956
969
|
activeConnection,
|
|
@@ -16,8 +16,8 @@ declare const PersistedProjectRecordSchema: z.ZodObject<{
|
|
|
16
16
|
archivedAt: string | null;
|
|
17
17
|
kind: "git" | "non_git";
|
|
18
18
|
projectId: string;
|
|
19
|
-
rootPath: string;
|
|
20
19
|
displayName: string;
|
|
20
|
+
rootPath: string;
|
|
21
21
|
customName: string | null;
|
|
22
22
|
}, {
|
|
23
23
|
createdAt: string;
|
|
@@ -25,8 +25,8 @@ declare const PersistedProjectRecordSchema: z.ZodObject<{
|
|
|
25
25
|
archivedAt: string | null;
|
|
26
26
|
kind: "git" | "non_git";
|
|
27
27
|
projectId: string;
|
|
28
|
-
rootPath: string;
|
|
29
28
|
displayName: string;
|
|
29
|
+
rootPath: string;
|
|
30
30
|
customName?: string | null | undefined;
|
|
31
31
|
}>;
|
|
32
32
|
declare const PersistedWorkspaceRecordSchema: z.ZodObject<{
|
|
@@ -44,7 +44,7 @@ declare const PersistedWorkspaceRecordSchema: z.ZodObject<{
|
|
|
44
44
|
createdAt: string;
|
|
45
45
|
updatedAt: string;
|
|
46
46
|
archivedAt: string | null;
|
|
47
|
-
kind: "
|
|
47
|
+
kind: "local_checkout" | "worktree" | "directory";
|
|
48
48
|
projectId: string;
|
|
49
49
|
displayName: string;
|
|
50
50
|
}, {
|
|
@@ -53,7 +53,7 @@ declare const PersistedWorkspaceRecordSchema: z.ZodObject<{
|
|
|
53
53
|
createdAt: string;
|
|
54
54
|
updatedAt: string;
|
|
55
55
|
archivedAt: string | null;
|
|
56
|
-
kind: "
|
|
56
|
+
kind: "local_checkout" | "worktree" | "directory";
|
|
57
57
|
projectId: string;
|
|
58
58
|
displayName: string;
|
|
59
59
|
}>;
|
|
@@ -129,7 +129,7 @@ const AgentMetadataGenerationSchema = z
|
|
|
129
129
|
providers: z.array(StructuredGenerationProviderConfigSchema).optional(),
|
|
130
130
|
})
|
|
131
131
|
.strict();
|
|
132
|
-
const BUILTIN_PROVIDER_IDS = ["claude", "codex", "copilot", "opencode", "pi"];
|
|
132
|
+
const BUILTIN_PROVIDER_IDS = ["claude", "codex", "copilot", "opencode", "pi", "omp"];
|
|
133
133
|
function isLegacyProviderEntry(value) {
|
|
134
134
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
135
135
|
return false;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@getpaseo/server",
|
|
3
|
-
"version": "0.1.91
|
|
3
|
+
"version": "0.1.91",
|
|
4
4
|
"description": "Paseo backend server",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist/server",
|
|
@@ -59,10 +59,10 @@
|
|
|
59
59
|
"dependencies": {
|
|
60
60
|
"@agentclientprotocol/sdk": "^0.17.1",
|
|
61
61
|
"@anthropic-ai/claude-agent-sdk": "^0.2.133",
|
|
62
|
-
"@getpaseo/client": "0.1.91
|
|
63
|
-
"@getpaseo/highlight": "0.1.91
|
|
64
|
-
"@getpaseo/protocol": "0.1.91
|
|
65
|
-
"@getpaseo/relay": "0.1.91
|
|
62
|
+
"@getpaseo/client": "0.1.91",
|
|
63
|
+
"@getpaseo/highlight": "0.1.91",
|
|
64
|
+
"@getpaseo/protocol": "0.1.91",
|
|
65
|
+
"@getpaseo/relay": "0.1.91",
|
|
66
66
|
"@isaacs/ttlcache": "^2.1.4",
|
|
67
67
|
"@modelcontextprotocol/sdk": "^1.20.1",
|
|
68
68
|
"@opencode-ai/sdk": "1.14.46",
|