@aitne/daemon 0.1.2 → 0.1.4
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/LICENSE +21 -0
- package/dist/adapters/whatsapp-adapter.d.ts.map +1 -1
- package/dist/adapters/whatsapp-adapter.js +0 -1
- package/dist/adapters/whatsapp-adapter.js.map +1 -1
- package/dist/api/integration-route-gate.d.ts +15 -11
- package/dist/api/integration-route-gate.d.ts.map +1 -1
- package/dist/api/integration-route-gate.js +60 -23
- package/dist/api/integration-route-gate.js.map +1 -1
- package/dist/api/json-body.d.ts +22 -7
- package/dist/api/json-body.d.ts.map +1 -1
- package/dist/api/json-body.js +27 -8
- package/dist/api/json-body.js.map +1 -1
- package/dist/api/routes/agent.d.ts.map +1 -1
- package/dist/api/routes/agent.js +18 -0
- package/dist/api/routes/agent.js.map +1 -1
- package/dist/api/routes/backends.d.ts.map +1 -1
- package/dist/api/routes/backends.js +96 -1
- package/dist/api/routes/backends.js.map +1 -1
- package/dist/api/routes/books.js +1 -1
- package/dist/api/routes/books.js.map +1 -1
- package/dist/api/routes/context.d.ts.map +1 -1
- package/dist/api/routes/context.js +13 -1
- package/dist/api/routes/context.js.map +1 -1
- package/dist/api/routes/dashboard.d.ts.map +1 -1
- package/dist/api/routes/dashboard.js +75 -5
- package/dist/api/routes/dashboard.js.map +1 -1
- package/dist/api/routes/github.d.ts.map +1 -1
- package/dist/api/routes/github.js +38 -5
- package/dist/api/routes/github.js.map +1 -1
- package/dist/api/routes/integrations.d.ts +35 -6
- package/dist/api/routes/integrations.d.ts.map +1 -1
- package/dist/api/routes/integrations.js +191 -16
- package/dist/api/routes/integrations.js.map +1 -1
- package/dist/api/routes/mail.d.ts.map +1 -1
- package/dist/api/routes/mail.js +112 -46
- package/dist/api/routes/mail.js.map +1 -1
- package/dist/api/routes/observations.d.ts.map +1 -1
- package/dist/api/routes/observations.js +161 -8
- package/dist/api/routes/observations.js.map +1 -1
- package/dist/api/routes/setup-migrate.d.ts +9 -1
- package/dist/api/routes/setup-migrate.d.ts.map +1 -1
- package/dist/api/routes/setup-migrate.js +4 -2
- package/dist/api/routes/setup-migrate.js.map +1 -1
- package/dist/api/routes/skills.d.ts.map +1 -1
- package/dist/api/routes/skills.js +39 -1
- package/dist/api/routes/skills.js.map +1 -1
- package/dist/api/routes/voice.d.ts.map +1 -1
- package/dist/api/routes/voice.js +154 -14
- package/dist/api/routes/voice.js.map +1 -1
- package/dist/bootstrap/adapters.d.ts +109 -0
- package/dist/bootstrap/adapters.d.ts.map +1 -0
- package/dist/bootstrap/adapters.js +237 -0
- package/dist/bootstrap/adapters.js.map +1 -0
- package/dist/bootstrap/catchup.d.ts +23 -0
- package/dist/bootstrap/catchup.d.ts.map +1 -0
- package/dist/bootstrap/catchup.js +124 -0
- package/dist/bootstrap/catchup.js.map +1 -0
- package/dist/bootstrap/schedule-helpers.d.ts +18 -0
- package/dist/bootstrap/schedule-helpers.d.ts.map +1 -0
- package/dist/bootstrap/schedule-helpers.js +96 -0
- package/dist/bootstrap/schedule-helpers.js.map +1 -0
- package/dist/bootstrap/services.d.ts +60 -0
- package/dist/bootstrap/services.d.ts.map +1 -0
- package/dist/bootstrap/services.js +209 -0
- package/dist/bootstrap/services.js.map +1 -0
- package/dist/core/backends/backend-router.d.ts +23 -0
- package/dist/core/backends/backend-router.d.ts.map +1 -1
- package/dist/core/backends/backend-router.js +48 -3
- package/dist/core/backends/backend-router.js.map +1 -1
- package/dist/core/backends/claude-auth.d.ts +70 -0
- package/dist/core/backends/claude-auth.d.ts.map +1 -0
- package/dist/core/backends/claude-auth.js +198 -0
- package/dist/core/backends/claude-auth.js.map +1 -0
- package/dist/core/backends/claude-code-core.d.ts +47 -119
- package/dist/core/backends/claude-code-core.d.ts.map +1 -1
- package/dist/core/backends/claude-code-core.js +112 -1565
- package/dist/core/backends/claude-code-core.js.map +1 -1
- package/dist/core/backends/claude-delegated.d.ts +86 -0
- package/dist/core/backends/claude-delegated.d.ts.map +1 -0
- package/dist/core/backends/claude-delegated.js +801 -0
- package/dist/core/backends/claude-delegated.js.map +1 -0
- package/dist/core/backends/claude-errors.d.ts +39 -0
- package/dist/core/backends/claude-errors.d.ts.map +1 -0
- package/dist/core/backends/claude-errors.js +71 -0
- package/dist/core/backends/claude-errors.js.map +1 -0
- package/dist/core/backends/claude-probe.d.ts +103 -0
- package/dist/core/backends/claude-probe.d.ts.map +1 -0
- package/dist/core/backends/claude-probe.js +336 -0
- package/dist/core/backends/claude-probe.js.map +1 -0
- package/dist/core/backends/claude-tool-collection.d.ts +135 -0
- package/dist/core/backends/claude-tool-collection.d.ts.map +1 -0
- package/dist/core/backends/claude-tool-collection.js +831 -0
- package/dist/core/backends/claude-tool-collection.js.map +1 -0
- package/dist/core/backends/gemini-cli-core.d.ts +21 -0
- package/dist/core/backends/gemini-cli-core.d.ts.map +1 -1
- package/dist/core/backends/gemini-cli-core.js +84 -6
- package/dist/core/backends/gemini-cli-core.js.map +1 -1
- package/dist/core/backends/prompt-utils.d.ts +1 -0
- package/dist/core/backends/prompt-utils.d.ts.map +1 -1
- package/dist/core/backends/prompt-utils.js +60 -3
- package/dist/core/backends/prompt-utils.js.map +1 -1
- package/dist/core/context-builder.d.ts +36 -12
- package/dist/core/context-builder.d.ts.map +1 -1
- package/dist/core/context-builder.js +179 -89
- package/dist/core/context-builder.js.map +1 -1
- package/dist/core/dispatcher-date-utils.d.ts +49 -0
- package/dist/core/dispatcher-date-utils.d.ts.map +1 -0
- package/dist/core/dispatcher-date-utils.js +132 -0
- package/dist/core/dispatcher-date-utils.js.map +1 -0
- package/dist/core/dispatcher-error-handling.d.ts +159 -0
- package/dist/core/dispatcher-error-handling.d.ts.map +1 -0
- package/dist/core/dispatcher-error-handling.js +393 -0
- package/dist/core/dispatcher-error-handling.js.map +1 -0
- package/dist/core/dispatcher-hourly-check.d.ts +150 -0
- package/dist/core/dispatcher-hourly-check.d.ts.map +1 -0
- package/dist/core/dispatcher-hourly-check.js +665 -0
- package/dist/core/dispatcher-hourly-check.js.map +1 -0
- package/dist/core/dispatcher-message-handler.d.ts +170 -0
- package/dist/core/dispatcher-message-handler.d.ts.map +1 -0
- package/dist/core/dispatcher-message-handler.js +1054 -0
- package/dist/core/dispatcher-message-handler.js.map +1 -0
- package/dist/core/dispatcher-morning-routine.d.ts +169 -0
- package/dist/core/dispatcher-morning-routine.d.ts.map +1 -0
- package/dist/core/dispatcher-morning-routine.js +434 -0
- package/dist/core/dispatcher-morning-routine.js.map +1 -0
- package/dist/core/dispatcher-prompt.d.ts +107 -0
- package/dist/core/dispatcher-prompt.d.ts.map +1 -0
- package/dist/core/dispatcher-prompt.js +227 -0
- package/dist/core/dispatcher-prompt.js.map +1 -0
- package/dist/core/dispatcher-repository-helpers.d.ts +39 -0
- package/dist/core/dispatcher-repository-helpers.d.ts.map +1 -0
- package/dist/core/dispatcher-repository-helpers.js +86 -0
- package/dist/core/dispatcher-repository-helpers.js.map +1 -0
- package/dist/core/dispatcher-result-processor.d.ts +145 -0
- package/dist/core/dispatcher-result-processor.d.ts.map +1 -0
- package/dist/core/dispatcher-result-processor.js +414 -0
- package/dist/core/dispatcher-result-processor.js.map +1 -0
- package/dist/core/dispatcher-scheduled-tasks.d.ts +406 -0
- package/dist/core/dispatcher-scheduled-tasks.d.ts.map +1 -0
- package/dist/core/dispatcher-scheduled-tasks.js +998 -0
- package/dist/core/dispatcher-scheduled-tasks.js.map +1 -0
- package/dist/core/dispatcher-types.d.ts +296 -0
- package/dist/core/dispatcher-types.d.ts.map +1 -0
- package/dist/core/dispatcher-types.js +106 -0
- package/dist/core/dispatcher-types.js.map +1 -0
- package/dist/core/dispatcher.d.ts +86 -610
- package/dist/core/dispatcher.d.ts.map +1 -1
- package/dist/core/dispatcher.js +293 -3542
- package/dist/core/dispatcher.js.map +1 -1
- package/dist/core/integration-health.d.ts +18 -10
- package/dist/core/integration-health.d.ts.map +1 -1
- package/dist/core/integration-health.js +31 -1
- package/dist/core/integration-health.js.map +1 -1
- package/dist/core/integration-lifecycle.d.ts +65 -0
- package/dist/core/integration-lifecycle.d.ts.map +1 -1
- package/dist/core/integration-lifecycle.js +167 -16
- package/dist/core/integration-lifecycle.js.map +1 -1
- package/dist/core/integration-main-backend.d.ts +40 -0
- package/dist/core/integration-main-backend.d.ts.map +1 -1
- package/dist/core/integration-main-backend.js +89 -2
- package/dist/core/integration-main-backend.js.map +1 -1
- package/dist/core/management-md.d.ts +51 -17
- package/dist/core/management-md.d.ts.map +1 -1
- package/dist/core/management-md.js +233 -56
- package/dist/core/management-md.js.map +1 -1
- package/dist/core/output-language-policy.d.ts +74 -0
- package/dist/core/output-language-policy.d.ts.map +1 -0
- package/dist/core/output-language-policy.js +194 -0
- package/dist/core/output-language-policy.js.map +1 -0
- package/dist/core/prompts.d.ts +1 -0
- package/dist/core/prompts.d.ts.map +1 -1
- package/dist/core/prompts.js +121 -3
- package/dist/core/prompts.js.map +1 -1
- package/dist/core/repository-management-docs.d.ts +24 -0
- package/dist/core/repository-management-docs.d.ts.map +1 -1
- package/dist/core/repository-management-docs.js +210 -26
- package/dist/core/repository-management-docs.js.map +1 -1
- package/dist/core/routine-acquisition-plan.d.ts +131 -0
- package/dist/core/routine-acquisition-plan.d.ts.map +1 -0
- package/dist/core/routine-acquisition-plan.js +268 -0
- package/dist/core/routine-acquisition-plan.js.map +1 -0
- package/dist/core/routine-fetch-window-runner.d.ts +201 -0
- package/dist/core/routine-fetch-window-runner.d.ts.map +1 -0
- package/dist/core/routine-fetch-window-runner.js +661 -0
- package/dist/core/routine-fetch-window-runner.js.map +1 -0
- package/dist/core/routine-windows.d.ts +156 -0
- package/dist/core/routine-windows.d.ts.map +1 -0
- package/dist/core/routine-windows.js +330 -0
- package/dist/core/routine-windows.js.map +1 -0
- package/dist/core/skills-compiler.d.ts +11 -0
- package/dist/core/skills-compiler.d.ts.map +1 -1
- package/dist/core/skills-compiler.js +102 -13
- package/dist/core/skills-compiler.js.map +1 -1
- package/dist/core/skills-manifest.d.ts.map +1 -1
- package/dist/core/skills-manifest.js +26 -0
- package/dist/core/skills-manifest.js.map +1 -1
- package/dist/core/system-reset.d.ts.map +1 -1
- package/dist/core/system-reset.js +25 -2
- package/dist/core/system-reset.js.map +1 -1
- package/dist/db/observations.d.ts +45 -2
- package/dist/db/observations.d.ts.map +1 -1
- package/dist/db/observations.js +112 -14
- package/dist/db/observations.js.map +1 -1
- package/dist/db/schema.d.ts.map +1 -1
- package/dist/db/schema.js +13 -25
- package/dist/db/schema.js.map +1 -1
- package/dist/index.js +83 -610
- package/dist/index.js.map +1 -1
- package/dist/observers/delegated-sync-worker.d.ts +45 -2
- package/dist/observers/delegated-sync-worker.d.ts.map +1 -1
- package/dist/observers/delegated-sync-worker.js +71 -21
- package/dist/observers/delegated-sync-worker.js.map +1 -1
- package/dist/observers/mail-poller.d.ts +12 -5
- package/dist/observers/mail-poller.d.ts.map +1 -1
- package/dist/observers/mail-poller.js +36 -14
- package/dist/observers/mail-poller.js.map +1 -1
- package/dist/observers/manager.d.ts +37 -5
- package/dist/observers/manager.d.ts.map +1 -1
- package/dist/observers/manager.js +28 -10
- package/dist/observers/manager.js.map +1 -1
- package/dist/safety/risk-classifier.d.ts.map +1 -1
- package/dist/safety/risk-classifier.js +5 -0
- package/dist/safety/risk-classifier.js.map +1 -1
- package/dist/services/delegated-backend-invoker.d.ts +1 -51
- package/dist/services/delegated-backend-invoker.d.ts.map +1 -1
- package/dist/services/delegated-backend-invoker.js +41 -480
- package/dist/services/delegated-backend-invoker.js.map +1 -1
- package/dist/services/delegated-invoker-audit.d.ts +94 -0
- package/dist/services/delegated-invoker-audit.d.ts.map +1 -0
- package/dist/services/delegated-invoker-audit.js +238 -0
- package/dist/services/delegated-invoker-audit.js.map +1 -0
- package/dist/services/delegated-invoker-cache-hits.d.ts +34 -0
- package/dist/services/delegated-invoker-cache-hits.d.ts.map +1 -0
- package/dist/services/delegated-invoker-cache-hits.js +104 -0
- package/dist/services/delegated-invoker-cache-hits.js.map +1 -0
- package/dist/services/delegated-invoker-janitors.d.ts +28 -0
- package/dist/services/delegated-invoker-janitors.d.ts.map +1 -0
- package/dist/services/delegated-invoker-janitors.js +104 -0
- package/dist/services/delegated-invoker-janitors.js.map +1 -0
- package/dist/services/delegated-invoker-utils.d.ts +42 -0
- package/dist/services/delegated-invoker-utils.d.ts.map +1 -0
- package/dist/services/delegated-invoker-utils.js +100 -0
- package/dist/services/delegated-invoker-utils.js.map +1 -0
- package/dist/services/delegated-task-runtime.d.ts +1 -1
- package/dist/services/delegated-task-runtime.js +1 -1
- package/dist/services/integrations/snapshot-partitions.d.ts +5 -0
- package/dist/services/integrations/snapshot-partitions.d.ts.map +1 -1
- package/dist/services/integrations/snapshot-partitions.js +12 -0
- package/dist/services/integrations/snapshot-partitions.js.map +1 -1
- package/dist/services/voice/transcriber-impl.d.ts.map +1 -1
- package/dist/services/voice/transcriber-impl.js +46 -0
- package/dist/services/voice/transcriber-impl.js.map +1 -1
- package/package.json +12 -12
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `PromptAssembler` — composes the dispatcher's per-turn prompt and
|
|
3
|
+
* owns the inbound-attachment lifecycle (staging into the session dir,
|
|
4
|
+
* transcribing audio via local Whisper, and rendering the
|
|
5
|
+
* "[Attached files]" prompt block).
|
|
6
|
+
*
|
|
7
|
+
* Extracted from `core/dispatcher.ts` as part of phase D-2 of
|
|
8
|
+
* `docs/design/appendices/file-split-plan.md`. Pattern B (stateful
|
|
9
|
+
* coordinator): the assembler owns its own logic but borrows live
|
|
10
|
+
* references / accessors for state that the dispatcher continues to
|
|
11
|
+
* own (the `activeTurnTokens` Map, the lazily-injected
|
|
12
|
+
* `AttachmentStore`, and the lazily-injected `VoiceTranscriber`).
|
|
13
|
+
*
|
|
14
|
+
* Dispatcher entry points served:
|
|
15
|
+
* - every `dispatch.*` path that needs a task-flow prompt
|
|
16
|
+
* (`runStage2Triage`, `executeMorningRoutine`,
|
|
17
|
+
* `executeScheduledTask`, `executeDefault`, `handleMessage`);
|
|
18
|
+
* - `handleMessage` for the inbound attachment lifecycle
|
|
19
|
+
* (`stageInboundAttachments` → `transcribeAttachments` →
|
|
20
|
+
* `buildAttachmentPromptBlock`);
|
|
21
|
+
* - `validateAttachmentTurnToken` (public on `EventDispatcher`,
|
|
22
|
+
* reads the live `activeTurnTokens` Map this assembler issues
|
|
23
|
+
* into via `issueAttachmentTurnToken`).
|
|
24
|
+
*
|
|
25
|
+
* Shared-state references held:
|
|
26
|
+
* - `activeTurnTokens: Map<string, number>` — live reference,
|
|
27
|
+
* mutated in place via `issueAttachmentTurnToken` /
|
|
28
|
+
* `releaseAttachmentTurnToken`. The dispatcher's
|
|
29
|
+
* `validateAttachmentTurnToken` reads the same map.
|
|
30
|
+
* - `getAttachmentStore` / `getVoiceTranscriber` — getter callbacks
|
|
31
|
+
* because both are set lazily by `index.ts` after the dispatcher
|
|
32
|
+
* is constructed. The assembler must read the *current* value at
|
|
33
|
+
* each call, not capture it once.
|
|
34
|
+
*/
|
|
35
|
+
import { randomUUID } from "node:crypto";
|
|
36
|
+
import { getContextDir } from "../config.js";
|
|
37
|
+
import { appendPolicyBlocks, createPromptInjectionBudget, } from "./policy-files.js";
|
|
38
|
+
import { appendReviewContextBlocks } from "./review-context.js";
|
|
39
|
+
import { anyMcpServerEnabled } from "../services/mcp/registry.js";
|
|
40
|
+
import { readIntegrations } from "../db/integrations-store.js";
|
|
41
|
+
import { isDegraded as readDegradedMode } from "../db/runtime-state.js";
|
|
42
|
+
import { createLogger } from "../logging.js";
|
|
43
|
+
const logger = createLogger("dispatcher-prompt");
|
|
44
|
+
export class PromptAssembler {
|
|
45
|
+
db;
|
|
46
|
+
config;
|
|
47
|
+
getTaskFlow;
|
|
48
|
+
activeTurnTokens;
|
|
49
|
+
getAttachmentStore;
|
|
50
|
+
getVoiceTranscriber;
|
|
51
|
+
constructor(deps) {
|
|
52
|
+
this.db = deps.db;
|
|
53
|
+
this.config = deps.config;
|
|
54
|
+
this.getTaskFlow = deps.getTaskFlow;
|
|
55
|
+
this.activeTurnTokens = deps.activeTurnTokens;
|
|
56
|
+
this.getAttachmentStore = deps.getAttachmentStore;
|
|
57
|
+
this.getVoiceTranscriber = deps.getVoiceTranscriber;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* B-007 §5.8 — compose the final prompt by loading the task-flow
|
|
61
|
+
* template and appending the vault policy-files block (rules/*.md,
|
|
62
|
+
* routines/<cadence>.md, custom routine file, etc.). Centralised
|
|
63
|
+
* here so every dispatch path sees the same policy bundle.
|
|
64
|
+
*/
|
|
65
|
+
assemble(eventType, processKey, backendId, flags) {
|
|
66
|
+
const integrations = readIntegrations(this.db);
|
|
67
|
+
const base = this.getTaskFlow(eventType, backendId, integrations);
|
|
68
|
+
const contextDir = this.getPromptPolicyContextDir();
|
|
69
|
+
if (!contextDir) {
|
|
70
|
+
return base;
|
|
71
|
+
}
|
|
72
|
+
// B-003 Phase 3 — the `rules/mcp.md` PolicyFileRef is registered with
|
|
73
|
+
// `injectIf: ctx.flags?.mcpEnabled === true`. Compute the flag here so
|
|
74
|
+
// every dispatch path (DM, routine, scheduled task, fallback reassembly)
|
|
75
|
+
// injects the policy without each call site having to remember it.
|
|
76
|
+
const mergedFlags = {
|
|
77
|
+
...(flags ?? {}),
|
|
78
|
+
mcpEnabled: anyMcpServerEnabled(this.db),
|
|
79
|
+
};
|
|
80
|
+
// Share a single budget across policy + review-context injection so the
|
|
81
|
+
// aggregate cap (POLICY_TOTAL_MAX_BYTES) covers both — avoids the
|
|
82
|
+
// double-accounting bug where each injector independently consumed the
|
|
83
|
+
// full cap and inflated the effective prompt-injection ceiling to 2×.
|
|
84
|
+
const budget = createPromptInjectionBudget();
|
|
85
|
+
const withPolicies = appendPolicyBlocks(base, {
|
|
86
|
+
contextDir,
|
|
87
|
+
processKey,
|
|
88
|
+
flags: mergedFlags,
|
|
89
|
+
budget,
|
|
90
|
+
});
|
|
91
|
+
return appendReviewContextBlocks(withPolicies, {
|
|
92
|
+
contextDir,
|
|
93
|
+
processKey,
|
|
94
|
+
flags: {
|
|
95
|
+
useReviewDossiers: this.config.useReviewDossiers,
|
|
96
|
+
useContextIndex: this.config.useContextIndex,
|
|
97
|
+
},
|
|
98
|
+
budget,
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Policy-file prompt assembly must not fall back to `<dataDir>/context`
|
|
103
|
+
* while degraded. Reactive sessions still run so the user can repair the
|
|
104
|
+
* vault, but the prompt must not silently inject stale rulebooks from a
|
|
105
|
+
* legacy location.
|
|
106
|
+
*/
|
|
107
|
+
getPromptPolicyContextDir() {
|
|
108
|
+
if (readDegradedMode(this.db)) {
|
|
109
|
+
return null;
|
|
110
|
+
}
|
|
111
|
+
return getContextDir(this.config);
|
|
112
|
+
}
|
|
113
|
+
/** Internal — issue a turn token bound to a session. Cleared by
|
|
114
|
+
* `releaseAttachmentTurnToken` in a `finally`. */
|
|
115
|
+
issueAttachmentTurnToken(sessionId) {
|
|
116
|
+
const token = randomUUID();
|
|
117
|
+
this.activeTurnTokens.set(token, sessionId);
|
|
118
|
+
return token;
|
|
119
|
+
}
|
|
120
|
+
releaseAttachmentTurnToken(token) {
|
|
121
|
+
this.activeTurnTokens.delete(token);
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Stage inbound attachments into `<sessionDir>/_attachments/` via
|
|
125
|
+
* hard-link (or copy on EXDEV). Returns the rows that were actually
|
|
126
|
+
* staged — callers feed these into the prompt-block builder.
|
|
127
|
+
*/
|
|
128
|
+
stageInboundAttachments(event, sessionDir) {
|
|
129
|
+
const attachmentStore = this.getAttachmentStore();
|
|
130
|
+
if (!attachmentStore || !sessionDir)
|
|
131
|
+
return [];
|
|
132
|
+
if (!event.attachments || event.attachments.length === 0)
|
|
133
|
+
return [];
|
|
134
|
+
const staged = [];
|
|
135
|
+
for (const ref of event.attachments) {
|
|
136
|
+
const row = attachmentStore.get(ref.id);
|
|
137
|
+
if (!row)
|
|
138
|
+
continue;
|
|
139
|
+
try {
|
|
140
|
+
attachmentStore.stageIntoWorkdir({ row, sessionDir });
|
|
141
|
+
staged.push(row);
|
|
142
|
+
}
|
|
143
|
+
catch (err) {
|
|
144
|
+
logger.warn({ err, attachmentId: row.id }, "Failed to stage attachment");
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
return staged;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Run local-Whisper transcription on every audio attachment in `rows`.
|
|
151
|
+
* Cached transcripts are returned without re-running inference. Returns
|
|
152
|
+
* an empty map when the transcriber is unset, when no rows are audio,
|
|
153
|
+
* or when every transcription failed — callers always render the path
|
|
154
|
+
* even if the transcript is missing.
|
|
155
|
+
*/
|
|
156
|
+
async transcribeAttachments(rows) {
|
|
157
|
+
const transcripts = new Map();
|
|
158
|
+
const voiceTranscriber = this.getVoiceTranscriber();
|
|
159
|
+
if (!voiceTranscriber || rows.length === 0)
|
|
160
|
+
return transcripts;
|
|
161
|
+
for (const row of rows) {
|
|
162
|
+
if (!voiceTranscriber.isAudio(row.mimeType))
|
|
163
|
+
continue;
|
|
164
|
+
try {
|
|
165
|
+
const result = await voiceTranscriber.transcribe({
|
|
166
|
+
attachmentId: row.id,
|
|
167
|
+
path: row.path,
|
|
168
|
+
mimeType: row.mimeType,
|
|
169
|
+
});
|
|
170
|
+
if (result)
|
|
171
|
+
transcripts.set(row.id, result);
|
|
172
|
+
}
|
|
173
|
+
catch (err) {
|
|
174
|
+
logger.warn({ err, attachmentId: row.id }, "voice transcription threw; falling back to path-only prompt");
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return transcripts;
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Compose the "[Attached files]" prompt block that the dispatcher
|
|
181
|
+
* appends to the task-flow body for turns with inbound attachments.
|
|
182
|
+
* Kept on the assembler (not in prompts.ts) because the attachment
|
|
183
|
+
* rows are local state for this turn only.
|
|
184
|
+
*/
|
|
185
|
+
buildAttachmentPromptBlock(rows, transcripts) {
|
|
186
|
+
if (rows.length === 0)
|
|
187
|
+
return "";
|
|
188
|
+
const lines = [
|
|
189
|
+
"",
|
|
190
|
+
"[Attached files]",
|
|
191
|
+
"The user attached the following files for this turn. Paths are relative",
|
|
192
|
+
"to your working directory. Use the appropriate local tool for each",
|
|
193
|
+
"file type: images/PDFs may be readable directly, while audio/video",
|
|
194
|
+
"are staged as files for inspection, transcription, or conversion when",
|
|
195
|
+
"the active backend has suitable tools.",
|
|
196
|
+
];
|
|
197
|
+
const voiceTranscriber = this.getVoiceTranscriber();
|
|
198
|
+
const transcriberEnabled = voiceTranscriber?.isEnabled() ?? false;
|
|
199
|
+
for (const row of rows) {
|
|
200
|
+
const rel = `_attachments/${row.safeFilename}`;
|
|
201
|
+
const size = `${Math.max(1, Math.round(row.sizeBytes / 1024))} KB`;
|
|
202
|
+
const captionPart = row.caption ? ` — caption: ${JSON.stringify(row.caption)}` : "";
|
|
203
|
+
lines.push(`- ${rel} (${row.mimeType}, ${size})${captionPart}`);
|
|
204
|
+
const transcript = transcripts?.get(row.id);
|
|
205
|
+
if (transcript) {
|
|
206
|
+
const langPart = transcript.language
|
|
207
|
+
? ` (lang=${transcript.language})`
|
|
208
|
+
: "";
|
|
209
|
+
const durationPart = transcript.durationSec !== null
|
|
210
|
+
? `, ${transcript.durationSec.toFixed(1)}s`
|
|
211
|
+
: "";
|
|
212
|
+
lines.push(` Voice transcript${langPart}${durationPart}: ${JSON.stringify(transcript.transcript)}`);
|
|
213
|
+
}
|
|
214
|
+
else if (transcriberEnabled &&
|
|
215
|
+
voiceTranscriber?.isAudio(row.mimeType)) {
|
|
216
|
+
// Audio attachment but no transcript was produced. Could be too long,
|
|
217
|
+
// a decoder/inference failure, or a model still warming up. Surface a
|
|
218
|
+
// marker so the agent can ask the user to retype rather than silently
|
|
219
|
+
// pretending the audio was readable.
|
|
220
|
+
lines.push(" (voice transcript unavailable — audio may be too long, untranscribable, or the local model is unavailable)");
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
lines.push("", "If your reply should include a generated file (md/PDF/CSV/image/etc.),", "deliver it via the `attach` skill — write the bytes to a temp path, then", "POST /api/chat/outbound-attachments with `X-Turn-Token: $PA_TURN_TOKEN`.", "`_attachments/` is the read-only inbound staging area, not an output", "location. Never write a filesystem path into your reply and claim you", "created a file unless you actually uploaded it through that endpoint.");
|
|
224
|
+
return lines.join("\n");
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
//# sourceMappingURL=dispatcher-prompt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dispatcher-prompt.js","sourceRoot":"","sources":["../../src/core/dispatcher-prompt.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Zero-dependency repository-run helpers used by the dispatcher's
|
|
3
|
+
* `executeRepositoryRunTask` / `executeScheduledTask` paths.
|
|
4
|
+
*
|
|
5
|
+
* These are pure functions — they read the inbound `taskContext` payload
|
|
6
|
+
* (off the `AgentTaskEvent`) or normalise free-form repository metadata
|
|
7
|
+
* (slug, classification, category) without touching dispatcher instance
|
|
8
|
+
* state. Kept in their own module so the dispatcher's main file stays
|
|
9
|
+
* focused on routing/lifecycle concerns; phase D-1 of
|
|
10
|
+
* `docs/design/appendices/file-split-plan.md`.
|
|
11
|
+
*
|
|
12
|
+
* Not re-exported from `dispatcher.ts` on purpose — these were
|
|
13
|
+
* file-private before the split and no external caller imports them.
|
|
14
|
+
*/
|
|
15
|
+
import type { AgentTaskEvent, BackendId } from "@aitne/shared";
|
|
16
|
+
import type { RepositoryDTO } from "../db/repositories-store.js";
|
|
17
|
+
export type RepositoryRunWorkdirMode = "temp" | "local-clone";
|
|
18
|
+
export interface RepositoryRunTaskContext {
|
|
19
|
+
triggerSource: string;
|
|
20
|
+
repositoryId: string;
|
|
21
|
+
slug: string;
|
|
22
|
+
localPath: string | null;
|
|
23
|
+
githubRepo: string | null;
|
|
24
|
+
workdirMode: RepositoryRunWorkdirMode;
|
|
25
|
+
prompt: string;
|
|
26
|
+
instructionMd: string | null;
|
|
27
|
+
timeoutMinutes: number | null;
|
|
28
|
+
triggerId?: string;
|
|
29
|
+
triggerName?: string;
|
|
30
|
+
triggerEventType?: string;
|
|
31
|
+
triggerEventPayload?: unknown;
|
|
32
|
+
}
|
|
33
|
+
export declare function parseRepositoryRunTaskContext(taskCtx: AgentTaskEvent["taskContext"]): RepositoryRunTaskContext | null;
|
|
34
|
+
export declare function repositoryRunInstructionFilename(backendId: BackendId): string;
|
|
35
|
+
export declare function safeRepositoryRunDirName(slug: string): string;
|
|
36
|
+
export declare function parseGithubRepoSlug(value: string | null): [string | null, string | null];
|
|
37
|
+
export declare function normalizeRepositoryClassification(value: unknown): RepositoryDTO["classification"];
|
|
38
|
+
export declare function normalizeRepositoryCategory(value: unknown): RepositoryDTO["category"];
|
|
39
|
+
//# sourceMappingURL=dispatcher-repository-helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dispatcher-repository-helpers.d.ts","sourceRoot":"","sources":["../../src/core/dispatcher-repository-helpers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC/D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAEjE,MAAM,MAAM,wBAAwB,GAAG,MAAM,GAAG,aAAa,CAAC;AAE9D,MAAM,WAAW,wBAAwB;IACvC,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,WAAW,EAAE,wBAAwB,CAAC;IACtC,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED,wBAAgB,6BAA6B,CAC3C,OAAO,EAAE,cAAc,CAAC,aAAa,CAAC,GACrC,wBAAwB,GAAG,IAAI,CA0CjC;AAED,wBAAgB,gCAAgC,CAAC,SAAS,EAAE,SAAS,GAAG,MAAM,CAI7E;AAED,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAM7D;AAED,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,MAAM,GAAG,IAAI,GACnB,CAAC,MAAM,GAAG,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC,CAKhC;AAED,wBAAgB,iCAAiC,CAC/C,KAAK,EAAE,OAAO,GACb,aAAa,CAAC,gBAAgB,CAAC,CAEjC;AAED,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,OAAO,GAAG,aAAa,CAAC,UAAU,CAAC,CAQrF"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Zero-dependency repository-run helpers used by the dispatcher's
|
|
3
|
+
* `executeRepositoryRunTask` / `executeScheduledTask` paths.
|
|
4
|
+
*
|
|
5
|
+
* These are pure functions — they read the inbound `taskContext` payload
|
|
6
|
+
* (off the `AgentTaskEvent`) or normalise free-form repository metadata
|
|
7
|
+
* (slug, classification, category) without touching dispatcher instance
|
|
8
|
+
* state. Kept in their own module so the dispatcher's main file stays
|
|
9
|
+
* focused on routing/lifecycle concerns; phase D-1 of
|
|
10
|
+
* `docs/design/appendices/file-split-plan.md`.
|
|
11
|
+
*
|
|
12
|
+
* Not re-exported from `dispatcher.ts` on purpose — these were
|
|
13
|
+
* file-private before the split and no external caller imports them.
|
|
14
|
+
*/
|
|
15
|
+
export function parseRepositoryRunTaskContext(taskCtx) {
|
|
16
|
+
if (!taskCtx || typeof taskCtx !== "object")
|
|
17
|
+
return null;
|
|
18
|
+
const ctx = taskCtx;
|
|
19
|
+
if (ctx.triggerSource !== "manual"
|
|
20
|
+
&& ctx.triggerSource !== "trigger_manual_fire"
|
|
21
|
+
&& ctx.triggerSource !== "repository_trigger") {
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
if (typeof ctx.repositoryId !== "string"
|
|
25
|
+
|| typeof ctx.slug !== "string"
|
|
26
|
+
|| typeof ctx.prompt !== "string"
|
|
27
|
+
|| (ctx.workdirMode !== "temp" && ctx.workdirMode !== "local-clone")) {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
const localPath = typeof ctx.localPath === "string" && ctx.localPath.length > 0
|
|
31
|
+
? ctx.localPath
|
|
32
|
+
: null;
|
|
33
|
+
const githubRepo = typeof ctx.githubRepo === "string" && ctx.githubRepo.length > 0
|
|
34
|
+
? ctx.githubRepo
|
|
35
|
+
: null;
|
|
36
|
+
return {
|
|
37
|
+
triggerSource: ctx.triggerSource,
|
|
38
|
+
repositoryId: ctx.repositoryId,
|
|
39
|
+
slug: ctx.slug,
|
|
40
|
+
localPath,
|
|
41
|
+
githubRepo,
|
|
42
|
+
workdirMode: ctx.workdirMode,
|
|
43
|
+
prompt: ctx.prompt,
|
|
44
|
+
instructionMd: typeof ctx.instructionMd === "string" ? ctx.instructionMd : null,
|
|
45
|
+
timeoutMinutes: typeof ctx.timeoutMinutes === "number" ? ctx.timeoutMinutes : null,
|
|
46
|
+
...(typeof ctx.triggerId === "string" ? { triggerId: ctx.triggerId } : {}),
|
|
47
|
+
...(typeof ctx.triggerName === "string" ? { triggerName: ctx.triggerName } : {}),
|
|
48
|
+
...(typeof ctx.triggerEventType === "string" ? { triggerEventType: ctx.triggerEventType } : {}),
|
|
49
|
+
...("triggerEventPayload" in ctx ? { triggerEventPayload: ctx.triggerEventPayload } : {}),
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
export function repositoryRunInstructionFilename(backendId) {
|
|
53
|
+
if (backendId === "codex")
|
|
54
|
+
return "AGENTS.md";
|
|
55
|
+
if (backendId === "gemini")
|
|
56
|
+
return "GEMINI.md";
|
|
57
|
+
return "CLAUDE.md";
|
|
58
|
+
}
|
|
59
|
+
export function safeRepositoryRunDirName(slug) {
|
|
60
|
+
const safe = slug
|
|
61
|
+
.toLowerCase()
|
|
62
|
+
.replace(/[^a-z0-9._-]+/g, "-")
|
|
63
|
+
.replace(/^-+|-+$/g, "");
|
|
64
|
+
return safe || "repository";
|
|
65
|
+
}
|
|
66
|
+
export function parseGithubRepoSlug(value) {
|
|
67
|
+
if (!value)
|
|
68
|
+
return [null, null];
|
|
69
|
+
const parts = value.split("/");
|
|
70
|
+
if (parts.length !== 2 || !parts[0] || !parts[1])
|
|
71
|
+
return [null, null];
|
|
72
|
+
return [parts[0], parts[1]];
|
|
73
|
+
}
|
|
74
|
+
export function normalizeRepositoryClassification(value) {
|
|
75
|
+
return value === "project" ? "project" : "repo-only";
|
|
76
|
+
}
|
|
77
|
+
export function normalizeRepositoryCategory(value) {
|
|
78
|
+
return value === "work" ||
|
|
79
|
+
value === "personal" ||
|
|
80
|
+
value === "research" ||
|
|
81
|
+
value === "client" ||
|
|
82
|
+
value === "other"
|
|
83
|
+
? value
|
|
84
|
+
: "other";
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=dispatcher-repository-helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dispatcher-repository-helpers.js","sourceRoot":"","sources":["../../src/core/dispatcher-repository-helpers.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `ResultProcessor` — closes out the dispatch lifecycle on the success
|
|
3
|
+
* side: forwards the agent's final output to the notification manager
|
|
4
|
+
* (when applicable), writes the audit log row, finalizes the
|
|
5
|
+
* agent_schedule + repository_management bookkeeping, and exposes the
|
|
6
|
+
* cross-session conversation history + proactive-forward heuristics
|
|
7
|
+
* the message handler consults.
|
|
8
|
+
*
|
|
9
|
+
* Extracted from `core/dispatcher.ts` as part of phase D-2 of
|
|
10
|
+
* `docs/design/appendices/file-split-plan.md`. Pattern B (stateful
|
|
11
|
+
* coordinator): the processor holds no mutable state of its own; it
|
|
12
|
+
* borrows the dispatcher's `notifiedEvents` Set as a live reference
|
|
13
|
+
* (the post-success consume site) and reads dispatcher-state via a
|
|
14
|
+
* minimal isReactive callback so the cost-cap / autonomous-trigger
|
|
15
|
+
* classification stays single-sourced.
|
|
16
|
+
*
|
|
17
|
+
* Dispatcher entry points served:
|
|
18
|
+
* - the message handler / routine handler / scheduled-task handler
|
|
19
|
+
* all call `processResult` once the backend run terminates;
|
|
20
|
+
* - `handleError` (now on `DispatcherErrorRouter`) bridges back into
|
|
21
|
+
* `finalizeRetemplateRun` / `finalizeManagementScan` via the
|
|
22
|
+
* `onRetemplateFinalize` / `onManagementScanFinalize` callbacks
|
|
23
|
+
* wired from `EventDispatcher` so the failure path lands the same
|
|
24
|
+
* bookkeeping rows as the success path;
|
|
25
|
+
* - the message handler reads
|
|
26
|
+
* `hasRecentProactiveForwardContext` /
|
|
27
|
+
* `buildCrossSessionConversationHistory` /
|
|
28
|
+
* `formatSummaryRole` for cross-surface DM continuity, and calls
|
|
29
|
+
* `logProactiveForwardDisavowalIfMatched` after the assistant
|
|
30
|
+
* reply lands.
|
|
31
|
+
*
|
|
32
|
+
* Shared-state references held:
|
|
33
|
+
* - `notifiedEvents: Set<string>` — live reference; `processResult`
|
|
34
|
+
* consumes the entry the agent's `/api/notify` call deposited so
|
|
35
|
+
* the dispatcher doesn't double-DM with the closing assistant
|
|
36
|
+
* turn.
|
|
37
|
+
* - `isReactive: (event) => boolean` — getter; mirrors the
|
|
38
|
+
* dispatcher's classification so audit-log `trigger` and observer
|
|
39
|
+
* logs stay consistent.
|
|
40
|
+
*/
|
|
41
|
+
import type Database from "better-sqlite3";
|
|
42
|
+
import type { Event, MessageEvent, AgentResult } from "@aitne/shared";
|
|
43
|
+
import type { AgentConfig } from "../config.js";
|
|
44
|
+
import type { IAuditLogger, INotificationManager, ISessionManager } from "./dispatcher-types.js";
|
|
45
|
+
/**
|
|
46
|
+
* English-only patterns by CLAUDE.md convention. The disavowal tripwire
|
|
47
|
+
* is a numerator over a `disavowed / injected` ratio (dm-channel-timeline.md
|
|
48
|
+
* §C.1) — false negatives are tolerated; non-English replies that happen to
|
|
49
|
+
* disavow will simply not contribute to the numerator. Operators monitor the
|
|
50
|
+
* ratio and flip `proactiveForwardForceFreshSession` on rise; that fallback
|
|
51
|
+
* path is language-agnostic.
|
|
52
|
+
*/
|
|
53
|
+
export declare const PROACTIVE_FORWARD_DISAVOWAL_PATTERNS: RegExp[];
|
|
54
|
+
export interface ResultProcessorDeps {
|
|
55
|
+
db: Database.Database;
|
|
56
|
+
config: AgentConfig;
|
|
57
|
+
audit: IAuditLogger;
|
|
58
|
+
notificationMgr: INotificationManager;
|
|
59
|
+
sessionMgr: ISessionManager;
|
|
60
|
+
/** Live reference to the dispatcher's notify-dedup set. */
|
|
61
|
+
notifiedEvents: Set<string>;
|
|
62
|
+
/** Mirrors `EventDispatcher.isReactive` for audit-trigger classification. */
|
|
63
|
+
isReactive: (event: Event) => boolean;
|
|
64
|
+
/**
|
|
65
|
+
* Whether the messages table has the `backend` and `model_id`
|
|
66
|
+
* columns. Computed once at dispatcher startup; the cross-session
|
|
67
|
+
* history builder branches on it to keep ancient deployments
|
|
68
|
+
* upgradable.
|
|
69
|
+
*/
|
|
70
|
+
hasMessageBackendMetadataColumns: boolean;
|
|
71
|
+
}
|
|
72
|
+
export declare class ResultProcessor {
|
|
73
|
+
private readonly db;
|
|
74
|
+
private readonly config;
|
|
75
|
+
private readonly audit;
|
|
76
|
+
private readonly notificationMgr;
|
|
77
|
+
private readonly sessionMgr;
|
|
78
|
+
private readonly notifiedEvents;
|
|
79
|
+
private readonly isReactive;
|
|
80
|
+
private readonly hasMessageBackendMetadataColumns;
|
|
81
|
+
constructor(deps: ResultProcessorDeps);
|
|
82
|
+
processResult(result: AgentResult, event: Event, skipNotify?: boolean, options?: {
|
|
83
|
+
originSessionId?: number;
|
|
84
|
+
dmFreshness?: {
|
|
85
|
+
resumed: boolean;
|
|
86
|
+
agentLogLagMinutes: number;
|
|
87
|
+
loudWritesSinceSessionStart: number;
|
|
88
|
+
quietWritesSinceSessionStart: number;
|
|
89
|
+
refetchedToday: boolean;
|
|
90
|
+
triggerMatched: boolean;
|
|
91
|
+
};
|
|
92
|
+
}): Promise<void>;
|
|
93
|
+
/**
|
|
94
|
+
* P6 (git-lifecycle-and-triggers.md Decision 8) — restore in-flight
|
|
95
|
+
* `git.project.retemplate` targets from backup whenever a retemplate
|
|
96
|
+
* scheduled task settles. The agent itself cannot reliably roll back
|
|
97
|
+
* its own writes (process exit, exceeded turns, backend faults), so
|
|
98
|
+
* the daemon owns rollback at the dispatcher's two terminal sites
|
|
99
|
+
* (`processResult` + `handleError`). The status grid is the source of
|
|
100
|
+
* truth for which files to restore; `finalizeRetemplate` is idempotent
|
|
101
|
+
* via the `finalizedAt` marker so calling both paths is safe.
|
|
102
|
+
*/
|
|
103
|
+
finalizeRetemplateRunIfApplicable(event: Event, options: {
|
|
104
|
+
errored: boolean;
|
|
105
|
+
}): void;
|
|
106
|
+
/**
|
|
107
|
+
* Unified-repositories §4.5 — settle a `repository_management` row when
|
|
108
|
+
* a `git.project.init` / `git.project.update` event the daemon emitted
|
|
109
|
+
* for management terminates. Runs unconditionally on every event
|
|
110
|
+
* because management events live on the EventBus only (no
|
|
111
|
+
* `agent_schedule` row), so the scheduleId-guarded path can't see
|
|
112
|
+
* them; the method early-returns for any taskContext that doesn't
|
|
113
|
+
* carry management metadata.
|
|
114
|
+
*
|
|
115
|
+
* Status mapping (v1):
|
|
116
|
+
* - `git.project.init` success → `recordManagementInitDone`
|
|
117
|
+
* - `git.project.update` success → `recordManagementScan('ok')`
|
|
118
|
+
* (resets `scan_failure_count`)
|
|
119
|
+
* - either, error → `recordManagementScan('failed')`
|
|
120
|
+
* (bumps `scan_failure_count`)
|
|
121
|
+
*
|
|
122
|
+
* `'skipped_no_activity'` is reserved for future task-flow callback —
|
|
123
|
+
* the dispatcher cannot reliably distinguish "agent decided no
|
|
124
|
+
* journal entry needed" from "agent succeeded but didn't write" here.
|
|
125
|
+
*/
|
|
126
|
+
finalizeManagementScanIfApplicable(event: Event, options: {
|
|
127
|
+
errored: boolean;
|
|
128
|
+
}): void;
|
|
129
|
+
hasRecentProactiveForwardContext(event: MessageEvent, sessionId: number): boolean;
|
|
130
|
+
logProactiveForwardDisavowalIfMatched(sessionId: number, reply: string): void;
|
|
131
|
+
formatSummaryRole(message: {
|
|
132
|
+
role: string;
|
|
133
|
+
metadata?: string | null;
|
|
134
|
+
}): string;
|
|
135
|
+
buildCrossSessionConversationHistory(event: MessageEvent): string | null;
|
|
136
|
+
shouldNotify(event: Event): boolean;
|
|
137
|
+
/**
|
|
138
|
+
* Autonomous "observer" events: external-change detections that the
|
|
139
|
+
* daemon pushes into the pipeline, as opposed to user-initiated
|
|
140
|
+
* messages, cron routines, or scheduled tasks. Used for the
|
|
141
|
+
* contextUpdated observability log in processResult.
|
|
142
|
+
*/
|
|
143
|
+
isObserverEvent(event: Event): boolean;
|
|
144
|
+
}
|
|
145
|
+
//# sourceMappingURL=dispatcher-result-processor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dispatcher-result-processor.d.ts","sourceRoot":"","sources":["../../src/core/dispatcher-result-processor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AAEH,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAC3C,OAAO,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,WAAW,EAAa,MAAM,eAAe,CAAC;AASjF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAkBhD,OAAO,KAAK,EACV,YAAY,EACZ,oBAAoB,EACpB,eAAe,EAChB,MAAM,uBAAuB,CAAC;AAK/B;;;;;;;GAOG;AACH,eAAO,MAAM,oCAAoC,EAAE,MAAM,EAKxD,CAAC;AAEF,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,QAAQ,CAAC,QAAQ,CAAC;IACtB,MAAM,EAAE,WAAW,CAAC;IACpB,KAAK,EAAE,YAAY,CAAC;IACpB,eAAe,EAAE,oBAAoB,CAAC;IACtC,UAAU,EAAE,eAAe,CAAC;IAC5B,2DAA2D;IAC3D,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC5B,6EAA6E;IAC7E,UAAU,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC;IACtC;;;;;OAKG;IACH,gCAAgC,EAAE,OAAO,CAAC;CAC3C;AAED,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAoB;IACvC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAc;IACrC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAe;IACrC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAuB;IACvD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAkB;IAC7C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAc;IAC7C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA4B;IACvD,OAAO,CAAC,QAAQ,CAAC,gCAAgC,CAAU;gBAE/C,IAAI,EAAE,mBAAmB;IAW/B,aAAa,CACjB,MAAM,EAAE,WAAW,EACnB,KAAK,EAAE,KAAK,EACZ,UAAU,UAAQ,EAClB,OAAO,GAAE;QACP,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,WAAW,CAAC,EAAE;YACZ,OAAO,EAAE,OAAO,CAAC;YACjB,kBAAkB,EAAE,MAAM,CAAC;YAC3B,2BAA2B,EAAE,MAAM,CAAC;YACpC,4BAA4B,EAAE,MAAM,CAAC;YACrC,cAAc,EAAE,OAAO,CAAC;YACxB,cAAc,EAAE,OAAO,CAAC;SACzB,CAAC;KACE,GACL,OAAO,CAAC,IAAI,CAAC;IAgFhB;;;;;;;;;OASG;IACH,iCAAiC,CAC/B,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,GAC5B,IAAI;IAmCP;;;;;;;;;;;;;;;;;;;OAmBG;IACH,kCAAkC,CAChC,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,GAC5B,IAAI;IAgDP,gCAAgC,CAC9B,KAAK,EAAE,YAAY,EACnB,SAAS,EAAE,MAAM,GAChB,OAAO;IA2DV,qCAAqC,CACnC,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,GACZ,IAAI;IAgCP,iBAAiB,CAAC,OAAO,EAAE;QACzB,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;KAC1B,GAAG,MAAM;IAQV,oCAAoC,CAAC,KAAK,EAAE,YAAY,GAAG,MAAM,GAAG,IAAI;IAiExE,YAAY,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO;IAmBnC;;;;;OAKG;IACH,eAAe,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO;CAUvC"}
|