/** * trigger-author - Task 3, the heart (G1 + G3). * * The agent recognizes a recurring situation in a window of polled events and AUTHORS a * trigger (its match keywords, memoryQuery, procedure, requiredEvidence). This replaces both * Kagemusha's hardcoded regex markers (G1) and its 4-profile executable catalog (G3). * * The agent is injected (`AskAgent`) so the flow is deterministic + unit-testable; the real * claude-CLI agent is `askAgentCLI`, exercised by the LLM eval. * * G3 GUARD: validation is STRUCTURAL only. `kind` and `procedure[].action` are open strings; * unknown VALUES are accepted. Never narrow them to a fixed enum - that re-freezes G3. */ import type { CodexRuntimeProcessOptions } from '../multi-agent/runtime-process.js'; import type { IModelRunner } from '../agent/model-runner.js'; import type { OperatorChannelEvent } from './operator-interfaces.js'; import type { TriggerRecord } from './trigger-types.js'; import type { TriggerRegistry } from './trigger-registry.js'; /** Injected agent: prompt in, raw text answer out. */ export type AskAgent = (prompt: string) => Promise; /** What the agent returns (a CreateTriggerInput minus server-managed fields). */ export interface TriggerSpec { id?: string; kind: string; memoryQuery: string; match: { keywords: string[]; keywordMode: 'any' | 'every'; scopeChannelIds?: string[]; minConfidence: number; }; procedure: { action: string; description: string; }[]; requiredEvidence: string[]; } export interface AuthorOptions { note?: string; } type TriggerCodexRunner = Pick; type TriggerClineRunner = Pick; export interface TriggerAgentRuntimeOptions { model?: string; cwd?: string; command?: string; requestTimeout?: number; provider?: string; dataDir?: string; } export interface TriggerAgentRuntime { askAuthor: AskAgent; askReview: AskAgent; stop(): Promise; } export interface TriggerAgentRuntimeDependencies { askClaude?: AskAgent; createClaudeAsk?: (options: { model?: string; signal?: AbortSignal; }) => AskAgent; createCodexRuntime?: (options: CodexRuntimeProcessOptions) => TriggerCodexRunner; createClineRuntime?: (options: { command?: string; provider?: string; model?: string; systemPrompt?: string; cwd?: string; dataDir?: string; requestTimeout?: number; }) => TriggerClineRunner; } export type ClaudeCliExecutor = (file: string, args: string[], options: { maxBuffer: number; signal?: AbortSignal; }) => Promise<{ stdout: string; }>; export declare function authorTriggers(events: OperatorChannelEvent[], registry: TriggerRegistry, askAgent: AskAgent, opts?: AuthorOptions): Promise; export declare function buildAuthorPrompt(events: OperatorChannelEvent[], existing: TriggerRecord[]): string; export declare function parseTriggerSpecs(text: string): TriggerSpec[]; export declare function validateTriggerSpec(spec: unknown): TriggerSpec; export declare function createAskAgentCLI(execute?: ClaudeCliExecutor, options?: { model?: string; signal?: AbortSignal; }): AskAgent; /** Real agent: the local claude CLI (CLI-over-API). Preserved for eval compatibility. */ export declare const askAgentCLI: AskAgent; /** * Provider boundary for trigger authoring and review. * * Claude keeps an isolated JSON-only CLI path. Codex shares one app-server * connection, but every structured task starts a fresh, isolated, read-only * session and advertises no host tools. */ export declare function createTriggerAgentRuntime(backend: 'claude' | 'codex' | 'cline', options?: TriggerAgentRuntimeOptions, dependencies?: TriggerAgentRuntimeDependencies): TriggerAgentRuntime; /** * One line naming the failure, with the command line left OUT. * * Node's own message embeds the whole argv, which here is the 240 KB prompt - that is what * made every past failure unreadable in the log without telling anyone anything. */ export declare function describeCliFailure(file: string, error: unknown): string; export {}; //# sourceMappingURL=trigger-author.d.ts.map