@getpaseo/server 0.1.87 → 0.1.89
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/server/server/agent/agent-manager.js +4 -1
- package/dist/server/server/agent/agent-storage.d.ts +22 -22
- package/dist/server/server/agent/create-agent/create.d.ts +2 -0
- package/dist/server/server/agent/create-agent/create.js +16 -5
- package/dist/server/server/agent/create-agent-lifecycle-dispatch.d.ts +1 -0
- package/dist/server/server/agent/create-agent-lifecycle-dispatch.js +4 -0
- package/dist/server/server/agent/mcp-server.d.ts +1 -0
- package/dist/server/server/agent/mcp-server.js +137 -63
- package/dist/server/server/agent/mcp-shared.d.ts +1 -0
- package/dist/server/server/agent/providers/pi/agent.js +13 -0
- package/dist/server/server/agent/providers/pi/rpc-types.d.ts +3 -0
- package/dist/server/server/agent/timeline-projection.d.ts +17 -1
- package/dist/server/server/agent/timeline-projection.js +82 -17
- package/dist/server/server/auto-archive-on-merge/archive-if-safe.d.ts +1 -0
- package/dist/server/server/auto-archive-on-merge/archive-if-safe.js +6 -1
- package/dist/server/server/bootstrap.d.ts +7 -2
- package/dist/server/server/bootstrap.js +152 -115
- package/dist/server/server/config.js +41 -0
- package/dist/server/server/loop-service.d.ts +22 -22
- package/dist/server/server/package-version.d.ts +2 -2
- package/dist/server/server/paseo-worktree-archive-service.d.ts +2 -0
- package/dist/server/server/paseo-worktree-archive-service.js +28 -9
- package/dist/server/server/persisted-config.d.ts +89 -33
- package/dist/server/server/persisted-config.js +17 -0
- package/dist/server/server/pid-lock.d.ts +2 -2
- package/dist/server/server/schedule/cron.js +52 -5
- package/dist/server/server/script-health-monitor.d.ts +4 -4
- package/dist/server/server/script-health-monitor.js +6 -6
- package/dist/server/server/script-proxy.d.ts +2 -39
- package/dist/server/server/script-proxy.js +1 -244
- package/dist/server/server/script-route-branch-handler.d.ts +2 -2
- package/dist/server/server/script-route-branch-handler.js +3 -37
- package/dist/server/server/script-status-projection.d.ts +6 -4
- package/dist/server/server/script-status-projection.js +85 -37
- package/dist/server/server/service-proxy.d.ts +237 -0
- package/dist/server/server/service-proxy.js +714 -0
- package/dist/server/server/session.d.ts +11 -4
- package/dist/server/server/session.js +96 -99
- package/dist/server/server/websocket-server.d.ts +7 -4
- package/dist/server/server/websocket-server.js +9 -4
- package/dist/server/server/workspace-directory.js +4 -0
- package/dist/server/server/workspace-git-service.d.ts +3 -0
- package/dist/server/server/workspace-git-service.js +53 -12
- package/dist/server/server/workspace-registry.d.ts +2 -2
- package/dist/server/server/workspace-service-env.d.ts +1 -0
- package/dist/server/server/workspace-service-env.js +23 -18
- package/dist/server/server/worktree/commands.d.ts +2 -0
- package/dist/server/server/worktree/commands.js +4 -1
- package/dist/server/server/worktree-bootstrap.d.ts +4 -3
- package/dist/server/server/worktree-bootstrap.js +14 -13
- package/dist/server/server/worktree-core.d.ts +1 -0
- package/dist/server/server/worktree-core.js +2 -0
- package/dist/server/server/worktree-session.d.ts +6 -2
- package/dist/server/server/worktree-session.js +3 -0
- package/dist/server/services/github-service.d.ts +1 -0
- package/dist/server/services/github-service.js +7 -1
- package/dist/server/terminal/terminal-manager.js +11 -1
- package/dist/server/terminal/terminal-session-controller.d.ts +3 -1
- package/dist/server/terminal/terminal-session-controller.js +22 -12
- package/dist/server/terminal/terminal.d.ts +1 -0
- package/dist/server/terminal/terminal.js +34 -0
- package/dist/server/utils/checkout-git.d.ts +6 -2
- package/dist/server/utils/checkout-git.js +136 -54
- package/dist/server/utils/worktree.d.ts +17 -12
- package/dist/server/utils/worktree.js +39 -22
- package/dist/src/server/persisted-config.js +17 -0
- package/package.json +5 -5
- package/dist/server/utils/script-hostname.d.ts +0 -8
- package/dist/server/utils/script-hostname.js +0 -14
|
@@ -15,7 +15,7 @@ import type { AgentStorage } from "./agent/agent-storage.js";
|
|
|
15
15
|
import { type PersistedWorkspaceRecord, type ProjectRegistry, type WorkspaceRegistry } from "./workspace-registry.js";
|
|
16
16
|
import { DownloadTokenStore } from "./file-download/token-store.js";
|
|
17
17
|
import { PushTokenStore } from "./push/token-store.js";
|
|
18
|
-
import type {
|
|
18
|
+
import type { ServiceProxySubsystem } from "./service-proxy.js";
|
|
19
19
|
import { CheckoutDiffManager } from "./checkout-diff-manager.js";
|
|
20
20
|
import { type Resolvable } from "./speech/provider-resolver.js";
|
|
21
21
|
import type { SpeechReadinessSnapshot } from "./speech/speech-runtime.js";
|
|
@@ -46,6 +46,7 @@ export interface SessionOptions {
|
|
|
46
46
|
downloadTokenStore: DownloadTokenStore;
|
|
47
47
|
pushTokenStore: PushTokenStore;
|
|
48
48
|
paseoHome: string;
|
|
49
|
+
worktreesRoot?: string;
|
|
49
50
|
agentManager: AgentManager;
|
|
50
51
|
agentStorage: AgentStorage;
|
|
51
52
|
projectRegistry: ProjectRegistry;
|
|
@@ -64,12 +65,13 @@ export interface SessionOptions {
|
|
|
64
65
|
tts: Resolvable<TextToSpeechProvider | null>;
|
|
65
66
|
terminalManager: TerminalManager | null;
|
|
66
67
|
providerSnapshotManager: ProviderSnapshotManager;
|
|
67
|
-
|
|
68
|
+
serviceProxy?: ServiceProxySubsystem;
|
|
68
69
|
scriptRuntimeStore?: WorkspaceScriptRuntimeStore;
|
|
69
70
|
workspaceSetupSnapshots?: Map<string, WorkspaceSetupSnapshot>;
|
|
70
71
|
onBranchChanged?: (workspaceId: string, oldBranch: string | null, newBranch: string | null) => void;
|
|
71
72
|
getDaemonTcpPort?: () => number | null;
|
|
72
73
|
getDaemonTcpHost?: () => string | null;
|
|
74
|
+
serviceProxyPublicBaseUrl?: string | null;
|
|
73
75
|
resolveScriptHealth?: (hostname: string) => ScriptHealthState | null;
|
|
74
76
|
voice?: {
|
|
75
77
|
turnDetection?: Resolvable<TurnDetectionProvider | null>;
|
|
@@ -124,6 +126,7 @@ export declare class Session {
|
|
|
124
126
|
private readonly onLifecycleIntent;
|
|
125
127
|
private readonly sessionLogger;
|
|
126
128
|
private readonly paseoHome;
|
|
129
|
+
private readonly worktreesRoot;
|
|
127
130
|
private abortController;
|
|
128
131
|
private processingPhase;
|
|
129
132
|
private isVoiceMode;
|
|
@@ -163,11 +166,12 @@ export declare class Session {
|
|
|
163
166
|
private readonly terminalManager;
|
|
164
167
|
private readonly providerSnapshotManager;
|
|
165
168
|
private unsubscribeProviderSnapshotEvents;
|
|
166
|
-
private readonly
|
|
169
|
+
private readonly serviceProxy;
|
|
167
170
|
private readonly scriptRuntimeStore;
|
|
168
171
|
private readonly onBranchChanged?;
|
|
169
172
|
private readonly getDaemonTcpPort;
|
|
170
173
|
private readonly getDaemonTcpHost;
|
|
174
|
+
private readonly serviceProxyPublicBaseUrl;
|
|
171
175
|
private readonly resolveScriptHealth;
|
|
172
176
|
private readonly terminalController;
|
|
173
177
|
private inflightRequests;
|
|
@@ -489,7 +493,10 @@ export declare class Session {
|
|
|
489
493
|
private handleWorkspaceSetupStatusRequest;
|
|
490
494
|
private handleArchiveWorkspaceRequest;
|
|
491
495
|
private handleFetchAgent;
|
|
492
|
-
private
|
|
496
|
+
private shouldUseFullTimelineForProjectedPage;
|
|
497
|
+
private selectCanonicalTimelineProjection;
|
|
498
|
+
private selectProjectedTimelineProjection;
|
|
499
|
+
private selectTimelineProjection;
|
|
493
500
|
private handleFetchAgentTimelineRequest;
|
|
494
501
|
private handleSendAgentMessageRequest;
|
|
495
502
|
private handleWaitForFinish;
|
|
@@ -38,7 +38,7 @@ import { createAgentCommand } from "./agent/create-agent/create.js";
|
|
|
38
38
|
import { archiveAgentCommand, cancelAgentRunCommand, closeAgentCommand, setAgentModeCommand, updateAgentCommand, } from "./agent/lifecycle-command.js";
|
|
39
39
|
import { buildStoredAgentPayload, resolveEffectiveThinkingOptionId, resolveStoredAgentPayloadUpdatedAt, toAgentPayload, } from "./agent/agent-projections.js";
|
|
40
40
|
import { appendTimelineItemIfAgentKnown, emitLiveTimelineItemIfAgentKnown, } from "./agent/timeline-append.js";
|
|
41
|
-
import { projectTimelineRows,
|
|
41
|
+
import { projectTimelineRows, selectProjectedTimelinePage, } from "./agent/timeline-projection.js";
|
|
42
42
|
import { StructuredAgentFallbackError, StructuredAgentResponseError, generateStructuredAgentResponseWithFallback, } from "./agent/agent-response-loop.js";
|
|
43
43
|
import { resolveStructuredGenerationProviders, } from "./agent/structured-generation-providers.js";
|
|
44
44
|
import { getAgentStreamEventTurnId, } from "./agent/agent-sdk-types.js";
|
|
@@ -334,7 +334,7 @@ export class Session {
|
|
|
334
334
|
}
|
|
335
335
|
},
|
|
336
336
|
});
|
|
337
|
-
const { clientId, appVersion, clientCapabilities, onMessage, onBinaryMessage, onLifecycleIntent, logger, downloadTokenStore, pushTokenStore, paseoHome, agentManager, agentStorage, projectRegistry, workspaceRegistry, chatService, scheduleService, loopService, checkoutDiffManager, github, workspaceGitService, daemonConfigStore, mcpBaseUrl, stt, sttLanguage, tts, terminalManager, providerSnapshotManager,
|
|
337
|
+
const { clientId, appVersion, clientCapabilities, onMessage, onBinaryMessage, onLifecycleIntent, logger, downloadTokenStore, pushTokenStore, paseoHome, worktreesRoot, agentManager, agentStorage, projectRegistry, workspaceRegistry, chatService, scheduleService, loopService, checkoutDiffManager, github, workspaceGitService, daemonConfigStore, mcpBaseUrl, stt, sttLanguage, tts, terminalManager, providerSnapshotManager, serviceProxy, scriptRuntimeStore, workspaceSetupSnapshots, onBranchChanged, getDaemonTcpPort, getDaemonTcpHost, serviceProxyPublicBaseUrl, resolveScriptHealth, voice, voiceBridge, dictation, serverId, daemonVersion, daemonRuntimeConfig, } = options;
|
|
338
338
|
this.clientId = clientId;
|
|
339
339
|
this.appVersion = appVersion ?? null;
|
|
340
340
|
this.clientCapabilities = parseClientCapabilities(clientCapabilities);
|
|
@@ -345,6 +345,7 @@ export class Session {
|
|
|
345
345
|
this.downloadTokenStore = downloadTokenStore;
|
|
346
346
|
this.pushTokenStore = pushTokenStore;
|
|
347
347
|
this.paseoHome = paseoHome;
|
|
348
|
+
this.worktreesRoot = worktreesRoot;
|
|
348
349
|
this.sessionLogger = logger.child({
|
|
349
350
|
module: "session",
|
|
350
351
|
clientId: this.clientId,
|
|
@@ -370,9 +371,11 @@ export class Session {
|
|
|
370
371
|
hasBinaryChannel: () => this.onBinaryMessage !== null,
|
|
371
372
|
isPathWithinRoot: (rootPath, candidatePath) => this.isPathWithinRoot(rootPath, candidatePath),
|
|
372
373
|
sessionLogger: this.sessionLogger,
|
|
374
|
+
clientSupportsWrapReflow: () => this.clientCapabilities.has(CLIENT_CAPS.terminalReflowableSnapshot),
|
|
373
375
|
});
|
|
374
376
|
this.createAgentLifecycleDispatch = new CreateAgentLifecycleDispatch({
|
|
375
377
|
paseoHome: this.paseoHome,
|
|
378
|
+
worktreesRoot: this.worktreesRoot,
|
|
376
379
|
agentManager: this.agentManager,
|
|
377
380
|
agentStorage: this.agentStorage,
|
|
378
381
|
github: this.github,
|
|
@@ -397,12 +400,13 @@ export class Session {
|
|
|
397
400
|
logger: this.sessionLogger,
|
|
398
401
|
});
|
|
399
402
|
this.providerSnapshotManager = providerSnapshotManager;
|
|
400
|
-
this.
|
|
403
|
+
this.serviceProxy = serviceProxy ?? null;
|
|
401
404
|
this.scriptRuntimeStore = scriptRuntimeStore ?? null;
|
|
402
405
|
this.workspaceSetupSnapshots = workspaceSetupSnapshots ?? new Map();
|
|
403
406
|
this.onBranchChanged = onBranchChanged;
|
|
404
407
|
this.getDaemonTcpPort = getDaemonTcpPort ?? null;
|
|
405
408
|
this.getDaemonTcpHost = getDaemonTcpHost ?? null;
|
|
409
|
+
this.serviceProxyPublicBaseUrl = serviceProxyPublicBaseUrl ?? null;
|
|
406
410
|
this.resolveScriptHealth = resolveScriptHealth ?? null;
|
|
407
411
|
this.sttLanguage = sttLanguage ?? "en";
|
|
408
412
|
this.subscribeToOptionalManagers();
|
|
@@ -2093,6 +2097,7 @@ export class Session {
|
|
|
2093
2097
|
agentStorage: this.agentStorage,
|
|
2094
2098
|
logger: this.sessionLogger,
|
|
2095
2099
|
paseoHome: this.paseoHome,
|
|
2100
|
+
worktreesRoot: this.worktreesRoot,
|
|
2096
2101
|
workspaceGitService: this.workspaceGitService,
|
|
2097
2102
|
providerSnapshotManager: this.providerSnapshotManager,
|
|
2098
2103
|
daemonConfig: this.readStructuredGenerationDaemonConfig(),
|
|
@@ -2427,6 +2432,7 @@ export class Session {
|
|
|
2427
2432
|
async buildAgentSessionConfig(config, gitOptions, legacyWorktreeName, firstAgentContext) {
|
|
2428
2433
|
return buildWorktreeAgentSessionConfig({
|
|
2429
2434
|
paseoHome: this.paseoHome,
|
|
2435
|
+
worktreesRoot: this.worktreesRoot,
|
|
2430
2436
|
sessionLogger: this.sessionLogger,
|
|
2431
2437
|
workspaceGitService: this.workspaceGitService,
|
|
2432
2438
|
createPaseoWorktree: (input, serviceOptions) => this.createPaseoWorktreeWorkflow(input, {
|
|
@@ -3872,7 +3878,7 @@ export class Session {
|
|
|
3872
3878
|
const mutatedCwd = await mergeToBase(cwd, {
|
|
3873
3879
|
baseRef,
|
|
3874
3880
|
mode: msg.strategy === "squash" ? "squash" : "merge",
|
|
3875
|
-
}, { paseoHome: this.paseoHome });
|
|
3881
|
+
}, { paseoHome: this.paseoHome, worktreesRoot: this.worktreesRoot });
|
|
3876
3882
|
await Promise.all([
|
|
3877
3883
|
this.notifyGitMutation(mutatedCwd, "merge-to-base", { invalidateGithub: true }),
|
|
3878
3884
|
...(mutatedCwd !== cwd ? [this.notifyGitMutation(cwd, "merge-to-base")] : []),
|
|
@@ -4292,6 +4298,7 @@ export class Session {
|
|
|
4292
4298
|
async handlePaseoWorktreeArchiveRequest(msg) {
|
|
4293
4299
|
return handleWorktreeArchiveRequest({
|
|
4294
4300
|
paseoHome: this.paseoHome,
|
|
4301
|
+
worktreesRoot: this.worktreesRoot,
|
|
4295
4302
|
github: this.github,
|
|
4296
4303
|
workspaceGitService: this.workspaceGitService,
|
|
4297
4304
|
agentManager: this.agentManager,
|
|
@@ -4729,14 +4736,15 @@ export class Session {
|
|
|
4729
4736
|
status: "done",
|
|
4730
4737
|
activityAt: null,
|
|
4731
4738
|
diffStat,
|
|
4732
|
-
scripts: this.
|
|
4739
|
+
scripts: this.serviceProxy && this.scriptRuntimeStore
|
|
4733
4740
|
? buildWorkspaceScriptPayloads({
|
|
4734
4741
|
workspaceId: workspace.workspaceId,
|
|
4735
4742
|
workspaceDirectory: workspace.cwd,
|
|
4736
4743
|
paseoConfig: readPaseoConfigForProjection(workspace.cwd, this.sessionLogger),
|
|
4737
|
-
|
|
4744
|
+
serviceProxy: this.serviceProxy,
|
|
4738
4745
|
runtimeStore: this.scriptRuntimeStore,
|
|
4739
4746
|
daemonPort: this.getDaemonTcpPort?.() ?? null,
|
|
4747
|
+
serviceProxyPublicBaseUrl: this.serviceProxyPublicBaseUrl,
|
|
4740
4748
|
gitMetadata: this.resolveWorkspaceScriptGitMetadata(workspace.cwd),
|
|
4741
4749
|
resolveHealth: this.resolveScriptHealth ?? undefined,
|
|
4742
4750
|
})
|
|
@@ -5398,16 +5406,17 @@ export class Session {
|
|
|
5398
5406
|
}
|
|
5399
5407
|
}
|
|
5400
5408
|
buildWorkspaceScriptPayloadSnapshot(workspaceId, workspaceDirectory) {
|
|
5401
|
-
if (!this.
|
|
5409
|
+
if (!this.serviceProxy || !this.scriptRuntimeStore) {
|
|
5402
5410
|
return [];
|
|
5403
5411
|
}
|
|
5404
5412
|
return buildWorkspaceScriptPayloads({
|
|
5405
5413
|
workspaceId,
|
|
5406
5414
|
workspaceDirectory,
|
|
5407
5415
|
paseoConfig: readPaseoConfigForProjection(workspaceDirectory, this.sessionLogger),
|
|
5408
|
-
|
|
5416
|
+
serviceProxy: this.serviceProxy,
|
|
5409
5417
|
runtimeStore: this.scriptRuntimeStore,
|
|
5410
5418
|
daemonPort: this.getDaemonTcpPort?.() ?? null,
|
|
5419
|
+
serviceProxyPublicBaseUrl: this.serviceProxyPublicBaseUrl,
|
|
5411
5420
|
gitMetadata: this.resolveWorkspaceScriptGitMetadata(workspaceDirectory),
|
|
5412
5421
|
resolveHealth: this.resolveScriptHealth ?? undefined,
|
|
5413
5422
|
});
|
|
@@ -5442,7 +5451,7 @@ export class Session {
|
|
|
5442
5451
|
}
|
|
5443
5452
|
async handleStartWorkspaceScriptRequest(request) {
|
|
5444
5453
|
try {
|
|
5445
|
-
if (!this.terminalManager || !this.
|
|
5454
|
+
if (!this.terminalManager || !this.serviceProxy || !this.scriptRuntimeStore) {
|
|
5446
5455
|
throw new Error("Workspace scripts are not available on this daemon");
|
|
5447
5456
|
}
|
|
5448
5457
|
const workspace = await this.workspaceRegistry.get(request.workspaceId);
|
|
@@ -5458,7 +5467,8 @@ export class Session {
|
|
|
5458
5467
|
scriptName: request.scriptName,
|
|
5459
5468
|
daemonPort: this.getDaemonTcpPort?.() ?? null,
|
|
5460
5469
|
daemonListenHost: this.getDaemonTcpHost?.() ?? null,
|
|
5461
|
-
|
|
5470
|
+
serviceProxyPublicBaseUrl: this.serviceProxyPublicBaseUrl,
|
|
5471
|
+
serviceProxy: this.serviceProxy,
|
|
5462
5472
|
runtimeStore: this.scriptRuntimeStore,
|
|
5463
5473
|
terminalManager: this.terminalManager,
|
|
5464
5474
|
logger: this.sessionLogger,
|
|
@@ -5553,6 +5563,7 @@ export class Session {
|
|
|
5553
5563
|
async handleCreatePaseoWorktreeRequest(request) {
|
|
5554
5564
|
return handleCreateWorktreeRequest({
|
|
5555
5565
|
paseoHome: this.paseoHome,
|
|
5566
|
+
worktreesRoot: this.worktreesRoot,
|
|
5556
5567
|
describeWorkspaceRecord: (result) => this.describeCreatedWorktreeWorkspace(result),
|
|
5557
5568
|
emit: (message) => this.emit(message),
|
|
5558
5569
|
sessionLogger: this.sessionLogger,
|
|
@@ -5562,6 +5573,7 @@ export class Session {
|
|
|
5562
5573
|
async createPaseoWorktreeWorkflow(input, options) {
|
|
5563
5574
|
return createWorktreeWorkflow({
|
|
5564
5575
|
paseoHome: this.paseoHome,
|
|
5576
|
+
worktreesRoot: this.worktreesRoot,
|
|
5565
5577
|
createPaseoWorktree: (workflowInput, serviceOptions) => this.createPaseoWorktree(workflowInput, serviceOptions),
|
|
5566
5578
|
warmWorkspaceGitData: (workspace) => this.warmWorkspaceGitDataForWorkspace(workspace),
|
|
5567
5579
|
autoNameWorkspaceBranchForFirstAgent: (autoNameInput) => this.scheduleAutoNameWorkspaceBranchForFirstAgent(autoNameInput),
|
|
@@ -5573,10 +5585,11 @@ export class Session {
|
|
|
5573
5585
|
sessionLogger: this.sessionLogger,
|
|
5574
5586
|
terminalManager: this.terminalManager,
|
|
5575
5587
|
archiveWorkspaceRecord: (workspaceId) => this.archiveWorkspaceRecord(workspaceId),
|
|
5576
|
-
|
|
5588
|
+
serviceProxy: this.serviceProxy,
|
|
5577
5589
|
scriptRuntimeStore: this.scriptRuntimeStore,
|
|
5578
5590
|
getDaemonTcpPort: this.getDaemonTcpPort,
|
|
5579
5591
|
getDaemonTcpHost: this.getDaemonTcpHost,
|
|
5592
|
+
serviceProxyPublicBaseUrl: this.serviceProxyPublicBaseUrl,
|
|
5580
5593
|
onScriptsChanged: (workspaceId, workspaceDirectory) => {
|
|
5581
5594
|
this.emitWorkspaceScriptStatusUpdate(workspaceId, workspaceDirectory);
|
|
5582
5595
|
},
|
|
@@ -5652,62 +5665,63 @@ export class Session {
|
|
|
5652
5665
|
payload: { requestId, agent, project, error: null },
|
|
5653
5666
|
});
|
|
5654
5667
|
}
|
|
5655
|
-
|
|
5656
|
-
const {
|
|
5657
|
-
|
|
5658
|
-
|
|
5659
|
-
|
|
5660
|
-
|
|
5668
|
+
shouldUseFullTimelineForProjectedPage(input) {
|
|
5669
|
+
const { timeline } = input;
|
|
5670
|
+
if (timeline.reset || timeline.rows.length === 0 || !timeline.hasOlder) {
|
|
5671
|
+
return false;
|
|
5672
|
+
}
|
|
5673
|
+
const firstRow = timeline.rows[0];
|
|
5674
|
+
if (firstRow?.item.type === "assistant_message" ||
|
|
5675
|
+
firstRow?.item.type === "reasoning" ||
|
|
5676
|
+
firstRow?.item.type === "tool_call") {
|
|
5677
|
+
return true;
|
|
5678
|
+
}
|
|
5679
|
+
return timeline.rows.some((row) => row.item.type === "tool_call");
|
|
5680
|
+
}
|
|
5681
|
+
selectCanonicalTimelineProjection(input) {
|
|
5682
|
+
const entries = projectTimelineRows({ rows: input.timeline.rows, mode: "canonical" });
|
|
5683
|
+
return {
|
|
5684
|
+
timeline: input.timeline,
|
|
5685
|
+
entries,
|
|
5686
|
+
startSeq: entries[0]?.seqStart ?? null,
|
|
5687
|
+
endSeq: entries[entries.length - 1]?.seqEnd ?? null,
|
|
5688
|
+
hasOlder: input.timeline.hasOlder,
|
|
5689
|
+
hasNewer: input.timeline.hasNewer,
|
|
5690
|
+
};
|
|
5691
|
+
}
|
|
5692
|
+
selectProjectedTimelineProjection(input) {
|
|
5693
|
+
const timeline = this.shouldUseFullTimelineForProjectedPage({
|
|
5694
|
+
timeline: input.controlTimeline,
|
|
5695
|
+
})
|
|
5696
|
+
? this.agentManager.fetchTimeline(input.agentId, { direction: "tail", limit: 0 })
|
|
5697
|
+
: input.controlTimeline;
|
|
5698
|
+
const page = selectProjectedTimelinePage({
|
|
5661
5699
|
rows: timeline.rows,
|
|
5662
|
-
|
|
5663
|
-
|
|
5664
|
-
|
|
5700
|
+
bounds: timeline.window,
|
|
5701
|
+
direction: input.controlTimeline.reset ? "tail" : input.direction,
|
|
5702
|
+
...(input.cursor ? { cursorSeq: input.cursor.seq } : {}),
|
|
5703
|
+
limit: input.pageLimit,
|
|
5665
5704
|
});
|
|
5666
|
-
while (timeline.hasOlder) {
|
|
5667
|
-
const needsMoreProjectedEntries = projectedWindow.projectedEntries.length < projectedLimit;
|
|
5668
|
-
const firstLoadedRow = timeline.rows[0];
|
|
5669
|
-
const firstSelectedRow = projectedWindow.selectedRows[0];
|
|
5670
|
-
const startsAtLoadedBoundary = firstLoadedRow != null &&
|
|
5671
|
-
firstSelectedRow != null &&
|
|
5672
|
-
firstSelectedRow.seq === firstLoadedRow.seq;
|
|
5673
|
-
const boundaryIsAssistantChunk = startsAtLoadedBoundary && firstLoadedRow.item.type === "assistant_message";
|
|
5674
|
-
if (!needsMoreProjectedEntries && !boundaryIsAssistantChunk) {
|
|
5675
|
-
break;
|
|
5676
|
-
}
|
|
5677
|
-
const maxRows = Math.max(0, timeline.window.maxSeq - timeline.window.minSeq + 1);
|
|
5678
|
-
const nextFetchLimit = Math.min(maxRows, fetchLimit * 2);
|
|
5679
|
-
if (nextFetchLimit <= fetchLimit) {
|
|
5680
|
-
break;
|
|
5681
|
-
}
|
|
5682
|
-
fetchLimit = nextFetchLimit;
|
|
5683
|
-
timeline = this.agentManager.fetchTimeline(agentId, {
|
|
5684
|
-
direction,
|
|
5685
|
-
cursor,
|
|
5686
|
-
limit: fetchLimit,
|
|
5687
|
-
});
|
|
5688
|
-
projectedWindow = selectTimelineWindowByProjectedLimit({
|
|
5689
|
-
rows: timeline.rows,
|
|
5690
|
-
direction,
|
|
5691
|
-
limit: projectedLimit,
|
|
5692
|
-
collapseToolLifecycle: false,
|
|
5693
|
-
});
|
|
5694
|
-
}
|
|
5695
5705
|
return {
|
|
5696
5706
|
timeline,
|
|
5697
|
-
|
|
5698
|
-
|
|
5699
|
-
|
|
5707
|
+
entries: page.entries,
|
|
5708
|
+
startSeq: page.startSeq,
|
|
5709
|
+
endSeq: page.endSeq,
|
|
5710
|
+
hasOlder: page.hasOlder || (page.startSeq !== null && page.startSeq > timeline.window.minSeq),
|
|
5711
|
+
hasNewer: page.hasNewer,
|
|
5700
5712
|
};
|
|
5701
5713
|
}
|
|
5714
|
+
selectTimelineProjection(input) {
|
|
5715
|
+
if (input.projection === "canonical") {
|
|
5716
|
+
return this.selectCanonicalTimelineProjection({ timeline: input.controlTimeline });
|
|
5717
|
+
}
|
|
5718
|
+
return this.selectProjectedTimelineProjection(input);
|
|
5719
|
+
}
|
|
5702
5720
|
async handleFetchAgentTimelineRequest(msg) {
|
|
5703
5721
|
const direction = msg.direction ?? (msg.cursor ? "after" : "tail");
|
|
5704
5722
|
const projection = msg.projection ?? "projected";
|
|
5705
5723
|
const requestedLimit = msg.limit;
|
|
5706
|
-
const
|
|
5707
|
-
const shouldLimitByProjectedWindow = projection === "canonical" &&
|
|
5708
|
-
direction === "tail" &&
|
|
5709
|
-
typeof requestedLimit === "number" &&
|
|
5710
|
-
requestedLimit > 0;
|
|
5724
|
+
const pageLimit = requestedLimit ?? (direction === "after" ? 0 : 200);
|
|
5711
5725
|
const cursor = msg.cursor
|
|
5712
5726
|
? {
|
|
5713
5727
|
epoch: msg.cursor.epoch,
|
|
@@ -5721,42 +5735,25 @@ export class Session {
|
|
|
5721
5735
|
logger: this.sessionLogger,
|
|
5722
5736
|
});
|
|
5723
5737
|
const agentPayload = await this.buildAgentPayload(snapshot);
|
|
5724
|
-
|
|
5738
|
+
const controlTimeline = this.agentManager.fetchTimeline(msg.agentId, {
|
|
5725
5739
|
direction,
|
|
5726
5740
|
cursor,
|
|
5727
|
-
limit:
|
|
5728
|
-
|
|
5729
|
-
|
|
5730
|
-
|
|
5731
|
-
|
|
5732
|
-
|
|
5733
|
-
|
|
5734
|
-
|
|
5735
|
-
|
|
5736
|
-
|
|
5737
|
-
|
|
5738
|
-
|
|
5739
|
-
|
|
5740
|
-
|
|
5741
|
-
|
|
5742
|
-
|
|
5743
|
-
});
|
|
5744
|
-
timeline = projectedResult.timeline;
|
|
5745
|
-
entries = projectTimelineRows({ rows: projectedResult.selectedRows, mode: projection });
|
|
5746
|
-
if (projectedResult.minSeq !== null && projectedResult.maxSeq !== null) {
|
|
5747
|
-
startCursor = { epoch: timeline.epoch, seq: projectedResult.minSeq };
|
|
5748
|
-
endCursor = { epoch: timeline.epoch, seq: projectedResult.maxSeq };
|
|
5749
|
-
hasOlder = projectedResult.minSeq > timeline.window.minSeq;
|
|
5750
|
-
hasNewer = false;
|
|
5751
|
-
}
|
|
5752
|
-
}
|
|
5753
|
-
else {
|
|
5754
|
-
const firstRow = timeline.rows[0];
|
|
5755
|
-
const lastRow = timeline.rows[timeline.rows.length - 1];
|
|
5756
|
-
startCursor = firstRow ? { epoch: timeline.epoch, seq: firstRow.seq } : null;
|
|
5757
|
-
endCursor = lastRow ? { epoch: timeline.epoch, seq: lastRow.seq } : null;
|
|
5758
|
-
entries = projectTimelineRows({ rows: timeline.rows, mode: projection });
|
|
5759
|
-
}
|
|
5741
|
+
limit: pageLimit,
|
|
5742
|
+
});
|
|
5743
|
+
const selectedTimeline = this.selectTimelineProjection({
|
|
5744
|
+
agentId: msg.agentId,
|
|
5745
|
+
projection,
|
|
5746
|
+
controlTimeline,
|
|
5747
|
+
direction,
|
|
5748
|
+
...(cursor ? { cursor } : {}),
|
|
5749
|
+
pageLimit,
|
|
5750
|
+
});
|
|
5751
|
+
const startCursor = selectedTimeline.startSeq !== null
|
|
5752
|
+
? { epoch: selectedTimeline.timeline.epoch, seq: selectedTimeline.startSeq }
|
|
5753
|
+
: null;
|
|
5754
|
+
const endCursor = selectedTimeline.endSeq !== null
|
|
5755
|
+
? { epoch: selectedTimeline.timeline.epoch, seq: selectedTimeline.endSeq }
|
|
5756
|
+
: null;
|
|
5760
5757
|
this.emit({
|
|
5761
5758
|
type: "fetch_agent_timeline_response",
|
|
5762
5759
|
payload: {
|
|
@@ -5765,16 +5762,16 @@ export class Session {
|
|
|
5765
5762
|
agent: agentPayload,
|
|
5766
5763
|
direction,
|
|
5767
5764
|
projection,
|
|
5768
|
-
epoch: timeline.epoch,
|
|
5769
|
-
reset:
|
|
5770
|
-
staleCursor:
|
|
5771
|
-
gap:
|
|
5772
|
-
window: timeline.window,
|
|
5765
|
+
epoch: selectedTimeline.timeline.epoch,
|
|
5766
|
+
reset: controlTimeline.reset,
|
|
5767
|
+
staleCursor: controlTimeline.staleCursor,
|
|
5768
|
+
gap: controlTimeline.gap,
|
|
5769
|
+
window: selectedTimeline.timeline.window,
|
|
5773
5770
|
startCursor,
|
|
5774
5771
|
endCursor,
|
|
5775
|
-
hasOlder,
|
|
5776
|
-
hasNewer,
|
|
5777
|
-
entries: entries.map((entry) => ({
|
|
5772
|
+
hasOlder: selectedTimeline.hasOlder,
|
|
5773
|
+
hasNewer: selectedTimeline.hasNewer,
|
|
5774
|
+
entries: selectedTimeline.entries.map((entry) => ({
|
|
5778
5775
|
provider: snapshot.provider,
|
|
5779
5776
|
item: entry.item,
|
|
5780
5777
|
timestamp: entry.timestamp,
|
|
@@ -17,7 +17,7 @@ import { ProviderSnapshotManager } from "./agent/provider-snapshot-manager.js";
|
|
|
17
17
|
import type { WorkspaceGitService } from "./workspace-git-service.js";
|
|
18
18
|
import { type PushNotificationSender } from "./push/notifications.js";
|
|
19
19
|
import type { ScriptHealthState } from "./script-health-monitor.js";
|
|
20
|
-
import type {
|
|
20
|
+
import type { ServiceProxySubsystem } from "./service-proxy.js";
|
|
21
21
|
import type { WorkspaceScriptRuntimeStore } from "./workspace-script-runtime-store.js";
|
|
22
22
|
import type { SpeechReadinessSnapshot, SpeechService } from "./speech/speech-runtime.js";
|
|
23
23
|
import type { VoiceCallerContext, VoiceSpeakHandler } from "./voice-types.js";
|
|
@@ -66,16 +66,18 @@ export declare class VoiceAssistantWebSocketServer {
|
|
|
66
66
|
private readonly workspaceGitService;
|
|
67
67
|
private readonly downloadTokenStore;
|
|
68
68
|
private readonly paseoHome;
|
|
69
|
+
private readonly worktreesRoot;
|
|
69
70
|
private readonly daemonConfigStore;
|
|
70
71
|
private readonly pushTokenStore;
|
|
71
72
|
private readonly pushNotificationSender;
|
|
72
73
|
private readonly mcpBaseUrl;
|
|
73
74
|
private speech;
|
|
74
75
|
private terminalManager;
|
|
75
|
-
private
|
|
76
|
+
private serviceProxy;
|
|
76
77
|
private scriptRuntimeStore;
|
|
77
78
|
private getDaemonTcpPort;
|
|
78
79
|
private getDaemonTcpHost;
|
|
80
|
+
private serviceProxyPublicBaseUrl;
|
|
79
81
|
private resolveScriptHealth;
|
|
80
82
|
private dictation;
|
|
81
83
|
private readonly voiceSpeakHandlers;
|
|
@@ -91,8 +93,9 @@ export declare class VoiceAssistantWebSocketServer {
|
|
|
91
93
|
private unsubscribeDaemonConfigChange;
|
|
92
94
|
constructor(server: HTTPServer, logger: pino.Logger, serverId: string, agentManager: AgentManager, agentStorage: AgentStorage, downloadTokenStore: DownloadTokenStore, paseoHome: string, daemonConfigStore: DaemonConfigStore, mcpBaseUrl: string | null, wsConfig: WebSocketServerConfig, auth?: DaemonAuthConfig, speech?: SpeechService | null, terminalManager?: TerminalManager | null, dictation?: {
|
|
93
95
|
finalTimeoutMs?: number;
|
|
94
|
-
}, daemonVersion?: string, onLifecycleIntent?: (intent: SessionLifecycleIntent) => void, projectRegistry?: ProjectRegistry, workspaceRegistry?: WorkspaceRegistry, chatService?: FileBackedChatService, loopService?: LoopService, scheduleService?: ScheduleService, checkoutDiffManager?: CheckoutDiffManager,
|
|
96
|
+
}, daemonVersion?: string, onLifecycleIntent?: (intent: SessionLifecycleIntent) => void, projectRegistry?: ProjectRegistry, workspaceRegistry?: WorkspaceRegistry, chatService?: FileBackedChatService, loopService?: LoopService, scheduleService?: ScheduleService, checkoutDiffManager?: CheckoutDiffManager, serviceProxy?: ServiceProxySubsystem | null, scriptRuntimeStore?: WorkspaceScriptRuntimeStore | null, onBranchChanged?: (workspaceId: string, oldBranch: string | null, newBranch: string | null) => void, getDaemonTcpPort?: () => number | null, getDaemonTcpHost?: () => string | null, resolveScriptHealth?: (hostname: string) => ScriptHealthState | null, workspaceGitService?: WorkspaceGitService, github?: GitHubService, pushNotificationSender?: PushNotificationSender, providerSnapshotManager?: ProviderSnapshotManager, daemonRuntimeConfig?: {
|
|
95
97
|
listen: string | null;
|
|
98
|
+
worktreesRoot?: string;
|
|
96
99
|
relay: {
|
|
97
100
|
enabled: boolean;
|
|
98
101
|
endpoint: string;
|
|
@@ -100,7 +103,7 @@ export declare class VoiceAssistantWebSocketServer {
|
|
|
100
103
|
useTls: boolean;
|
|
101
104
|
publicUseTls: boolean;
|
|
102
105
|
};
|
|
103
|
-
});
|
|
106
|
+
}, serviceProxyPublicBaseUrl?: string | null);
|
|
104
107
|
private assignOptionalServices;
|
|
105
108
|
private createWebSocketServer;
|
|
106
109
|
private startRuntimeMetricsInterval;
|
|
@@ -202,7 +202,7 @@ function requireWebSocketServices(params) {
|
|
|
202
202
|
* WebSocket server that only accepts sockets + parses/forwards messages to the session layer.
|
|
203
203
|
*/
|
|
204
204
|
export class VoiceAssistantWebSocketServer {
|
|
205
|
-
constructor(server, logger, serverId, agentManager, agentStorage, downloadTokenStore, paseoHome, daemonConfigStore, mcpBaseUrl, wsConfig, auth, speech, terminalManager, dictation, daemonVersion, onLifecycleIntent, projectRegistry, workspaceRegistry, chatService, loopService, scheduleService, checkoutDiffManager,
|
|
205
|
+
constructor(server, logger, serverId, agentManager, agentStorage, downloadTokenStore, paseoHome, daemonConfigStore, mcpBaseUrl, wsConfig, auth, speech, terminalManager, dictation, daemonVersion, onLifecycleIntent, projectRegistry, workspaceRegistry, chatService, loopService, scheduleService, checkoutDiffManager, serviceProxy, scriptRuntimeStore, onBranchChanged, getDaemonTcpPort, getDaemonTcpHost, resolveScriptHealth, workspaceGitService, github, pushNotificationSender, providerSnapshotManager, daemonRuntimeConfig, serviceProxyPublicBaseUrl) {
|
|
206
206
|
this.pendingConnections = new Map();
|
|
207
207
|
this.sessions = new Map();
|
|
208
208
|
this.externalSessionsByKey = new Map();
|
|
@@ -238,6 +238,7 @@ export class VoiceAssistantWebSocketServer {
|
|
|
238
238
|
this.workspaceGitService = workspaceGitService ?? createFallbackWorkspaceGitService();
|
|
239
239
|
this.downloadTokenStore = downloadTokenStore;
|
|
240
240
|
this.paseoHome = paseoHome;
|
|
241
|
+
this.worktreesRoot = daemonRuntimeConfig?.worktreesRoot;
|
|
241
242
|
this.daemonConfigStore = daemonConfigStore;
|
|
242
243
|
this.mcpBaseUrl = mcpBaseUrl;
|
|
243
244
|
this.assignOptionalServices({
|
|
@@ -245,11 +246,12 @@ export class VoiceAssistantWebSocketServer {
|
|
|
245
246
|
terminalManager,
|
|
246
247
|
dictation,
|
|
247
248
|
onLifecycleIntent,
|
|
248
|
-
|
|
249
|
+
serviceProxy,
|
|
249
250
|
scriptRuntimeStore,
|
|
250
251
|
onBranchChanged,
|
|
251
252
|
getDaemonTcpPort,
|
|
252
253
|
getDaemonTcpHost,
|
|
254
|
+
serviceProxyPublicBaseUrl,
|
|
253
255
|
resolveScriptHealth,
|
|
254
256
|
});
|
|
255
257
|
if (!providerSnapshotManager) {
|
|
@@ -286,11 +288,12 @@ export class VoiceAssistantWebSocketServer {
|
|
|
286
288
|
this.terminalManager = params.terminalManager ?? null;
|
|
287
289
|
this.dictation = params.dictation ?? null;
|
|
288
290
|
this.onLifecycleIntent = params.onLifecycleIntent ?? null;
|
|
289
|
-
this.
|
|
291
|
+
this.serviceProxy = params.serviceProxy ?? null;
|
|
290
292
|
this.scriptRuntimeStore = params.scriptRuntimeStore ?? null;
|
|
291
293
|
this.onBranchChanged = params.onBranchChanged ?? null;
|
|
292
294
|
this.getDaemonTcpPort = params.getDaemonTcpPort ?? null;
|
|
293
295
|
this.getDaemonTcpHost = params.getDaemonTcpHost ?? null;
|
|
296
|
+
this.serviceProxyPublicBaseUrl = params.serviceProxyPublicBaseUrl ?? null;
|
|
294
297
|
this.resolveScriptHealth = params.resolveScriptHealth ?? null;
|
|
295
298
|
}
|
|
296
299
|
createWebSocketServer(server, wsConfig, auth) {
|
|
@@ -550,6 +553,7 @@ export class VoiceAssistantWebSocketServer {
|
|
|
550
553
|
downloadTokenStore: this.downloadTokenStore,
|
|
551
554
|
pushTokenStore: this.pushTokenStore,
|
|
552
555
|
paseoHome: this.paseoHome,
|
|
556
|
+
worktreesRoot: this.worktreesRoot,
|
|
553
557
|
agentManager: this.agentManager,
|
|
554
558
|
agentStorage: this.agentStorage,
|
|
555
559
|
projectRegistry: this.projectRegistry,
|
|
@@ -567,12 +571,13 @@ export class VoiceAssistantWebSocketServer {
|
|
|
567
571
|
tts: () => this.speech?.resolveTts() ?? null,
|
|
568
572
|
terminalManager: this.terminalManager,
|
|
569
573
|
providerSnapshotManager: this.providerSnapshotManager,
|
|
570
|
-
|
|
574
|
+
serviceProxy: this.serviceProxy ?? undefined,
|
|
571
575
|
scriptRuntimeStore: this.scriptRuntimeStore ?? undefined,
|
|
572
576
|
workspaceSetupSnapshots: this.workspaceSetupSnapshots,
|
|
573
577
|
onBranchChanged: this.onBranchChanged ?? undefined,
|
|
574
578
|
getDaemonTcpPort: this.getDaemonTcpPort ?? undefined,
|
|
575
579
|
getDaemonTcpHost: this.getDaemonTcpHost ?? undefined,
|
|
580
|
+
serviceProxyPublicBaseUrl: this.serviceProxyPublicBaseUrl,
|
|
576
581
|
resolveScriptHealth: this.resolveScriptHealth ?? undefined,
|
|
577
582
|
voice: {
|
|
578
583
|
turnDetection: () => this.speech?.resolveTurnDetection() ?? null,
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { homedir } from "node:os";
|
|
2
2
|
import { sep } from "node:path";
|
|
3
3
|
import { deriveAgentStateBucket, getWorkspaceStateBucketPriority, } from "@getpaseo/protocol/agent-state-bucket";
|
|
4
|
+
import { isDelegatedAgent } from "@getpaseo/protocol/agent-labels";
|
|
4
5
|
import { SortablePager } from "./pagination/sortable-pager.js";
|
|
5
6
|
import { normalizeWorkspaceId } from "./workspace-registry-model.js";
|
|
6
7
|
const FETCH_WORKSPACES_SORT_KEYS = [
|
|
@@ -99,6 +100,9 @@ export class WorkspaceDirectory {
|
|
|
99
100
|
if (!this.deps.isProviderVisibleToClient(agent.provider)) {
|
|
100
101
|
continue;
|
|
101
102
|
}
|
|
103
|
+
if (isDelegatedAgent(agent)) {
|
|
104
|
+
continue;
|
|
105
|
+
}
|
|
102
106
|
const workspaceId = workspaceIdsByDirectory.get(normalizeWorkspaceId(agent.cwd));
|
|
103
107
|
if (workspaceId === undefined) {
|
|
104
108
|
continue;
|
|
@@ -150,11 +150,13 @@ interface WorkspaceGitServiceDependencies {
|
|
|
150
150
|
interface WorkspaceGitServiceOptions {
|
|
151
151
|
logger: pino.Logger;
|
|
152
152
|
paseoHome: string;
|
|
153
|
+
worktreesRoot?: string;
|
|
153
154
|
deps?: Partial<WorkspaceGitServiceDependencies>;
|
|
154
155
|
}
|
|
155
156
|
export declare class WorkspaceGitServiceImpl implements WorkspaceGitService {
|
|
156
157
|
private readonly logger;
|
|
157
158
|
private readonly paseoHome;
|
|
159
|
+
private readonly worktreesRoot;
|
|
158
160
|
private readonly deps;
|
|
159
161
|
private readonly snapshotUpdatedListeners;
|
|
160
162
|
private readonly workspaceTargets;
|
|
@@ -219,6 +221,7 @@ export declare class WorkspaceGitServiceImpl implements WorkspaceGitService {
|
|
|
219
221
|
private scheduleWorkspaceRefresh;
|
|
220
222
|
private startWorkspaceSubscriptionTimers;
|
|
221
223
|
private updateGitHubPollForTarget;
|
|
224
|
+
private resolveGitHubPollTarget;
|
|
222
225
|
private stopGitHubPollForTarget;
|
|
223
226
|
private addWorkingTreeWatcher;
|
|
224
227
|
private ensureLinuxRepoTreeWatchers;
|