@aitne/daemon 0.1.10 → 0.1.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapters/adapter-watchdog.d.ts +70 -0
- package/dist/adapters/adapter-watchdog.js +115 -0
- package/dist/adapters/discord.d.ts +17 -1
- package/dist/adapters/discord.js +33 -0
- package/dist/adapters/notification-manager.d.ts +27 -1
- package/dist/adapters/notification-manager.js +54 -39
- package/dist/adapters/slack-adapter.d.ts +26 -1
- package/dist/adapters/slack-adapter.js +41 -0
- package/dist/adapters/telegram-adapter.d.ts +18 -1
- package/dist/adapters/telegram-adapter.js +41 -2
- package/dist/adapters/types.d.ts +20 -0
- package/dist/adapters/whatsapp-adapter.d.ts +26 -7
- package/dist/adapters/whatsapp-adapter.js +74 -21
- package/dist/api/env-writer.js +8 -5
- package/dist/api/helpers/agent-errors-registry.d.ts +5 -5
- package/dist/api/helpers/agent-errors-registry.js +5 -5
- package/dist/api/routes/agent.js +33 -12
- package/dist/api/routes/agents/index.js +75 -16
- package/dist/api/routes/agents/views.d.ts +37 -2
- package/dist/api/routes/agents/views.js +64 -2
- package/dist/api/routes/background-task.d.ts +22 -0
- package/dist/api/routes/background-task.js +338 -0
- package/dist/api/routes/browser-history.js +9 -1
- package/dist/api/routes/context/permissions.js +3 -2
- package/dist/api/routes/context/snapshots.js +0 -3
- package/dist/api/routes/context/write.js +3 -17
- package/dist/api/routes/dashboard/config.js +48 -12
- package/dist/api/routes/dashboard/cost-approvals.js +66 -0
- package/dist/api/routes/dashboard/notifications.js +9 -9
- package/dist/api/routes/integrations/crud-patch.js +5 -1
- package/dist/api/routes/integrations-reconcile.js +2 -2
- package/dist/api/routes/notion.d.ts +1 -1
- package/dist/api/routes/observations.js +7 -7
- package/dist/api/routes/obsidian.d.ts +1 -1
- package/dist/api/routes/receipts.js +5 -1
- package/dist/api/routes/setup-migrate.js +1 -1
- package/dist/api/routes/setup.js +1 -1
- package/dist/api/routes/task-flows.d.ts +1 -1
- package/dist/api/routes/task-flows.js +1 -1
- package/dist/api/routes/tuning.d.ts +29 -0
- package/dist/api/routes/tuning.js +304 -0
- package/dist/api/server.d.ts +44 -16
- package/dist/api/server.js +9 -0
- package/dist/bootstrap/adapters.d.ts +19 -0
- package/dist/bootstrap/adapters.js +61 -0
- package/dist/bootstrap/api.d.ts +5 -3
- package/dist/bootstrap/api.js +45 -13
- package/dist/bootstrap/catchup.d.ts +1 -1
- package/dist/bootstrap/catchup.js +11 -11
- package/dist/bootstrap/event-pipeline.d.ts +11 -0
- package/dist/bootstrap/event-pipeline.js +245 -7
- package/dist/bootstrap/observers.js +9 -6
- package/dist/bootstrap/schedule-helpers.d.ts +104 -6
- package/dist/bootstrap/schedule-helpers.js +172 -19
- package/dist/config.js +26 -12
- package/dist/core/agent-core.d.ts +33 -1
- package/dist/core/agent-core.js +36 -1
- package/dist/core/agents/activity-scan-cadence.d.ts +103 -0
- package/dist/core/agents/activity-scan-cadence.js +127 -0
- package/dist/core/agents/agent-route-override.d.ts +53 -0
- package/dist/core/agents/agent-route-override.js +69 -0
- package/dist/core/agents/builtin-registry.d.ts +51 -14
- package/dist/core/agents/builtin-registry.js +92 -15
- package/dist/core/agents/config-gate-reconcile.d.ts +38 -0
- package/dist/core/agents/config-gate-reconcile.js +51 -0
- package/dist/core/agents/cron-substitute.d.ts +1 -1
- package/dist/core/agents/cron-substitute.js +1 -1
- package/dist/core/agents/custom-routine-migration.d.ts +60 -0
- package/dist/core/agents/custom-routine-migration.js +149 -0
- package/dist/core/agents/firing-blocked.d.ts +1 -1
- package/dist/core/agents/hourly-cadence.d.ts +102 -0
- package/dist/core/agents/hourly-cadence.js +126 -0
- package/dist/core/agents/loader-boot.js +23 -0
- package/dist/core/agents/loader.d.ts +19 -0
- package/dist/core/agents/loader.js +34 -2
- package/dist/core/agents/override-merge.d.ts +1 -1
- package/dist/core/agents/override-merge.js +9 -1
- package/dist/core/agents/recurrence-convert.d.ts +1 -1
- package/dist/core/agents/recurrence-convert.js +1 -1
- package/dist/core/agents/recurring-schedule-adapter.js +8 -0
- package/dist/core/alerts.js +6 -6
- package/dist/core/backends/auth-health-monitor.d.ts +2 -2
- package/dist/core/backends/auth-health-monitor.js +1 -1
- package/dist/core/backends/backend-router.d.ts +27 -1
- package/dist/core/backends/backend-router.js +165 -1
- package/dist/core/backends/claude-code-core.d.ts +71 -31
- package/dist/core/backends/claude-code-core.js +282 -54
- package/dist/core/backends/cli-quota-guards.d.ts +29 -1
- package/dist/core/backends/cli-quota-guards.js +40 -5
- package/dist/core/backends/codex-core.d.ts +6 -0
- package/dist/core/backends/codex-core.js +22 -6
- package/dist/core/backends/failure-spend.d.ts +58 -0
- package/dist/core/backends/failure-spend.js +137 -0
- package/dist/core/backends/gemini-cli-core.d.ts +6 -0
- package/dist/core/backends/gemini-cli-core.js +25 -6
- package/dist/core/backends/model-registry.d.ts +1 -1
- package/dist/core/backends/model-registry.js +4 -4
- package/dist/core/backends/opencode-core.d.ts +1 -1
- package/dist/core/backends/opencode-core.js +5 -5
- package/dist/core/backends/plan-presets.js +39 -15
- package/dist/core/bang-commands/commands-cost.js +3 -1
- package/dist/core/bang-commands/commands-report.js +4 -3
- package/dist/core/bang-commands/commands-research.js +4 -1
- package/dist/core/bang-commands/commands-revert-tuning.d.ts +18 -0
- package/dist/core/bang-commands/commands-revert-tuning.js +63 -0
- package/dist/core/bang-commands/commands-stop-start.js +3 -3
- package/dist/core/bang-commands/commands-task-control.d.ts +19 -0
- package/dist/core/bang-commands/commands-task-control.js +147 -0
- package/dist/core/bang-commands/commands-wiki.js +5 -5
- package/dist/core/bang-commands/index.d.ts +2 -0
- package/dist/core/bang-commands/index.js +12 -0
- package/dist/core/bang-commands/registry.d.ts +12 -0
- package/dist/core/browser-history/research-cluster-fanout.d.ts +28 -14
- package/dist/core/browser-history/research-cluster-fanout.js +39 -16
- package/dist/core/channel-timeline.d.ts +5 -1
- package/dist/core/channel-timeline.js +13 -0
- package/dist/core/context/index-reconciler.js +5 -2
- package/dist/core/context/policy-index-reconciler.d.ts +6 -4
- package/dist/core/context/policy-index-runner.js +25 -6
- package/dist/core/context-builder-calendar.js +10 -2
- package/dist/core/context-builder-conversation.d.ts +8 -1
- package/dist/core/context-builder-conversation.js +41 -7
- package/dist/core/context-builder-yesterday.js +4 -3
- package/dist/core/context-builder.d.ts +7 -2
- package/dist/core/context-builder.js +62 -20
- package/dist/core/context-file-serializer.d.ts +1 -1
- package/dist/core/context-file-serializer.js +1 -1
- package/dist/core/context-health.js +2 -2
- package/dist/core/context-paths.d.ts +1 -1
- package/dist/core/context-paths.js +1 -1
- package/dist/core/context-validation/prepare-write.js +1 -1
- package/dist/core/context-validation/routine-rulebook.d.ts +1 -1
- package/dist/core/context-vault-aliases.d.ts +0 -13
- package/dist/core/context-vault-aliases.js +37 -0
- package/dist/core/custom-routines.d.ts +99 -0
- package/dist/core/custom-routines.js +187 -0
- package/dist/core/daemon-api-cli.js +49 -0
- package/dist/core/day-boundary.d.ts +46 -0
- package/dist/core/day-boundary.js +40 -0
- package/dist/core/dispatcher-activity-scan.d.ts +221 -0
- package/dist/core/dispatcher-activity-scan.js +775 -0
- package/dist/core/dispatcher-error-handling.d.ts +6 -11
- package/dist/core/dispatcher-error-handling.js +38 -62
- package/dist/core/dispatcher-hourly-check.js +6 -1
- package/dist/core/dispatcher-message-handler.d.ts +10 -0
- package/dist/core/dispatcher-message-handler.js +17 -0
- package/dist/core/dispatcher-morning-routine.d.ts +6 -6
- package/dist/core/dispatcher-morning-routine.js +13 -13
- package/dist/core/dispatcher-result-processor.d.ts +33 -0
- package/dist/core/dispatcher-result-processor.js +167 -11
- package/dist/core/dispatcher-scheduled-background-task.d.ts +42 -0
- package/dist/core/dispatcher-scheduled-background-task.js +89 -0
- package/dist/core/dispatcher-scheduled-tasks.d.ts +63 -1
- package/dist/core/dispatcher-scheduled-tasks.js +213 -6
- package/dist/core/dispatcher-task-delivery.d.ts +105 -0
- package/dist/core/dispatcher-task-delivery.js +555 -0
- package/dist/core/dispatcher-types.d.ts +48 -9
- package/dist/core/dispatcher-types.js +3 -3
- package/dist/core/dispatcher.d.ts +112 -31
- package/dist/core/dispatcher.js +284 -59
- package/dist/core/dm-freshness-metrics.d.ts +1 -1
- package/dist/core/drift-effects.js +2 -2
- package/dist/core/feedback/consolidation-prep.js +17 -5
- package/dist/core/feedback/eviction-scorer.js +6 -2
- package/dist/core/feedback/lesson-format.js +9 -4
- package/dist/core/feedback/lesson-injection.d.ts +1 -1
- package/dist/core/feedback/lesson-injection.js +17 -2
- package/dist/core/feedback/lesson-store-overview.d.ts +8 -4
- package/dist/core/feedback/lesson-store-overview.js +8 -4
- package/dist/core/feedback/regeneralization-prep.js +29 -16
- package/dist/core/feedback/self-performance-prep.d.ts +186 -0
- package/dist/core/feedback/self-performance-prep.js +541 -0
- package/dist/core/feedback/tuning-actuator.d.ts +198 -0
- package/dist/core/feedback/tuning-actuator.js +432 -0
- package/dist/core/feedback/tuning-recommender.d.ts +247 -0
- package/dist/core/feedback/tuning-recommender.js +580 -0
- package/dist/core/feedback/tuning-revert-monitor.d.ts +90 -0
- package/dist/core/feedback/tuning-revert-monitor.js +213 -0
- package/dist/core/health-monitor.d.ts +6 -0
- package/dist/core/health-monitor.js +1 -1
- package/dist/core/injection-policy.d.ts +4 -4
- package/dist/core/injection-policy.js +4 -4
- package/dist/core/integration-main-backend.js +4 -0
- package/dist/core/management-md.d.ts +2 -2
- package/dist/core/management-md.js +51 -13
- package/dist/core/morning/orchestrator.d.ts +2 -2
- package/dist/core/morning/orchestrator.js +2 -2
- package/dist/core/notification-gate.d.ts +64 -0
- package/dist/core/notification-gate.js +51 -0
- package/dist/core/notification-rate-limit.d.ts +40 -0
- package/dist/core/notification-rate-limit.js +50 -0
- package/dist/core/policy-files.d.ts +1 -1
- package/dist/core/policy-files.js +2 -2
- package/dist/core/pre-pass-freshness.d.ts +4 -4
- package/dist/core/retention.d.ts +5 -0
- package/dist/core/retention.js +20 -4
- package/dist/core/review-context.d.ts +1 -1
- package/dist/core/review-context.js +10 -5
- package/dist/core/roadmap-write-lock.d.ts +2 -1
- package/dist/core/roadmap-write-lock.js +15 -10
- package/dist/core/routine-acquisition-plan.d.ts +47 -1
- package/dist/core/routine-acquisition-plan.js +78 -20
- package/dist/core/routine-fetch-window-retry.js +7 -4
- package/dist/core/routine-fetch-window-runner.d.ts +39 -3
- package/dist/core/routine-fetch-window-runner.js +264 -13
- package/dist/core/routine-windows.d.ts +2 -2
- package/dist/core/routine-windows.js +8 -5
- package/dist/core/scheduler.d.ts +175 -16
- package/dist/core/scheduler.js +559 -102
- package/dist/core/signal-detector.d.ts +12 -0
- package/dist/core/signal-detector.js +53 -9
- package/dist/core/skills-compiler-denied-tools.js +2 -2
- package/dist/core/skills-compiler-skill-index.d.ts +2 -2
- package/dist/core/skills-compiler-skill-index.js +2 -2
- package/dist/core/skills-compiler-variants.d.ts +1 -1
- package/dist/core/skills-compiler-variants.js +8 -0
- package/dist/core/skills-compiler.d.ts +29 -26
- package/dist/core/skills-compiler.js +117 -81
- package/dist/core/skills-manifest.d.ts +37 -0
- package/dist/core/skills-manifest.js +73 -2
- package/dist/core/sleep-inhibitor.d.ts +79 -0
- package/dist/core/sleep-inhibitor.js +132 -0
- package/dist/core/slim-system-prompt-loader.d.ts +77 -0
- package/dist/core/slim-system-prompt-loader.js +141 -0
- package/dist/core/spawn-gates.d.ts +126 -0
- package/dist/core/spawn-gates.js +180 -0
- package/dist/core/today-direct-writer.d.ts +2 -2
- package/dist/core/today-direct-writer.js +1 -1
- package/dist/core/today-write-lock.d.ts +4 -2
- package/dist/core/today-write-lock.js +30 -20
- package/dist/core/wake-detector.d.ts +55 -0
- package/dist/core/wake-detector.js +80 -0
- package/dist/core/wiki/compile-lock.d.ts +1 -1
- package/dist/core/wiki/compile-lock.js +1 -1
- package/dist/core/workdir.js +15 -6
- package/dist/db/activity-scan-signals.d.ts +77 -0
- package/dist/db/activity-scan-signals.js +378 -0
- package/dist/db/agents-store.d.ts +28 -0
- package/dist/db/agents-store.js +62 -0
- package/dist/db/background-task-clarifications-store.d.ts +81 -0
- package/dist/db/background-task-clarifications-store.js +152 -0
- package/dist/db/background-task-store.d.ts +207 -0
- package/dist/db/background-task-store.js +380 -0
- package/dist/db/browser-history-store.d.ts +39 -6
- package/dist/db/browser-history-store.js +51 -7
- package/dist/db/browser-task-clarifications-store.d.ts +12 -0
- package/dist/db/browser-task-clarifications-store.js +35 -5
- package/dist/db/browser-task-store.d.ts +3 -0
- package/dist/db/browser-task-store.js +29 -4
- package/dist/db/deferred-dm.d.ts +86 -0
- package/dist/db/deferred-dm.js +199 -0
- package/dist/db/migrations.js +330 -0
- package/dist/db/observations.d.ts +2 -2
- package/dist/db/observations.js +3 -3
- package/dist/db/schema.js +217 -16
- package/dist/db/voice-transcripts-store.d.ts +1 -1
- package/dist/index.js +86 -29
- package/dist/messaging/browser-task-mcp-notifier.d.ts +12 -70
- package/dist/messaging/browser-task-mcp-notifier.js +30 -151
- package/dist/messaging/browser-task-screenshot-attachment.d.ts +15 -0
- package/dist/messaging/browser-task-screenshot-attachment.js +63 -0
- package/dist/observers/delegated-sync-worker.d.ts +6 -6
- package/dist/observers/delegated-sync-worker.js +10 -10
- package/dist/observers/git-delegated-cron.d.ts +1 -1
- package/dist/observers/git-delegated-cron.js +2 -2
- package/dist/observers/github-poller-classifier.d.ts +3 -3
- package/dist/observers/github-poller-classifier.js +3 -3
- package/dist/observers/imminent-event-scheduler.d.ts +1 -1
- package/dist/observers/imminent-event-scheduler.js +1 -1
- package/dist/observers/mail-poller.d.ts +1 -0
- package/dist/observers/mail-poller.js +42 -3
- package/dist/observers/observation-summarizer/summarizer-client.d.ts +2 -2
- package/dist/observers/observation-summarizer/summarizer-client.js +2 -2
- package/dist/observers/observation-summarizer/worker.d.ts +2 -2
- package/dist/observers/observation-summarizer/worker.js +4 -4
- package/dist/observers/obsidian-watcher.d.ts +1 -1
- package/dist/observers/obsidian-watcher.js +1 -1
- package/dist/safety/agent-write-tracker.d.ts +4 -4
- package/dist/safety/agent-write-tracker.js +4 -4
- package/dist/safety/audit.d.ts +43 -5
- package/dist/safety/audit.js +86 -18
- package/dist/safety/risk-classifier.d.ts +6 -0
- package/dist/safety/risk-classifier.js +75 -11
- package/dist/scheduler/activity-scan-gate.d.ts +86 -0
- package/dist/scheduler/activity-scan-gate.js +132 -0
- package/dist/services/background-task/background-task-budget.d.ts +80 -0
- package/dist/services/background-task/background-task-budget.js +91 -0
- package/dist/services/background-task/background-task-driver.d.ts +105 -0
- package/dist/services/background-task/background-task-driver.js +416 -0
- package/dist/services/background-task/background-task-runner.d.ts +96 -0
- package/dist/services/background-task/background-task-runner.js +673 -0
- package/dist/services/background-task/background-task-tools.d.ts +84 -0
- package/dist/services/background-task/background-task-tools.js +247 -0
- package/dist/services/background-task/background-task-transition-events.d.ts +43 -0
- package/dist/services/background-task/background-task-transition-events.js +54 -0
- package/dist/services/browser-history/automation/egress-denylist.d.ts +1 -1
- package/dist/services/browser-history/automation/egress-denylist.js +16 -6
- package/dist/services/browser-history/managed-chromium/sandbox-launcher.js +0 -1
- package/dist/services/browser-task/browser-task-runner.js +53 -8
- package/dist/services/observations-batch.d.ts +1 -1
- package/dist/services/observations-batch.js +2 -2
- package/dist/settings/runtime-settings.d.ts +38 -11
- package/dist/settings/runtime-settings.js +203 -40
- package/dist/settings/settings-store.js +11 -3
- package/package.json +4 -4
|
@@ -113,18 +113,13 @@ export declare class DispatcherErrorRouter {
|
|
|
113
113
|
*/
|
|
114
114
|
notifyDashboardError(event: Event, message: string): void;
|
|
115
115
|
/**
|
|
116
|
-
*
|
|
117
|
-
*
|
|
118
|
-
*
|
|
119
|
-
*
|
|
120
|
-
*
|
|
121
|
-
* the size of every budget-rejected turn (in this repo it was a $2.26
|
|
122
|
-
* morning_routine that left the daily total at $0).
|
|
123
|
-
*
|
|
124
|
-
* Best-effort: a logging failure must not mask the original quota error
|
|
125
|
-
* — we catch and warn instead of rethrowing.
|
|
116
|
+
* The distinct per-backend failures hiding behind a thrown error.
|
|
117
|
+
* `BackendRouterHandledError` carries up to two (main + fallback —
|
|
118
|
+
* both may have billed before failing); any other error is its own
|
|
119
|
+
* single entry. Identity-deduped because `cause` usually aliases one
|
|
120
|
+
* of `mainFailure` / `fallbackFailure`.
|
|
126
121
|
*/
|
|
127
|
-
private
|
|
122
|
+
private collectSpendFailures;
|
|
128
123
|
extractQuotaError(error: unknown): BackendQuotaError | null;
|
|
129
124
|
formatQuotaMessage(quotaError: BackendQuotaError): string;
|
|
130
125
|
formatBackendLabel(backendId: BackendQuotaError["backendId"]): string;
|
|
@@ -41,6 +41,7 @@
|
|
|
41
41
|
import { isMessageEvent, isScheduledEvent } from "@aitne/shared";
|
|
42
42
|
import { BackendDecisiveFailure, BackendQuotaError, } from "./agent-core.js";
|
|
43
43
|
import { BackendRouterHandledError } from "./backends/backend-router.js";
|
|
44
|
+
import { extractFailureSpendInfo, recordFailureSpendRow, } from "./backends/failure-spend.js";
|
|
44
45
|
import { consultDelegatedConnectorHealth, markSignoutWarned, renderSignoutDm, } from "./delegated-connector-health.js";
|
|
45
46
|
import { compareLocalDateParts, getLocalDateParts, localDateTimeToUtcMs, } from "./dispatcher-date-utils.js";
|
|
46
47
|
import { createLogger } from "../logging.js";
|
|
@@ -137,16 +138,27 @@ export class DispatcherErrorRouter {
|
|
|
137
138
|
}
|
|
138
139
|
async handleError(event, error) {
|
|
139
140
|
logger.error({ event: event.type, error: error.message }, "Event processing error");
|
|
140
|
-
// Cost visibility for
|
|
141
|
-
//
|
|
142
|
-
//
|
|
143
|
-
// a
|
|
144
|
-
//
|
|
145
|
-
//
|
|
146
|
-
//
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
141
|
+
// Cost visibility for failed turns that already billed the provider —
|
|
142
|
+
// post-hoc budget rejections (Codex / Gemini run the turn to
|
|
143
|
+
// completion before the cap can reject; Claude's SDK aborts mid-
|
|
144
|
+
// stream with a partial-usage snapshot stamped by the core) and
|
|
145
|
+
// non-quota terminal errors that carried usage (auth-mid-run,
|
|
146
|
+
// timeout, transport failure). Write a `result='failed'`
|
|
147
|
+
// agent_actions row per distinct backend failure so the dashboard's
|
|
148
|
+
// cost dials reflect reality. Without this the success-only audit
|
|
149
|
+
// path (`logAction` in ResultProcessor) silently drops the spend.
|
|
150
|
+
// PREPASS_COST_REDUCTION_PLAN.md N1.
|
|
151
|
+
//
|
|
152
|
+
// `BackendRouterHandledError` is unwrapped into its per-backend
|
|
153
|
+
// failures (main + fallback can BOTH have billed); a raw failover
|
|
154
|
+
// signal is recorded as-is. Pre-N1 this looked only at the top-level
|
|
155
|
+
// error, so a no-fallback quota kill — which the router wraps —
|
|
156
|
+
// recorded nothing.
|
|
157
|
+
for (const failure of this.collectSpendFailures(error)) {
|
|
158
|
+
const spendInfo = extractFailureSpendInfo(failure);
|
|
159
|
+
if (spendInfo) {
|
|
160
|
+
recordFailureSpendRow(this.db, event, spendInfo, error.message);
|
|
161
|
+
}
|
|
150
162
|
}
|
|
151
163
|
// Defense-in-depth cleanup of the notify-dedup marker — processResult
|
|
152
164
|
// is the primary collection point, but if execution threw before
|
|
@@ -208,60 +220,24 @@ export class DispatcherErrorRouter {
|
|
|
208
220
|
this.getDashboardStream()?.sendError?.(event.channel, message);
|
|
209
221
|
}
|
|
210
222
|
/**
|
|
211
|
-
*
|
|
212
|
-
*
|
|
213
|
-
*
|
|
214
|
-
*
|
|
215
|
-
*
|
|
216
|
-
* the size of every budget-rejected turn (in this repo it was a $2.26
|
|
217
|
-
* morning_routine that left the daily total at $0).
|
|
218
|
-
*
|
|
219
|
-
* Best-effort: a logging failure must not mask the original quota error
|
|
220
|
-
* — we catch and warn instead of rethrowing.
|
|
223
|
+
* The distinct per-backend failures hiding behind a thrown error.
|
|
224
|
+
* `BackendRouterHandledError` carries up to two (main + fallback —
|
|
225
|
+
* both may have billed before failing); any other error is its own
|
|
226
|
+
* single entry. Identity-deduped because `cause` usually aliases one
|
|
227
|
+
* of `mainFailure` / `fallbackFailure`.
|
|
221
228
|
*/
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
"tokens_input",
|
|
233
|
-
"tokens_output",
|
|
234
|
-
"duration_ms",
|
|
235
|
-
"num_turns",
|
|
236
|
-
"result",
|
|
237
|
-
"backend",
|
|
238
|
-
"cost_source",
|
|
239
|
-
"error",
|
|
240
|
-
"completed_at",
|
|
241
|
-
];
|
|
242
|
-
const placeholders = columns.map(() => "?").join(", ");
|
|
243
|
-
const values = [
|
|
244
|
-
event.correlationId,
|
|
245
|
-
event.type,
|
|
246
|
-
spend.modelId,
|
|
247
|
-
spend.costUsd,
|
|
248
|
-
spend.usage.inputTokens,
|
|
249
|
-
spend.usage.outputTokens,
|
|
250
|
-
spend.durationMs,
|
|
251
|
-
spend.numTurns,
|
|
252
|
-
"failed",
|
|
253
|
-
quotaError.backendId,
|
|
254
|
-
spend.costSource ?? null,
|
|
255
|
-
errorMessage.slice(0, 4096),
|
|
256
|
-
new Date().toISOString(),
|
|
257
|
-
];
|
|
258
|
-
this.db
|
|
259
|
-
.prepare(`INSERT INTO agent_actions (${columns.join(", ")}) VALUES (${placeholders})`)
|
|
260
|
-
.run(...values);
|
|
261
|
-
}
|
|
262
|
-
catch (err) {
|
|
263
|
-
logger.warn({ err, eventType: event.type, backendId: quotaError.backendId }, "Failed to record post-hoc budget spend in agent_actions");
|
|
229
|
+
collectSpendFailures(error) {
|
|
230
|
+
if (error instanceof BackendRouterHandledError) {
|
|
231
|
+
const failures = [error.mainFailure];
|
|
232
|
+
if (error.fallbackFailure && error.fallbackFailure !== error.mainFailure) {
|
|
233
|
+
failures.push(error.fallbackFailure);
|
|
234
|
+
}
|
|
235
|
+
if (error.cause && !failures.includes(error.cause)) {
|
|
236
|
+
failures.push(error.cause);
|
|
237
|
+
}
|
|
238
|
+
return failures;
|
|
264
239
|
}
|
|
240
|
+
return [error];
|
|
265
241
|
}
|
|
266
242
|
extractQuotaError(error) {
|
|
267
243
|
if (error instanceof BackendQuotaError) {
|
|
@@ -62,6 +62,8 @@ import { parseStage2Verdict } from "./dispatcher-types.js";
|
|
|
62
62
|
import { morningRoutineRanToday } from "../bootstrap/schedule-helpers.js";
|
|
63
63
|
import { prePassLastRunRuntimeStateKey } from "./pre-pass-freshness.js";
|
|
64
64
|
import { readRuntimeState } from "../db/runtime-state.js";
|
|
65
|
+
import { getRuntimeWindow } from "../db/agents-store.js";
|
|
66
|
+
import { resolveHourlyCadence } from "./agents/hourly-cadence.js";
|
|
65
67
|
import { createLogger } from "../logging.js";
|
|
66
68
|
const logger = createLogger("dispatcher-hourly-check");
|
|
67
69
|
export class HourlyCheckCoordinator {
|
|
@@ -99,7 +101,10 @@ export class HourlyCheckCoordinator {
|
|
|
99
101
|
}
|
|
100
102
|
async trigger(source, options = {}) {
|
|
101
103
|
const forced = options.force === true;
|
|
102
|
-
|
|
104
|
+
// Observation threshold comes from the hourly-check agent row's
|
|
105
|
+
// runtime_window, with the legacy `hourlyCheckMinObservations` config key
|
|
106
|
+
// as fallback (AGENTS_HUB_REDESIGN_PLAN.md §2).
|
|
107
|
+
const minObservations = resolveHourlyCadence(getRuntimeWindow(this.db, "hourly-check"), this.config).minObservations;
|
|
103
108
|
// C1 fix: atomic check-and-set on hourlyCheckInProgress BEFORE any await
|
|
104
109
|
// boundary. Previously `await this.isMorningRoutineActive()` yielded to
|
|
105
110
|
// the microtask queue, allowing cron + /api/agent/run-now arriving in
|
|
@@ -110,6 +110,14 @@ export interface MessageHandlerDeps {
|
|
|
110
110
|
* either kind on the affected channel.
|
|
111
111
|
*/
|
|
112
112
|
getFinalConfirmHandler?: () => import("../services/browser-history/automation/final-confirm-handler.js").FinalConfirmHandler | null;
|
|
113
|
+
/**
|
|
114
|
+
* BACKGROUND_TASK_RUNNER_DESIGN.md Phase 4 — lazily-injected runner
|
|
115
|
+
* accessors for the per-task `!stop <id>` bang command. Null in tests
|
|
116
|
+
* and before the runners are wired at startup; the `!stop` handler tells
|
|
117
|
+
* the owner the runner is unavailable rather than dropping the request.
|
|
118
|
+
*/
|
|
119
|
+
getBackgroundTaskRunner?: () => import("../services/background-task/background-task-runner.js").BackgroundTaskRunner | null;
|
|
120
|
+
getBrowserTaskRunner?: () => import("../services/browser-task/browser-task-runner.js").BrowserTaskRunner | null;
|
|
113
121
|
/** Live getter for the dispatcher's `currentSetupMode` flag. */
|
|
114
122
|
getCurrentSetupMode: () => SetupMode | null;
|
|
115
123
|
/** Forward into the dispatcher's `beginSetupMode` so persistence stays
|
|
@@ -147,6 +155,8 @@ export declare class MessageHandler {
|
|
|
147
155
|
private readonly getBangCommandRegistry;
|
|
148
156
|
private readonly getPurchaseHandler;
|
|
149
157
|
private readonly getFinalConfirmHandler;
|
|
158
|
+
private readonly getBackgroundTaskRunner;
|
|
159
|
+
private readonly getBrowserTaskRunner;
|
|
150
160
|
private readonly getCurrentSetupMode;
|
|
151
161
|
private readonly beginSetupMode;
|
|
152
162
|
private readonly lookupCustomBangCommandForEvent;
|
|
@@ -81,6 +81,8 @@ export class MessageHandler {
|
|
|
81
81
|
getBangCommandRegistry;
|
|
82
82
|
getPurchaseHandler;
|
|
83
83
|
getFinalConfirmHandler;
|
|
84
|
+
getBackgroundTaskRunner;
|
|
85
|
+
getBrowserTaskRunner;
|
|
84
86
|
getCurrentSetupMode;
|
|
85
87
|
beginSetupMode;
|
|
86
88
|
lookupCustomBangCommandForEvent;
|
|
@@ -116,6 +118,10 @@ export class MessageHandler {
|
|
|
116
118
|
this.getPurchaseHandler = deps.getPurchaseHandler ?? (() => null);
|
|
117
119
|
this.getFinalConfirmHandler =
|
|
118
120
|
deps.getFinalConfirmHandler ?? (() => null);
|
|
121
|
+
this.getBackgroundTaskRunner =
|
|
122
|
+
deps.getBackgroundTaskRunner ?? (() => null);
|
|
123
|
+
this.getBrowserTaskRunner =
|
|
124
|
+
deps.getBrowserTaskRunner ?? (() => null);
|
|
119
125
|
this.getCurrentSetupMode = deps.getCurrentSetupMode;
|
|
120
126
|
this.beginSetupMode = deps.beginSetupMode;
|
|
121
127
|
this.lookupCustomBangCommandForEvent = deps.lookupCustomBangCommandForEvent;
|
|
@@ -492,6 +498,17 @@ export class MessageHandler {
|
|
|
492
498
|
enqueueBrowserResearchEvent: async (researchEvent) => {
|
|
493
499
|
await this.eventBus.put(researchEvent);
|
|
494
500
|
},
|
|
501
|
+
// Per-task `!stop <id>` — abort one detached worker. Resolved
|
|
502
|
+
// lazily from the live runner instances (which hold the in-memory
|
|
503
|
+
// handles the abort must reach); null until the runners are wired.
|
|
504
|
+
cancelBackgroundTask: async (taskId, reason) => {
|
|
505
|
+
const runner = this.getBackgroundTaskRunner();
|
|
506
|
+
return runner ? runner.cancel(taskId, reason) : false;
|
|
507
|
+
},
|
|
508
|
+
cancelBrowserTask: async (taskId, reason) => {
|
|
509
|
+
const runner = this.getBrowserTaskRunner();
|
|
510
|
+
return runner ? runner.cancel(taskId, reason) : false;
|
|
511
|
+
},
|
|
495
512
|
enqueueWikiApproval: async (approvalInput) => {
|
|
496
513
|
// WIKI_BUILDER_DESIGN.md §5.5 / §P2.E — escalate to Approve tier
|
|
497
514
|
// via the existing agent_schedule approval queue. The dashboard
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
* and bridges into a handful of dispatcher / coordinator methods that
|
|
27
27
|
* are still owned elsewhere (`rotateDayFiles`,
|
|
28
28
|
* `diagnoseTodayMdState`, `isRoadmapStale`, `emitRoadmapRefresh`,
|
|
29
|
-
* `
|
|
29
|
+
* `triggerActivityScan`).
|
|
30
30
|
*
|
|
31
31
|
* Dispatcher entry points served:
|
|
32
32
|
* - `EventDispatcher.dispatch` routes `routine === "morning_routine"`
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
* Shared-state references held:
|
|
39
39
|
* - `setMorningRoutineInProgress` — setter callback. The flag is
|
|
40
40
|
* flipped to true at the start of the execute → executeWithRetry
|
|
41
|
-
* wrapper and reset in `finally` so the
|
|
41
|
+
* wrapper and reset in `finally` so the activity scan can resume.
|
|
42
42
|
*/
|
|
43
43
|
import type Database from "better-sqlite3";
|
|
44
44
|
import type { Event } from "@aitne/shared";
|
|
@@ -104,10 +104,10 @@ export interface MorningRoutineRunnerDeps {
|
|
|
104
104
|
/** Bridges into the dispatcher's roadmap-refresh emit. */
|
|
105
105
|
emitRoadmapRefresh: (source: string) => void;
|
|
106
106
|
/**
|
|
107
|
-
* Bridges into `EventDispatcher.
|
|
108
|
-
* post-morning
|
|
107
|
+
* Bridges into `EventDispatcher.triggerActivityScan` so the deferred
|
|
108
|
+
* post-morning activity_scan can fire from `emitPostMorningCatchups`.
|
|
109
109
|
*/
|
|
110
|
-
|
|
110
|
+
triggerActivityScan: (source: string) => Promise<unknown>;
|
|
111
111
|
/**
|
|
112
112
|
* morning-routine-optimization.md Phase 5/6/7 — the split-stage
|
|
113
113
|
* pipeline orchestrator owns Stage A (today.md) + Stage B (daily
|
|
@@ -131,7 +131,7 @@ export declare class MorningRoutineRunner {
|
|
|
131
131
|
private readonly diagnoseTodayMdState;
|
|
132
132
|
private readonly isRoadmapStale;
|
|
133
133
|
private readonly emitRoadmapRefresh;
|
|
134
|
-
private readonly
|
|
134
|
+
private readonly triggerActivityScan;
|
|
135
135
|
private readonly pipelineOrchestrator;
|
|
136
136
|
constructor(deps: MorningRoutineRunnerDeps);
|
|
137
137
|
/**
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
* and bridges into a handful of dispatcher / coordinator methods that
|
|
27
27
|
* are still owned elsewhere (`rotateDayFiles`,
|
|
28
28
|
* `diagnoseTodayMdState`, `isRoadmapStale`, `emitRoadmapRefresh`,
|
|
29
|
-
* `
|
|
29
|
+
* `triggerActivityScan`).
|
|
30
30
|
*
|
|
31
31
|
* Dispatcher entry points served:
|
|
32
32
|
* - `EventDispatcher.dispatch` routes `routine === "morning_routine"`
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
* Shared-state references held:
|
|
39
39
|
* - `setMorningRoutineInProgress` — setter callback. The flag is
|
|
40
40
|
* flipped to true at the start of the execute → executeWithRetry
|
|
41
|
-
* wrapper and reset in `finally` so the
|
|
41
|
+
* wrapper and reset in `finally` so the activity scan can resume.
|
|
42
42
|
*/
|
|
43
43
|
import { EventPriority, createEvent, formatSqliteDatetime, } from "@aitne/shared";
|
|
44
44
|
import { flushPendingTodayRefresh } from "./drift-effects.js";
|
|
@@ -68,7 +68,7 @@ export class MorningRoutineRunner {
|
|
|
68
68
|
diagnoseTodayMdState;
|
|
69
69
|
isRoadmapStale;
|
|
70
70
|
emitRoadmapRefresh;
|
|
71
|
-
|
|
71
|
+
triggerActivityScan;
|
|
72
72
|
pipelineOrchestrator;
|
|
73
73
|
constructor(deps) {
|
|
74
74
|
this.db = deps.db;
|
|
@@ -82,7 +82,7 @@ export class MorningRoutineRunner {
|
|
|
82
82
|
this.diagnoseTodayMdState = deps.diagnoseTodayMdState;
|
|
83
83
|
this.isRoadmapStale = deps.isRoadmapStale;
|
|
84
84
|
this.emitRoadmapRefresh = deps.emitRoadmapRefresh;
|
|
85
|
-
this.
|
|
85
|
+
this.triggerActivityScan = deps.triggerActivityScan;
|
|
86
86
|
this.pipelineOrchestrator = deps.pipelineOrchestrator;
|
|
87
87
|
}
|
|
88
88
|
/**
|
|
@@ -141,15 +141,15 @@ export class MorningRoutineRunner {
|
|
|
141
141
|
logger.info({ promptKey, roadmapStale: roadmapStaleBeforeMorning, isRetry, retryCount, requestedTier: requestedTier ?? "default" }, "Morning routine dispatch");
|
|
142
142
|
// B2 fix + docs/design/appendices/routine-data-acquisition.md Phase 4 / D2 race fix:
|
|
143
143
|
// flip `morningRoutineInProgress=true` BEFORE the pre-pass fires so
|
|
144
|
-
//
|
|
145
|
-
// (`
|
|
144
|
+
// activity_scan can't squeeze through the cold-start window
|
|
145
|
+
// (`activityScan.trigger` skips when `isMorningRoutineActive()`
|
|
146
146
|
// returns true). The original B2 fix already widened the flag to
|
|
147
147
|
// span the whole retry chain; the pre-pass shifts the boundary
|
|
148
148
|
// earlier so the same guard covers context build + binding resolve
|
|
149
149
|
// + Haiku fetcher cold-start, all of which precede the executor.
|
|
150
150
|
// The flag is reset in `finally` regardless of whether the pre-pass,
|
|
151
151
|
// context build, or main session throws — so a partial-failure path
|
|
152
|
-
// cannot leave the flag stuck `true` and starve
|
|
152
|
+
// cannot leave the flag stuck `true` and starve activity_scan forever.
|
|
153
153
|
this.setMorningRoutineInProgress(true);
|
|
154
154
|
// `pipelineRun` is non-null when the orchestrator completed and
|
|
155
155
|
// Stage A produced an `AgentResult`. A null value means Stage A
|
|
@@ -214,7 +214,7 @@ export class MorningRoutineRunner {
|
|
|
214
214
|
// `routine.morning_routine` success audit row is durable opens a
|
|
215
215
|
// window where, for a cron-triggered (non-wake) run, both
|
|
216
216
|
// `isMorningRoutineActive()` and `morningRoutineRanToday()` read
|
|
217
|
-
// false — an
|
|
217
|
+
// false — an activity_scan tick would then take the
|
|
218
218
|
// `morning_routine_pending_for_today` branch and enqueue a
|
|
219
219
|
// spurious morning_routine wake. The flag is instead cleared in
|
|
220
220
|
// the post-finally try/finally below, AFTER the journal append +
|
|
@@ -368,7 +368,7 @@ export class MorningRoutineRunner {
|
|
|
368
368
|
// audit row is durable (journal append + emitParentAuditRow above).
|
|
369
369
|
// Reached on every post-finally exit path — success/catchup,
|
|
370
370
|
// retry-scheduled, and the `pipelineRun === null` branch — so a
|
|
371
|
-
// Stage-A failure cannot leak the flag and wedge
|
|
371
|
+
// Stage-A failure cannot leak the flag and wedge activity_scan.
|
|
372
372
|
this.setMorningRoutineInProgress(false);
|
|
373
373
|
}
|
|
374
374
|
}
|
|
@@ -387,9 +387,9 @@ export class MorningRoutineRunner {
|
|
|
387
387
|
routine,
|
|
388
388
|
});
|
|
389
389
|
}
|
|
390
|
-
if (event.data?.
|
|
391
|
-
logger.info("Triggering deferred
|
|
392
|
-
await this.
|
|
390
|
+
if (event.data?.postCatchupActivityScan === true) {
|
|
391
|
+
logger.info("Triggering deferred activity_scan after morning catchup");
|
|
392
|
+
await this.triggerActivityScan("post_morning_catchup");
|
|
393
393
|
}
|
|
394
394
|
}
|
|
395
395
|
/**
|
|
@@ -456,7 +456,7 @@ export class MorningRoutineRunner {
|
|
|
456
456
|
postCatchupRoutines: Array.isArray(event.data?.postCatchupRoutines)
|
|
457
457
|
? event.data.postCatchupRoutines
|
|
458
458
|
: [],
|
|
459
|
-
|
|
459
|
+
postCatchupActivityScan: event.data?.postCatchupActivityScan === true,
|
|
460
460
|
importance: "low",
|
|
461
461
|
});
|
|
462
462
|
// M1: dedup + INSERT in a single transaction so two concurrent
|
|
@@ -41,6 +41,7 @@
|
|
|
41
41
|
import type Database from "better-sqlite3";
|
|
42
42
|
import type { Event, MessageEvent, AgentResult } from "@aitne/shared";
|
|
43
43
|
import type { AgentConfig } from "../config.js";
|
|
44
|
+
import { type ProactiveForwardType } from "./channel-timeline.js";
|
|
44
45
|
import type { IAuditLogger, INotificationManager, ISessionManager } from "./dispatcher-types.js";
|
|
45
46
|
import type { AgentExecutionOutcome } from "./agents/agent-execution-tracker.js";
|
|
46
47
|
/**
|
|
@@ -161,6 +162,34 @@ export declare class ResultProcessor {
|
|
|
161
162
|
* contextUpdated observability log in processResult.
|
|
162
163
|
*/
|
|
163
164
|
isObserverEvent(event: Event): boolean;
|
|
165
|
+
/**
|
|
166
|
+
* RESEARCH_CLUSTER_COST_FIX_PLAN F5 — was the cluster journal actually
|
|
167
|
+
* written during this `routine.research_cluster_update` run?
|
|
168
|
+
*
|
|
169
|
+
* Detection is the on-disk journal file itself — the authoritative,
|
|
170
|
+
* path-specific, backend-agnostic signal. The daemon writes the journal
|
|
171
|
+
* via the context-API chokepoint (`writeFileAtomically`), so the file's
|
|
172
|
+
* mtime reflects the real write time; a write that landed inside the run
|
|
173
|
+
* window (`[min(event enqueue, now − durationMs) − buffer, now]`) proves
|
|
174
|
+
* the agent executed the append rather than narrating success.
|
|
175
|
+
*
|
|
176
|
+
* Why not the `context_write` audit row (the plan's first idea): that
|
|
177
|
+
* row is emitted only inside `notifyPromptContextChanged`, which fires
|
|
178
|
+
* solely for prompt-refreshing paths (`shouldRefreshPromptContext`).
|
|
179
|
+
* `research/*` is intentionally a *quiet* namespace — it never triggers
|
|
180
|
+
* a refresh — so a research write records **no** `context_write` row.
|
|
181
|
+
* (The plan's §1 "zero context_write rows ⇒ zero writes" inference was
|
|
182
|
+
* therefore unsound for this namespace; the on-disk check has none of
|
|
183
|
+
* that coupling.) F1 guarantees ≤ 1 cluster_update run/cluster/day, so
|
|
184
|
+
* the run window cannot collide with another run writing the same file;
|
|
185
|
+
* the sibling research flows write *different* files
|
|
186
|
+
* (`<slug>-assistance-<date>.md`, `<slug>-wiki.md`), never `<slug>.md`.
|
|
187
|
+
*
|
|
188
|
+
* Returns `true` (treat as written — do NOT downgrade) when the slug is
|
|
189
|
+
* absent/invalid or the stat fails for any reason other than ENOENT: a
|
|
190
|
+
* verification fault must never relabel a genuinely-successful run.
|
|
191
|
+
*/
|
|
192
|
+
private researchClusterJournalWritten;
|
|
164
193
|
/**
|
|
165
194
|
* Confirm that a `wiki.ingest_url` session actually wrote a raw note via
|
|
166
195
|
* the Wiki API before letting the agent's claimed success DM reach the
|
|
@@ -185,3 +214,7 @@ export declare class ResultProcessor {
|
|
|
185
214
|
*/
|
|
186
215
|
private verifyWikiIngestWriteOrRewrite;
|
|
187
216
|
}
|
|
217
|
+
export declare function readTaskDeliveryRecord(event: Event): {
|
|
218
|
+
notificationType: ProactiveForwardType;
|
|
219
|
+
metadata: Record<string, unknown>;
|
|
220
|
+
} | null;
|