@getpaseo/server 0.1.100 → 0.1.102-beta.2
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 +26 -8
- package/dist/server/executable-resolution/windows.js +3 -0
- package/dist/server/server/agent/activity-curator.d.ts +17 -0
- package/dist/server/server/agent/activity-curator.js +101 -24
- package/dist/server/server/agent/agent-manager.d.ts +10 -0
- package/dist/server/server/agent/agent-manager.js +69 -27
- package/dist/server/server/agent/agent-sdk-types.d.ts +15 -2
- package/dist/server/server/agent/mcp-server.d.ts +2 -45
- package/dist/server/server/agent/mcp-server.js +45 -1985
- package/dist/server/server/agent/prompt-attachments.js +6 -2
- package/dist/server/server/agent/provider-snapshot-manager.d.ts +12 -1
- package/dist/server/server/agent/provider-snapshot-manager.js +132 -42
- package/dist/server/server/agent/providers/acp-agent.d.ts +27 -1
- package/dist/server/server/agent/providers/acp-agent.js +178 -27
- package/dist/server/server/agent/providers/claude/agent.js +111 -24
- package/dist/server/server/agent/providers/claude/query.d.ts +3 -0
- package/dist/server/server/agent/providers/claude/query.js +4 -2
- package/dist/server/server/agent/providers/codex-app-server-agent.js +6 -57
- package/dist/server/server/agent/providers/diagnostic-utils.d.ts +1 -0
- package/dist/server/server/agent/providers/diagnostic-utils.js +1 -1
- package/dist/server/server/agent/providers/generic-acp-agent.d.ts +3 -0
- package/dist/server/server/agent/providers/generic-acp-agent.js +41 -23
- package/dist/server/server/agent/providers/mock-load-test-agent.js +12 -2
- package/dist/server/server/agent/providers/opencode/paths.d.ts +2 -0
- package/dist/server/server/agent/providers/opencode/paths.js +7 -0
- package/dist/server/server/agent/providers/opencode/server-manager.d.ts +2 -0
- package/dist/server/server/agent/providers/opencode/server-manager.js +34 -5
- package/dist/server/server/agent/providers/opencode-agent.d.ts +4 -0
- package/dist/server/server/agent/providers/opencode-agent.js +14 -2
- package/dist/server/server/agent/providers/pi/agent.d.ts +5 -1
- package/dist/server/server/agent/providers/pi/agent.js +12 -3
- package/dist/server/server/agent/providers/provider-image-output.d.ts +5 -0
- package/dist/server/server/agent/providers/provider-image-output.js +61 -1
- package/dist/server/server/agent/tools/paseo-tools.d.ts +48 -0
- package/dist/server/server/agent/tools/paseo-tools.js +2119 -0
- package/dist/server/server/agent/tools/types.d.ts +36 -0
- package/dist/server/server/agent/tools/types.js +2 -0
- package/dist/server/server/bootstrap.d.ts +7 -1
- package/dist/server/server/bootstrap.js +89 -62
- package/dist/server/server/config.d.ts +2 -0
- package/dist/server/server/config.js +57 -1
- package/dist/server/server/daemon-worker.js +19 -7
- package/dist/server/server/lifecycle-reasons.d.ts +4 -0
- package/dist/server/server/lifecycle-reasons.js +6 -0
- package/dist/server/server/persisted-config.d.ts +12 -0
- package/dist/server/server/persisted-config.js +18 -2
- package/dist/server/server/process-diagnostics.d.ts +17 -0
- package/dist/server/server/process-diagnostics.js +22 -0
- package/dist/server/server/relay-transport.js +1 -0
- package/dist/server/server/resolve-worktree-creation-intent.js +3 -1
- package/dist/server/server/session/agent-updates/agent-updates-service.d.ts +59 -0
- package/dist/server/server/session/agent-updates/agent-updates-service.js +220 -0
- package/dist/server/server/session/checkout/checkout-session.d.ts +13 -15
- package/dist/server/server/session/checkout/checkout-session.js +18 -16
- package/dist/server/server/session/checkout/git-metadata-generator.d.ts +53 -0
- package/dist/server/server/session/checkout/git-metadata-generator.js +159 -0
- package/dist/server/server/session/daemon/daemon-self-update-session-controller.d.ts +32 -0
- package/dist/server/server/session/daemon/daemon-self-update-session-controller.js +88 -0
- package/dist/server/server/session/daemon/daemon-self-updater.d.ts +32 -0
- package/dist/server/server/session/daemon/daemon-self-updater.js +56 -0
- package/dist/server/server/session/daemon/daemon-session.d.ts +26 -0
- package/dist/server/server/session/daemon/daemon-session.js +50 -0
- package/dist/server/server/session/daemon/diagnostics.d.ts +41 -0
- package/dist/server/server/session/daemon/diagnostics.js +431 -0
- package/dist/server/server/session/daemon/install-origin.d.ts +7 -0
- package/dist/server/server/session/daemon/install-origin.js +64 -0
- package/dist/server/server/session/daemon/npm-global-cli.d.ts +29 -0
- package/dist/server/server/session/daemon/npm-global-cli.js +98 -0
- package/dist/server/server/session/git-mutation/git-mutation-service.d.ts +34 -0
- package/dist/server/server/session/git-mutation/git-mutation-service.js +71 -0
- package/dist/server/server/session/provider/provider-catalog-session.js +8 -4
- package/dist/server/server/session/workspace-git-observer/workspace-git-observer-service.d.ts +36 -0
- package/dist/server/server/session/workspace-git-observer/workspace-git-observer-service.js +134 -0
- package/dist/server/server/session/workspace-provisioning/workspace-provisioning-service.d.ts +34 -0
- package/dist/server/server/session/workspace-provisioning/workspace-provisioning-service.js +190 -0
- package/dist/server/server/session/workspace-scripts/workspace-scripts-service.d.ts +41 -0
- package/dist/server/server/session/workspace-scripts/workspace-scripts-service.js +100 -0
- package/dist/server/server/session.d.ts +12 -54
- package/dist/server/server/session.js +187 -970
- package/dist/server/server/speech/providers/openai/config.d.ts +1 -2
- package/dist/server/server/speech/providers/openai/config.js +13 -9
- package/dist/server/server/speech/providers/openai/runtime.js +2 -16
- package/dist/server/server/speech/providers/openai/stt.d.ts +1 -0
- package/dist/server/server/speech/providers/openai/stt.js +4 -2
- package/dist/server/server/speech/providers/openai/tts.d.ts +1 -0
- package/dist/server/server/speech/providers/openai/tts.js +1 -0
- package/dist/server/server/web-ui.d.ts +10 -0
- package/dist/server/server/web-ui.js +205 -0
- package/dist/server/server/websocket/runtime-metrics.d.ts +23 -0
- package/dist/server/server/websocket-server.d.ts +4 -2
- package/dist/server/server/websocket-server.js +215 -52
- package/dist/server/server/worktree-bootstrap.d.ts +1 -1
- package/dist/server/server/worktree-branch-name-generator.js +3 -1
- package/dist/server/services/quota-fetcher/manifest.js +5 -0
- package/dist/server/services/quota-fetcher/providers/minimax.d.ts +29 -0
- package/dist/server/services/quota-fetcher/providers/minimax.js +227 -0
- package/dist/server/terminal/agent-hooks/agent-hook-installer.js +2 -2
- package/dist/server/utils/checkout-git.js +203 -25
- package/dist/server/utils/directory-suggestions.js +1 -4
- package/dist/server/utils/path.d.ts +2 -0
- package/dist/server/utils/path.js +13 -0
- package/dist/server/utils/worktree.d.ts +1 -0
- package/dist/server/utils/worktree.js +92 -11
- package/dist/server/web-ui/_expo/static/css/xterm-3bb1704bf6cb0876640973dc0244b4cb.css +1 -0
- package/dist/server/web-ui/_expo/static/css/xterm-3bb1704bf6cb0876640973dc0244b4cb.css.br +0 -0
- package/dist/server/web-ui/_expo/static/css/xterm-3bb1704bf6cb0876640973dc0244b4cb.css.gz +0 -0
- package/dist/server/web-ui/_expo/static/js/web/desktop-attachment-bridge-b01555c9b42665a03988c0a0032ef528.js +1 -0
- package/dist/server/web-ui/_expo/static/js/web/desktop-attachment-bridge-b01555c9b42665a03988c0a0032ef528.js.br +0 -0
- package/dist/server/web-ui/_expo/static/js/web/desktop-attachment-bridge-b01555c9b42665a03988c0a0032ef528.js.gz +0 -0
- package/dist/server/web-ui/_expo/static/js/web/desktop-attachment-store-648388eca5c510b496e1eddf523f70ff.js +1 -0
- package/dist/server/web-ui/_expo/static/js/web/desktop-attachment-store-648388eca5c510b496e1eddf523f70ff.js.br +0 -0
- package/dist/server/web-ui/_expo/static/js/web/desktop-attachment-store-648388eca5c510b496e1eddf523f70ff.js.gz +0 -0
- package/dist/server/web-ui/_expo/static/js/web/index-0ebbea2cd337f0c0680fdb3f8d4d5af3.js +16157 -0
- package/dist/server/web-ui/_expo/static/js/web/index-0ebbea2cd337f0c0680fdb3f8d4d5af3.js.br +0 -0
- package/dist/server/web-ui/_expo/static/js/web/index-0ebbea2cd337f0c0680fdb3f8d4d5af3.js.gz +0 -0
- package/dist/server/web-ui/_expo/static/js/web/indexeddb-attachment-store-c64fa2416284927857a39087fd8d1332.js +1 -0
- package/dist/server/web-ui/_expo/static/js/web/indexeddb-attachment-store-c64fa2416284927857a39087fd8d1332.js.br +0 -0
- package/dist/server/web-ui/_expo/static/js/web/indexeddb-attachment-store-c64fa2416284927857a39087fd8d1332.js.gz +0 -0
- package/dist/server/web-ui/_expo/static/js/web/native-file-attachment-store-a9784226715772edf87ef36c596599c2.js +3 -0
- package/dist/server/web-ui/_expo/static/js/web/native-file-attachment-store-a9784226715772edf87ef36c596599c2.js.br +0 -0
- package/dist/server/web-ui/_expo/static/js/web/native-file-attachment-store-a9784226715772edf87ef36c596599c2.js.gz +0 -0
- package/dist/server/web-ui/apple-touch-icon.png +0 -0
- package/dist/server/web-ui/assets/__node_modules/@react-navigation/elements/lib/module/assets/back-icon-mask.0a328cd9c1afd0afe8e3b1ec5165b1b4.png +0 -0
- package/dist/server/web-ui/assets/__node_modules/@react-navigation/elements/lib/module/assets/back-icon.35ba0eaec5a4f5ed12ca16fabeae451d.png +0 -0
- package/dist/server/web-ui/assets/__node_modules/@react-navigation/elements/lib/module/assets/clear-icon.c94f6478e7ae0cdd9f15de1fcb9e5e55.png +0 -0
- package/dist/server/web-ui/assets/__node_modules/@react-navigation/elements/lib/module/assets/clear-icon.c94f6478e7ae0cdd9f15de1fcb9e5e55@2x.png +0 -0
- package/dist/server/web-ui/assets/__node_modules/@react-navigation/elements/lib/module/assets/clear-icon.c94f6478e7ae0cdd9f15de1fcb9e5e55@3x.png +0 -0
- package/dist/server/web-ui/assets/__node_modules/@react-navigation/elements/lib/module/assets/clear-icon.c94f6478e7ae0cdd9f15de1fcb9e5e55@4x.png +0 -0
- package/dist/server/web-ui/assets/__node_modules/@react-navigation/elements/lib/module/assets/close-icon.808e1b1b9b53114ec2838071a7e6daa7.png +0 -0
- package/dist/server/web-ui/assets/__node_modules/@react-navigation/elements/lib/module/assets/close-icon.808e1b1b9b53114ec2838071a7e6daa7@2x.png +0 -0
- package/dist/server/web-ui/assets/__node_modules/@react-navigation/elements/lib/module/assets/close-icon.808e1b1b9b53114ec2838071a7e6daa7@3x.png +0 -0
- package/dist/server/web-ui/assets/__node_modules/@react-navigation/elements/lib/module/assets/close-icon.808e1b1b9b53114ec2838071a7e6daa7@4x.png +0 -0
- package/dist/server/web-ui/assets/__node_modules/@react-navigation/elements/lib/module/assets/search-icon.286d67d3f74808a60a78d3ebf1a5fb57.png +0 -0
- package/dist/server/web-ui/assets/__node_modules/expo-router/assets/arrow_down.017bc6ba3fc25503e5eb5e53826d48a8.png +0 -0
- package/dist/server/web-ui/assets/__node_modules/expo-router/assets/error.d1ea1496f9057eb392d5bbf3732a61b7.png +0 -0
- package/dist/server/web-ui/assets/__node_modules/expo-router/assets/file.19eeb73b9593a38f8e9f418337fc7d10.png +0 -0
- package/dist/server/web-ui/assets/__node_modules/expo-router/assets/forward.d8b800c443b8972542883e0b9de2bdc6.png +0 -0
- package/dist/server/web-ui/assets/__node_modules/expo-router/assets/pkg.ab19f4cbc543357183a20571f68380a3.png +0 -0
- package/dist/server/web-ui/assets/__node_modules/expo-router/assets/sitemap.412dd9275b6b48ad28f5e3d81bb1f626.png +0 -0
- package/dist/server/web-ui/assets/__node_modules/expo-router/assets/unmatched.20e71bdf79e3a97bf55fd9e164041578.png +0 -0
- package/dist/server/web-ui/assets/assets/images/editor-apps/antigravity.6e91a685c33435e0b466a56db86cf141.png +0 -0
- package/dist/server/web-ui/assets/assets/images/editor-apps/cursor.c31d6bce4fe9aadc3fe59962f4c4fcf3.png +0 -0
- package/dist/server/web-ui/assets/assets/images/editor-apps/file-explorer.3e15e8f72c825c85ce336bcb0cdef776.png +0 -0
- package/dist/server/web-ui/assets/assets/images/editor-apps/finder.7f68fc2c475621a672e1be09309d5567.png +0 -0
- package/dist/server/web-ui/assets/assets/images/editor-apps/vscode.832bdb4c685d930f1c864c793703600b.png +0 -0
- package/dist/server/web-ui/assets/assets/images/editor-apps/webstorm.aa5dc2cd8c20cc0a155c4c5c5ab3c5f5.png +0 -0
- package/dist/server/web-ui/assets/assets/images/editor-apps/zed.f3a670b7f9aa226da4fe53fb86f1abbd.png +0 -0
- package/dist/server/web-ui/assets/assets/images/favicon-dark-attention.882b3a27dcb2073e9e31b334f9ed9728.png +0 -0
- package/dist/server/web-ui/assets/assets/images/favicon-dark-running.8112342ff0d39e047a7f8d4fad9402f3.png +0 -0
- package/dist/server/web-ui/assets/assets/images/favicon-dark.8005ed36ac07a5a7c60de25780897bd4.png +0 -0
- package/dist/server/web-ui/assets/assets/images/favicon-light-attention.882b3a27dcb2073e9e31b334f9ed9728.png +0 -0
- package/dist/server/web-ui/assets/assets/images/favicon-light-running.8112342ff0d39e047a7f8d4fad9402f3.png +0 -0
- package/dist/server/web-ui/assets/assets/images/favicon-light.8005ed36ac07a5a7c60de25780897bd4.png +0 -0
- package/dist/server/web-ui/assets/assets/images/notification-icon.3bf81d33ddbf380606bdd248ba83e158.png +0 -0
- package/dist/server/web-ui/favicon.ico +0 -0
- package/dist/server/web-ui/index.html +90 -0
- package/dist/server/web-ui/index.html.br +0 -0
- package/dist/server/web-ui/index.html.gz +0 -0
- package/dist/server/web-ui/manifest.json +27 -0
- package/dist/server/web-ui/manifest.json.br +0 -0
- package/dist/server/web-ui/manifest.json.gz +0 -0
- package/dist/server/web-ui/metadata.json +1 -0
- package/dist/server/web-ui/metadata.json.br +1 -0
- package/dist/server/web-ui/metadata.json.gz +0 -0
- package/dist/server/web-ui/pwa-icon-192.png +0 -0
- package/dist/server/web-ui/pwa-icon-512.png +0 -0
- package/dist/server/web-ui/robots.txt +2 -0
- package/dist/src/executable-resolution/windows.js +3 -0
- package/dist/src/server/persisted-config.js +18 -2
- package/package.json +7 -7
- package/dist/server/server/speech/providers/openai/realtime-transcription-session.d.ts +0 -42
- package/dist/server/server/speech/providers/openai/realtime-transcription-session.js +0 -168
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { z } from "zod";
|
|
2
|
+
export interface PaseoToolExecutionContext {
|
|
3
|
+
signal?: AbortSignal;
|
|
4
|
+
}
|
|
5
|
+
export interface PaseoToolResult {
|
|
6
|
+
content: Array<{
|
|
7
|
+
type: string;
|
|
8
|
+
text?: string;
|
|
9
|
+
[key: string]: unknown;
|
|
10
|
+
}>;
|
|
11
|
+
structuredContent?: unknown;
|
|
12
|
+
isError?: boolean;
|
|
13
|
+
}
|
|
14
|
+
export interface PaseoToolConfig {
|
|
15
|
+
title?: string;
|
|
16
|
+
description?: string;
|
|
17
|
+
inputSchema?: z.ZodRawShape | z.ZodType;
|
|
18
|
+
outputSchema?: z.ZodRawShape | z.ZodType;
|
|
19
|
+
}
|
|
20
|
+
export interface PaseoToolDefinition extends PaseoToolConfig {
|
|
21
|
+
name: string;
|
|
22
|
+
description: string;
|
|
23
|
+
handler: (input: unknown, context: PaseoToolExecutionContext) => Promise<PaseoToolResult>;
|
|
24
|
+
}
|
|
25
|
+
export interface PaseoToolCatalog {
|
|
26
|
+
tools: ReadonlyMap<string, PaseoToolDefinition>;
|
|
27
|
+
getTool(name: string): PaseoToolDefinition | undefined;
|
|
28
|
+
executeTool(name: string, input: unknown, context?: PaseoToolExecutionContext): Promise<PaseoToolResult>;
|
|
29
|
+
}
|
|
30
|
+
export interface PaseoToolRuntimeContext {
|
|
31
|
+
callerAgentId?: string;
|
|
32
|
+
enableVoiceTools?: boolean;
|
|
33
|
+
voiceOnly?: boolean;
|
|
34
|
+
}
|
|
35
|
+
export type PaseoToolCatalogFactory = (context: PaseoToolRuntimeContext) => PaseoToolCatalog | Promise<PaseoToolCatalog>;
|
|
36
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -44,11 +44,12 @@ export type DaemonLifecycleIntent = {
|
|
|
44
44
|
type: "shutdown";
|
|
45
45
|
clientId: string;
|
|
46
46
|
requestId: string;
|
|
47
|
+
reason: string;
|
|
47
48
|
} | {
|
|
48
49
|
type: "restart";
|
|
49
50
|
clientId: string;
|
|
50
51
|
requestId: string;
|
|
51
|
-
reason
|
|
52
|
+
reason: string;
|
|
52
53
|
};
|
|
53
54
|
export interface PaseoDaemonConfig {
|
|
54
55
|
listen: string;
|
|
@@ -57,6 +58,7 @@ export interface PaseoDaemonConfig {
|
|
|
57
58
|
corsAllowedOrigins: string[];
|
|
58
59
|
allowedHosts?: HostnamesConfig;
|
|
59
60
|
hostnames?: HostnamesConfig;
|
|
61
|
+
trustedProxies?: true | string[];
|
|
60
62
|
mcpEnabled?: boolean;
|
|
61
63
|
mcpInjectIntoAgents?: boolean;
|
|
62
64
|
autoArchiveAfterMerge?: boolean;
|
|
@@ -77,6 +79,10 @@ export interface PaseoDaemonConfig {
|
|
|
77
79
|
publicBaseUrl: string | null;
|
|
78
80
|
standaloneListen: string | null;
|
|
79
81
|
};
|
|
82
|
+
webUi?: {
|
|
83
|
+
enabled: boolean;
|
|
84
|
+
distDir: string | null;
|
|
85
|
+
};
|
|
80
86
|
appBaseUrl?: string;
|
|
81
87
|
auth?: DaemonAuthConfig;
|
|
82
88
|
openai?: PaseoOpenAIConfig;
|
|
@@ -83,6 +83,7 @@ import { AgentManager } from "./agent/agent-manager.js";
|
|
|
83
83
|
import { AgentStorage } from "./agent/agent-storage.js";
|
|
84
84
|
import { attachAgentStoragePersistence } from "./persistence-hooks.js";
|
|
85
85
|
import { createAgentMcpServer } from "./agent/mcp-server.js";
|
|
86
|
+
import { createPaseoToolCatalog, } from "./agent/tools/paseo-tools.js";
|
|
86
87
|
import { ProviderSnapshotManager } from "./agent/provider-snapshot-manager.js";
|
|
87
88
|
import { bootstrapWorkspaceRegistries } from "./workspace-registry-bootstrap.js";
|
|
88
89
|
import { WorkspaceReconciliationService } from "./workspace-reconciliation-service.js";
|
|
@@ -112,6 +113,7 @@ import { createManagedProcessRegistry, createSystemManagedProcessTable, } from "
|
|
|
112
113
|
import { terminateWithTreeKill } from "../utils/tree-kill.js";
|
|
113
114
|
import { isHostnameAllowed } from "./hostnames.js";
|
|
114
115
|
import { createRequireBearerMiddleware, isAgentMcpRequestAuthorized, } from "./auth.js";
|
|
116
|
+
import { createWebUiMiddleware } from "./web-ui.js";
|
|
115
117
|
const MAX_MCP_DEBUG_BATCH_ITEMS = 10;
|
|
116
118
|
const REDACTED_LOG_VALUE = "[redacted]";
|
|
117
119
|
const DOWNLOAD_OPEN_FLAGS = process.platform === "win32" ? constants.O_RDONLY : constants.O_RDONLY | constants.O_NOFOLLOW;
|
|
@@ -229,6 +231,17 @@ async function reconcileManagedProcessLedger(managedProcesses, logger) {
|
|
|
229
231
|
logger.info(reapResult, "Managed helper process ledger reconciled");
|
|
230
232
|
}
|
|
231
233
|
}
|
|
234
|
+
function mountWebUi(app, config, logger) {
|
|
235
|
+
app.use(createWebUiMiddleware({
|
|
236
|
+
enabled: config.webUi?.enabled ?? false,
|
|
237
|
+
distDir: config.webUi?.distDir ?? null,
|
|
238
|
+
label: getHostname(),
|
|
239
|
+
logger,
|
|
240
|
+
}));
|
|
241
|
+
}
|
|
242
|
+
function resolveExpressTrustProxySetting(config) {
|
|
243
|
+
return config.trustedProxies ?? ["loopback"];
|
|
244
|
+
}
|
|
232
245
|
export async function createPaseoDaemon(config, rootLogger) {
|
|
233
246
|
const logger = rootLogger.child({ module: "bootstrap" });
|
|
234
247
|
const bootstrapStart = performance.now();
|
|
@@ -278,6 +291,7 @@ export async function createPaseoDaemon(config, rootLogger) {
|
|
|
278
291
|
const agentMcpAuthToken = randomUUID();
|
|
279
292
|
const listenTarget = parseListenString(config.listen);
|
|
280
293
|
const app = express();
|
|
294
|
+
app.set("trust proxy", resolveExpressTrustProxySetting(config));
|
|
281
295
|
let boundListenTarget = null;
|
|
282
296
|
let workspaceRegistry = null;
|
|
283
297
|
const terminalManager = createConfiguredTerminalManager({
|
|
@@ -362,6 +376,11 @@ export async function createPaseoDaemon(config, rootLogger) {
|
|
|
362
376
|
});
|
|
363
377
|
// Local, harmless, and token-gated; deliberately skips daemon auth.
|
|
364
378
|
app.post("/api/terminal-activity", express.json(), createTerminalActivityRouteHandler(terminalManager));
|
|
379
|
+
// Serve the bundled browser web UI when enabled. Mounted after service-proxy
|
|
380
|
+
// classification and host/CORS handling, but before daemon bearer auth, so
|
|
381
|
+
// static app files load without the daemon password while API/WebSocket calls
|
|
382
|
+
// remain protected.
|
|
383
|
+
mountWebUi(app, config, logger);
|
|
365
384
|
app.use(createRequireBearerMiddleware(config.auth, (context) => {
|
|
366
385
|
logger.warn(context, "Rejected HTTP request with invalid daemon password");
|
|
367
386
|
}));
|
|
@@ -612,73 +631,79 @@ export async function createPaseoDaemon(config, rootLogger) {
|
|
|
612
631
|
clearWorkspaceArchiving: clearWorkspaceArchivingExternal,
|
|
613
632
|
emitWorkspaceUpdatesForWorkspaceIds: emitWorkspaceUpdatesExternal,
|
|
614
633
|
});
|
|
634
|
+
const createPaseoWorktreeForTools = async (input, serviceOptions) => {
|
|
635
|
+
return createPaseoWorktreeWorkflow({
|
|
636
|
+
paseoHome: config.paseoHome,
|
|
637
|
+
worktreesRoot: config.worktreesRoot,
|
|
638
|
+
createPaseoWorktree: async (workflowInput, workflowOptions) => {
|
|
639
|
+
return createRegisteredPaseoWorktree(workflowInput, {
|
|
640
|
+
github,
|
|
641
|
+
...(workflowOptions?.resolveDefaultBranch
|
|
642
|
+
? {
|
|
643
|
+
resolveDefaultBranch: workflowOptions.resolveDefaultBranch,
|
|
644
|
+
}
|
|
645
|
+
: {}),
|
|
646
|
+
projectRegistry,
|
|
647
|
+
workspaceRegistry,
|
|
648
|
+
workspaceGitService,
|
|
649
|
+
});
|
|
650
|
+
},
|
|
651
|
+
warmWorkspaceGitData: async (workspace) => {
|
|
652
|
+
await Promise.all(wsServer
|
|
653
|
+
?.listActiveSessions()
|
|
654
|
+
.map((session) => session.warmWorkspaceGitDataForWorkspace(workspace)) ?? []);
|
|
655
|
+
},
|
|
656
|
+
emitWorkspaceUpdateForWorkspaceId: async (workspaceId) => {
|
|
657
|
+
await emitWorkspaceUpdatesExternal([workspaceId]);
|
|
658
|
+
},
|
|
659
|
+
cacheWorkspaceSetupSnapshot: () => { },
|
|
660
|
+
emit: emitExternalSessionMessage,
|
|
661
|
+
sessionLogger: logger,
|
|
662
|
+
terminalManager,
|
|
663
|
+
archiveWorkspaceRecord: archiveWorkspaceRecordExternal,
|
|
664
|
+
serviceProxy,
|
|
665
|
+
scriptRuntimeStore,
|
|
666
|
+
getDaemonTcpPort: () => (boundListenTarget?.type === "tcp" ? boundListenTarget.port : null),
|
|
667
|
+
getDaemonTcpHost: () => (boundListenTarget?.type === "tcp" ? boundListenTarget.host : null),
|
|
668
|
+
serviceProxyPublicBaseUrl,
|
|
669
|
+
onScriptsChanged: null,
|
|
670
|
+
}, input, serviceOptions);
|
|
671
|
+
};
|
|
672
|
+
const createAgentToolHostDependencies = (runtime) => ({
|
|
673
|
+
agentManager,
|
|
674
|
+
agentStorage,
|
|
675
|
+
terminalManager,
|
|
676
|
+
getDaemonTcpPort: () => (boundListenTarget?.type === "tcp" ? boundListenTarget.port : null),
|
|
677
|
+
scheduleService,
|
|
678
|
+
providerSnapshotManager,
|
|
679
|
+
github,
|
|
680
|
+
workspaceGitService,
|
|
681
|
+
findWorkspaceIdForCwd: findWorkspaceIdForCwdExternal,
|
|
682
|
+
listActiveWorkspaces: listActiveWorkspacesExternal,
|
|
683
|
+
archiveWorkspaceRecord: archiveWorkspaceRecordExternal,
|
|
684
|
+
emitWorkspaceUpdatesForWorkspaceIds: emitWorkspaceUpdatesExternal,
|
|
685
|
+
markWorkspaceArchiving: markWorkspaceArchivingExternal,
|
|
686
|
+
clearWorkspaceArchiving: clearWorkspaceArchivingExternal,
|
|
687
|
+
ensureWorkspaceForCreate: ensureWorkspaceForCreateExternal,
|
|
688
|
+
createPaseoWorktree: createPaseoWorktreeForTools,
|
|
689
|
+
paseoHome: config.paseoHome,
|
|
690
|
+
worktreesRoot: config.worktreesRoot,
|
|
691
|
+
callerAgentId: runtime.callerAgentId,
|
|
692
|
+
enableVoiceTools: runtime.enableVoiceTools,
|
|
693
|
+
voiceOnly: runtime.voiceOnly,
|
|
694
|
+
resolveSpeakHandler: (agentId) => wsServer?.resolveVoiceSpeakHandler(agentId) ?? null,
|
|
695
|
+
resolveCallerContext: (agentId) => wsServer?.resolveVoiceCallerContext(agentId) ?? null,
|
|
696
|
+
logger,
|
|
697
|
+
});
|
|
698
|
+
const createAgentToolCatalog = (runtime) => createPaseoToolCatalog(createAgentToolHostDependencies(runtime));
|
|
699
|
+
agentManager.setPaseoToolCatalogFactory(createAgentToolCatalog);
|
|
700
|
+
agentManager.setPaseoToolsEnabled(config.mcpInjectIntoAgents !== false);
|
|
615
701
|
const mcpEnabled = config.mcpEnabled ?? true;
|
|
616
702
|
let agentMcpBaseUrl = null;
|
|
617
703
|
if (mcpEnabled) {
|
|
618
704
|
const agentMcpRoute = "/mcp/agents";
|
|
619
705
|
const createAgentMcpSession = async (callerAgentId) => {
|
|
620
|
-
const agentMcpServer = await createAgentMcpServer({
|
|
621
|
-
agentManager,
|
|
622
|
-
agentStorage,
|
|
623
|
-
terminalManager,
|
|
624
|
-
getDaemonTcpPort: () => (boundListenTarget?.type === "tcp" ? boundListenTarget.port : null),
|
|
625
|
-
scheduleService,
|
|
626
|
-
providerSnapshotManager,
|
|
627
|
-
github,
|
|
628
|
-
workspaceGitService,
|
|
629
|
-
findWorkspaceIdForCwd: findWorkspaceIdForCwdExternal,
|
|
630
|
-
listActiveWorkspaces: listActiveWorkspacesExternal,
|
|
631
|
-
archiveWorkspaceRecord: archiveWorkspaceRecordExternal,
|
|
632
|
-
emitWorkspaceUpdatesForWorkspaceIds: emitWorkspaceUpdatesExternal,
|
|
633
|
-
markWorkspaceArchiving: markWorkspaceArchivingExternal,
|
|
634
|
-
clearWorkspaceArchiving: clearWorkspaceArchivingExternal,
|
|
635
|
-
ensureWorkspaceForCreate: ensureWorkspaceForCreateExternal,
|
|
636
|
-
createPaseoWorktree: async (input, serviceOptions) => {
|
|
637
|
-
return createPaseoWorktreeWorkflow({
|
|
638
|
-
paseoHome: config.paseoHome,
|
|
639
|
-
worktreesRoot: config.worktreesRoot,
|
|
640
|
-
createPaseoWorktree: async (workflowInput, workflowOptions) => {
|
|
641
|
-
return createRegisteredPaseoWorktree(workflowInput, {
|
|
642
|
-
github,
|
|
643
|
-
...(workflowOptions?.resolveDefaultBranch
|
|
644
|
-
? {
|
|
645
|
-
resolveDefaultBranch: workflowOptions.resolveDefaultBranch,
|
|
646
|
-
}
|
|
647
|
-
: {}),
|
|
648
|
-
projectRegistry,
|
|
649
|
-
workspaceRegistry,
|
|
650
|
-
workspaceGitService,
|
|
651
|
-
});
|
|
652
|
-
},
|
|
653
|
-
warmWorkspaceGitData: async (workspace) => {
|
|
654
|
-
await Promise.all(wsServer
|
|
655
|
-
?.listActiveSessions()
|
|
656
|
-
.map((session) => session.warmWorkspaceGitDataForWorkspace(workspace)) ?? []);
|
|
657
|
-
},
|
|
658
|
-
emitWorkspaceUpdateForWorkspaceId: async (workspaceId) => {
|
|
659
|
-
await emitWorkspaceUpdatesExternal([workspaceId]);
|
|
660
|
-
},
|
|
661
|
-
cacheWorkspaceSetupSnapshot: () => { },
|
|
662
|
-
emit: emitExternalSessionMessage,
|
|
663
|
-
sessionLogger: logger,
|
|
664
|
-
terminalManager,
|
|
665
|
-
archiveWorkspaceRecord: archiveWorkspaceRecordExternal,
|
|
666
|
-
serviceProxy,
|
|
667
|
-
scriptRuntimeStore,
|
|
668
|
-
getDaemonTcpPort: () => boundListenTarget?.type === "tcp" ? boundListenTarget.port : null,
|
|
669
|
-
getDaemonTcpHost: () => boundListenTarget?.type === "tcp" ? boundListenTarget.host : null,
|
|
670
|
-
serviceProxyPublicBaseUrl,
|
|
671
|
-
onScriptsChanged: null,
|
|
672
|
-
}, input, serviceOptions);
|
|
673
|
-
},
|
|
674
|
-
paseoHome: config.paseoHome,
|
|
675
|
-
worktreesRoot: config.worktreesRoot,
|
|
676
|
-
callerAgentId,
|
|
677
|
-
enableVoiceTools: false,
|
|
678
|
-
resolveSpeakHandler: (agentId) => wsServer?.resolveVoiceSpeakHandler(agentId) ?? null,
|
|
679
|
-
resolveCallerContext: (agentId) => wsServer?.resolveVoiceCallerContext(agentId) ?? null,
|
|
680
|
-
logger,
|
|
681
|
-
});
|
|
706
|
+
const agentMcpServer = await createAgentMcpServer(createAgentToolHostDependencies({ callerAgentId }));
|
|
682
707
|
// Stateless mode: each HTTP request builds a fresh server + transport that is
|
|
683
708
|
// torn down when the response closes, so no per-session state is retained between
|
|
684
709
|
// requests. The agent control plane only lists and calls tools, neither of which
|
|
@@ -810,8 +835,10 @@ export async function createPaseoDaemon(config, rootLogger) {
|
|
|
810
835
|
const mcpBaseUrl = mcpEnabled ? createAgentMcpBaseUrl(boundListenTarget) : null;
|
|
811
836
|
agentMcpBaseUrl = config.mcpInjectIntoAgents === false ? null : mcpBaseUrl;
|
|
812
837
|
agentManager.setMcpBaseUrl(agentMcpBaseUrl);
|
|
838
|
+
agentManager.setPaseoToolsEnabled(config.mcpInjectIntoAgents !== false);
|
|
813
839
|
daemonConfigStore.onFieldChange("mcp.injectIntoAgents", (value) => {
|
|
814
840
|
agentManager.setMcpBaseUrl(value ? mcpBaseUrl : null);
|
|
841
|
+
agentManager.setPaseoToolsEnabled(value !== false);
|
|
815
842
|
});
|
|
816
843
|
daemonConfigStore.onFieldChange("appendSystemPrompt", (value) => {
|
|
817
844
|
agentManager.setAppendSystemPrompt(typeof value === "string" ? value : "");
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import type { PaseoDaemonConfig } from "./bootstrap.js";
|
|
2
2
|
import { type HostnamesConfig } from "./hostnames.js";
|
|
3
|
+
export declare function resolveBundledWebUiDistDir(moduleUrl?: string | URL): string;
|
|
3
4
|
export type CliConfigOverrides = Partial<{
|
|
4
5
|
listen: string;
|
|
5
6
|
relayEnabled: boolean;
|
|
6
7
|
relayUseTls: boolean;
|
|
7
8
|
mcpEnabled: boolean;
|
|
8
9
|
mcpInjectIntoAgents: boolean;
|
|
10
|
+
webUiEnabled: boolean;
|
|
9
11
|
hostnames: HostnamesConfig;
|
|
10
12
|
}>;
|
|
11
13
|
export declare function loadConfig(paseoHome: string, options?: {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
|
+
import { fileURLToPath } from "node:url";
|
|
2
3
|
import { resolvePaseoNodeEnv } from "./paseo-env.js";
|
|
3
4
|
import { z } from "zod";
|
|
4
5
|
import { expandTilde } from "../utils/path.js";
|
|
@@ -11,6 +12,20 @@ import { mergeHostnames, parseHostnamesEnv } from "./hostnames.js";
|
|
|
11
12
|
const DEFAULT_PORT = 6767;
|
|
12
13
|
const DEFAULT_RELAY_ENDPOINT = "relay.paseo.sh:443";
|
|
13
14
|
const DEFAULT_APP_BASE_URL = "https://app.paseo.sh";
|
|
15
|
+
const DEFAULT_TRUSTED_PROXIES = ["loopback"];
|
|
16
|
+
export function resolveBundledWebUiDistDir(moduleUrl = import.meta.url) {
|
|
17
|
+
const moduleDir = path.dirname(fileURLToPath(moduleUrl));
|
|
18
|
+
if (path.basename(moduleDir) === "server" && path.basename(path.dirname(moduleDir)) === "src") {
|
|
19
|
+
return path.resolve(moduleDir, "..", "..", "dist", "server", "web-ui");
|
|
20
|
+
}
|
|
21
|
+
if (path.basename(moduleDir) === "server" &&
|
|
22
|
+
path.basename(path.dirname(moduleDir)) === "server" &&
|
|
23
|
+
path.basename(path.dirname(path.dirname(moduleDir))) === "dist") {
|
|
24
|
+
return path.resolve(moduleDir, "..", "web-ui");
|
|
25
|
+
}
|
|
26
|
+
return path.resolve(moduleDir, "web-ui");
|
|
27
|
+
}
|
|
28
|
+
const BUNDLED_WEB_UI_DIST_DIR = resolveBundledWebUiDistDir();
|
|
14
29
|
function parseBooleanEnv(value) {
|
|
15
30
|
if (value === undefined) {
|
|
16
31
|
return undefined;
|
|
@@ -137,6 +152,21 @@ function resolveServiceProxyConfig(env, persisted) {
|
|
|
137
152
|
: null;
|
|
138
153
|
return { publicBaseUrl, standaloneListen };
|
|
139
154
|
}
|
|
155
|
+
function resolveWebUiConfig(paseoHome, env, cli, persisted) {
|
|
156
|
+
const enabled = cli?.webUiEnabled ??
|
|
157
|
+
parseBooleanEnv(env.PASEO_WEB_UI_ENABLED) ??
|
|
158
|
+
persisted.features?.webUi?.enabled ??
|
|
159
|
+
false;
|
|
160
|
+
const rawDistDir = env.PASEO_WEB_UI_DIST_DIR ?? persisted.features?.webUi?.distDir;
|
|
161
|
+
const trimmedDistDir = rawDistDir?.trim();
|
|
162
|
+
const distDir = trimmedDistDir
|
|
163
|
+
? path.resolve(path.isAbsolute(trimmedDistDir) ? trimmedDistDir : paseoHome, trimmedDistDir)
|
|
164
|
+
: BUNDLED_WEB_UI_DIST_DIR;
|
|
165
|
+
return {
|
|
166
|
+
enabled,
|
|
167
|
+
distDir,
|
|
168
|
+
};
|
|
169
|
+
}
|
|
140
170
|
function resolveVoiceLlmConfig(env, persisted) {
|
|
141
171
|
const envVoiceLlmProvider = parseOptionalVoiceLlmProvider(env.PASEO_VOICE_LLM_PROVIDER);
|
|
142
172
|
const persistedVoiceLlmProvider = parseOptionalVoiceLlmProvider(persisted.features?.voiceMode?.llm?.provider);
|
|
@@ -153,6 +183,28 @@ function resolveCorsAllowedOrigins(env, persisted) {
|
|
|
153
183
|
const persistedCorsOrigins = persisted.daemon?.cors?.allowedOrigins ?? [];
|
|
154
184
|
return Array.from(new Set([...persistedCorsOrigins, ...envCorsOrigins].filter((s) => s.length > 0)));
|
|
155
185
|
}
|
|
186
|
+
function parseTrustedProxiesEnv(value) {
|
|
187
|
+
const trimmed = value?.trim();
|
|
188
|
+
if (!trimmed) {
|
|
189
|
+
return undefined;
|
|
190
|
+
}
|
|
191
|
+
const normalized = trimmed.toLowerCase();
|
|
192
|
+
if (["1", "true", "yes", "on"].includes(normalized)) {
|
|
193
|
+
return true;
|
|
194
|
+
}
|
|
195
|
+
if (["0", "false", "no", "off"].includes(normalized)) {
|
|
196
|
+
return [];
|
|
197
|
+
}
|
|
198
|
+
return trimmed
|
|
199
|
+
.split(",")
|
|
200
|
+
.map((proxy) => proxy.trim())
|
|
201
|
+
.filter((proxy) => proxy.length > 0);
|
|
202
|
+
}
|
|
203
|
+
function resolveTrustedProxiesConfig(env, persisted) {
|
|
204
|
+
return (parseTrustedProxiesEnv(env.PASEO_TRUSTED_PROXIES) ??
|
|
205
|
+
persisted.daemon?.trustedProxies ??
|
|
206
|
+
DEFAULT_TRUSTED_PROXIES);
|
|
207
|
+
}
|
|
156
208
|
// PASEO_LISTEN can be:
|
|
157
209
|
// - host:port (TCP)
|
|
158
210
|
// - /path/to/socket (Unix socket)
|
|
@@ -198,6 +250,7 @@ function resolveStaticLoadConfigSettings(env, cli, persisted) {
|
|
|
198
250
|
parseHostnamesEnv(env.PASEO_HOSTNAMES ?? env.PASEO_ALLOWED_HOSTS),
|
|
199
251
|
cli?.hostnames,
|
|
200
252
|
]),
|
|
253
|
+
trustedProxies: resolveTrustedProxiesConfig(env, persisted),
|
|
201
254
|
appBaseUrl: env.PASEO_APP_BASE_URL ?? persisted.app?.baseUrl ?? DEFAULT_APP_BASE_URL,
|
|
202
255
|
};
|
|
203
256
|
}
|
|
@@ -205,7 +258,7 @@ export function loadConfig(paseoHome, options) {
|
|
|
205
258
|
const env = options?.env ?? process.env;
|
|
206
259
|
const persisted = loadPersistedConfig(paseoHome);
|
|
207
260
|
const listen = resolveListenAddress(env, options?.cli, persisted);
|
|
208
|
-
const { mcpEnabled, mcpInjectIntoAgents, autoArchiveAfterMerge, appendSystemPrompt, terminalProfiles, hostnames, appBaseUrl, } = resolveStaticLoadConfigSettings(env, options?.cli, persisted);
|
|
261
|
+
const { mcpEnabled, mcpInjectIntoAgents, autoArchiveAfterMerge, appendSystemPrompt, terminalProfiles, hostnames, trustedProxies, appBaseUrl, } = resolveStaticLoadConfigSettings(env, options?.cli, persisted);
|
|
209
262
|
const relay = resolveRelayConfig({
|
|
210
263
|
env,
|
|
211
264
|
persisted,
|
|
@@ -213,6 +266,7 @@ export function loadConfig(paseoHome, options) {
|
|
|
213
266
|
cliRelayUseTls: options?.cli?.relayUseTls,
|
|
214
267
|
});
|
|
215
268
|
const serviceProxy = resolveServiceProxyConfig(env, persisted);
|
|
269
|
+
const webUi = resolveWebUiConfig(paseoHome, env, options?.cli, persisted);
|
|
216
270
|
const { openai, speech } = resolveSpeechConfig({
|
|
217
271
|
paseoHome,
|
|
218
272
|
env,
|
|
@@ -226,6 +280,7 @@ export function loadConfig(paseoHome, options) {
|
|
|
226
280
|
worktreesRoot: resolveWorktreesRoot(paseoHome, persisted),
|
|
227
281
|
corsAllowedOrigins: resolveCorsAllowedOrigins(env, persisted),
|
|
228
282
|
hostnames,
|
|
283
|
+
trustedProxies,
|
|
229
284
|
mcpEnabled,
|
|
230
285
|
mcpInjectIntoAgents,
|
|
231
286
|
autoArchiveAfterMerge,
|
|
@@ -243,6 +298,7 @@ export function loadConfig(paseoHome, options) {
|
|
|
243
298
|
relayUseTls: relay.useTls,
|
|
244
299
|
relayPublicUseTls: relay.publicUseTls,
|
|
245
300
|
serviceProxy,
|
|
301
|
+
webUi,
|
|
246
302
|
appBaseUrl,
|
|
247
303
|
auth: resolveAuthConfig(env, persisted),
|
|
248
304
|
openai,
|
|
@@ -4,6 +4,7 @@ import { createPaseoDaemon } from "./bootstrap.js";
|
|
|
4
4
|
import { loadConfig } from "./config.js";
|
|
5
5
|
import { resolvePaseoHome } from "./paseo-home.js";
|
|
6
6
|
import { createRootLogger } from "./logger.js";
|
|
7
|
+
import { getProcessDiagnostics } from "./process-diagnostics.js";
|
|
7
8
|
process.title = "Paseo Daemon";
|
|
8
9
|
function isPidAlive(pid) {
|
|
9
10
|
try {
|
|
@@ -60,6 +61,12 @@ function applyCliFlagOverrides(config) {
|
|
|
60
61
|
if (process.argv.includes("--no-inject-mcp")) {
|
|
61
62
|
config.mcpInjectIntoAgents = false;
|
|
62
63
|
}
|
|
64
|
+
if (process.argv.includes("--web-ui")) {
|
|
65
|
+
config.webUi = { ...(config.webUi ?? { distDir: null }), enabled: true };
|
|
66
|
+
}
|
|
67
|
+
if (process.argv.includes("--no-web-ui")) {
|
|
68
|
+
config.webUi = { ...(config.webUi ?? { distDir: null }), enabled: false };
|
|
69
|
+
}
|
|
63
70
|
}
|
|
64
71
|
async function main() {
|
|
65
72
|
const { paseoHome, logger, config } = bootstrapFromEnvironment();
|
|
@@ -77,11 +84,12 @@ async function main() {
|
|
|
77
84
|
});
|
|
78
85
|
};
|
|
79
86
|
const beginShutdown = (signal, options) => {
|
|
87
|
+
const reason = options?.reason ?? `worker_received_${signal}`;
|
|
80
88
|
if (!shutdownPromise) {
|
|
81
|
-
logger.info(`${signal} received, shutting down gracefully...`);
|
|
89
|
+
logger.info({ signal, reason, ...getProcessDiagnostics() }, `${signal} received, shutting down gracefully...`);
|
|
82
90
|
shutdownPromise = (async () => {
|
|
83
91
|
const forceExit = setTimeout(() => {
|
|
84
|
-
logger.warn("Forcing shutdown - HTTP server didn't close in time");
|
|
92
|
+
logger.warn({ signal, reason, ...getProcessDiagnostics() }, "Forcing shutdown - HTTP server didn't close in time");
|
|
85
93
|
process.exit(1);
|
|
86
94
|
}, 10000);
|
|
87
95
|
try {
|
|
@@ -103,7 +111,7 @@ async function main() {
|
|
|
103
111
|
})();
|
|
104
112
|
}
|
|
105
113
|
else {
|
|
106
|
-
logger.info(`${signal} received while shutdown is already in progress`);
|
|
114
|
+
logger.info({ signal, reason, ...getProcessDiagnostics() }, `${signal} received while shutdown is already in progress`);
|
|
107
115
|
}
|
|
108
116
|
installExitHook();
|
|
109
117
|
};
|
|
@@ -122,11 +130,11 @@ async function main() {
|
|
|
122
130
|
};
|
|
123
131
|
const handleLifecycleIntent = (intent) => {
|
|
124
132
|
if (intent.type === "shutdown") {
|
|
125
|
-
logger.warn({ clientId: intent.clientId, requestId: intent.requestId }, "Shutdown requested via websocket");
|
|
126
|
-
if (sendSupervisorLifecycleMessage({ type: "paseo:shutdown" })) {
|
|
133
|
+
logger.warn({ clientId: intent.clientId, requestId: intent.requestId, reason: intent.reason }, "Shutdown requested via websocket");
|
|
134
|
+
if (sendSupervisorLifecycleMessage({ type: "paseo:shutdown", reason: intent.reason })) {
|
|
127
135
|
return;
|
|
128
136
|
}
|
|
129
|
-
beginShutdown("shutdown lifecycle intent");
|
|
137
|
+
beginShutdown("shutdown lifecycle intent", { reason: intent.reason });
|
|
130
138
|
return;
|
|
131
139
|
}
|
|
132
140
|
logger.warn({ clientId: intent.clientId, requestId: intent.requestId, reason: intent.reason }, "Restart requested via websocket");
|
|
@@ -136,7 +144,10 @@ async function main() {
|
|
|
136
144
|
})) {
|
|
137
145
|
return;
|
|
138
146
|
}
|
|
139
|
-
beginShutdown("restart lifecycle intent", {
|
|
147
|
+
beginShutdown("restart lifecycle intent", {
|
|
148
|
+
reason: intent.reason,
|
|
149
|
+
successExitCode: 0,
|
|
150
|
+
});
|
|
140
151
|
};
|
|
141
152
|
const installSupervisorLivenessGuard = () => {
|
|
142
153
|
if (typeof process.send !== "function") {
|
|
@@ -152,6 +163,7 @@ async function main() {
|
|
|
152
163
|
supervisorExitRequested = true;
|
|
153
164
|
writeWorkerLifecycleLog(paseoHome, "Supervisor liveness lost; worker exiting", {
|
|
154
165
|
reason,
|
|
166
|
+
...getProcessDiagnostics(),
|
|
155
167
|
supervisorPid,
|
|
156
168
|
currentParentPid: process.ppid,
|
|
157
169
|
ipcConnected: typeof process.connected === "boolean" ? process.connected : null,
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export declare const CLIENT_SHUTDOWN_RPC_REASON = "client_shutdown_rpc";
|
|
2
|
+
export declare const DEFAULT_CLIENT_RESTART_RPC_REASON = "client_restart_rpc";
|
|
3
|
+
export declare function normalizeClientRestartRpcReason(reason: string | undefined): string;
|
|
4
|
+
//# sourceMappingURL=lifecycle-reasons.d.ts.map
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export const CLIENT_SHUTDOWN_RPC_REASON = "client_shutdown_rpc";
|
|
2
|
+
export const DEFAULT_CLIENT_RESTART_RPC_REASON = "client_restart_rpc";
|
|
3
|
+
export function normalizeClientRestartRpcReason(reason) {
|
|
4
|
+
return reason?.trim() || DEFAULT_CLIENT_RESTART_RPC_REASON;
|
|
5
|
+
}
|
|
6
|
+
//# sourceMappingURL=lifecycle-reasons.js.map
|
|
@@ -19,6 +19,7 @@ export declare const PersistedConfigSchema: z.ZodObject<{
|
|
|
19
19
|
listen: z.ZodOptional<z.ZodString>;
|
|
20
20
|
hostnames: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<true>, z.ZodArray<z.ZodString>]>>;
|
|
21
21
|
allowedHosts: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<true>, z.ZodArray<z.ZodString>]>>;
|
|
22
|
+
trustedProxies: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<true>, z.ZodArray<z.ZodString>]>>;
|
|
22
23
|
mcp: z.ZodOptional<z.ZodObject<{
|
|
23
24
|
enabled: z.ZodOptional<z.ZodBoolean>;
|
|
24
25
|
injectIntoAgents: z.ZodOptional<z.ZodBoolean>;
|
|
@@ -54,6 +55,7 @@ export declare const PersistedConfigSchema: z.ZodObject<{
|
|
|
54
55
|
}, z.core.$strict>, z.ZodTransform<{
|
|
55
56
|
listen?: string | undefined;
|
|
56
57
|
hostnames?: true | string[] | undefined;
|
|
58
|
+
trustedProxies?: true | string[] | undefined;
|
|
57
59
|
mcp?: {
|
|
58
60
|
[x: string]: unknown;
|
|
59
61
|
enabled?: boolean | undefined;
|
|
@@ -92,6 +94,7 @@ export declare const PersistedConfigSchema: z.ZodObject<{
|
|
|
92
94
|
listen?: string | undefined;
|
|
93
95
|
hostnames?: true | string[] | undefined;
|
|
94
96
|
allowedHosts?: true | string[] | undefined;
|
|
97
|
+
trustedProxies?: true | string[] | undefined;
|
|
95
98
|
mcp?: {
|
|
96
99
|
[x: string]: unknown;
|
|
97
100
|
enabled?: boolean | undefined;
|
|
@@ -133,6 +136,11 @@ export declare const PersistedConfigSchema: z.ZodObject<{
|
|
|
133
136
|
providers: z.ZodOptional<z.ZodObject<{
|
|
134
137
|
openai: z.ZodOptional<z.ZodObject<{
|
|
135
138
|
apiKey: z.ZodOptional<z.ZodString>;
|
|
139
|
+
voice: z.ZodOptional<z.ZodObject<{
|
|
140
|
+
apiKey: z.ZodOptional<z.ZodString>;
|
|
141
|
+
baseUrl: z.ZodOptional<z.ZodString>;
|
|
142
|
+
}, z.core.$strict>>;
|
|
143
|
+
baseUrl: z.ZodOptional<z.ZodString>;
|
|
136
144
|
}, z.core.$strict>>;
|
|
137
145
|
local: z.ZodOptional<z.ZodObject<{
|
|
138
146
|
modelsDir: z.ZodOptional<z.ZodString>;
|
|
@@ -236,6 +244,10 @@ export declare const PersistedConfigSchema: z.ZodObject<{
|
|
|
236
244
|
speed: z.ZodOptional<z.ZodNumber>;
|
|
237
245
|
}, z.core.$strict>>;
|
|
238
246
|
}, z.core.$strict>>;
|
|
247
|
+
webUi: z.ZodOptional<z.ZodObject<{
|
|
248
|
+
enabled: z.ZodOptional<z.ZodBoolean>;
|
|
249
|
+
distDir: z.ZodOptional<z.ZodString>;
|
|
250
|
+
}, z.core.$strict>>;
|
|
239
251
|
}, z.core.$strict>>;
|
|
240
252
|
log: z.ZodOptional<z.ZodObject<{
|
|
241
253
|
level: z.ZodOptional<z.ZodEnum<{
|
|
@@ -34,9 +34,17 @@ const LogConfigSchema = z
|
|
|
34
34
|
.optional(),
|
|
35
35
|
})
|
|
36
36
|
.strict();
|
|
37
|
-
const
|
|
37
|
+
const OpenAiVoiceProviderSchema = z
|
|
38
|
+
.object({
|
|
39
|
+
apiKey: z.string().trim().min(1).optional(),
|
|
40
|
+
baseUrl: z.string().trim().min(1).optional(),
|
|
41
|
+
})
|
|
42
|
+
.strict();
|
|
43
|
+
const OpenAiProviderSchema = z
|
|
38
44
|
.object({
|
|
39
45
|
apiKey: z.string().min(1).optional(),
|
|
46
|
+
voice: OpenAiVoiceProviderSchema.optional(),
|
|
47
|
+
baseUrl: z.string().trim().min(1).optional(),
|
|
40
48
|
})
|
|
41
49
|
.strict();
|
|
42
50
|
const LocalSpeechProviderSchema = z
|
|
@@ -46,7 +54,7 @@ const LocalSpeechProviderSchema = z
|
|
|
46
54
|
.strict();
|
|
47
55
|
const ProvidersSchema = z
|
|
48
56
|
.object({
|
|
49
|
-
openai:
|
|
57
|
+
openai: OpenAiProviderSchema.optional(),
|
|
50
58
|
local: LocalSpeechProviderSchema.optional(),
|
|
51
59
|
})
|
|
52
60
|
.strict();
|
|
@@ -118,6 +126,12 @@ const FeatureVoiceModeSchema = z
|
|
|
118
126
|
.optional(),
|
|
119
127
|
})
|
|
120
128
|
.strict();
|
|
129
|
+
const FeatureWebUiSchema = z
|
|
130
|
+
.object({
|
|
131
|
+
enabled: z.boolean().optional(),
|
|
132
|
+
distDir: z.string().min(1).optional(),
|
|
133
|
+
})
|
|
134
|
+
.strict();
|
|
121
135
|
const StructuredGenerationProviderConfigSchema = z
|
|
122
136
|
.object({
|
|
123
137
|
provider: z.string().min(1),
|
|
@@ -179,6 +193,7 @@ export const PersistedConfigSchema = z
|
|
|
179
193
|
listen: z.string().optional(),
|
|
180
194
|
hostnames: z.union([z.literal(true), z.array(z.string())]).optional(),
|
|
181
195
|
allowedHosts: z.union([z.literal(true), z.array(z.string())]).optional(),
|
|
196
|
+
trustedProxies: z.union([z.literal(true), z.array(z.string())]).optional(),
|
|
182
197
|
mcp: z
|
|
183
198
|
.object({
|
|
184
199
|
enabled: z.boolean().optional(),
|
|
@@ -244,6 +259,7 @@ export const PersistedConfigSchema = z
|
|
|
244
259
|
.object({
|
|
245
260
|
dictation: FeatureDictationSchema.optional(),
|
|
246
261
|
voiceMode: FeatureVoiceModeSchema.optional(),
|
|
262
|
+
webUi: FeatureWebUiSchema.optional(),
|
|
247
263
|
})
|
|
248
264
|
.strict()
|
|
249
265
|
.optional(),
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export interface ProcessMemoryDiagnostics {
|
|
2
|
+
rss: number;
|
|
3
|
+
heapTotal: number;
|
|
4
|
+
heapUsed: number;
|
|
5
|
+
external: number;
|
|
6
|
+
arrayBuffers: number;
|
|
7
|
+
}
|
|
8
|
+
export interface ProcessDiagnostics {
|
|
9
|
+
pid: number;
|
|
10
|
+
ppid: number;
|
|
11
|
+
uptimeSeconds: number;
|
|
12
|
+
memory: ProcessMemoryDiagnostics;
|
|
13
|
+
}
|
|
14
|
+
export declare function getProcessMemoryDiagnostics(): ProcessMemoryDiagnostics;
|
|
15
|
+
export declare function getProcessUptimeSeconds(): number;
|
|
16
|
+
export declare function getProcessDiagnostics(): ProcessDiagnostics;
|
|
17
|
+
//# sourceMappingURL=process-diagnostics.d.ts.map
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export function getProcessMemoryDiagnostics() {
|
|
2
|
+
const memory = process.memoryUsage();
|
|
3
|
+
return {
|
|
4
|
+
rss: memory.rss,
|
|
5
|
+
heapTotal: memory.heapTotal,
|
|
6
|
+
heapUsed: memory.heapUsed,
|
|
7
|
+
external: memory.external,
|
|
8
|
+
arrayBuffers: memory.arrayBuffers,
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
export function getProcessUptimeSeconds() {
|
|
12
|
+
return Math.round(process.uptime() * 1000) / 1000;
|
|
13
|
+
}
|
|
14
|
+
export function getProcessDiagnostics() {
|
|
15
|
+
return {
|
|
16
|
+
pid: process.pid,
|
|
17
|
+
ppid: process.ppid,
|
|
18
|
+
uptimeSeconds: getProcessUptimeSeconds(),
|
|
19
|
+
memory: getProcessMemoryDiagnostics(),
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=process-diagnostics.js.map
|
|
@@ -335,6 +335,7 @@ export function startRelayTransport({ logger, attachSocket, relayEndpoint, relay
|
|
|
335
335
|
const externalMetadata = {
|
|
336
336
|
transport: "relay",
|
|
337
337
|
externalSessionKey: `session:${connectionId}`,
|
|
338
|
+
relayConnectionId: connectionId,
|
|
338
339
|
};
|
|
339
340
|
if (daemonKeyPair) {
|
|
340
341
|
void attachEncryptedSocket(socket, daemonKeyPair, relayLogger.child({ connectionId }), attachSocket, externalMetadata);
|