@meetquinn/animactl 0.1.2 → 0.1.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/README.md +11 -6
- package/dist/server/{runtime/activity-payload.d.ts → activities/format.d.ts} +4 -1
- package/dist/server/activities/format.d.ts.map +1 -0
- package/dist/server/{runtime/activity-payload.js → activities/format.js} +16 -1
- package/dist/server/agents/agent-skills.d.ts +7 -3
- package/dist/server/agents/agent-skills.d.ts.map +1 -1
- package/dist/server/agents/agent-skills.js +243 -38
- package/dist/server/agents/agent-slack.service.d.ts +15 -0
- package/dist/server/agents/agent-slack.service.d.ts.map +1 -1
- package/dist/server/agents/agent-slack.service.js +43 -6
- package/dist/server/agents/default-skills.d.ts +9 -0
- package/dist/server/agents/default-skills.d.ts.map +1 -0
- package/dist/server/agents/default-skills.js +52 -0
- package/dist/server/cli/runtime-cli.d.ts +7 -1
- package/dist/server/cli/runtime-cli.d.ts.map +1 -1
- package/dist/server/cli/runtime-cli.js +107 -3
- package/dist/server/cli/services-cli.d.ts.map +1 -1
- package/dist/server/cli/services-cli.js +39 -0
- package/dist/server/inbox/slack-subscriber.d.ts +2 -0
- package/dist/server/inbox/slack-subscriber.d.ts.map +1 -1
- package/dist/server/inbox/slack-subscriber.js +28 -2
- package/dist/server/inbox/slack-subscription.service.d.ts.map +1 -1
- package/dist/server/inbox/slack-subscription.service.js +13 -1
- package/dist/server/inbox/wake-queue.service.d.ts +3 -1
- package/dist/server/inbox/wake-queue.service.d.ts.map +1 -1
- package/dist/server/inbox/wake-queue.service.js +5 -3
- package/dist/server/provider-usage/http.d.ts +1 -0
- package/dist/server/provider-usage/http.d.ts.map +1 -1
- package/dist/server/provider-usage/http.js +23 -1
- package/dist/server/provider-usage/provider-usage.service.d.ts +1 -4
- package/dist/server/provider-usage/provider-usage.service.d.ts.map +1 -1
- package/dist/server/provider-usage/provider-usage.service.js +1 -18
- package/dist/server/provider-usage/providers/claude.d.ts +1 -1
- package/dist/server/provider-usage/providers/claude.d.ts.map +1 -1
- package/dist/server/provider-usage/providers/claude.js +1 -1
- package/dist/server/provider-usage/providers/codex.d.ts +1 -1
- package/dist/server/provider-usage/providers/codex.d.ts.map +1 -1
- package/dist/server/provider-usage/providers/codex.js +1 -1
- package/dist/server/provider-usage/providers/kimi.d.ts +1 -1
- package/dist/server/provider-usage/providers/kimi.d.ts.map +1 -1
- package/dist/server/provider-usage/providers/kimi.js +4 -4
- package/dist/server/provider-usage/result.d.ts +5 -0
- package/dist/server/provider-usage/result.d.ts.map +1 -0
- package/dist/server/provider-usage/result.js +18 -0
- package/dist/server/providers/active-runtime.d.ts +1 -1
- package/dist/server/providers/active-runtime.d.ts.map +1 -1
- package/dist/server/providers/claude-events.d.ts +1 -1
- package/dist/server/providers/claude-events.d.ts.map +1 -1
- package/dist/server/providers/claude-events.js +2 -2
- package/dist/server/providers/claude.d.ts +1 -1
- package/dist/server/providers/claude.d.ts.map +1 -1
- package/dist/server/providers/claude.js +2 -2
- package/dist/server/providers/codex-app-server.d.ts +1 -1
- package/dist/server/providers/codex-app-server.d.ts.map +1 -1
- package/dist/server/providers/codex-app-server.js +1 -1
- package/dist/server/providers/codex-events.js +1 -1
- package/dist/server/providers/codex.d.ts +1 -1
- package/dist/server/providers/codex.d.ts.map +1 -1
- package/dist/server/providers/codex.js +2 -2
- package/dist/server/{runtime/provider-contract.d.ts → providers/contract.d.ts} +1 -1
- package/dist/server/providers/contract.d.ts.map +1 -0
- package/dist/server/providers/factory.d.ts +1 -1
- package/dist/server/providers/factory.d.ts.map +1 -1
- package/dist/server/providers/kimi-events.d.ts +1 -1
- package/dist/server/providers/kimi-events.d.ts.map +1 -1
- package/dist/server/providers/kimi-events.js +1 -1
- package/dist/server/providers/kimi.d.ts +1 -1
- package/dist/server/providers/kimi.d.ts.map +1 -1
- package/dist/server/providers/kimi.js +3 -2
- package/dist/server/providers/reasoning-events.js +1 -1
- package/dist/server/runtime/active-run-control.d.ts +19 -0
- package/dist/server/runtime/active-run-control.d.ts.map +1 -0
- package/dist/server/runtime/active-run-control.js +89 -0
- package/dist/server/runtime/activity.js +1 -1
- package/dist/server/runtime/agent-runner.d.ts +1 -1
- package/dist/server/runtime/agent-runner.d.ts.map +1 -1
- package/dist/server/runtime/delivery-prompt.d.ts +6 -0
- package/dist/server/runtime/delivery-prompt.d.ts.map +1 -1
- package/dist/server/runtime/delivery-prompt.js +53 -34
- package/dist/server/runtime/followup-appender.d.ts +20 -0
- package/dist/server/runtime/followup-appender.d.ts.map +1 -0
- package/dist/server/runtime/followup-appender.js +128 -0
- package/dist/server/runtime/host.d.ts +2 -0
- package/dist/server/runtime/host.d.ts.map +1 -1
- package/dist/server/runtime/host.js +8 -0
- package/dist/server/runtime/provider-runner.d.ts +16 -0
- package/dist/server/runtime/provider-runner.d.ts.map +1 -0
- package/dist/server/runtime/provider-runner.js +86 -0
- package/dist/server/runtime/runtime-bridge.d.ts +1 -1
- package/dist/server/runtime/runtime-bridge.d.ts.map +1 -1
- package/dist/server/runtime/runtime-session.service.d.ts +1 -1
- package/dist/server/runtime/runtime-session.service.d.ts.map +1 -1
- package/dist/server/runtime/runtime-session.service.js +1 -1
- package/dist/server/runtime/runtime-worker.d.ts +2 -10
- package/dist/server/runtime/runtime-worker.d.ts.map +1 -1
- package/dist/server/runtime/runtime-worker.js +60 -286
- package/dist/server/runtime-management/managed-runtime.d.ts.map +1 -0
- package/dist/server/runtime-management/runtime-release.d.ts.map +1 -0
- package/dist/server/{runtime → runtime-management}/runtime-upgrade.d.ts +1 -0
- package/dist/server/runtime-management/runtime-upgrade.d.ts.map +1 -0
- package/dist/server/{runtime → runtime-management}/runtime-upgrade.js +14 -0
- package/dist/server/services/system.service.d.ts +41 -0
- package/dist/server/services/system.service.d.ts.map +1 -0
- package/dist/server/services/system.service.js +154 -0
- package/dist/server/settings/settings.service.d.ts +2 -1
- package/dist/server/settings/settings.service.d.ts.map +1 -1
- package/dist/server/settings/settings.service.js +9 -1
- package/dist/server/slack/shortcuts.d.ts +0 -3
- package/dist/server/slack/shortcuts.d.ts.map +1 -1
- package/dist/server/slack/shortcuts.js +0 -3
- package/dist/server/slack-interactions/shortcut-ids.d.ts +4 -0
- package/dist/server/slack-interactions/shortcut-ids.d.ts.map +1 -0
- package/dist/server/slack-interactions/shortcut-ids.js +3 -0
- package/dist/server/slack-interactions/shortcut-views.d.ts +65 -0
- package/dist/server/slack-interactions/shortcut-views.d.ts.map +1 -0
- package/dist/server/slack-interactions/shortcut-views.js +211 -0
- package/dist/server/{slack → slack-interactions}/shortcut.service.d.ts +2 -47
- package/dist/server/slack-interactions/shortcut.service.d.ts.map +1 -0
- package/dist/server/slack-interactions/shortcut.service.js +227 -0
- package/dist/server/storage/jsonl-log.d.ts +9 -0
- package/dist/server/storage/jsonl-log.d.ts.map +1 -1
- package/dist/server/storage/jsonl-log.js +36 -1
- package/dist/server/storage/schema/server.store.d.ts +5 -0
- package/dist/server/storage/schema/server.store.d.ts.map +1 -1
- package/dist/server/storage/schema/server.store.js +2 -1
- package/dist/server/storage/schema/wake-queue.store.d.ts +15 -1
- package/dist/server/storage/schema/wake-queue.store.d.ts.map +1 -1
- package/dist/server/storage/schema/wake-queue.store.js +5 -3
- package/dist/server/tests/agent-config.test.d.ts +2 -0
- package/dist/server/tests/agent-config.test.d.ts.map +1 -0
- package/dist/server/tests/agent-config.test.js +229 -0
- package/dist/server/tests/agent-runtime.test.d.ts +2 -0
- package/dist/server/tests/agent-runtime.test.d.ts.map +1 -0
- package/dist/server/tests/agent-runtime.test.js +1110 -0
- package/dist/server/tests/agent-seed-memory.test.d.ts +2 -0
- package/dist/server/tests/agent-seed-memory.test.d.ts.map +1 -0
- package/dist/server/tests/agent-seed-memory.test.js +16 -0
- package/dist/server/tests/agent-skills.test.d.ts +2 -0
- package/dist/server/tests/agent-skills.test.d.ts.map +1 -0
- package/dist/server/tests/agent-skills.test.js +140 -0
- package/dist/server/tests/anima-home.d.ts +2 -0
- package/dist/server/tests/anima-home.d.ts.map +1 -0
- package/dist/server/tests/anima-home.js +4 -0
- package/dist/server/tests/cli-file.test.d.ts +2 -0
- package/dist/server/tests/cli-file.test.d.ts.map +1 -0
- package/dist/server/tests/cli-file.test.js +596 -0
- package/dist/server/tests/cli-message.test.d.ts +2 -0
- package/dist/server/tests/cli-message.test.d.ts.map +1 -0
- package/dist/server/tests/cli-message.test.js +1196 -0
- package/dist/server/tests/client-error-routes.test.d.ts +2 -0
- package/dist/server/tests/client-error-routes.test.d.ts.map +1 -0
- package/dist/server/tests/client-error-routes.test.js +163 -0
- package/dist/server/tests/config.test.d.ts +2 -0
- package/dist/server/tests/config.test.d.ts.map +1 -0
- package/dist/server/tests/config.test.js +497 -0
- package/dist/server/tests/default-skills.test.d.ts +2 -0
- package/dist/server/tests/default-skills.test.d.ts.map +1 -0
- package/dist/server/tests/default-skills.test.js +57 -0
- package/dist/server/tests/helpers/inbox.d.ts +10 -0
- package/dist/server/tests/helpers/inbox.d.ts.map +1 -0
- package/dist/server/tests/helpers/inbox.js +21 -0
- package/dist/server/tests/helpers/slack.d.ts +11 -0
- package/dist/server/tests/helpers/slack.d.ts.map +1 -0
- package/dist/server/tests/helpers/slack.js +17 -0
- package/dist/server/tests/helpers/state.d.ts +19 -0
- package/dist/server/tests/helpers/state.d.ts.map +1 -0
- package/dist/server/tests/helpers/state.js +69 -0
- package/dist/server/tests/inbox-slack-events.test.d.ts +2 -0
- package/dist/server/tests/inbox-slack-events.test.d.ts.map +1 -0
- package/dist/server/tests/inbox-slack-events.test.js +271 -0
- package/dist/server/tests/inbox.test.d.ts +2 -0
- package/dist/server/tests/inbox.test.d.ts.map +1 -0
- package/dist/server/tests/inbox.test.js +144 -0
- package/dist/server/tests/interactive-ask.test.d.ts +2 -0
- package/dist/server/tests/interactive-ask.test.d.ts.map +1 -0
- package/dist/server/tests/interactive-ask.test.js +387 -0
- package/dist/server/tests/kb.test.d.ts +2 -0
- package/dist/server/tests/kb.test.d.ts.map +1 -0
- package/dist/server/tests/kb.test.js +371 -0
- package/dist/server/tests/message.service.test.d.ts +2 -0
- package/dist/server/tests/message.service.test.d.ts.map +1 -0
- package/dist/server/tests/message.service.test.js +151 -0
- package/dist/server/tests/messages.test.d.ts +2 -0
- package/dist/server/tests/messages.test.d.ts.map +1 -0
- package/dist/server/tests/messages.test.js +12 -0
- package/dist/server/tests/prompt-attachments.test.d.ts +2 -0
- package/dist/server/tests/prompt-attachments.test.d.ts.map +1 -0
- package/dist/server/tests/prompt-attachments.test.js +274 -0
- package/dist/server/tests/provider-usage.test.d.ts +2 -0
- package/dist/server/tests/provider-usage.test.d.ts.map +1 -0
- package/dist/server/tests/provider-usage.test.js +97 -0
- package/dist/server/tests/reminders.test.d.ts +2 -0
- package/dist/server/tests/reminders.test.d.ts.map +1 -0
- package/dist/server/tests/reminders.test.js +383 -0
- package/dist/server/tests/runtime-cli.test.d.ts +2 -0
- package/dist/server/tests/runtime-cli.test.d.ts.map +1 -0
- package/dist/server/tests/runtime-cli.test.js +21 -0
- package/dist/server/tests/runtime-upgrade.test.d.ts +2 -0
- package/dist/server/tests/runtime-upgrade.test.d.ts.map +1 -0
- package/dist/server/tests/runtime-upgrade.test.js +307 -0
- package/dist/server/tests/runtime-worker.test.d.ts +2 -0
- package/dist/server/tests/runtime-worker.test.d.ts.map +1 -0
- package/dist/server/tests/runtime-worker.test.js +1021 -0
- package/dist/server/tests/runtime.test.d.ts +2 -0
- package/dist/server/tests/runtime.test.d.ts.map +1 -0
- package/dist/server/tests/runtime.test.js +354 -0
- package/dist/server/tests/services.test.d.ts +2 -0
- package/dist/server/tests/services.test.d.ts.map +1 -0
- package/dist/server/tests/services.test.js +636 -0
- package/dist/server/tests/slack-files.test.d.ts +2 -0
- package/dist/server/tests/slack-files.test.d.ts.map +1 -0
- package/dist/server/tests/slack-files.test.js +118 -0
- package/dist/server/tests/slack-shortcuts.test.d.ts +2 -0
- package/dist/server/tests/slack-shortcuts.test.d.ts.map +1 -0
- package/dist/server/tests/slack-shortcuts.test.js +310 -0
- package/dist/server/tests/slack.test.d.ts +2 -0
- package/dist/server/tests/slack.test.d.ts.map +1 -0
- package/dist/server/tests/slack.test.js +213 -0
- package/dist/server/tests/state-cache.test.d.ts +2 -0
- package/dist/server/tests/state-cache.test.d.ts.map +1 -0
- package/dist/server/tests/state-cache.test.js +184 -0
- package/dist/server/tests/subscriptions.test.d.ts +2 -0
- package/dist/server/tests/subscriptions.test.d.ts.map +1 -0
- package/dist/server/tests/subscriptions.test.js +292 -0
- package/dist/server/tests/system-service.test.d.ts +2 -0
- package/dist/server/tests/system-service.test.d.ts.map +1 -0
- package/dist/server/tests/system-service.test.js +20 -0
- package/dist/server/tests/url-routes.test.d.ts +2 -0
- package/dist/server/tests/url-routes.test.d.ts.map +1 -0
- package/dist/server/tests/url-routes.test.js +217 -0
- package/dist/server/tests/web-api.test.d.ts +2 -0
- package/dist/server/tests/web-api.test.d.ts.map +1 -0
- package/dist/server/tests/web-api.test.js +1759 -0
- package/dist/server/web/app.d.ts.map +1 -1
- package/dist/server/web/app.js +2 -0
- package/dist/server/web/client-error-routes.d.ts +3 -0
- package/dist/server/web/client-error-routes.d.ts.map +1 -0
- package/dist/server/web/client-error-routes.js +101 -0
- package/dist/server/web/system-routes.d.ts.map +1 -1
- package/dist/server/web/system-routes.js +21 -131
- package/dist/shared/agent-config.d.ts +8 -18
- package/dist/shared/agent-config.d.ts.map +1 -1
- package/dist/shared/agent-config.js +3 -4
- package/dist/shared/inbox.d.ts +27 -0
- package/dist/shared/inbox.d.ts.map +1 -1
- package/dist/shared/inbox.js +1 -0
- package/dist/shared/server-info.d.ts +6 -5
- package/dist/shared/server-info.d.ts.map +1 -1
- package/dist/shared/server-info.js +3 -1
- package/dist/shared/server-settings.d.ts +6 -0
- package/dist/shared/server-settings.d.ts.map +1 -1
- package/dist/shared/server-settings.js +1 -0
- package/dist/shared/skills.d.ts +24 -3
- package/dist/shared/skills.d.ts.map +1 -1
- package/dist/web/assets/activity-DHjip8tY.js +7 -0
- package/dist/web/assets/clipboard-D2NSC52v.js +1 -0
- package/dist/web/assets/{external-link-Dt0qTpmV.js → external-link-Bhr1WdRS.js} +1 -1
- package/dist/web/assets/{file-text-Dd9ys6py.js → file-text-CYMA_SMA.js} +1 -1
- package/dist/web/assets/{index-CzAQnbuO.js → index-CVpew409.js} +5 -5
- package/dist/web/assets/index-mh0uJTkY.css +2 -0
- package/dist/web/assets/kb-DDVpYkT9.js +35 -0
- package/dist/web/assets/profile-CBy6GNzp.js +1 -0
- package/dist/web/assets/reminders-Bbwb9QNT.js +1 -0
- package/dist/web/favicon.svg +1 -1
- package/dist/web/index.html +2 -2
- package/package.json +1 -1
- package/templates/runtime-standing-prompt.md +16 -2
- package/templates/skills/find-skills/SKILL.md +133 -0
- package/dist/server/runtime/activity-payload.d.ts.map +0 -1
- package/dist/server/runtime/activity-text.d.ts +0 -4
- package/dist/server/runtime/activity-text.d.ts.map +0 -1
- package/dist/server/runtime/activity-text.js +0 -16
- package/dist/server/runtime/managed-runtime.d.ts.map +0 -1
- package/dist/server/runtime/provider-contract.d.ts.map +0 -1
- package/dist/server/runtime/runtime-release.d.ts.map +0 -1
- package/dist/server/runtime/runtime-upgrade.d.ts.map +0 -1
- package/dist/server/slack/shortcut.service.d.ts.map +0 -1
- package/dist/server/slack/shortcut.service.js +0 -493
- package/dist/web/assets/activity-BP0C81IV.js +0 -7
- package/dist/web/assets/globe-DmDZSgDP.js +0 -1
- package/dist/web/assets/index-DKecrvN0.css +0 -2
- package/dist/web/assets/kb-3wFeP2Jt.js +0 -32
- package/dist/web/assets/profile-D7wPZXW_.js +0 -1
- package/dist/web/assets/reminders-DOhroVwo.js +0 -1
- /package/dist/server/{runtime/provider-contract.js → providers/contract.js} +0 -0
- /package/dist/server/{runtime → runtime-management}/managed-runtime.d.ts +0 -0
- /package/dist/server/{runtime → runtime-management}/managed-runtime.js +0 -0
- /package/dist/server/{runtime → runtime-management}/runtime-release.d.ts +0 -0
- /package/dist/server/{runtime → runtime-management}/runtime-release.js +0 -0
|
@@ -5,16 +5,13 @@ import { isRestartDrainActive } from '../services/restart-drain.js';
|
|
|
5
5
|
import { AgentRuntimeBridge } from './runtime-bridge.js';
|
|
6
6
|
import { runtimeContextForItemId } from './context.js';
|
|
7
7
|
import { clearActiveRuntimeItem, setActiveRuntimeItem } from './active-item.js';
|
|
8
|
-
import { recordRuntimeAborted,
|
|
9
|
-
import {
|
|
8
|
+
import { recordRuntimeAborted, recordRuntimeEvent, } from './activity.js';
|
|
9
|
+
import { startActiveRunControl } from './active-run-control.js';
|
|
10
|
+
import { appendQueuedFollowupsUntilFinished } from './followup-appender.js';
|
|
11
|
+
import { recordFinalRuntimeFailure, runProviderWithCrashRetries } from './provider-runner.js';
|
|
10
12
|
// Executor for one agent: claims queued inbox items, runs the provider runtime,
|
|
11
13
|
// appends follow-up items into the active run, and settles item lifecycle state.
|
|
12
14
|
const IDLE_TIMEOUT_MS_DEFAULT = PROVIDER_IDLE_TIMEOUT_MS_DEFAULT;
|
|
13
|
-
const IDLE_CHECK_INTERVAL_FLOOR_MS = 50;
|
|
14
|
-
const IDLE_CHECK_INTERVAL_CAP_MS = 1_000;
|
|
15
|
-
const FOLLOWUP_POLL_MS = 100;
|
|
16
|
-
const PROVIDER_CRASH_MAX_RETRIES = 3;
|
|
17
|
-
const PROVIDER_CRASH_RETRY_BACKOFF_MS = 500;
|
|
18
15
|
export class AgentRuntimeWorker {
|
|
19
16
|
options;
|
|
20
17
|
logger;
|
|
@@ -120,7 +117,23 @@ export class AgentRuntimeWorker {
|
|
|
120
117
|
let followupError;
|
|
121
118
|
try {
|
|
122
119
|
context = await runtimeContextForItemId(item.id, this.options);
|
|
123
|
-
|
|
120
|
+
const activeContext = context;
|
|
121
|
+
followupLoop = appendQueuedFollowupsUntilFinished({
|
|
122
|
+
activeContext,
|
|
123
|
+
agentRuntime: this.options.agentRuntime,
|
|
124
|
+
itemDone: itemAbort.signal,
|
|
125
|
+
logger: this.logger,
|
|
126
|
+
onFollowupAccepted: () => handle.noteActivity(),
|
|
127
|
+
onFollowupAppended: async (followupContext, _text) => {
|
|
128
|
+
handle.appendedFollowups.push(followupContext);
|
|
129
|
+
await this.notifyItemFollowupAppended(activeContext, followupContext);
|
|
130
|
+
},
|
|
131
|
+
onFollowupSettled: (followupContext) => this.notifySettledItems([followupContext]),
|
|
132
|
+
queue: this.queue,
|
|
133
|
+
runtimeBridge: this.runtimeBridge,
|
|
134
|
+
runtimeConfig: this.options,
|
|
135
|
+
workerId: this.workerId,
|
|
136
|
+
}).catch((error) => {
|
|
124
137
|
followupError = error;
|
|
125
138
|
});
|
|
126
139
|
const agentConfig = await defaultAgentRegistryService.serviceFor(this.options.agentId).getConfig();
|
|
@@ -131,17 +144,28 @@ export class AgentRuntimeWorker {
|
|
|
131
144
|
workerId: this.workerId,
|
|
132
145
|
});
|
|
133
146
|
await this.notifyItemStarted(context);
|
|
134
|
-
|
|
135
|
-
context
|
|
136
|
-
|
|
147
|
+
if (context.item.handling.resumeReason === 'runtime_restart') {
|
|
148
|
+
await this.recordRestartResumeActivity(context);
|
|
149
|
+
}
|
|
150
|
+
const runContext = context;
|
|
151
|
+
const result = await runProviderWithCrashRetries({
|
|
152
|
+
agentId: this.options.agentId,
|
|
153
|
+
agentRuntime: this.options.agentRuntime,
|
|
154
|
+
buildInput: (retryNotice) => this.runtimeBridge.runInput({
|
|
155
|
+
context: runContext,
|
|
156
|
+
onActivity: () => handle.noteActivity(),
|
|
157
|
+
profile: {
|
|
158
|
+
displayName: agentConfig.profile?.displayName ?? this.options.agentId,
|
|
159
|
+
...(agentConfig.profile?.role ? { role: agentConfig.profile.role } : {}),
|
|
160
|
+
},
|
|
161
|
+
retryNotice,
|
|
162
|
+
session: runContext.session,
|
|
163
|
+
signal: itemAbort.signal,
|
|
164
|
+
suppressFailureRecord: true,
|
|
165
|
+
}),
|
|
137
166
|
onFinalFailureRecorded: () => {
|
|
138
167
|
runtimeFailureRecorded = true;
|
|
139
168
|
},
|
|
140
|
-
profile: {
|
|
141
|
-
displayName: agentConfig.profile?.displayName ?? this.options.agentId,
|
|
142
|
-
...(agentConfig.profile?.role ? { role: agentConfig.profile.role } : {}),
|
|
143
|
-
},
|
|
144
|
-
session: context.session,
|
|
145
169
|
signal: itemAbort.signal,
|
|
146
170
|
});
|
|
147
171
|
itemAbort.abort('completed');
|
|
@@ -171,7 +195,12 @@ export class AgentRuntimeWorker {
|
|
|
171
195
|
itemSettled = true;
|
|
172
196
|
}
|
|
173
197
|
else if (context && !runtimeFailureRecorded) {
|
|
174
|
-
await
|
|
198
|
+
await recordFinalRuntimeFailure({
|
|
199
|
+
agentId: this.options.agentId,
|
|
200
|
+
agentRuntime: this.options.agentRuntime,
|
|
201
|
+
error,
|
|
202
|
+
retryAttempts: 0,
|
|
203
|
+
});
|
|
175
204
|
}
|
|
176
205
|
if (!itemSettled)
|
|
177
206
|
await this.queue.fail(item.id);
|
|
@@ -201,209 +230,31 @@ export class AgentRuntimeWorker {
|
|
|
201
230
|
}
|
|
202
231
|
}
|
|
203
232
|
registerActiveItem(itemId, abortController) {
|
|
204
|
-
const
|
|
205
|
-
const tickInterval = Math.max(IDLE_CHECK_INTERVAL_FLOOR_MS, Math.min(IDLE_CHECK_INTERVAL_CAP_MS, Math.floor(this.idleTimeoutMs / 2)));
|
|
206
|
-
const handle = {
|
|
233
|
+
const handle = startActiveRunControl({
|
|
207
234
|
abortController,
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
return;
|
|
215
|
-
const now = Date.now();
|
|
216
|
-
if (now - handle.lastActivityAt >= this.idleTimeoutMs) {
|
|
217
|
-
abortController.abort('idle_timeout');
|
|
218
|
-
return;
|
|
219
|
-
}
|
|
220
|
-
void this.checkExternalRequests(itemId, abortController, handle);
|
|
221
|
-
}, tickInterval),
|
|
222
|
-
};
|
|
235
|
+
agentRuntime: this.options.agentRuntime,
|
|
236
|
+
idleTimeoutMs: this.idleTimeoutMs,
|
|
237
|
+
itemId,
|
|
238
|
+
logger: this.logger,
|
|
239
|
+
queue: this.queue,
|
|
240
|
+
});
|
|
223
241
|
this.activeItem = handle;
|
|
224
242
|
return handle;
|
|
225
243
|
}
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
let previousError;
|
|
232
|
-
for (;;) {
|
|
233
|
-
try {
|
|
234
|
-
return await this.options.agentRuntime.run(await this.runtimeBridge.runInput({
|
|
235
|
-
context: input.context,
|
|
236
|
-
onActivity: () => this.noteProviderActivity(input.handle),
|
|
237
|
-
profile: input.profile,
|
|
238
|
-
retryNotice: retryCount > 0
|
|
239
|
-
? providerCrashRetryPrompt({
|
|
240
|
-
attempt: retryCount,
|
|
241
|
-
maxRetries: PROVIDER_CRASH_MAX_RETRIES,
|
|
242
|
-
previousError: errorMessage(previousError),
|
|
243
|
-
})
|
|
244
|
-
: undefined,
|
|
245
|
-
session: input.session,
|
|
246
|
-
signal: input.signal,
|
|
247
|
-
suppressFailureRecord: true,
|
|
248
|
-
}));
|
|
249
|
-
}
|
|
250
|
-
catch (error) {
|
|
251
|
-
previousError = error;
|
|
252
|
-
if (input.signal.aborted)
|
|
253
|
-
throw error;
|
|
254
|
-
if (!isProviderCrashError(error) || retryCount >= PROVIDER_CRASH_MAX_RETRIES) {
|
|
255
|
-
await this.recordFinalRuntimeFailure(error, retryCount, { providerFailure: true });
|
|
256
|
-
input.onFinalFailureRecorded();
|
|
257
|
-
throw error;
|
|
258
|
-
}
|
|
259
|
-
retryCount += 1;
|
|
260
|
-
const retryAfterMs = PROVIDER_CRASH_RETRY_BACKOFF_MS * retryCount;
|
|
261
|
-
await recordRuntimeEvent({ agentId: this.options.agentId }, this.options.agentRuntime.kind, this.options.agentRuntime.env, {
|
|
262
|
-
attempt: retryCount,
|
|
263
|
-
error: errorMessage(error),
|
|
264
|
-
eventType: 'provider.crash.retry',
|
|
265
|
-
maxRetries: PROVIDER_CRASH_MAX_RETRIES,
|
|
266
|
-
retryAfterMs,
|
|
267
|
-
});
|
|
268
|
-
await this.options.agentRuntime.close?.();
|
|
269
|
-
await sleep(retryAfterMs, input.signal);
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
async recordFinalRuntimeFailure(error, retryAttempts, options = {}) {
|
|
274
|
-
const processCrash = isProviderCrashError(error);
|
|
275
|
-
await recordRuntimeActivity({ agentId: this.options.agentId }, this.options.agentRuntime.kind, 'runtime.failed', {
|
|
276
|
-
...runtimeErrorPayload(error),
|
|
277
|
-
...(options.providerFailure
|
|
278
|
-
? {
|
|
279
|
-
failureSource: 'provider',
|
|
280
|
-
maxRetries: PROVIDER_CRASH_MAX_RETRIES,
|
|
281
|
-
providerReason: processCrash ? 'process_crash' : 'provider_error',
|
|
282
|
-
retryAttempts,
|
|
283
|
-
retryable: processCrash && retryAttempts < PROVIDER_CRASH_MAX_RETRIES,
|
|
284
|
-
}
|
|
285
|
-
: {}),
|
|
244
|
+
async recordRestartResumeActivity(context) {
|
|
245
|
+
await recordRuntimeEvent({ agentId: this.options.agentId }, this.options.agentRuntime.kind, this.options.agentRuntime.env, {
|
|
246
|
+
eventType: 'runtime.restart_resumed',
|
|
247
|
+
itemId: context.item.id,
|
|
248
|
+
message: 'Resumed after restart',
|
|
286
249
|
});
|
|
287
250
|
}
|
|
288
|
-
async checkExternalRequests(itemId, abortController, handle) {
|
|
289
|
-
try {
|
|
290
|
-
const item = await this.queue.find(itemId);
|
|
291
|
-
if (item?.handling.stopRequestedAt && !abortController.signal.aborted) {
|
|
292
|
-
abortController.abort('user_stop');
|
|
293
|
-
return;
|
|
294
|
-
}
|
|
295
|
-
const drainRequestedAt = item?.handling.drainRequestedAt;
|
|
296
|
-
if (drainRequestedAt &&
|
|
297
|
-
!handle.drainRequestInFlight &&
|
|
298
|
-
handle.drainRequestedAt !== drainRequestedAt &&
|
|
299
|
-
!abortController.signal.aborted) {
|
|
300
|
-
handle.drainRequestInFlight = true;
|
|
301
|
-
handle.drainRequestedAt = drainRequestedAt;
|
|
302
|
-
void this.drainActiveItem(itemId, item.handling.drainTimeoutMs, abortController, handle);
|
|
303
|
-
}
|
|
304
|
-
}
|
|
305
|
-
catch (error) {
|
|
306
|
-
this.logger.error(`Runtime worker control check failed for item ${itemId}: ${errorMessage(error)}`);
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
async drainActiveItem(itemId, timeoutMs, abortController, handle) {
|
|
310
|
-
try {
|
|
311
|
-
if (!this.options.agentRuntime.requestDrain)
|
|
312
|
-
return;
|
|
313
|
-
await withTimeout(this.options.agentRuntime.requestDrain({ activeItemId: itemId, signal: abortController.signal }), timeoutMs ?? 15_000, `Timed out waiting for item ${itemId} to reach a restart drain point`);
|
|
314
|
-
const current = await this.queue.find(itemId);
|
|
315
|
-
if (current?.handling.drainRequestedAt !== handle.drainRequestedAt)
|
|
316
|
-
return;
|
|
317
|
-
if (!abortController.signal.aborted)
|
|
318
|
-
abortController.abort('restart_drain');
|
|
319
|
-
}
|
|
320
|
-
catch (error) {
|
|
321
|
-
this.logger.error(`Runtime worker drain request failed for item ${itemId}: ${errorMessage(error)}`);
|
|
322
|
-
}
|
|
323
|
-
finally {
|
|
324
|
-
handle.drainRequestInFlight = false;
|
|
325
|
-
}
|
|
326
|
-
}
|
|
327
251
|
releaseActiveItem() {
|
|
328
252
|
const handle = this.activeItem;
|
|
329
253
|
if (!handle)
|
|
330
254
|
return;
|
|
331
|
-
|
|
255
|
+
handle.release();
|
|
332
256
|
this.activeItem = undefined;
|
|
333
257
|
}
|
|
334
|
-
async appendQueuedFollowupsUntilFinished(activeContext, itemDone, handle) {
|
|
335
|
-
const skippedItemIds = new Set();
|
|
336
|
-
while (!itemDone.aborted) {
|
|
337
|
-
if (await isRestartDrainActive()) {
|
|
338
|
-
await sleep(FOLLOWUP_POLL_MS, itemDone);
|
|
339
|
-
continue;
|
|
340
|
-
}
|
|
341
|
-
const item = await this.queue.claimNextFollowup({
|
|
342
|
-
activeItemId: activeContext.item.id,
|
|
343
|
-
excludedItemIds: skippedItemIds,
|
|
344
|
-
workerId: this.workerId,
|
|
345
|
-
});
|
|
346
|
-
if (!item) {
|
|
347
|
-
await sleep(FOLLOWUP_POLL_MS, itemDone);
|
|
348
|
-
continue;
|
|
349
|
-
}
|
|
350
|
-
await this.tryOneFollowupItem(activeContext, item, handle, itemDone, skippedItemIds);
|
|
351
|
-
}
|
|
352
|
-
}
|
|
353
|
-
async tryOneFollowupItem(activeContext, item, handle, itemDone, skippedItemIds) {
|
|
354
|
-
let appended = false;
|
|
355
|
-
let context;
|
|
356
|
-
try {
|
|
357
|
-
context = await runtimeContextForItemId(item.id, this.options);
|
|
358
|
-
const followup = await appendRuntimeFollowup({
|
|
359
|
-
activeContext,
|
|
360
|
-
agentRuntime: this.options.agentRuntime,
|
|
361
|
-
context,
|
|
362
|
-
runtimeBridge: this.runtimeBridge,
|
|
363
|
-
});
|
|
364
|
-
if (followup.status === 'appended') {
|
|
365
|
-
await this.recordFollowupAppendSuccess(activeContext, context, followup.text, handle);
|
|
366
|
-
appended = true;
|
|
367
|
-
return;
|
|
368
|
-
}
|
|
369
|
-
await this.recordFollowupAppendSkip(activeContext, item, followup);
|
|
370
|
-
skippedItemIds.add(item.id);
|
|
371
|
-
await this.queue.requeue(item.id);
|
|
372
|
-
await sleep(FOLLOWUP_POLL_MS, itemDone);
|
|
373
|
-
}
|
|
374
|
-
catch (error) {
|
|
375
|
-
skippedItemIds.add(item.id);
|
|
376
|
-
await this.queue.requeue(item.id);
|
|
377
|
-
await recordRuntimeFollowupFailed({ agentId: this.options.agentId }, {
|
|
378
|
-
activeItemId: activeContext.item.id,
|
|
379
|
-
agentRuntime: this.options.agentRuntime.kind,
|
|
380
|
-
error: errorMessage(error),
|
|
381
|
-
reason: 'followup_failed',
|
|
382
|
-
});
|
|
383
|
-
this.logger.error(`Runtime worker follow-up append failed for item ${item.id}: ${errorMessage(error)}`);
|
|
384
|
-
await sleep(FOLLOWUP_POLL_MS, itemDone);
|
|
385
|
-
}
|
|
386
|
-
finally {
|
|
387
|
-
const current = context && !appended ? await this.queue.find(context.item.id).catch(() => undefined) : undefined;
|
|
388
|
-
if (context && (current?.handling.status === 'completed' || current?.handling.status === 'failed')) {
|
|
389
|
-
await this.notifySettledItems([context]);
|
|
390
|
-
}
|
|
391
|
-
}
|
|
392
|
-
}
|
|
393
|
-
async recordFollowupAppendSuccess(activeContext, context, text, handle) {
|
|
394
|
-
this.noteProviderActivity(handle);
|
|
395
|
-
await this.queue.complete(context.item.id);
|
|
396
|
-
handle.appendedFollowups.push(context);
|
|
397
|
-
await this.notifyItemFollowupAppended(activeContext, context);
|
|
398
|
-
this.logger.log(JSON.stringify({
|
|
399
|
-
activeItemId: activeContext.item.id,
|
|
400
|
-
agentRuntime: this.options.agentRuntime.kind,
|
|
401
|
-
event: 'runtime.followup_appended',
|
|
402
|
-
itemId: context.item.id,
|
|
403
|
-
text,
|
|
404
|
-
workerId: this.workerId,
|
|
405
|
-
}, null, 2));
|
|
406
|
-
}
|
|
407
258
|
async notifyItemStarted(context) {
|
|
408
259
|
try {
|
|
409
260
|
await this.options.onItemStarted?.(context);
|
|
@@ -430,22 +281,10 @@ export class AgentRuntimeWorker {
|
|
|
430
281
|
}
|
|
431
282
|
}
|
|
432
283
|
}
|
|
433
|
-
async recordFollowupAppendSkip(activeContext, item, followup) {
|
|
434
|
-
if (followup.status === 'rejected') {
|
|
435
|
-
await recordRuntimePending({ agentId: this.options.agentId }, {
|
|
436
|
-
activeItemId: activeContext.item.id,
|
|
437
|
-
agentRuntime: this.options.agentRuntime.kind,
|
|
438
|
-
reason: 'followup_rejected',
|
|
439
|
-
});
|
|
440
|
-
}
|
|
441
|
-
if (followup.status === 'failed') {
|
|
442
|
-
this.logger.error(`Runtime worker follow-up append failed for item ${item.id}: ${followup.error}`);
|
|
443
|
-
}
|
|
444
|
-
}
|
|
445
284
|
async settleAbortedItem(context, abortReason) {
|
|
446
285
|
await recordRuntimeAborted({ agentId: this.options.agentId }, abortReason, abortReason === 'idle_timeout' ? { timeoutMs: this.idleTimeoutMs } : undefined);
|
|
447
286
|
if (abortReason === 'restart_drain') {
|
|
448
|
-
await this.queue.requeue(context.item.id);
|
|
287
|
+
await this.queue.requeue(context.item.id, { resumeReason: 'runtime_restart' });
|
|
449
288
|
return;
|
|
450
289
|
}
|
|
451
290
|
await this.queue.fail(context.item.id);
|
|
@@ -460,32 +299,6 @@ function abortReasonOf(signal) {
|
|
|
460
299
|
? reason
|
|
461
300
|
: undefined;
|
|
462
301
|
}
|
|
463
|
-
async function appendRuntimeFollowup(input) {
|
|
464
|
-
try {
|
|
465
|
-
const result = await input.agentRuntime.appendToActiveRun(await input.runtimeBridge.followupInput({
|
|
466
|
-
activeContext: input.activeContext,
|
|
467
|
-
context: input.context,
|
|
468
|
-
}));
|
|
469
|
-
if (!result.accepted)
|
|
470
|
-
return { status: 'rejected' };
|
|
471
|
-
await recordRuntimeFollowupAppended({ agentId: input.context.agentId }, {
|
|
472
|
-
activeItemId: input.activeContext.item.id,
|
|
473
|
-
agentRuntime: input.agentRuntime.kind,
|
|
474
|
-
text: result.text,
|
|
475
|
-
});
|
|
476
|
-
return { status: 'appended', text: result.text };
|
|
477
|
-
}
|
|
478
|
-
catch (error) {
|
|
479
|
-
const message = errorMessage(error);
|
|
480
|
-
await recordRuntimeFollowupFailed({ agentId: input.context.agentId }, {
|
|
481
|
-
activeItemId: input.activeContext.item.id,
|
|
482
|
-
agentRuntime: input.agentRuntime.kind,
|
|
483
|
-
error: message,
|
|
484
|
-
reason: 'followup_failed',
|
|
485
|
-
});
|
|
486
|
-
return { error: message, status: 'failed' };
|
|
487
|
-
}
|
|
488
|
-
}
|
|
489
302
|
function isWorkerAlive(workerId) {
|
|
490
303
|
const pidText = workerId.split(':').at(-1);
|
|
491
304
|
const pid = pidText ? Number.parseInt(pidText, 10) : Number.NaN;
|
|
@@ -499,42 +312,3 @@ function isWorkerAlive(workerId) {
|
|
|
499
312
|
return false;
|
|
500
313
|
}
|
|
501
314
|
}
|
|
502
|
-
function isProviderCrashError(error) {
|
|
503
|
-
const message = errorMessage(error);
|
|
504
|
-
return (/runtime exited before completing/i.test(message) ||
|
|
505
|
-
/runtime terminated by/i.test(message) ||
|
|
506
|
-
/runtime exited with code/i.test(message) ||
|
|
507
|
-
/stdin is closed/i.test(message));
|
|
508
|
-
}
|
|
509
|
-
function providerCrashRetryPrompt(input) {
|
|
510
|
-
return [
|
|
511
|
-
'Anima system note: the previous provider process crashed before completing this same item.',
|
|
512
|
-
`This is retry ${input.attempt}/${input.maxRetries}.`,
|
|
513
|
-
`Previous error: ${input.previousError}`,
|
|
514
|
-
'Continue the original task from the current files, conversation, and Slack state.',
|
|
515
|
-
'Do not repeat completed external side effects such as Slack messages, file sends, or file edits; inspect state first if needed.',
|
|
516
|
-
].join('\n');
|
|
517
|
-
}
|
|
518
|
-
function sleep(ms, signal) {
|
|
519
|
-
if (signal.aborted)
|
|
520
|
-
return Promise.resolve();
|
|
521
|
-
return new Promise((resolve) => {
|
|
522
|
-
const done = () => {
|
|
523
|
-
clearTimeout(timer);
|
|
524
|
-
signal.removeEventListener('abort', done);
|
|
525
|
-
resolve();
|
|
526
|
-
};
|
|
527
|
-
const timer = setTimeout(done, ms);
|
|
528
|
-
signal.addEventListener('abort', done, { once: true });
|
|
529
|
-
});
|
|
530
|
-
}
|
|
531
|
-
function withTimeout(promise, timeoutMs, message) {
|
|
532
|
-
let timer;
|
|
533
|
-
const timeout = new Promise((_, reject) => {
|
|
534
|
-
timer = setTimeout(() => reject(new Error(message)), timeoutMs);
|
|
535
|
-
});
|
|
536
|
-
return Promise.race([promise, timeout]).finally(() => {
|
|
537
|
-
if (timer)
|
|
538
|
-
clearTimeout(timer);
|
|
539
|
-
});
|
|
540
|
-
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"managed-runtime.d.ts","sourceRoot":"","sources":["../../../server/runtime-management/managed-runtime.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime-release.d.ts","sourceRoot":"","sources":["../../../server/runtime-management/runtime-release.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,mBAAmB,EAAE,wBAAwB,EAAE,MAAM,iCAAiC,CAAC;AAKrG,MAAM,MAAM,oBAAoB,GAAG,CAAC,KAAK,EAAE;IACzC,WAAW,EAAE,MAAM,CAAC;IACpB,GAAG,EAAE,MAAM,CAAC;CACb,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;AAEtB,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,mBAAmB,GAAG,MAAM,CAExE;AAED,wBAAsB,gBAAgB,CAAC,KAAK,EAAE;IAC5C,WAAW,EAAE,MAAM,CAAC;IACpB,GAAG,EAAE,MAAM,CAAC;CACb,GAAG,OAAO,CAAC,MAAM,CAAC,CAsBlB;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,OAAO,GAAG,wBAAwB,CAQjF;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAmB1E"}
|
|
@@ -51,6 +51,7 @@ export declare class RuntimeUpgradeService {
|
|
|
51
51
|
private readonly settings;
|
|
52
52
|
constructor(options?: RuntimeUpgradeServiceOptions);
|
|
53
53
|
status(): Promise<RuntimeUpgradeStatusResponse>;
|
|
54
|
+
checkNow(): Promise<RuntimeUpgradeStatusResponse>;
|
|
54
55
|
prepareApply(input: {
|
|
55
56
|
animactlScript: string;
|
|
56
57
|
dashboardHost?: string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime-upgrade.d.ts","sourceRoot":"","sources":["../../../server/runtime-management/runtime-upgrade.ts"],"names":[],"mappings":"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"}
|
|
@@ -74,6 +74,20 @@ export class RuntimeUpgradeService {
|
|
|
74
74
|
updateAvailable,
|
|
75
75
|
};
|
|
76
76
|
}
|
|
77
|
+
async checkNow() {
|
|
78
|
+
const [currentVersion, releaseTrack, operation] = await Promise.all([
|
|
79
|
+
this.packageVersion(),
|
|
80
|
+
this.settings.getReleaseTrack(),
|
|
81
|
+
this.operationStore.read(),
|
|
82
|
+
]);
|
|
83
|
+
const refreshed = await this.refreshCheckCache(releaseTrack);
|
|
84
|
+
return this.statusFromCheck({
|
|
85
|
+
check: refreshed,
|
|
86
|
+
currentVersion,
|
|
87
|
+
operation,
|
|
88
|
+
releaseTrack,
|
|
89
|
+
});
|
|
90
|
+
}
|
|
77
91
|
async prepareApply(input) {
|
|
78
92
|
const [currentVersion, releaseTrack, operation] = await Promise.all([
|
|
79
93
|
this.packageVersion(),
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { type ServerSettingsService } from '../settings/settings.service.js';
|
|
2
|
+
import type { ServerInfo, ServicesRestartResponse } from '../../shared/server-info.js';
|
|
3
|
+
import { type ProviderAvailability } from '../../shared/provider-catalog.js';
|
|
4
|
+
export interface PreparedServicesRestart {
|
|
5
|
+
response: ServicesRestartResponse;
|
|
6
|
+
spawn: () => Promise<void>;
|
|
7
|
+
}
|
|
8
|
+
export interface SystemServiceOptions {
|
|
9
|
+
animactlScript?: string;
|
|
10
|
+
commandPresent?: (command: string) => Promise<boolean>;
|
|
11
|
+
commit?: Promise<string | undefined> | string;
|
|
12
|
+
now?: () => Date;
|
|
13
|
+
packageVersion?: () => Promise<string>;
|
|
14
|
+
projectRoot?: string;
|
|
15
|
+
restartDelayMs?: number;
|
|
16
|
+
settings?: ServerSettingsService;
|
|
17
|
+
startedAt?: string;
|
|
18
|
+
}
|
|
19
|
+
export declare class SystemServiceError extends Error {
|
|
20
|
+
}
|
|
21
|
+
export declare class SystemService {
|
|
22
|
+
private readonly animactlScript;
|
|
23
|
+
private readonly commandPresent;
|
|
24
|
+
private readonly commit;
|
|
25
|
+
private readonly now;
|
|
26
|
+
private readonly packageVersion;
|
|
27
|
+
private readonly projectRoot;
|
|
28
|
+
private readonly restartDelayMs;
|
|
29
|
+
private readonly settings;
|
|
30
|
+
private readonly startedAt;
|
|
31
|
+
constructor(options?: SystemServiceOptions);
|
|
32
|
+
providerAvailability(): Promise<{
|
|
33
|
+
providers: ProviderAvailability[];
|
|
34
|
+
}>;
|
|
35
|
+
serverInfo(): Promise<ServerInfo>;
|
|
36
|
+
serverStartedAt(): string;
|
|
37
|
+
prepareServicesRestart(): PreparedServicesRestart;
|
|
38
|
+
}
|
|
39
|
+
export declare const defaultSystemService: SystemService;
|
|
40
|
+
export declare function docsUrl(track: 'dev' | 'canary' | 'stable'): string;
|
|
41
|
+
//# sourceMappingURL=system.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"system.service.d.ts","sourceRoot":"","sources":["../../../server/services/system.service.ts"],"names":[],"mappings":"AAQA,OAAO,EAAgC,KAAK,qBAAqB,EAAE,MAAM,iCAAiC,CAAC;AAO3G,OAAO,KAAK,EAAE,UAAU,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAC;AACvF,OAAO,EAAoB,KAAK,oBAAoB,EAAE,MAAM,kCAAkC,CAAC;AAM/F,MAAM,WAAW,uBAAuB;IACtC,QAAQ,EAAE,uBAAuB,CAAC;IAClC,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5B;AAED,MAAM,WAAW,oBAAoB;IACnC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACvD,MAAM,CAAC,EAAE,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,GAAG,MAAM,CAAC;IAC9C,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IACvC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,qBAAqB,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,qBAAa,kBAAmB,SAAQ,KAAK;CAAG;AAEhD,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAwC;IACvE,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA8B;IACrD,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAa;IACjC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAwB;IACvD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAwB;IACjD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;gBAEvB,OAAO,GAAE,oBAAyB;IAYxC,oBAAoB,IAAI,OAAO,CAAC;QAAE,SAAS,EAAE,oBAAoB,EAAE,CAAA;KAAE,CAAC;IAStE,UAAU,IAAI,OAAO,CAAC,UAAU,CAAC;IAuBvC,eAAe,IAAI,MAAM;IAIzB,sBAAsB,IAAI,uBAAuB;CAyBlD;AAED,eAAO,MAAM,oBAAoB,eAAsB,CAAC;AAsDxD,wBAAgB,OAAO,CAAC,KAAK,EAAE,KAAK,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,CAKlE"}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import { execFile, spawn } from 'node:child_process';
|
|
2
|
+
import { existsSync } from 'node:fs';
|
|
3
|
+
import { mkdir, open, readFile, rm } from 'node:fs/promises';
|
|
4
|
+
import { dirname, join, resolve } from 'node:path';
|
|
5
|
+
import { fileURLToPath } from 'node:url';
|
|
6
|
+
import { promisify } from 'node:util';
|
|
7
|
+
import { resolveAnimaHome } from '../anima-home.js';
|
|
8
|
+
import { defaultServerSettingsService } from '../settings/settings.service.js';
|
|
9
|
+
import { cleanServiceEnv } from './env.js';
|
|
10
|
+
import { readLastServicesRestart, servicesRestartLogPath, servicesRestartResultPath, } from './restart-result.js';
|
|
11
|
+
import { PROVIDER_CATALOG } from '../../shared/provider-catalog.js';
|
|
12
|
+
const execFileAsync = promisify(execFile);
|
|
13
|
+
const PROJECT_ROOT = resolve(dirname(fileURLToPath(import.meta.url)), '../../..');
|
|
14
|
+
const RESTART_AFTER_RESPONSE_DELAY_MS = 250;
|
|
15
|
+
export class SystemServiceError extends Error {
|
|
16
|
+
}
|
|
17
|
+
export class SystemService {
|
|
18
|
+
animactlScript;
|
|
19
|
+
commandPresent;
|
|
20
|
+
commit;
|
|
21
|
+
now;
|
|
22
|
+
packageVersion;
|
|
23
|
+
projectRoot;
|
|
24
|
+
restartDelayMs;
|
|
25
|
+
settings;
|
|
26
|
+
startedAt;
|
|
27
|
+
constructor(options = {}) {
|
|
28
|
+
this.projectRoot = options.projectRoot ?? PROJECT_ROOT;
|
|
29
|
+
this.animactlScript = options.animactlScript ?? join(this.projectRoot, 'dist/server/cli/animactl.js');
|
|
30
|
+
this.commandPresent = options.commandPresent ?? commandPresent;
|
|
31
|
+
this.commit = Promise.resolve(options.commit ?? gitShortCommit(this.projectRoot));
|
|
32
|
+
this.now = options.now ?? (() => new Date());
|
|
33
|
+
this.packageVersion = options.packageVersion ?? (() => packageVersion(this.projectRoot));
|
|
34
|
+
this.restartDelayMs = options.restartDelayMs ?? RESTART_AFTER_RESPONSE_DELAY_MS;
|
|
35
|
+
this.settings = options.settings ?? defaultServerSettingsService;
|
|
36
|
+
this.startedAt = options.startedAt ?? this.now().toISOString();
|
|
37
|
+
}
|
|
38
|
+
async providerAvailability() {
|
|
39
|
+
return {
|
|
40
|
+
providers: await Promise.all(PROVIDER_CATALOG.map(async (entry) => ({
|
|
41
|
+
kind: entry.kind,
|
|
42
|
+
present: await this.commandPresent(entry.command),
|
|
43
|
+
}))),
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
async serverInfo() {
|
|
47
|
+
const animaHome = resolveAnimaHome();
|
|
48
|
+
const [config, version, commit, lastRestart] = await Promise.all([
|
|
49
|
+
this.settings.readConfig(),
|
|
50
|
+
this.packageVersion(),
|
|
51
|
+
this.commit,
|
|
52
|
+
readLastServicesRestart(animaHome),
|
|
53
|
+
]);
|
|
54
|
+
const track = config.track ?? config.releaseTrack ?? 'stable';
|
|
55
|
+
return {
|
|
56
|
+
animaHome,
|
|
57
|
+
...(commit ? { commit } : {}),
|
|
58
|
+
dashboardPort: config.dashboardPort ?? 4174,
|
|
59
|
+
docsUrl: docsUrl(track),
|
|
60
|
+
...(lastRestart ? { lastRestart } : {}),
|
|
61
|
+
ok: true,
|
|
62
|
+
startedAt: this.startedAt,
|
|
63
|
+
track,
|
|
64
|
+
uptimeSeconds: Math.max(0, Math.floor((this.now().getTime() - Date.parse(this.startedAt)) / 1000)),
|
|
65
|
+
version,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
serverStartedAt() {
|
|
69
|
+
return this.startedAt;
|
|
70
|
+
}
|
|
71
|
+
prepareServicesRestart() {
|
|
72
|
+
if (!existsSync(this.animactlScript)) {
|
|
73
|
+
throw new SystemServiceError(`animactl not found: ${this.animactlScript}`);
|
|
74
|
+
}
|
|
75
|
+
const animaHome = resolveAnimaHome();
|
|
76
|
+
const logPath = servicesRestartLogPath(animaHome);
|
|
77
|
+
const resultPath = servicesRestartResultPath(animaHome);
|
|
78
|
+
return {
|
|
79
|
+
response: {
|
|
80
|
+
ok: true,
|
|
81
|
+
animaHome,
|
|
82
|
+
delayMs: this.restartDelayMs,
|
|
83
|
+
logPath,
|
|
84
|
+
scheduled: true,
|
|
85
|
+
},
|
|
86
|
+
spawn: () => restartServicesDetached({
|
|
87
|
+
animaHome,
|
|
88
|
+
animactlScript: this.animactlScript,
|
|
89
|
+
logPath,
|
|
90
|
+
now: this.now,
|
|
91
|
+
projectRoot: this.projectRoot,
|
|
92
|
+
resultPath,
|
|
93
|
+
}),
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
export const defaultSystemService = new SystemService();
|
|
98
|
+
async function restartServicesDetached(input) {
|
|
99
|
+
let log;
|
|
100
|
+
try {
|
|
101
|
+
await mkdir(dirname(input.logPath), { recursive: true });
|
|
102
|
+
await rm(input.resultPath, { force: true });
|
|
103
|
+
log = await open(input.logPath, 'a');
|
|
104
|
+
await log.write(`\n[${input.now().toISOString()}] web app requested services restart\n`);
|
|
105
|
+
}
|
|
106
|
+
catch (error) {
|
|
107
|
+
console.error(`Failed to open restart log ${input.logPath}: ${error instanceof Error ? error.message : String(error)}`);
|
|
108
|
+
}
|
|
109
|
+
const child = spawn(process.execPath, [input.animactlScript, 'services', 'restart', '--drain-active', '--resume-running'], {
|
|
110
|
+
cwd: input.projectRoot,
|
|
111
|
+
detached: true,
|
|
112
|
+
env: { ...cleanServiceEnv(), ANIMA_HOME: input.animaHome, ANIMA_RESTART_RESULT_FILE: input.resultPath },
|
|
113
|
+
stdio: log ? ['ignore', log.fd, log.fd] : 'ignore',
|
|
114
|
+
});
|
|
115
|
+
child.on('error', (error) => {
|
|
116
|
+
console.error(`Failed to start services restart: ${error.message}`);
|
|
117
|
+
});
|
|
118
|
+
child.unref();
|
|
119
|
+
await log?.close();
|
|
120
|
+
}
|
|
121
|
+
async function packageVersion(projectRoot) {
|
|
122
|
+
try {
|
|
123
|
+
const pkg = JSON.parse(await readFile(join(projectRoot, 'package.json'), 'utf8'));
|
|
124
|
+
return typeof pkg.version === 'string' && pkg.version ? pkg.version : 'unknown';
|
|
125
|
+
}
|
|
126
|
+
catch {
|
|
127
|
+
return 'unknown';
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
async function gitShortCommit(projectRoot) {
|
|
131
|
+
try {
|
|
132
|
+
const { stdout } = await execFileAsync('git', ['rev-parse', '--short', 'HEAD'], { cwd: projectRoot });
|
|
133
|
+
return stdout.trim() || undefined;
|
|
134
|
+
}
|
|
135
|
+
catch {
|
|
136
|
+
return undefined;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
export function docsUrl(track) {
|
|
140
|
+
const configured = process.env.ANIMA_DOCS_URL?.trim();
|
|
141
|
+
if (configured)
|
|
142
|
+
return configured;
|
|
143
|
+
if (track === 'dev')
|
|
144
|
+
return 'http://127.0.0.1:14175/';
|
|
145
|
+
return 'https://anima.meetquinn.ai/';
|
|
146
|
+
}
|
|
147
|
+
function commandPresent(command) {
|
|
148
|
+
return new Promise((resolvePresent) => {
|
|
149
|
+
const child = execFile(command, ['--version'], { encoding: 'utf8', timeout: 2_000 }, (error) => {
|
|
150
|
+
resolvePresent(!error);
|
|
151
|
+
});
|
|
152
|
+
child.stdin?.end();
|
|
153
|
+
});
|
|
154
|
+
}
|