@getpaseo/server 0.1.91-beta.1 → 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/agent-sdk-types.d.ts +15 -0
- 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 +22 -4
- package/dist/server/server/agent/provider-snapshot-manager.js +19 -1
- package/dist/server/server/agent/providers/claude/agent.d.ts +5 -2
- package/dist/server/server/agent/providers/claude/agent.js +6 -2
- package/dist/server/server/agent/providers/claude/models.d.ts +1 -1
- package/dist/server/server/agent/providers/claude/models.js +6 -6
- 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/auth.js +16 -1
- 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 +11 -0
- package/dist/server/server/persisted-config.js +2 -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/server/utils/directory-suggestions.js +10 -5
- package/dist/server/utils/worktree.d.ts +4 -0
- package/dist/server/utils/worktree.js +19 -2
- package/dist/src/server/persisted-config.js +2 -1
- package/package.json +5 -5
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import { appendFile, mkdir, rm, writeFile } from "node:fs/promises";
|
|
2
|
+
import { basename, join } from "node:path";
|
|
3
|
+
import { FileTransferOpcode } from "@getpaseo/protocol/binary-frames/index";
|
|
4
|
+
import { getErrorMessage } from "@getpaseo/protocol/error-utils";
|
|
5
|
+
export class FileUploadStore {
|
|
6
|
+
constructor(options) {
|
|
7
|
+
this.pending = new Map();
|
|
8
|
+
this.paseoHome = options.paseoHome;
|
|
9
|
+
this.staleUploadTimeoutMs =
|
|
10
|
+
options.staleUploadTimeoutMs ?? FileUploadStore.defaultStaleUploadTimeoutMs;
|
|
11
|
+
}
|
|
12
|
+
beginUpload(request) {
|
|
13
|
+
const existingUpload = this.pending.get(request.requestId);
|
|
14
|
+
if (existingUpload) {
|
|
15
|
+
this.clearPendingUpload(existingUpload);
|
|
16
|
+
void existingUpload.queue.then(() => this.removeUploadDirectory(existingUpload));
|
|
17
|
+
}
|
|
18
|
+
const fileName = sanitizeFileName(request.fileName);
|
|
19
|
+
const attempt = existingUpload ? existingUpload.attempt + 1 : 1;
|
|
20
|
+
const id = buildUploadId(request.requestId, attempt);
|
|
21
|
+
const uploadDir = join(this.paseoHome, "uploads", id);
|
|
22
|
+
const upload = {
|
|
23
|
+
requestId: request.requestId,
|
|
24
|
+
id,
|
|
25
|
+
attempt,
|
|
26
|
+
fileName,
|
|
27
|
+
mimeType: request.mimeType,
|
|
28
|
+
size: request.size,
|
|
29
|
+
path: join(uploadDir, fileName),
|
|
30
|
+
receivedBytes: 0,
|
|
31
|
+
started: false,
|
|
32
|
+
staleTimeout: this.createStaleUploadTimeout(request.requestId),
|
|
33
|
+
queue: Promise.resolve(),
|
|
34
|
+
};
|
|
35
|
+
this.pending.set(request.requestId, upload);
|
|
36
|
+
}
|
|
37
|
+
async receiveFrame(frame) {
|
|
38
|
+
const upload = this.pending.get(frame.requestId);
|
|
39
|
+
if (!upload) {
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
this.refreshStaleUploadTimeout(upload);
|
|
43
|
+
const operation = upload.queue.then(() => this.applyFrame(upload, frame));
|
|
44
|
+
upload.queue = operation.then(() => undefined, () => undefined);
|
|
45
|
+
return operation;
|
|
46
|
+
}
|
|
47
|
+
async applyFrame(upload, frame) {
|
|
48
|
+
if (this.pending.get(upload.requestId) !== upload) {
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
try {
|
|
52
|
+
if (frame.opcode === FileTransferOpcode.FileBegin) {
|
|
53
|
+
await this.startWriting(upload);
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
if (frame.opcode === FileTransferOpcode.FileChunk) {
|
|
57
|
+
await this.writeChunk(upload, frame.payload);
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
return await this.completeUpload(upload);
|
|
61
|
+
}
|
|
62
|
+
catch (error) {
|
|
63
|
+
await this.removeFailedUpload(upload);
|
|
64
|
+
return buildUploadResponse(upload, getErrorMessage(error));
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
async startWriting(upload) {
|
|
68
|
+
await mkdir(join(this.paseoHome, "uploads", upload.id), { recursive: true });
|
|
69
|
+
await writeFile(upload.path, new Uint8Array());
|
|
70
|
+
upload.started = true;
|
|
71
|
+
}
|
|
72
|
+
async writeChunk(upload, bytes) {
|
|
73
|
+
if (!upload.started) {
|
|
74
|
+
throw new Error("Upload chunks arrived before file begin.");
|
|
75
|
+
}
|
|
76
|
+
const nextReceivedBytes = upload.receivedBytes + bytes.byteLength;
|
|
77
|
+
if (nextReceivedBytes > upload.size) {
|
|
78
|
+
throw new Error(`Upload exceeded declared size: expected ${upload.size}, received ${nextReceivedBytes}.`);
|
|
79
|
+
}
|
|
80
|
+
await appendFile(upload.path, bytes);
|
|
81
|
+
upload.receivedBytes += bytes.byteLength;
|
|
82
|
+
}
|
|
83
|
+
async completeUpload(upload) {
|
|
84
|
+
this.clearPendingUpload(upload);
|
|
85
|
+
if (upload.receivedBytes !== upload.size) {
|
|
86
|
+
await this.removeUploadDirectory(upload);
|
|
87
|
+
return buildUploadResponse(upload, `Upload size mismatch: expected ${upload.size}, received ${upload.receivedBytes}.`);
|
|
88
|
+
}
|
|
89
|
+
return buildUploadResponse(upload, null);
|
|
90
|
+
}
|
|
91
|
+
createStaleUploadTimeout(requestId) {
|
|
92
|
+
const timeout = setTimeout(() => {
|
|
93
|
+
this.expireStaleUpload(requestId);
|
|
94
|
+
}, this.staleUploadTimeoutMs);
|
|
95
|
+
timeout.unref?.();
|
|
96
|
+
return timeout;
|
|
97
|
+
}
|
|
98
|
+
refreshStaleUploadTimeout(upload) {
|
|
99
|
+
clearTimeout(upload.staleTimeout);
|
|
100
|
+
upload.staleTimeout = this.createStaleUploadTimeout(upload.requestId);
|
|
101
|
+
}
|
|
102
|
+
expireStaleUpload(requestId) {
|
|
103
|
+
const upload = this.pending.get(requestId);
|
|
104
|
+
if (!upload) {
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
this.clearPendingUpload(upload);
|
|
108
|
+
const cleanup = upload.queue.then(() => this.removeUploadDirectory(upload), () => this.removeUploadDirectory(upload));
|
|
109
|
+
upload.queue = cleanup.then(() => undefined, () => undefined);
|
|
110
|
+
}
|
|
111
|
+
clearPendingUpload(upload) {
|
|
112
|
+
clearTimeout(upload.staleTimeout);
|
|
113
|
+
if (this.pending.get(upload.requestId) === upload) {
|
|
114
|
+
this.pending.delete(upload.requestId);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
async removeFailedUpload(upload) {
|
|
118
|
+
this.clearPendingUpload(upload);
|
|
119
|
+
await this.removeUploadDirectory(upload);
|
|
120
|
+
}
|
|
121
|
+
async removeUploadDirectory(upload) {
|
|
122
|
+
await rm(join(this.paseoHome, "uploads", upload.id), { recursive: true, force: true }).catch(() => undefined);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
FileUploadStore.defaultStaleUploadTimeoutMs = 10 * 60 * 1000;
|
|
126
|
+
function buildUploadResponse(upload, error) {
|
|
127
|
+
return {
|
|
128
|
+
type: "file.upload.response",
|
|
129
|
+
payload: {
|
|
130
|
+
requestId: upload.requestId,
|
|
131
|
+
file: error
|
|
132
|
+
? null
|
|
133
|
+
: {
|
|
134
|
+
type: "uploaded_file",
|
|
135
|
+
id: upload.id,
|
|
136
|
+
fileName: upload.fileName,
|
|
137
|
+
mimeType: upload.mimeType,
|
|
138
|
+
size: upload.size,
|
|
139
|
+
path: upload.path,
|
|
140
|
+
},
|
|
141
|
+
error,
|
|
142
|
+
},
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
function sanitizeUploadId(value) {
|
|
146
|
+
return value.replace(/[^a-zA-Z0-9._-]/g, "_") || "file";
|
|
147
|
+
}
|
|
148
|
+
function buildUploadId(requestId, attempt) {
|
|
149
|
+
const baseId = `upload_${sanitizeUploadId(requestId)}`;
|
|
150
|
+
return attempt === 1 ? baseId : `${baseId}_${attempt}`;
|
|
151
|
+
}
|
|
152
|
+
function sanitizeFileName(value) {
|
|
153
|
+
const name = basename(value)
|
|
154
|
+
.replace(/[^a-zA-Z0-9._ -]/g, "_")
|
|
155
|
+
.trim();
|
|
156
|
+
return name.length > 0 && name !== "." && name !== ".." ? name : "upload";
|
|
157
|
+
}
|
|
158
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -13,16 +13,16 @@ declare const LoopLogEntrySchema: z.ZodObject<{
|
|
|
13
13
|
}, "strip", z.ZodTypeAny, {
|
|
14
14
|
text: string;
|
|
15
15
|
level: "error" | "info";
|
|
16
|
-
source: "worker" | "loop" | "verifier" | "verify-check";
|
|
17
|
-
timestamp: string;
|
|
18
16
|
seq: number;
|
|
17
|
+
timestamp: string;
|
|
18
|
+
source: "worker" | "loop" | "verifier" | "verify-check";
|
|
19
19
|
iteration: number | null;
|
|
20
20
|
}, {
|
|
21
21
|
text: string;
|
|
22
22
|
level: "error" | "info";
|
|
23
|
-
source: "worker" | "loop" | "verifier" | "verify-check";
|
|
24
|
-
timestamp: string;
|
|
25
23
|
seq: number;
|
|
24
|
+
timestamp: string;
|
|
25
|
+
source: "worker" | "loop" | "verifier" | "verify-check";
|
|
26
26
|
iteration: number | null;
|
|
27
27
|
}>;
|
|
28
28
|
declare const LoopVerifyCheckResultSchema: z.ZodObject<{
|
|
@@ -312,16 +312,16 @@ declare const LoopRecordSchema: z.ZodObject<{
|
|
|
312
312
|
}, "strip", z.ZodTypeAny, {
|
|
313
313
|
text: string;
|
|
314
314
|
level: "error" | "info";
|
|
315
|
-
source: "worker" | "loop" | "verifier" | "verify-check";
|
|
316
|
-
timestamp: string;
|
|
317
315
|
seq: number;
|
|
316
|
+
timestamp: string;
|
|
317
|
+
source: "worker" | "loop" | "verifier" | "verify-check";
|
|
318
318
|
iteration: number | null;
|
|
319
319
|
}, {
|
|
320
320
|
text: string;
|
|
321
321
|
level: "error" | "info";
|
|
322
|
-
source: "worker" | "loop" | "verifier" | "verify-check";
|
|
323
|
-
timestamp: string;
|
|
324
322
|
seq: number;
|
|
323
|
+
timestamp: string;
|
|
324
|
+
source: "worker" | "loop" | "verifier" | "verify-check";
|
|
325
325
|
iteration: number | null;
|
|
326
326
|
}>, "many">;
|
|
327
327
|
nextLogSeq: z.ZodNumber;
|
|
@@ -382,9 +382,9 @@ declare const LoopRecordSchema: z.ZodObject<{
|
|
|
382
382
|
logs: {
|
|
383
383
|
text: string;
|
|
384
384
|
level: "error" | "info";
|
|
385
|
-
source: "worker" | "loop" | "verifier" | "verify-check";
|
|
386
|
-
timestamp: string;
|
|
387
385
|
seq: number;
|
|
386
|
+
timestamp: string;
|
|
387
|
+
source: "worker" | "loop" | "verifier" | "verify-check";
|
|
388
388
|
iteration: number | null;
|
|
389
389
|
}[];
|
|
390
390
|
nextLogSeq: number;
|
|
@@ -443,9 +443,9 @@ declare const LoopRecordSchema: z.ZodObject<{
|
|
|
443
443
|
logs: {
|
|
444
444
|
text: string;
|
|
445
445
|
level: "error" | "info";
|
|
446
|
-
source: "worker" | "loop" | "verifier" | "verify-check";
|
|
447
|
-
timestamp: string;
|
|
448
446
|
seq: number;
|
|
447
|
+
timestamp: string;
|
|
448
|
+
source: "worker" | "loop" | "verifier" | "verify-check";
|
|
449
449
|
iteration: number | null;
|
|
450
450
|
}[];
|
|
451
451
|
nextLogSeq: number;
|
|
@@ -3,6 +3,7 @@ import type { AgentProviderRuntimeSettingsMap } from "./agent/provider-launch-co
|
|
|
3
3
|
export declare const LogLevelSchema: z.ZodEnum<["trace", "debug", "info", "warn", "error", "fatal"]>;
|
|
4
4
|
export declare const LogFormatSchema: z.ZodEnum<["pretty", "json"]>;
|
|
5
5
|
export declare const PersistedConfigSchema: z.ZodObject<{
|
|
6
|
+
$schema: z.ZodOptional<z.ZodString>;
|
|
6
7
|
version: z.ZodOptional<z.ZodLiteral<1>>;
|
|
7
8
|
daemon: z.ZodOptional<z.ZodEffects<z.ZodObject<{
|
|
8
9
|
listen: z.ZodOptional<z.ZodString>;
|
|
@@ -229,6 +230,7 @@ export declare const PersistedConfigSchema: z.ZodObject<{
|
|
|
229
230
|
description: z.ZodOptional<z.ZodString>;
|
|
230
231
|
command: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
231
232
|
env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
233
|
+
params: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
232
234
|
models: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
233
235
|
id: z.ZodString;
|
|
234
236
|
label: z.ZodString;
|
|
@@ -322,6 +324,7 @@ export declare const PersistedConfigSchema: z.ZodObject<{
|
|
|
322
324
|
order: z.ZodOptional<z.ZodNumber>;
|
|
323
325
|
}, "strip", z.ZodTypeAny, {
|
|
324
326
|
description?: string | undefined;
|
|
327
|
+
params?: Record<string, unknown> | undefined;
|
|
325
328
|
label?: string | undefined;
|
|
326
329
|
enabled?: boolean | undefined;
|
|
327
330
|
command?: string[] | undefined;
|
|
@@ -355,6 +358,7 @@ export declare const PersistedConfigSchema: z.ZodObject<{
|
|
|
355
358
|
order?: number | undefined;
|
|
356
359
|
}, {
|
|
357
360
|
description?: string | undefined;
|
|
361
|
+
params?: Record<string, unknown> | undefined;
|
|
358
362
|
label?: string | undefined;
|
|
359
363
|
enabled?: boolean | undefined;
|
|
360
364
|
command?: string[] | undefined;
|
|
@@ -388,6 +392,7 @@ export declare const PersistedConfigSchema: z.ZodObject<{
|
|
|
388
392
|
order?: number | undefined;
|
|
389
393
|
}>>, Record<string, {
|
|
390
394
|
description?: string | undefined;
|
|
395
|
+
params?: Record<string, unknown> | undefined;
|
|
391
396
|
label?: string | undefined;
|
|
392
397
|
enabled?: boolean | undefined;
|
|
393
398
|
command?: string[] | undefined;
|
|
@@ -421,6 +426,7 @@ export declare const PersistedConfigSchema: z.ZodObject<{
|
|
|
421
426
|
order?: number | undefined;
|
|
422
427
|
}>, Record<string, {
|
|
423
428
|
description?: string | undefined;
|
|
429
|
+
params?: Record<string, unknown> | undefined;
|
|
424
430
|
label?: string | undefined;
|
|
425
431
|
enabled?: boolean | undefined;
|
|
426
432
|
command?: string[] | undefined;
|
|
@@ -454,6 +460,7 @@ export declare const PersistedConfigSchema: z.ZodObject<{
|
|
|
454
460
|
order?: number | undefined;
|
|
455
461
|
}>>, Record<string, {
|
|
456
462
|
description?: string | undefined;
|
|
463
|
+
params?: Record<string, unknown> | undefined;
|
|
457
464
|
label?: string | undefined;
|
|
458
465
|
enabled?: boolean | undefined;
|
|
459
466
|
command?: string[] | undefined;
|
|
@@ -523,6 +530,7 @@ export declare const PersistedConfigSchema: z.ZodObject<{
|
|
|
523
530
|
} | undefined;
|
|
524
531
|
providers?: Record<string, {
|
|
525
532
|
description?: string | undefined;
|
|
533
|
+
params?: Record<string, unknown> | undefined;
|
|
526
534
|
label?: string | undefined;
|
|
527
535
|
enabled?: boolean | undefined;
|
|
528
536
|
command?: string[] | undefined;
|
|
@@ -924,6 +932,7 @@ export declare const PersistedConfigSchema: z.ZodObject<{
|
|
|
924
932
|
} | undefined;
|
|
925
933
|
providers?: Record<string, {
|
|
926
934
|
description?: string | undefined;
|
|
935
|
+
params?: Record<string, unknown> | undefined;
|
|
927
936
|
label?: string | undefined;
|
|
928
937
|
enabled?: boolean | undefined;
|
|
929
938
|
command?: string[] | undefined;
|
|
@@ -957,6 +966,7 @@ export declare const PersistedConfigSchema: z.ZodObject<{
|
|
|
957
966
|
order?: number | undefined;
|
|
958
967
|
}> | undefined;
|
|
959
968
|
} | undefined;
|
|
969
|
+
$schema?: string | undefined;
|
|
960
970
|
app?: {
|
|
961
971
|
baseUrl?: string | undefined;
|
|
962
972
|
} | undefined;
|
|
@@ -1061,6 +1071,7 @@ export declare const PersistedConfigSchema: z.ZodObject<{
|
|
|
1061
1071
|
} | undefined;
|
|
1062
1072
|
providers?: unknown;
|
|
1063
1073
|
} | undefined;
|
|
1074
|
+
$schema?: string | undefined;
|
|
1064
1075
|
app?: {
|
|
1065
1076
|
baseUrl?: string | undefined;
|
|
1066
1077
|
} | undefined;
|
|
@@ -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;
|
|
@@ -169,6 +169,7 @@ function normalizeAgentProviders(value) {
|
|
|
169
169
|
}
|
|
170
170
|
export const PersistedConfigSchema = z
|
|
171
171
|
.object({
|
|
172
|
+
$schema: z.string().optional(),
|
|
172
173
|
// v1 schema marker
|
|
173
174
|
version: z.literal(1).optional(),
|
|
174
175
|
// v1 config layout
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { stripInternalPaseoMcpServer } from "./agent/runtime-mcp-config.js";
|
|
1
2
|
function getLogger(logger) {
|
|
2
3
|
return logger.child({ module: "persistence" });
|
|
3
4
|
}
|
|
@@ -21,7 +22,8 @@ export function attachAgentStoragePersistence(logger, agentManager, storage) {
|
|
|
21
22
|
return unsubscribe;
|
|
22
23
|
}
|
|
23
24
|
export function buildConfigOverrides(record) {
|
|
24
|
-
return {
|
|
25
|
+
return stripInternalPaseoMcpServer({
|
|
26
|
+
provider: record.provider,
|
|
25
27
|
cwd: record.cwd,
|
|
26
28
|
modeId: record.lastModeId ?? record.config?.modeId ?? undefined,
|
|
27
29
|
model: record.config?.model ?? undefined,
|
|
@@ -30,7 +32,7 @@ export function buildConfigOverrides(record) {
|
|
|
30
32
|
extra: record.config?.extra ?? undefined,
|
|
31
33
|
systemPrompt: record.config?.systemPrompt ?? undefined,
|
|
32
34
|
mcpServers: record.config?.mcpServers ?? undefined,
|
|
33
|
-
};
|
|
35
|
+
});
|
|
34
36
|
}
|
|
35
37
|
export function buildSessionConfig(record, options) {
|
|
36
38
|
const validProviders = options?.validProviders;
|
|
@@ -39,7 +41,7 @@ export function buildSessionConfig(record, options) {
|
|
|
39
41
|
return null;
|
|
40
42
|
}
|
|
41
43
|
const overrides = buildConfigOverrides(record);
|
|
42
|
-
return {
|
|
44
|
+
return stripInternalPaseoMcpServer({
|
|
43
45
|
provider: record.provider,
|
|
44
46
|
cwd: record.cwd,
|
|
45
47
|
modeId: overrides.modeId,
|
|
@@ -49,7 +51,7 @@ export function buildSessionConfig(record, options) {
|
|
|
49
51
|
extra: overrides.extra,
|
|
50
52
|
systemPrompt: overrides.systemPrompt,
|
|
51
53
|
mcpServers: overrides.mcpServers,
|
|
52
|
-
};
|
|
54
|
+
});
|
|
53
55
|
}
|
|
54
56
|
export function isStoredAgentProviderAvailable(record, validProviders) {
|
|
55
57
|
return buildSessionConfig(record, { validProviders }) !== null;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type ClientCapability } from "@getpaseo/protocol/client-capabilities";
|
|
2
2
|
import { type AgentSnapshotPayload, type SessionInboundMessage, type SessionOutboundMessage, type WorkspaceSetupSnapshot } from "./messages.js";
|
|
3
3
|
import type { TerminalManager } from "../terminal/terminal-manager.js";
|
|
4
|
-
import { type
|
|
4
|
+
import { type BinaryFrame } from "@getpaseo/protocol/binary-frames/index";
|
|
5
5
|
import type { SpeechToTextProvider, TextToSpeechProvider } from "./speech/speech-provider.js";
|
|
6
6
|
import type { TurnDetectionProvider } from "./speech/turn-detection-provider.js";
|
|
7
7
|
import type { VoiceCallerContext, VoiceSpeakHandler } from "./voice-types.js";
|
|
@@ -181,6 +181,7 @@ export declare class Session {
|
|
|
181
181
|
private readonly workspaceSetupSnapshots;
|
|
182
182
|
private readonly workspaceGitFetchSubscriptions;
|
|
183
183
|
private readonly workspaceGitSubscriptions;
|
|
184
|
+
private readonly fileUploads;
|
|
184
185
|
private readonly workspaceDirectory;
|
|
185
186
|
private registerVoiceSpeakHandler?;
|
|
186
187
|
private unregisterVoiceSpeakHandler?;
|
|
@@ -286,7 +287,7 @@ export declare class Session {
|
|
|
286
287
|
private dispatchScheduleMessage;
|
|
287
288
|
private dispatchMiscMessage;
|
|
288
289
|
resetPeakInflight(): void;
|
|
289
|
-
handleBinaryFrame(
|
|
290
|
+
handleBinaryFrame(binaryFrame: BinaryFrame): Promise<void>;
|
|
290
291
|
private handleRestartServerRequest;
|
|
291
292
|
private handleShutdownServerRequest;
|
|
292
293
|
private emitLifecycleIntent;
|
|
@@ -420,6 +421,8 @@ export declare class Session {
|
|
|
420
421
|
* Handle read-only file explorer requests scoped to a workspace cwd
|
|
421
422
|
*/
|
|
422
423
|
private handleFileExplorerRequest;
|
|
424
|
+
private handleFileUploadRequest;
|
|
425
|
+
private handleFileTransferFrame;
|
|
423
426
|
/**
|
|
424
427
|
* Handle project icon request for a given cwd
|
|
425
428
|
*/
|
|
@@ -8,6 +8,7 @@ import { CLIENT_CAPS } from "@getpaseo/protocol/client-capabilities";
|
|
|
8
8
|
import { serializeAgentStreamEvent, } from "./messages.js";
|
|
9
9
|
import { TerminalSessionController } from "../terminal/terminal-session-controller.js";
|
|
10
10
|
import { encodeFileTransferFrame, FileTransferOpcode, } from "@getpaseo/protocol/binary-frames/index";
|
|
11
|
+
import { FileUploadStore } from "./file-upload/index.js";
|
|
11
12
|
import { CursorError } from "./pagination/cursor.js";
|
|
12
13
|
import { SortablePager } from "./pagination/sortable-pager.js";
|
|
13
14
|
import { TTSManager } from "./agent/tts-manager.js";
|
|
@@ -327,6 +328,7 @@ export class Session {
|
|
|
327
328
|
this.onLifecycleIntent = onLifecycleIntent ?? null;
|
|
328
329
|
this.downloadTokenStore = downloadTokenStore;
|
|
329
330
|
this.pushTokenStore = pushTokenStore;
|
|
331
|
+
this.fileUploads = new FileUploadStore({ paseoHome });
|
|
330
332
|
this.paseoHome = paseoHome;
|
|
331
333
|
this.worktreesRoot = worktreesRoot;
|
|
332
334
|
this.sessionLogger = logger.child({
|
|
@@ -1322,6 +1324,9 @@ export class Session {
|
|
|
1322
1324
|
return this.handleProjectIconRequest(msg);
|
|
1323
1325
|
case "file_download_token_request":
|
|
1324
1326
|
return this.handleFileDownloadTokenRequest(msg);
|
|
1327
|
+
case "file.upload.request":
|
|
1328
|
+
this.handleFileUploadRequest(msg);
|
|
1329
|
+
return undefined;
|
|
1325
1330
|
default:
|
|
1326
1331
|
return undefined;
|
|
1327
1332
|
}
|
|
@@ -1419,8 +1424,12 @@ export class Session {
|
|
|
1419
1424
|
resetPeakInflight() {
|
|
1420
1425
|
this.peakInflightRequests = this.inflightRequests;
|
|
1421
1426
|
}
|
|
1422
|
-
handleBinaryFrame(
|
|
1423
|
-
|
|
1427
|
+
async handleBinaryFrame(binaryFrame) {
|
|
1428
|
+
if (binaryFrame.kind === "file_transfer") {
|
|
1429
|
+
await this.handleFileTransferFrame(binaryFrame.frame);
|
|
1430
|
+
return;
|
|
1431
|
+
}
|
|
1432
|
+
this.terminalController.handleBinaryFrame(binaryFrame.frame);
|
|
1424
1433
|
}
|
|
1425
1434
|
async handleRestartServerRequest(requestId, reason) {
|
|
1426
1435
|
const payload = {
|
|
@@ -4395,6 +4404,15 @@ export class Session {
|
|
|
4395
4404
|
});
|
|
4396
4405
|
}
|
|
4397
4406
|
}
|
|
4407
|
+
handleFileUploadRequest(request) {
|
|
4408
|
+
this.fileUploads.beginUpload(request);
|
|
4409
|
+
}
|
|
4410
|
+
async handleFileTransferFrame(frame) {
|
|
4411
|
+
const response = await this.fileUploads.receiveFrame(frame);
|
|
4412
|
+
if (response) {
|
|
4413
|
+
this.emit(response);
|
|
4414
|
+
}
|
|
4415
|
+
}
|
|
4398
4416
|
/**
|
|
4399
4417
|
* Handle project icon request for a given cwd
|
|
4400
4418
|
*/
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { EventEmitter } from "node:events";
|
|
2
|
+
import { Readable } from "node:stream";
|
|
2
3
|
import type pino from "pino";
|
|
3
4
|
import type { SpeechStreamResult, SpeechToTextProvider, StreamingTranscriptionSession, TextToSpeechProvider } from "../../speech-provider.js";
|
|
4
5
|
import type { TurnDetectionProvider, TurnDetectionSession } from "../../turn-detection-provider.js";
|
|
@@ -6,20 +7,24 @@ import type { LocalSpeechSessionKind, LocalSpeechTranscriptionResult, LocalSpeec
|
|
|
6
7
|
interface LocalSpeechWorkerProcess {
|
|
7
8
|
connected: boolean;
|
|
8
9
|
killed: boolean;
|
|
10
|
+
pid?: number;
|
|
11
|
+
stderr?: Readable | null;
|
|
9
12
|
send(message: LocalSpeechWorkerRequest, callback: (error: Error | null) => void): boolean;
|
|
10
13
|
disconnect(): void;
|
|
11
14
|
kill(): boolean;
|
|
12
15
|
on(event: "message", listener: (message: LocalSpeechWorkerToParentMessage) => void): this;
|
|
13
|
-
on(event: "
|
|
16
|
+
on(event: "close", listener: (code: number | null, signal: NodeJS.Signals | null) => void): this;
|
|
14
17
|
}
|
|
15
18
|
interface LocalSpeechWorkerClientOptions {
|
|
16
19
|
config: LocalSpeechWorkerConfig;
|
|
20
|
+
logger: pino.Logger;
|
|
17
21
|
requestTimeoutMs?: number;
|
|
18
22
|
idleTtlMs?: number;
|
|
19
23
|
forkWorker?: () => LocalSpeechWorkerProcess;
|
|
20
24
|
}
|
|
21
25
|
export declare class LocalSpeechWorkerClient {
|
|
22
26
|
private readonly config;
|
|
27
|
+
private readonly logger;
|
|
23
28
|
private readonly requestTimeoutMs;
|
|
24
29
|
private readonly idleTtlMs;
|
|
25
30
|
private readonly forkWorker;
|
|
@@ -27,8 +32,12 @@ export declare class LocalSpeechWorkerClient {
|
|
|
27
32
|
private readonly activeSessionIds;
|
|
28
33
|
private readonly sessionEmitters;
|
|
29
34
|
private worker;
|
|
35
|
+
private workerPid;
|
|
36
|
+
private stderrTail;
|
|
37
|
+
private stderrLineBuffer;
|
|
30
38
|
private inFlightRequests;
|
|
31
39
|
private idleTimer;
|
|
40
|
+
private readonly intentionalWorkerCloses;
|
|
32
41
|
constructor(options: LocalSpeechWorkerClientOptions);
|
|
33
42
|
synthesizeSpeech(text: string): Promise<SpeechStreamResult>;
|
|
34
43
|
transcribeVoice(audio: Buffer, format: string): Promise<LocalSpeechTranscriptionResult>;
|
|
@@ -45,10 +54,14 @@ export declare class LocalSpeechWorkerClient {
|
|
|
45
54
|
shutdown(): void;
|
|
46
55
|
private sendRequest;
|
|
47
56
|
private ensureWorker;
|
|
57
|
+
private handleWorkerStderr;
|
|
48
58
|
private handleWorkerMessage;
|
|
49
59
|
private handleWorkerExit;
|
|
60
|
+
private describePendingRequests;
|
|
61
|
+
private getStderrTail;
|
|
50
62
|
private rejectAllPending;
|
|
51
63
|
private emitSessionError;
|
|
64
|
+
private emitErrorIfObserved;
|
|
52
65
|
private scheduleIdleShutdownIfReady;
|
|
53
66
|
private clearIdleTimer;
|
|
54
67
|
}
|