@nordbyte/nordrelay 0.8.1 → 0.8.3
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/.env.example +9 -0
- package/README.md +84 -1205
- package/dist/{access-control.js → access/access-control.js} +1 -1
- package/dist/{audit-log.js → access/audit-log.js} +32 -15
- package/dist/{session-locks.js → access/session-locks.js} +1 -1
- package/dist/{user-management.js → access/user-management.js} +1 -1
- package/dist/{claude-code-cli.js → agents/claude-code/claude-code-cli.js} +2 -2
- package/dist/{claude-code-session.js → agents/claude-code/claude-code-session.js} +1 -1
- package/dist/{codex-cli.js → agents/codex/codex-cli.js} +14 -5
- package/dist/{codex-session.js → agents/codex/codex-session.js} +2 -4
- package/dist/{hermes-cli.js → agents/hermes/hermes-cli.js} +2 -2
- package/dist/{hermes-launch.js → agents/hermes/hermes-launch.js} +1 -1
- package/dist/{hermes-session.js → agents/hermes/hermes-session.js} +1 -1
- package/dist/{openclaw-cli.js → agents/openclaw/openclaw-cli.js} +2 -2
- package/dist/{openclaw-launch.js → agents/openclaw/openclaw-launch.js} +1 -1
- package/dist/{openclaw-session.js → agents/openclaw/openclaw-session.js} +1 -1
- package/dist/{pi-cli.js → agents/pi/pi-cli.js} +2 -2
- package/dist/{pi-launch.js → agents/pi/pi-launch.js} +1 -1
- package/dist/{pi-session.js → agents/pi/pi-session.js} +1 -1
- package/dist/{adapter-conformance.js → agents/shared/adapter-conformance.js} +2 -2
- package/dist/{agent-activity.js → agents/shared/agent-activity.js} +5 -5
- package/dist/agents/shared/agent-auth-commands.js +30 -0
- package/dist/{agent-factory.js → agents/shared/agent-factory.js} +5 -5
- package/dist/{agent-feature-matrix.js → agents/shared/agent-feature-matrix.js} +2 -2
- package/dist/{agent-updates.js → agents/shared/agent-updates.js} +7 -7
- package/dist/{discord-artifacts.js → channels/discord/discord-artifacts.js} +4 -4
- package/dist/{discord-bot.js → channels/discord/discord-bot.js} +176 -451
- package/dist/{discord-channel-runtime.js → channels/discord/discord-channel-runtime.js} +2 -2
- package/dist/{discord-command-surface.js → channels/discord/discord-command-surface.js} +3 -3
- package/dist/{bot-rendering.js → channels/shared/bot-rendering.js} +6 -6
- package/dist/{channel-actions.js → channels/shared/channel-actions.js} +4 -4
- package/dist/channels/shared/channel-bridge-controller.js +69 -0
- package/dist/channels/shared/channel-cli-artifacts.js +51 -0
- package/dist/{channel-command-service.js → channels/shared/channel-command-service.js} +51 -28
- package/dist/channels/shared/channel-external-mirror-controller.js +193 -0
- package/dist/channels/shared/channel-external-monitor.js +52 -0
- package/dist/{channel-mirror-registry.js → channels/shared/channel-mirror-registry.js} +14 -6
- package/dist/{channel-peer-prompt.js → channels/shared/channel-peer-prompt.js} +3 -3
- package/dist/channels/shared/channel-prompt-queue.js +37 -0
- package/dist/{channel-turn-service.js → channels/shared/channel-turn-service.js} +25 -11
- package/dist/{context-key.js → channels/shared/context-key.js} +1 -1
- package/dist/{session-format.js → channels/shared/session-format.js} +2 -2
- package/dist/{slack-artifacts.js → channels/slack/slack-artifacts.js} +4 -4
- package/dist/{slack-bot.js → channels/slack/slack-bot.js} +171 -309
- package/dist/{slack-channel-runtime.js → channels/slack/slack-channel-runtime.js} +2 -2
- package/dist/{slack-command-surface.js → channels/slack/slack-command-surface.js} +2 -2
- package/dist/{slack-diagnostics.js → channels/slack/slack-diagnostics.js} +2 -2
- package/dist/{bot-ui.js → channels/telegram/bot-ui.js} +1 -1
- package/dist/{bot.js → channels/telegram/bot.js} +195 -430
- package/dist/{telegram-access-commands.js → channels/telegram/telegram-access-commands.js} +3 -3
- package/dist/{telegram-access-middleware.js → channels/telegram/telegram-access-middleware.js} +4 -4
- package/dist/{telegram-agent-commands.js → channels/telegram/telegram-agent-commands.js} +9 -9
- package/dist/{telegram-artifact-commands.js → channels/telegram/telegram-artifact-commands.js} +4 -4
- package/dist/{telegram-channel-runtime.js → channels/telegram/telegram-channel-runtime.js} +2 -2
- package/dist/{telegram-command-menu.js → channels/telegram/telegram-command-menu.js} +1 -1
- package/dist/{telegram-diagnostics-command.js → channels/telegram/telegram-diagnostics-command.js} +7 -7
- package/dist/{telegram-general-commands.js → channels/telegram/telegram-general-commands.js} +4 -4
- package/dist/{telegram-operational-commands.js → channels/telegram/telegram-operational-commands.js} +5 -5
- package/dist/{telegram-output.js → channels/telegram/telegram-output.js} +2 -2
- package/dist/{telegram-preference-commands.js → channels/telegram/telegram-preference-commands.js} +3 -3
- package/dist/{telegram-queue-commands.js → channels/telegram/telegram-queue-commands.js} +6 -6
- package/dist/{telegram-support-command.js → channels/telegram/telegram-support-command.js} +4 -4
- package/dist/{telegram-update-commands.js → channels/telegram/telegram-update-commands.js} +5 -5
- package/dist/{config-metadata.js → core/config-metadata.js} +8 -0
- package/dist/{config.js → core/config.js} +11 -3
- package/dist/core/pagination.js +22 -0
- package/dist/index.js +27 -23
- package/dist/peers/peer-discovery-jobs.js +206 -0
- package/dist/peers/peer-discovery.js +223 -0
- package/dist/peers/peer-health-monitor.js +49 -0
- package/dist/{peer-identity.js → peers/peer-identity.js} +50 -1
- package/dist/{peer-runtime-service.js → peers/peer-runtime-service.js} +29 -7
- package/dist/{peer-server.js → peers/peer-server.js} +3 -2
- package/dist/{peer-store.js → peers/peer-store.js} +96 -9
- package/dist/{peer-types.js → peers/peer-types.js} +28 -0
- package/dist/peers/peer-web-proxy-contract.js +129 -0
- package/dist/{metrics.js → runtime/metrics.js} +5 -3
- package/dist/{relay-artifact-service.js → runtime/relay-artifact-service.js} +1 -1
- package/dist/runtime/relay-auth-service.js +63 -0
- package/dist/runtime/relay-dashboard-service.js +139 -0
- package/dist/{relay-external-activity-monitor.js → runtime/relay-external-activity-monitor.js} +155 -53
- package/dist/{relay-queue-service.js → runtime/relay-queue-service.js} +1 -0
- package/dist/runtime/relay-runtime-active-sessions.js +387 -0
- package/dist/runtime/relay-runtime-dashboard.js +204 -0
- package/dist/{relay-runtime-helpers.js → runtime/relay-runtime-helpers.js} +3 -0
- package/dist/runtime/relay-runtime-prompt-queue-artifacts.js +311 -0
- package/dist/runtime/relay-runtime-sessions.js +631 -0
- package/dist/runtime/relay-runtime-trace.js +92 -0
- package/dist/runtime/relay-runtime-types.js +1 -0
- package/dist/runtime/relay-runtime-updates-jobs.js +366 -0
- package/dist/runtime/relay-runtime.js +461 -0
- package/dist/runtime/runtime-cache.js +117 -0
- package/dist/{prompt-store.js → state/prompt-store.js} +13 -1
- package/dist/{session-registry.js → state/session-registry.js} +3 -3
- package/dist/{operations.js → support/operations.js} +7 -7
- package/dist/{support-bundle.js → support/support-bundle.js} +1 -1
- package/dist/{web-api-contract.js → web/web-api-contract.js} +19 -3
- package/dist/web/web-api-types.js +1 -0
- package/dist/{web-dashboard-access-routes.js → web/web-dashboard-access-routes.js} +17 -14
- package/dist/{web-dashboard-artifact-routes.js → web/web-dashboard-artifact-routes.js} +6 -2
- package/dist/{web-dashboard-assets.js → web/web-dashboard-assets.js} +25 -2
- package/dist/{web-dashboard-http.js → web/web-dashboard-http.js} +41 -5
- package/dist/{web-dashboard-pages.js → web/web-dashboard-pages.js} +95 -30
- package/dist/{web-dashboard-peer-routes.js → web/web-dashboard-peer-routes.js} +121 -7
- package/dist/{web-dashboard-runtime-routes.js → web/web-dashboard-runtime-routes.js} +8 -1
- package/dist/web/web-dashboard-security.js +14 -0
- package/dist/{web-dashboard-session-routes.js → web/web-dashboard-session-routes.js} +29 -13
- package/dist/web/web-dashboard-ui.js +56 -0
- package/dist/{web-dashboard.js → web/web-dashboard.js} +132 -48
- package/dist/web/web-performance.js +62 -0
- package/dist/web/web-rate-limit.js +19 -0
- package/dist/{web-state.js → web/web-state.js} +107 -9
- package/dist/webui-assets/dashboard.css +398 -49
- package/dist/webui-assets/dashboard.js +1239 -103
- package/dist/webui-assets/favicon.ico +0 -0
- package/dist/webui-assets/favicon.png +0 -0
- package/dist/webui-assets/logo.png +0 -0
- package/package.json +6 -3
- package/plugins/nordrelay/scripts/nordrelay.mjs +346 -12
- package/plugins/nordrelay/scripts/service-installer.mjs +183 -0
- package/{launchd/start.sh → scripts/launchd-start.sh} +1 -1
- package/scripts/postinstall.mjs +122 -0
- package/dist/relay-runtime.js +0 -1916
- package/dist/runtime-cache.js +0 -57
- package/dist/web-dashboard-ui.js +0 -20
- /package/dist/{user-management-crypto.js → access/user-management-crypto.js} +0 -0
- /package/dist/{user-management-normalize.js → access/user-management-normalize.js} +0 -0
- /package/dist/{user-management-types.js → access/user-management-types.js} +0 -0
- /package/dist/{claude-code-auth.js → agents/claude-code/claude-code-auth.js} +0 -0
- /package/dist/{claude-code-launch.js → agents/claude-code/claude-code-launch.js} +0 -0
- /package/dist/{claude-code-state.js → agents/claude-code/claude-code-state.js} +0 -0
- /package/dist/{codex-auth.js → agents/codex/codex-auth.js} +0 -0
- /package/dist/{codex-config.js → agents/codex/codex-config.js} +0 -0
- /package/dist/{codex-launch.js → agents/codex/codex-launch.js} +0 -0
- /package/dist/{codex-state.js → agents/codex/codex-state.js} +0 -0
- /package/dist/{hermes-api.js → agents/hermes/hermes-api.js} +0 -0
- /package/dist/{hermes-auth.js → agents/hermes/hermes-auth.js} +0 -0
- /package/dist/{hermes-state.js → agents/hermes/hermes-state.js} +0 -0
- /package/dist/{openclaw-auth.js → agents/openclaw/openclaw-auth.js} +0 -0
- /package/dist/{openclaw-gateway.js → agents/openclaw/openclaw-gateway.js} +0 -0
- /package/dist/{openclaw-state.js → agents/openclaw/openclaw-state.js} +0 -0
- /package/dist/{pi-auth.js → agents/pi/pi-auth.js} +0 -0
- /package/dist/{pi-rpc.js → agents/pi/pi-rpc.js} +0 -0
- /package/dist/{pi-state.js → agents/pi/pi-state.js} +0 -0
- /package/dist/{agent-adapter.js → agents/shared/agent-adapter.js} +0 -0
- /package/dist/{agent.js → agents/shared/agent.js} +0 -0
- /package/dist/{artifacts.js → artifacts/artifacts.js} +0 -0
- /package/dist/{attachments.js → artifacts/attachments.js} +0 -0
- /package/dist/{voice.js → artifacts/voice.js} +0 -0
- /package/dist/{discord-rate-limit.js → channels/discord/discord-rate-limit.js} +0 -0
- /package/dist/{channel-adapter.js → channels/shared/channel-adapter.js} +0 -0
- /package/dist/{relay-runtime-types.js → channels/shared/channel-bridge-state.js} +0 -0
- /package/dist/{channel-command-catalog.js → channels/shared/channel-command-catalog.js} +0 -0
- /package/dist/{channel-command-core.js → channels/shared/channel-command-core.js} +0 -0
- /package/dist/{channel-prompt-engine.js → channels/shared/channel-prompt-engine.js} +0 -0
- /package/dist/{channel-runtime.js → channels/shared/channel-runtime.js} +0 -0
- /package/dist/{channel-turn-lifecycle.js → channels/shared/channel-turn-lifecycle.js} +0 -0
- /package/dist/{slack-rate-limit.js → channels/slack/slack-rate-limit.js} +0 -0
- /package/dist/{telegram-command-types.js → channels/telegram/telegram-command-types.js} +0 -0
- /package/dist/{telegram-rate-limit.js → channels/telegram/telegram-rate-limit.js} +0 -0
- /package/dist/{activity-events.js → core/activity-events.js} +0 -0
- /package/dist/{error-messages.js → core/error-messages.js} +0 -0
- /package/dist/{format.js → core/format.js} +0 -0
- /package/dist/{logger.js → core/logger.js} +0 -0
- /package/dist/{redaction.js → core/redaction.js} +0 -0
- /package/dist/{settings-service.js → core/settings-service.js} +0 -0
- /package/dist/{settings-wizard-test.js → core/settings-wizard-test.js} +0 -0
- /package/dist/{workspace-policy.js → core/workspace-policy.js} +0 -0
- /package/dist/{peer-auth.js → peers/peer-auth.js} +0 -0
- /package/dist/{peer-client.js → peers/peer-client.js} +0 -0
- /package/dist/{peer-context.js → peers/peer-context.js} +0 -0
- /package/dist/{peer-readiness.js → peers/peer-readiness.js} +0 -0
- /package/dist/{web-api-types.js → runtime/relay-runtime-delegate.js} +0 -0
- /package/dist/{remote-prompt.js → runtime/remote-prompt.js} +0 -0
- /package/dist/{bot-preferences.js → state/bot-preferences.js} +0 -0
- /package/dist/{job-store.js → state/job-store.js} +0 -0
- /package/dist/{persistence.js → state/persistence.js} +0 -0
- /package/dist/{state-backend.js → state/state-backend.js} +0 -0
- /package/dist/{zip-writer.js → support/zip-writer.js} +0 -0
|
@@ -0,0 +1,461 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { ensureOutDir } from "../artifacts/artifacts.js";
|
|
3
|
+
import { buildFileInstructions, outboxPath, stageFile, } from "../artifacts/attachments.js";
|
|
4
|
+
import { CODEX_AGENT_CAPABILITIES, agentLabel, agentReasoningLabel, agentReasoningOptions, isAgentId, } from "../agents/shared/agent.js";
|
|
5
|
+
import { getExternalSnapshotForSession } from "../agents/shared/agent-activity.js";
|
|
6
|
+
import { listAgentAdapterDescriptors } from "../agents/shared/agent-adapter.js";
|
|
7
|
+
import { AgentUpdateManager } from "../agents/shared/agent-updates.js";
|
|
8
|
+
import { createAgentSessionService, enabledAgents } from "../agents/shared/agent-factory.js";
|
|
9
|
+
import { AuditLogStore } from "../access/audit-log.js";
|
|
10
|
+
import { BotPreferencesStore } from "../state/bot-preferences.js";
|
|
11
|
+
import { ChannelCommandService } from "../channels/shared/channel-command-service.js";
|
|
12
|
+
import { ChannelTurnService } from "../channels/shared/channel-turn-service.js";
|
|
13
|
+
import { activeSessionSourceForContextKey, ChannelMirrorRegistry } from "../channels/shared/channel-mirror-registry.js";
|
|
14
|
+
import { listThreads as listCodexThreads } from "../agents/codex/codex-state.js";
|
|
15
|
+
import { friendlyErrorText } from "../core/error-messages.js";
|
|
16
|
+
import { clearLogFile, getAgentUpdateLogPath, getConnectorHealth, getConnectorLogPath, getPackageVersion, getUpdateLogPath, getVersionChecks, readConnectorState, readFormattedLogTail, spawnConnectorRestart, spawnSelfUpdate } from "../support/operations.js";
|
|
17
|
+
import { PromptStore, toPromptEnvelope } from "../state/prompt-store.js";
|
|
18
|
+
import { UnifiedJobStore } from "../state/job-store.js";
|
|
19
|
+
import { buildRuntimeMetrics } from "./metrics.js";
|
|
20
|
+
import { RelayArtifactService } from "./relay-artifact-service.js";
|
|
21
|
+
import { RelayAuthService } from "./relay-auth-service.js";
|
|
22
|
+
import { RelayExternalActivityMonitor } from "./relay-external-activity-monitor.js";
|
|
23
|
+
import { RelayQueueService } from "./relay-queue-service.js";
|
|
24
|
+
import { RuntimeSnapshotCache } from "./runtime-cache.js";
|
|
25
|
+
import { activeSessionPriority, activityToUnifiedJob, agentUpdateStatusToUnified, dedupeJobs, hostLoginCommand, hostLogoutCommand, isPromptTerminalActivity, normalizeMimeType, promptActivityToUnifiedJob, shouldRefreshActiveSessions, taskToUnifiedJob, uploadFileDtos, } from "./relay-runtime-helpers.js";
|
|
26
|
+
import { RelayDashboardService } from "./relay-dashboard-service.js";
|
|
27
|
+
import { capabilitiesOf } from "../channels/shared/bot-rendering.js";
|
|
28
|
+
import { renderSessionInfoPlain, renderSessionUsageRows } from "../channels/shared/session-format.js";
|
|
29
|
+
import { SessionLockStore } from "../access/session-locks.js";
|
|
30
|
+
import { SessionRegistry } from "../state/session-registry.js";
|
|
31
|
+
import { createSupportBundle } from "../support/support-bundle.js";
|
|
32
|
+
import { transcribeAudio } from "../artifacts/voice.js";
|
|
33
|
+
import { WebActivityStore, WebChatStore, } from "../web/web-state.js";
|
|
34
|
+
import { evaluateWorkspacePolicy, filterAllowedWorkspaces } from "../core/workspace-policy.js";
|
|
35
|
+
import { relayRuntimeSubscribe, relayRuntimeSnapshot, relayRuntimeStatus, relayRuntimeBootstrapStatus, relayRuntimeVersion, relayRuntimeDiagnostics, relayRuntimeAdapterHealth, relayRuntimePermissions, relayRuntimeMetrics, relayRuntimeAudit, relayRuntimeAuditPage, relayRuntimeSupportBundle, relayRuntimeLogs, relayRuntimeClearLogs, relayRuntimeRestartConnector, relayRuntimeDispose } from "./relay-runtime-dashboard.js";
|
|
36
|
+
import { relayRuntimeTrace } from "./relay-runtime-trace.js";
|
|
37
|
+
import { relayRuntimeUpdateConnector, relayRuntimeAgentUpdateJobs, relayRuntimeStartAgentUpdate, relayRuntimeAgentUpdateLog, relayRuntimeDeleteAgentUpdateLog, relayRuntimeSendAgentUpdateInput, relayRuntimeCancelAgentUpdate, relayRuntimeTasks, relayRuntimeJobs, relayRuntimeJobLog, relayRuntimeJobAction, relayRuntimeRecordAgentUpdateLifecycle } from "./relay-runtime-updates-jobs.js";
|
|
38
|
+
import { relayRuntimeActiveSessions, relayRuntimeGetSession, relayRuntimeListKnownContextMetadata, relayRuntimeDiscoverRunningConnectorSessions, relayRuntimeDiscoverActiveCodexSessions, relayRuntimeExternalActiveSession, relayRuntimeSessionStubForMetadata, relayRuntimeCapabilitiesForAgent, relayRuntimeActiveSessionKey, relayRuntimePreferredActiveSession, relayRuntimeRecordActivity, relayRuntimeAppendActivity, relayRuntimeEnrichActivityInput, relayRuntimeEnrichActivityEvent, relayRuntimeEnrichActivityFields, relayRuntimeAppendAudit, relayRuntimeUpdateCurrentProgress, relayRuntimeAddCurrentTool, relayRuntimeBroadcastQueue, relayRuntimeBroadcastStatus, relayRuntimeBroadcast, relayRuntimeScheduleActiveSessionsBroadcast, relayRuntimePublicInfo } from "./relay-runtime-active-sessions.js";
|
|
39
|
+
import { relayRuntimeLocks, relayRuntimeLockWebSession, relayRuntimeUnlockWebSession, relayRuntimeControlOptions, relayRuntimeAuthStatus, relayRuntimeLogin, relayRuntimeLogout, relayRuntimeChatHistory, relayRuntimeWebMirrorPreference, relayRuntimeSessionDetail, relayRuntimeClearChatHistory, relayRuntimeActivity, relayRuntimeActivityPage, relayRuntimeRetry, relayRuntimeSync, relayRuntimeListSessions, relayRuntimeListSessionsPage, relayRuntimeFilteredSessions, relayRuntimeListModels, relayRuntimeSetAgent, relayRuntimeNewSession, relayRuntimeSwitchSession, relayRuntimeAttachSession, relayRuntimeSetModel, relayRuntimeSetReasoningEffort, relayRuntimeSetFastMode, relayRuntimeSetLaunchProfile, relayRuntimeHandback, relayRuntimeAbort, relayRuntimeGetControlSession, relayRuntimeCliPathOptions } from "./relay-runtime-sessions.js";
|
|
40
|
+
import { relayRuntimeSendPrompt, relayRuntimeSendUploadPrompt, relayRuntimeSendEnvelope, relayRuntimeQueue, relayRuntimeQueuePaused, relayRuntimeQueueAction, relayRuntimeArtifacts, relayRuntimeArtifact, relayRuntimeDeleteArtifact, relayRuntimeCreateArtifactZip, relayRuntimeArtifactPreview, relayRuntimeEnsureActiveThread, relayRuntimeEnsureIdle, relayRuntimeRunPrompt, relayRuntimeDrainQueue, relayRuntimeUpdateSession } from "./relay-runtime-prompt-queue-artifacts.js";
|
|
41
|
+
export const WEB_CONTEXT_KEY = "web:dashboard";
|
|
42
|
+
const ACTIVE_CODEX_DISCOVERY_LIMIT = 200;
|
|
43
|
+
const ACTIVE_ACTIVITY_TTL_MS = 6 * 60 * 60 * 1000;
|
|
44
|
+
const MAX_WEB_SESSION_PAGE_SIZE = 50;
|
|
45
|
+
const MAX_CHAT_HISTORY = 250;
|
|
46
|
+
export class RelayRuntime {
|
|
47
|
+
config;
|
|
48
|
+
contextKey;
|
|
49
|
+
registry;
|
|
50
|
+
promptStore;
|
|
51
|
+
chatStore;
|
|
52
|
+
activityStore;
|
|
53
|
+
auditStore;
|
|
54
|
+
preferencesStore;
|
|
55
|
+
lockStore;
|
|
56
|
+
agentUpdates;
|
|
57
|
+
queueService;
|
|
58
|
+
jobStore;
|
|
59
|
+
artifactService;
|
|
60
|
+
mirrorRegistry;
|
|
61
|
+
externalActivityMonitor;
|
|
62
|
+
cache = new RuntimeSnapshotCache();
|
|
63
|
+
dashboardService;
|
|
64
|
+
turnService;
|
|
65
|
+
authService;
|
|
66
|
+
subscribers = new Set();
|
|
67
|
+
agentUpdateActors = new Map();
|
|
68
|
+
agentUpdateStates = new Map();
|
|
69
|
+
externalMonitor;
|
|
70
|
+
activeSessionsBroadcastTimer = null;
|
|
71
|
+
activeSessionsLastBroadcastAt = 0;
|
|
72
|
+
draining = false;
|
|
73
|
+
currentTurnId = null;
|
|
74
|
+
accumulatedText = "";
|
|
75
|
+
currentTurnStartedAt = 0;
|
|
76
|
+
currentProgress = null;
|
|
77
|
+
constructor(config, options = {}) {
|
|
78
|
+
this.config = config;
|
|
79
|
+
this.contextKey = options.contextKey ?? WEB_CONTEXT_KEY;
|
|
80
|
+
this.registry = new SessionRegistry(config, {
|
|
81
|
+
fileName: options.registryFileName ?? "web-contexts.json",
|
|
82
|
+
sqliteKey: options.registrySqliteKey ?? "web-contexts",
|
|
83
|
+
});
|
|
84
|
+
this.promptStore = new PromptStore(config.workspace, config.stateBackend);
|
|
85
|
+
this.chatStore = new WebChatStore(config.workspace, config.stateBackend, MAX_CHAT_HISTORY);
|
|
86
|
+
this.activityStore = new WebActivityStore(config.workspace, config.stateBackend, config.auditMaxEvents);
|
|
87
|
+
this.auditStore = new AuditLogStore(config.workspace, config.stateBackend, config.auditMaxEvents);
|
|
88
|
+
this.preferencesStore = new BotPreferencesStore(config.workspace, config.stateBackend);
|
|
89
|
+
this.lockStore = new SessionLockStore(config.workspace, config.stateBackend);
|
|
90
|
+
this.queueService = new RelayQueueService(this.promptStore, this.contextKey);
|
|
91
|
+
this.jobStore = new UnifiedJobStore(config.workspace, config.stateBackend, config.unifiedJobMaxItems);
|
|
92
|
+
this.artifactService = new RelayArtifactService(config);
|
|
93
|
+
this.authService = new RelayAuthService(config);
|
|
94
|
+
this.mirrorRegistry = new ChannelMirrorRegistry(config, this.promptStore);
|
|
95
|
+
this.agentUpdates = new AgentUpdateManager({
|
|
96
|
+
onUpdate: (job) => {
|
|
97
|
+
this.broadcast({ type: "agent_update", job });
|
|
98
|
+
this.recordAgentUpdateLifecycle(job);
|
|
99
|
+
},
|
|
100
|
+
});
|
|
101
|
+
this.externalActivityMonitor = new RelayExternalActivityMonitor({
|
|
102
|
+
config,
|
|
103
|
+
getSession: () => this.getSession(true),
|
|
104
|
+
publicInfo: (session) => this.publicInfo(session),
|
|
105
|
+
queueLength: () => this.queueService.length(),
|
|
106
|
+
mirrorMode: () => this.preferencesStore.get(this.contextKey).mirrorMode ?? this.config.webMirrorMode,
|
|
107
|
+
mirrorMinUpdateMs: () => this.config.webMirrorMinUpdateMs,
|
|
108
|
+
chatStore: this.chatStore,
|
|
109
|
+
chatHistory: () => this.chatHistory(),
|
|
110
|
+
persistWorkspaceArtifactsForTurn: (workspace, turnId, startedAt) => this.artifactService.persistWorkspaceArtifactsForTurn(workspace, turnId, startedAt),
|
|
111
|
+
drainQueue: () => this.drainQueue(),
|
|
112
|
+
appendActivity: (input) => this.appendActivity(input),
|
|
113
|
+
broadcast: (event) => this.broadcast(event),
|
|
114
|
+
broadcastStatus: (message, level) => this.broadcastStatus(message, level),
|
|
115
|
+
});
|
|
116
|
+
this.dashboardService = new RelayDashboardService({
|
|
117
|
+
config,
|
|
118
|
+
cache: this.cache,
|
|
119
|
+
snapshot: () => this.snapshot(),
|
|
120
|
+
getSession: () => this.getSession(true),
|
|
121
|
+
queuePaused: () => this.queueService.isPaused(),
|
|
122
|
+
externalMirror: () => this.externalActivityMonitor.snapshot(),
|
|
123
|
+
authStatus: (agentId) => this.authStatus(agentId),
|
|
124
|
+
cliPathOptions: () => this.cliPathOptions(),
|
|
125
|
+
});
|
|
126
|
+
this.dashboardService.startBackgroundRefresh();
|
|
127
|
+
if (config.codexExternalBusyCheckMs > 0) {
|
|
128
|
+
this.externalMonitor = setInterval(() => {
|
|
129
|
+
void this.externalActivityMonitor.monitorSafe();
|
|
130
|
+
}, config.codexExternalBusyCheckMs);
|
|
131
|
+
this.externalMonitor.unref?.();
|
|
132
|
+
}
|
|
133
|
+
this.turnService = new ChannelTurnService({
|
|
134
|
+
source: "web",
|
|
135
|
+
contextKey: this.contextKey,
|
|
136
|
+
chatStore: this.chatStore,
|
|
137
|
+
artifactService: this.artifactService,
|
|
138
|
+
checkAuth: (info) => this.authService.check(info),
|
|
139
|
+
ensureActiveThread: (session) => this.ensureActiveThread(session),
|
|
140
|
+
updateSession: (session) => this.updateSession(session),
|
|
141
|
+
appendActivity: (input) => this.appendActivity(input),
|
|
142
|
+
appendAudit: (input) => this.appendAudit(input),
|
|
143
|
+
broadcast: (event) => this.broadcast(event),
|
|
144
|
+
chatHistory: () => this.chatHistory(),
|
|
145
|
+
setLastPrompt: (envelope) => this.queueService.setLastPrompt(envelope),
|
|
146
|
+
getCurrentProgress: () => this.currentProgress,
|
|
147
|
+
setCurrentProgress: (progress) => {
|
|
148
|
+
this.currentProgress = progress;
|
|
149
|
+
},
|
|
150
|
+
setCurrentTurn: (id, startedAt, accumulatedText) => {
|
|
151
|
+
this.currentTurnId = id;
|
|
152
|
+
if (startedAt !== undefined)
|
|
153
|
+
this.currentTurnStartedAt = startedAt;
|
|
154
|
+
if (accumulatedText !== undefined)
|
|
155
|
+
this.accumulatedText = accumulatedText;
|
|
156
|
+
},
|
|
157
|
+
getCurrentTurnStartedAt: () => this.currentTurnStartedAt,
|
|
158
|
+
getAccumulatedText: () => this.accumulatedText,
|
|
159
|
+
setAccumulatedText: (text) => {
|
|
160
|
+
this.accumulatedText = text;
|
|
161
|
+
},
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
subscribe(callback) {
|
|
165
|
+
return relayRuntimeSubscribe(this, callback);
|
|
166
|
+
}
|
|
167
|
+
async snapshot() {
|
|
168
|
+
return relayRuntimeSnapshot(this);
|
|
169
|
+
}
|
|
170
|
+
async status() {
|
|
171
|
+
return relayRuntimeStatus(this);
|
|
172
|
+
}
|
|
173
|
+
async bootstrapStatus() {
|
|
174
|
+
return relayRuntimeBootstrapStatus(this);
|
|
175
|
+
}
|
|
176
|
+
async version() {
|
|
177
|
+
return relayRuntimeVersion(this);
|
|
178
|
+
}
|
|
179
|
+
updateConnector(actor) {
|
|
180
|
+
return relayRuntimeUpdateConnector(this, actor);
|
|
181
|
+
}
|
|
182
|
+
agentUpdateJobs() {
|
|
183
|
+
return relayRuntimeAgentUpdateJobs(this);
|
|
184
|
+
}
|
|
185
|
+
startAgentUpdate(agentId, operation = "update", actor) {
|
|
186
|
+
return relayRuntimeStartAgentUpdate(this, agentId, operation, actor);
|
|
187
|
+
}
|
|
188
|
+
agentUpdateLog(id) {
|
|
189
|
+
return relayRuntimeAgentUpdateLog(this, id);
|
|
190
|
+
}
|
|
191
|
+
deleteAgentUpdateLog(id, actor) {
|
|
192
|
+
return relayRuntimeDeleteAgentUpdateLog(this, id, actor);
|
|
193
|
+
}
|
|
194
|
+
sendAgentUpdateInput(id, input, actor) {
|
|
195
|
+
return relayRuntimeSendAgentUpdateInput(this, id, input, actor);
|
|
196
|
+
}
|
|
197
|
+
cancelAgentUpdate(id, actor) {
|
|
198
|
+
return relayRuntimeCancelAgentUpdate(this, id, actor);
|
|
199
|
+
}
|
|
200
|
+
async diagnostics() {
|
|
201
|
+
return relayRuntimeDiagnostics(this);
|
|
202
|
+
}
|
|
203
|
+
async adapterHealth() {
|
|
204
|
+
return relayRuntimeAdapterHealth(this);
|
|
205
|
+
}
|
|
206
|
+
permissions() {
|
|
207
|
+
return relayRuntimePermissions(this);
|
|
208
|
+
}
|
|
209
|
+
tasks() {
|
|
210
|
+
return relayRuntimeTasks(this);
|
|
211
|
+
}
|
|
212
|
+
async jobs(options = {}) {
|
|
213
|
+
return relayRuntimeJobs(this, options);
|
|
214
|
+
}
|
|
215
|
+
async jobLog(id) {
|
|
216
|
+
return relayRuntimeJobLog(this, id);
|
|
217
|
+
}
|
|
218
|
+
async jobAction(id, action, actor) {
|
|
219
|
+
return relayRuntimeJobAction(this, id, action, actor);
|
|
220
|
+
}
|
|
221
|
+
async activeSessions() {
|
|
222
|
+
return relayRuntimeActiveSessions(this);
|
|
223
|
+
}
|
|
224
|
+
async metrics() {
|
|
225
|
+
return relayRuntimeMetrics(this);
|
|
226
|
+
}
|
|
227
|
+
audit(options = 50) {
|
|
228
|
+
return relayRuntimeAudit(this, options);
|
|
229
|
+
}
|
|
230
|
+
auditPage(options = {}) {
|
|
231
|
+
return relayRuntimeAuditPage(this, options);
|
|
232
|
+
}
|
|
233
|
+
async trace(correlationId) {
|
|
234
|
+
return relayRuntimeTrace(this, correlationId);
|
|
235
|
+
}
|
|
236
|
+
async supportBundle(actor) {
|
|
237
|
+
return relayRuntimeSupportBundle(this, actor);
|
|
238
|
+
}
|
|
239
|
+
locks() {
|
|
240
|
+
return relayRuntimeLocks(this);
|
|
241
|
+
}
|
|
242
|
+
lockWebSession(ownerName = "Web dashboard", actor) {
|
|
243
|
+
return relayRuntimeLockWebSession(this, ownerName, actor);
|
|
244
|
+
}
|
|
245
|
+
unlockWebSession(actor) {
|
|
246
|
+
return relayRuntimeUnlockWebSession(this, actor);
|
|
247
|
+
}
|
|
248
|
+
async controlOptions(agentId) {
|
|
249
|
+
return relayRuntimeControlOptions(this, agentId);
|
|
250
|
+
}
|
|
251
|
+
async authStatus(agentId) {
|
|
252
|
+
return relayRuntimeAuthStatus(this, agentId);
|
|
253
|
+
}
|
|
254
|
+
async login(agentId, actor) {
|
|
255
|
+
return relayRuntimeLogin(this, agentId, actor);
|
|
256
|
+
}
|
|
257
|
+
async logout(agentId, actor) {
|
|
258
|
+
return relayRuntimeLogout(this, agentId, actor);
|
|
259
|
+
}
|
|
260
|
+
async chatHistory(limit = 200) {
|
|
261
|
+
return relayRuntimeChatHistory(this, limit);
|
|
262
|
+
}
|
|
263
|
+
async webMirrorPreference(argument = "", actor) {
|
|
264
|
+
return relayRuntimeWebMirrorPreference(this, argument, actor);
|
|
265
|
+
}
|
|
266
|
+
async sessionDetail(threadId) {
|
|
267
|
+
return relayRuntimeSessionDetail(this, threadId);
|
|
268
|
+
}
|
|
269
|
+
async clearChatHistory(actor) {
|
|
270
|
+
return relayRuntimeClearChatHistory(this, actor);
|
|
271
|
+
}
|
|
272
|
+
activity(options = {}) {
|
|
273
|
+
return relayRuntimeActivity(this, options);
|
|
274
|
+
}
|
|
275
|
+
activityPage(options = {}) {
|
|
276
|
+
return relayRuntimeActivityPage(this, options);
|
|
277
|
+
}
|
|
278
|
+
async retry(actor) {
|
|
279
|
+
return relayRuntimeRetry(this, actor);
|
|
280
|
+
}
|
|
281
|
+
async sync(actor) {
|
|
282
|
+
return relayRuntimeSync(this, actor);
|
|
283
|
+
}
|
|
284
|
+
async listSessions(limit = 80, query = "", agentId) {
|
|
285
|
+
return relayRuntimeListSessions(this, limit, query, agentId);
|
|
286
|
+
}
|
|
287
|
+
async listSessionsPage(page = 1, pageSize = MAX_WEB_SESSION_PAGE_SIZE, query = "", agentId) {
|
|
288
|
+
return relayRuntimeListSessionsPage(this, page, pageSize, query, agentId);
|
|
289
|
+
}
|
|
290
|
+
filteredSessions(session, query, limit) {
|
|
291
|
+
return relayRuntimeFilteredSessions(this, session, query, limit);
|
|
292
|
+
}
|
|
293
|
+
async listModels() {
|
|
294
|
+
return relayRuntimeListModels(this);
|
|
295
|
+
}
|
|
296
|
+
async setAgent(agentId, actor) {
|
|
297
|
+
return relayRuntimeSetAgent(this, agentId, actor);
|
|
298
|
+
}
|
|
299
|
+
async newSession(options = {}, actor) {
|
|
300
|
+
return relayRuntimeNewSession(this, options, actor);
|
|
301
|
+
}
|
|
302
|
+
async switchSession(threadId, actor) {
|
|
303
|
+
return relayRuntimeSwitchSession(this, threadId, actor);
|
|
304
|
+
}
|
|
305
|
+
async attachSession(threadId, actor) {
|
|
306
|
+
return relayRuntimeAttachSession(this, threadId, actor);
|
|
307
|
+
}
|
|
308
|
+
async setModel(model, actor) {
|
|
309
|
+
return relayRuntimeSetModel(this, model, actor);
|
|
310
|
+
}
|
|
311
|
+
async setReasoningEffort(effort, actor) {
|
|
312
|
+
return relayRuntimeSetReasoningEffort(this, effort, actor);
|
|
313
|
+
}
|
|
314
|
+
async setFastMode(enabled, actor) {
|
|
315
|
+
return relayRuntimeSetFastMode(this, enabled, actor);
|
|
316
|
+
}
|
|
317
|
+
async setLaunchProfile(profileId, actor) {
|
|
318
|
+
return relayRuntimeSetLaunchProfile(this, profileId, actor);
|
|
319
|
+
}
|
|
320
|
+
async handback(actor) {
|
|
321
|
+
return relayRuntimeHandback(this, actor);
|
|
322
|
+
}
|
|
323
|
+
async abort(actor) {
|
|
324
|
+
return relayRuntimeAbort(this, actor);
|
|
325
|
+
}
|
|
326
|
+
async sendPrompt(text, actor) {
|
|
327
|
+
return relayRuntimeSendPrompt(this, text, actor);
|
|
328
|
+
}
|
|
329
|
+
async sendUploadPrompt(options, actor) {
|
|
330
|
+
return relayRuntimeSendUploadPrompt(this, options, actor);
|
|
331
|
+
}
|
|
332
|
+
async sendEnvelope(envelope, actor) {
|
|
333
|
+
return relayRuntimeSendEnvelope(this, envelope, actor);
|
|
334
|
+
}
|
|
335
|
+
queue() {
|
|
336
|
+
return relayRuntimeQueue(this);
|
|
337
|
+
}
|
|
338
|
+
queuePaused() {
|
|
339
|
+
return relayRuntimeQueuePaused(this);
|
|
340
|
+
}
|
|
341
|
+
queueAction(action, id, actor) {
|
|
342
|
+
return relayRuntimeQueueAction(this, action, id, actor);
|
|
343
|
+
}
|
|
344
|
+
async artifacts(limit = 20) {
|
|
345
|
+
return relayRuntimeArtifacts(this, limit);
|
|
346
|
+
}
|
|
347
|
+
async artifact(turnId) {
|
|
348
|
+
return relayRuntimeArtifact(this, turnId);
|
|
349
|
+
}
|
|
350
|
+
async deleteArtifact(turnId, actor) {
|
|
351
|
+
return relayRuntimeDeleteArtifact(this, turnId, actor);
|
|
352
|
+
}
|
|
353
|
+
async createArtifactZip(turnId, actor) {
|
|
354
|
+
return relayRuntimeCreateArtifactZip(this, turnId, actor);
|
|
355
|
+
}
|
|
356
|
+
async artifactPreview(turnId, relativePath) {
|
|
357
|
+
return relayRuntimeArtifactPreview(this, turnId, relativePath);
|
|
358
|
+
}
|
|
359
|
+
async logs(target = "connector", lines = 100) {
|
|
360
|
+
return relayRuntimeLogs(this, target, lines);
|
|
361
|
+
}
|
|
362
|
+
clearLogs(target = "connector", actor) {
|
|
363
|
+
return relayRuntimeClearLogs(this, target, actor);
|
|
364
|
+
}
|
|
365
|
+
restartConnector(actor) {
|
|
366
|
+
return relayRuntimeRestartConnector(this, actor);
|
|
367
|
+
}
|
|
368
|
+
dispose() {
|
|
369
|
+
return relayRuntimeDispose(this);
|
|
370
|
+
}
|
|
371
|
+
async getSession(deferThreadStart) {
|
|
372
|
+
return relayRuntimeGetSession(this, deferThreadStart);
|
|
373
|
+
}
|
|
374
|
+
listKnownContextMetadata() {
|
|
375
|
+
return relayRuntimeListKnownContextMetadata(this);
|
|
376
|
+
}
|
|
377
|
+
discoverRunningConnectorSessions() {
|
|
378
|
+
return relayRuntimeDiscoverRunningConnectorSessions(this);
|
|
379
|
+
}
|
|
380
|
+
discoverActiveCodexSessions(knownContexts, preferences) {
|
|
381
|
+
return relayRuntimeDiscoverActiveCodexSessions(this, knownContexts, preferences);
|
|
382
|
+
}
|
|
383
|
+
externalActiveSession(meta, knownContexts, preferences) {
|
|
384
|
+
return relayRuntimeExternalActiveSession(this, meta, knownContexts, preferences);
|
|
385
|
+
}
|
|
386
|
+
sessionStubForMetadata(meta, agentId, capabilities) {
|
|
387
|
+
return relayRuntimeSessionStubForMetadata(this, meta, agentId, capabilities);
|
|
388
|
+
}
|
|
389
|
+
capabilitiesForAgent(agentId) {
|
|
390
|
+
return relayRuntimeCapabilitiesForAgent(this, agentId);
|
|
391
|
+
}
|
|
392
|
+
activeSessionKey(session) {
|
|
393
|
+
return relayRuntimeActiveSessionKey(this, session);
|
|
394
|
+
}
|
|
395
|
+
preferredActiveSession(existing, candidate) {
|
|
396
|
+
return relayRuntimePreferredActiveSession(this, existing, candidate);
|
|
397
|
+
}
|
|
398
|
+
async getControlSession(agentId) {
|
|
399
|
+
return relayRuntimeGetControlSession(this, agentId);
|
|
400
|
+
}
|
|
401
|
+
cliPathOptions() {
|
|
402
|
+
return relayRuntimeCliPathOptions(this);
|
|
403
|
+
}
|
|
404
|
+
async ensureActiveThread(session) {
|
|
405
|
+
return relayRuntimeEnsureActiveThread(this, session);
|
|
406
|
+
}
|
|
407
|
+
ensureIdle(session) {
|
|
408
|
+
return relayRuntimeEnsureIdle(this, session);
|
|
409
|
+
}
|
|
410
|
+
async runPrompt(session, envelope) {
|
|
411
|
+
return relayRuntimeRunPrompt(this, session, envelope);
|
|
412
|
+
}
|
|
413
|
+
async drainQueue() {
|
|
414
|
+
return relayRuntimeDrainQueue(this);
|
|
415
|
+
}
|
|
416
|
+
updateSession(session) {
|
|
417
|
+
return relayRuntimeUpdateSession(this, session);
|
|
418
|
+
}
|
|
419
|
+
recordActivity(input) {
|
|
420
|
+
return relayRuntimeRecordActivity(this, input);
|
|
421
|
+
}
|
|
422
|
+
recordAgentUpdateLifecycle(job) {
|
|
423
|
+
return relayRuntimeRecordAgentUpdateLifecycle(this, job);
|
|
424
|
+
}
|
|
425
|
+
appendActivity(input) {
|
|
426
|
+
return relayRuntimeAppendActivity(this, input);
|
|
427
|
+
}
|
|
428
|
+
enrichActivityInput(input) {
|
|
429
|
+
return relayRuntimeEnrichActivityInput(this, input);
|
|
430
|
+
}
|
|
431
|
+
enrichActivityEvent(event, info) {
|
|
432
|
+
return relayRuntimeEnrichActivityEvent(this, event, info);
|
|
433
|
+
}
|
|
434
|
+
enrichActivityFields(event, info) {
|
|
435
|
+
return relayRuntimeEnrichActivityFields(this, event, info);
|
|
436
|
+
}
|
|
437
|
+
appendAudit(input) {
|
|
438
|
+
return relayRuntimeAppendAudit(this, input);
|
|
439
|
+
}
|
|
440
|
+
updateCurrentProgress(patch = {}) {
|
|
441
|
+
return relayRuntimeUpdateCurrentProgress(this, patch);
|
|
442
|
+
}
|
|
443
|
+
addCurrentTool(toolName) {
|
|
444
|
+
return relayRuntimeAddCurrentTool(this, toolName);
|
|
445
|
+
}
|
|
446
|
+
broadcastQueue() {
|
|
447
|
+
return relayRuntimeBroadcastQueue(this);
|
|
448
|
+
}
|
|
449
|
+
broadcastStatus(message, level = "info") {
|
|
450
|
+
return relayRuntimeBroadcastStatus(this, message, level);
|
|
451
|
+
}
|
|
452
|
+
broadcast(event) {
|
|
453
|
+
return relayRuntimeBroadcast(this, event);
|
|
454
|
+
}
|
|
455
|
+
scheduleActiveSessionsBroadcast() {
|
|
456
|
+
return relayRuntimeScheduleActiveSessionsBroadcast(this);
|
|
457
|
+
}
|
|
458
|
+
publicInfo(session) {
|
|
459
|
+
return relayRuntimePublicInfo(this, session);
|
|
460
|
+
}
|
|
461
|
+
}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
export class RuntimeSnapshotCache {
|
|
2
|
+
entries = new Map();
|
|
3
|
+
register(key, producer) {
|
|
4
|
+
const entry = this.entries.get(key);
|
|
5
|
+
if (entry) {
|
|
6
|
+
entry.producer = producer;
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
this.entries.set(key, { producer, refreshedAt: 0 });
|
|
10
|
+
}
|
|
11
|
+
async get(key, ttlMs, producer) {
|
|
12
|
+
if (producer) {
|
|
13
|
+
this.register(key, producer);
|
|
14
|
+
}
|
|
15
|
+
const now = Date.now();
|
|
16
|
+
const entry = this.entries.get(key);
|
|
17
|
+
const activeProducer = producer ?? entry?.producer;
|
|
18
|
+
if (!activeProducer) {
|
|
19
|
+
throw new Error(`Runtime cache producer is not registered for ${key}.`);
|
|
20
|
+
}
|
|
21
|
+
const hasFreshValue = entry?.value !== undefined && ttlMs > 0 && now - entry.refreshedAt <= ttlMs;
|
|
22
|
+
if (hasFreshValue) {
|
|
23
|
+
return {
|
|
24
|
+
value: entry.value,
|
|
25
|
+
refreshedAt: new Date(entry.refreshedAt).toISOString(),
|
|
26
|
+
stale: false,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
if (entry?.value !== undefined) {
|
|
30
|
+
if (!entry.refresh) {
|
|
31
|
+
entry.refresh = activeProducer()
|
|
32
|
+
.then((value) => {
|
|
33
|
+
entry.value = value;
|
|
34
|
+
entry.refreshedAt = Date.now();
|
|
35
|
+
return value;
|
|
36
|
+
})
|
|
37
|
+
.catch(() => entry.value)
|
|
38
|
+
.finally(() => {
|
|
39
|
+
entry.refresh = undefined;
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
return {
|
|
43
|
+
value: entry.value,
|
|
44
|
+
refreshedAt: new Date(entry.refreshedAt).toISOString(),
|
|
45
|
+
stale: true,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
const pending = entry?.refresh ?? activeProducer();
|
|
49
|
+
this.entries.set(key, { ...entry, producer: activeProducer, refresh: pending, refreshedAt: now });
|
|
50
|
+
try {
|
|
51
|
+
const value = await pending;
|
|
52
|
+
const refreshedAt = Date.now();
|
|
53
|
+
this.entries.set(key, { value, refreshedAt, producer: activeProducer });
|
|
54
|
+
return {
|
|
55
|
+
value,
|
|
56
|
+
refreshedAt: new Date(refreshedAt).toISOString(),
|
|
57
|
+
stale: false,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
this.entries.delete(key);
|
|
62
|
+
throw error;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
refresh(key) {
|
|
66
|
+
const entry = this.entries.get(key);
|
|
67
|
+
if (!entry?.producer) {
|
|
68
|
+
throw new Error(`Runtime cache producer is not registered for ${key}.`);
|
|
69
|
+
}
|
|
70
|
+
if (!entry.refresh) {
|
|
71
|
+
entry.refresh = entry.producer()
|
|
72
|
+
.then((value) => {
|
|
73
|
+
entry.value = value;
|
|
74
|
+
entry.refreshedAt = Date.now();
|
|
75
|
+
return value;
|
|
76
|
+
})
|
|
77
|
+
.finally(() => {
|
|
78
|
+
entry.refresh = undefined;
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
return entry.refresh.then((value) => ({
|
|
82
|
+
value,
|
|
83
|
+
refreshedAt: new Date(entry.refreshedAt).toISOString(),
|
|
84
|
+
stale: false,
|
|
85
|
+
}));
|
|
86
|
+
}
|
|
87
|
+
warm(keys) {
|
|
88
|
+
const targetKeys = keys ?? [...this.entries.keys()];
|
|
89
|
+
for (const key of targetKeys) {
|
|
90
|
+
if (!this.entries.get(key)?.producer)
|
|
91
|
+
continue;
|
|
92
|
+
void this.refresh(key).catch(() => {
|
|
93
|
+
// Best-effort dashboard warm-up. Foreground requests will surface errors.
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
invalidate(key) {
|
|
98
|
+
if (key) {
|
|
99
|
+
const entry = this.entries.get(key);
|
|
100
|
+
if (entry?.producer) {
|
|
101
|
+
this.entries.set(key, { producer: entry.producer, refreshedAt: 0 });
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
this.entries.delete(key);
|
|
105
|
+
}
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
for (const [entryKey, entry] of this.entries.entries()) {
|
|
109
|
+
if (entry.producer) {
|
|
110
|
+
this.entries.set(entryKey, { producer: entry.producer, refreshedAt: 0 });
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
this.entries.delete(entryKey);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
@@ -224,6 +224,16 @@ export function toPromptEnvelope(input, artifactOutDir) {
|
|
|
224
224
|
description: describePromptInput(input),
|
|
225
225
|
};
|
|
226
226
|
}
|
|
227
|
+
export function createCorrelationId() {
|
|
228
|
+
return randomUUID().replace(/-/g, "").slice(0, 12);
|
|
229
|
+
}
|
|
230
|
+
export function ensurePromptCorrelationId(prompt) {
|
|
231
|
+
const existing = prompt.correlationId?.trim();
|
|
232
|
+
if (existing) {
|
|
233
|
+
return { ...prompt, correlationId: existing };
|
|
234
|
+
}
|
|
235
|
+
return { ...prompt, correlationId: createCorrelationId() };
|
|
236
|
+
}
|
|
227
237
|
function createQueueId() {
|
|
228
238
|
return randomUUID().replace(/-/g, "").slice(0, 8);
|
|
229
239
|
}
|
|
@@ -232,7 +242,9 @@ function isPromptEnvelope(value) {
|
|
|
232
242
|
return false;
|
|
233
243
|
}
|
|
234
244
|
const candidate = value;
|
|
235
|
-
return isCodexPromptInput(candidate.input) &&
|
|
245
|
+
return isCodexPromptInput(candidate.input) &&
|
|
246
|
+
typeof candidate.description === "string" &&
|
|
247
|
+
(candidate.correlationId === undefined || typeof candidate.correlationId === "string");
|
|
236
248
|
}
|
|
237
249
|
function isQueuedPrompt(value) {
|
|
238
250
|
return isPromptEnvelope(value) &&
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { createAgentSessionService } from "
|
|
2
|
-
import { CODEX_AGENT_CAPABILITIES } from "
|
|
3
|
-
import { findLaunchProfile } from "
|
|
1
|
+
import { createAgentSessionService } from "../agents/shared/agent-factory.js";
|
|
2
|
+
import { CODEX_AGENT_CAPABILITIES } from "../agents/shared/agent.js";
|
|
3
|
+
import { findLaunchProfile } from "../agents/codex/codex-launch.js";
|
|
4
4
|
import { createDocumentStore } from "./state-backend.js";
|
|
5
5
|
export class SessionRegistry {
|
|
6
6
|
config;
|
|
@@ -3,12 +3,12 @@ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
|
3
3
|
import { readFile, stat } from "node:fs/promises";
|
|
4
4
|
import os from "node:os";
|
|
5
5
|
import path from "node:path";
|
|
6
|
-
import { describeCodexCli, findExecutableOnPath, resolveCodexCli } from "
|
|
7
|
-
import { findLatestDatabase } from "
|
|
8
|
-
import { describeClaudeCodeCli, resolveClaudeCodeCli } from "
|
|
9
|
-
import { describeHermesCli, resolveHermesCli } from "
|
|
10
|
-
import { describeOpenClawCli, resolveOpenClawCli } from "
|
|
11
|
-
import { describePiCli, resolvePiCli } from "
|
|
6
|
+
import { describeCodexCli, findExecutableOnPath, resolveCodexCli } from "../agents/codex/codex-cli.js";
|
|
7
|
+
import { findLatestDatabase } from "../agents/codex/codex-state.js";
|
|
8
|
+
import { describeClaudeCodeCli, resolveClaudeCodeCli } from "../agents/claude-code/claude-code-cli.js";
|
|
9
|
+
import { describeHermesCli, resolveHermesCli } from "../agents/hermes/hermes-cli.js";
|
|
10
|
+
import { describeOpenClawCli, resolveOpenClawCli } from "../agents/openclaw/openclaw-cli.js";
|
|
11
|
+
import { describePiCli, resolvePiCli } from "../agents/pi/pi-cli.js";
|
|
12
12
|
const APP_NAME = "nordrelay";
|
|
13
13
|
const PACKAGE_NAME = "@nordbyte/nordrelay";
|
|
14
14
|
const CODEX_PACKAGE_NAME = "@openai/codex";
|
|
@@ -480,7 +480,7 @@ export function resolveNpmSpawnCommand(env = process.env) {
|
|
|
480
480
|
shell: false,
|
|
481
481
|
};
|
|
482
482
|
}
|
|
483
|
-
const pathMatch = findExecutableOnPath("npm", env.PATH);
|
|
483
|
+
const pathMatch = findExecutableOnPath("npm", env.PATH, { pathext: env.PATHEXT });
|
|
484
484
|
if (pathMatch) {
|
|
485
485
|
return {
|
|
486
486
|
command: pathMatch,
|
|
@@ -3,7 +3,7 @@ import { mkdir, stat, writeFile } from "node:fs/promises";
|
|
|
3
3
|
import os from "node:os";
|
|
4
4
|
import path from "node:path";
|
|
5
5
|
import { getAgentUpdateLogPath, getConnectorHealth, getConnectorHome, getConnectorLogPath, getConnectorStatePath, getSourceRoot, getUpdateLogPath, getVersionChecks, readFormattedLogTail, resolveNpmSpawnCommand, } from "./operations.js";
|
|
6
|
-
import { redactText } from "
|
|
6
|
+
import { redactText } from "../core/redaction.js";
|
|
7
7
|
import { createZipBuffer } from "./zip-writer.js";
|
|
8
8
|
export async function createSupportBundle(options) {
|
|
9
9
|
const createdAt = new Date();
|