qlogicagent 2.18.1 → 2.18.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.
Files changed (91) hide show
  1. package/dist/agent.js +40 -22
  2. package/dist/cli.js +1 -1
  3. package/dist/index.js +528 -470
  4. package/dist/orchestration.js +11 -11
  5. package/dist/protocol.js +1 -1
  6. package/dist/skills/mcp/astraclaw-native-mcp-server.js +8 -6
  7. package/dist/types/agent/memory-recall-injection.d.ts +2 -1
  8. package/dist/types/agent/tool-loop/budget-continuation-policy.d.ts +4 -0
  9. package/dist/types/agent/tool-loop/completion-action-policy.d.ts +9 -1
  10. package/dist/types/agent/tool-loop/compression-pipeline.d.ts +2 -0
  11. package/dist/types/agent/tool-loop/loop-helpers.d.ts +1 -0
  12. package/dist/types/agent/tool-loop/tool-failure-policy.d.ts +13 -1
  13. package/dist/types/agent/tool-loop.d.ts +8 -0
  14. package/dist/types/agent/types.d.ts +2 -0
  15. package/dist/types/cli/credential-vault.d.ts +6 -0
  16. package/dist/types/cli/handlers/turn-handler.d.ts +50 -1
  17. package/dist/types/cli/handlers/workflow-handler.d.ts +1 -0
  18. package/dist/types/cli/memory-coordinator.d.ts +4 -0
  19. package/dist/types/cli/pet-runtime.d.ts +2 -0
  20. package/dist/types/cli/rpc-registry.d.ts +11 -0
  21. package/dist/types/cli/runtime-hook-bootstrap.d.ts +2 -0
  22. package/dist/types/cli/skill-tools-bootstrap.d.ts +5 -0
  23. package/dist/types/cli/stdio-acp-request-host.d.ts +2 -1
  24. package/dist/types/cli/stdio-rpc-handler-hosts.d.ts +1 -0
  25. package/dist/types/cli/stdio-server.d.ts +4 -0
  26. package/dist/types/cli/task-distillation-coordinator.d.ts +79 -0
  27. package/dist/types/cli/tool-bootstrap-core-registration.d.ts +24 -0
  28. package/dist/types/cli/turn-core.d.ts +0 -6
  29. package/dist/types/cli/turn-project-router.d.ts +9 -0
  30. package/dist/types/contracts/hooks.d.ts +3 -0
  31. package/dist/types/contracts/turn-event.d.ts +8 -4
  32. package/dist/types/orchestration/agent-instance.d.ts +11 -1
  33. package/dist/types/orchestration/agent-roster.d.ts +12 -0
  34. package/dist/types/orchestration/context/reactive-compact.d.ts +4 -6
  35. package/dist/types/orchestration/dag-scheduler.d.ts +3 -0
  36. package/dist/types/orchestration/delegation-coordinator.d.ts +6 -1
  37. package/dist/types/orchestration/error-handling/retry-loop.d.ts +0 -22
  38. package/dist/types/orchestration/goal-loop-coordinator.d.ts +10 -1
  39. package/dist/types/orchestration/goal-mode-adapters.d.ts +23 -2
  40. package/dist/types/orchestration/goal-run-types.d.ts +12 -0
  41. package/dist/types/orchestration/product-budget.d.ts +13 -0
  42. package/dist/types/orchestration/product-planner.d.ts +7 -2
  43. package/dist/types/orchestration/product-run-coordinator.d.ts +1 -0
  44. package/dist/types/orchestration/skill-improvement.d.ts +7 -2
  45. package/dist/types/orchestration/workflow/budget-permission-gate.d.ts +9 -0
  46. package/dist/types/orchestration/workflow/node-schema.d.ts +4 -1
  47. package/dist/types/orchestration/workflow/run-history-store.d.ts +2 -0
  48. package/dist/types/orchestration/workflow/workflow-runtime.d.ts +8 -0
  49. package/dist/types/orchestration/workflow/workflow-trigger.d.ts +5 -1
  50. package/dist/types/protocol/wire/acp-agent-management.d.ts +3 -0
  51. package/dist/types/protocol/wire/agent-events.d.ts +2 -2
  52. package/dist/types/protocol/wire/gateway-rpc.d.ts +1 -0
  53. package/dist/types/protocol/wire/memory-provider-lifecycle.d.ts +3 -0
  54. package/dist/types/protocol/wire/notification-payloads.d.ts +27 -0
  55. package/dist/types/runtime/config/tunable-defaults.d.ts +6 -0
  56. package/dist/types/runtime/execution/memory-decay.d.ts +5 -1
  57. package/dist/types/runtime/execution/streaming-tool-executor.d.ts +2 -0
  58. package/dist/types/runtime/execution/tool-result-storage.d.ts +6 -4
  59. package/dist/types/runtime/hooks/context-compression.d.ts +5 -0
  60. package/dist/types/runtime/hooks/memory-hooks.d.ts +10 -0
  61. package/dist/types/runtime/infra/acp-detector.d.ts +8 -0
  62. package/dist/types/runtime/infra/acp-protocol-adapter.d.ts +19 -1
  63. package/dist/types/runtime/infra/agent-process.d.ts +6 -0
  64. package/dist/types/runtime/infra/astraclaw-capabilities.d.ts +9 -0
  65. package/dist/types/runtime/infra/external-agent-pool.d.ts +12 -0
  66. package/dist/types/runtime/infra/working-materials-store.d.ts +8 -14
  67. package/dist/types/runtime/pet/pet-profile-service.d.ts +7 -0
  68. package/dist/types/runtime/pet/petdex-forge-service.d.ts +3 -1
  69. package/dist/types/runtime/ports/agent-runtime-ports.d.ts +4 -1
  70. package/dist/types/runtime/ports/memory-provider.d.ts +2 -0
  71. package/dist/types/runtime/ports/project-memory-store.d.ts +2 -0
  72. package/dist/types/runtime/prompt/environment-context.d.ts +25 -3
  73. package/dist/types/runtime/prompt/fresh-workspace-evidence.d.ts +7 -2
  74. package/dist/types/runtime/prompt/instruction-loader.d.ts +0 -1
  75. package/dist/types/runtime/session/inbound-upload-persistence.d.ts +12 -0
  76. package/dist/types/runtime/session/session-catalog.d.ts +8 -0
  77. package/dist/types/runtime/session/session-resource-key.d.ts +28 -0
  78. package/dist/types/runtime/session/session-resume.d.ts +5 -0
  79. package/dist/types/runtime/session/session-transcript-store.d.ts +10 -1
  80. package/dist/types/runtime/session/session-types.d.ts +29 -0
  81. package/dist/types/skills/mcp/mcp-manager.d.ts +25 -1
  82. package/dist/types/skills/memory/local-memory-provider.d.ts +14 -0
  83. package/dist/types/skills/memory/local-store.d.ts +2 -0
  84. package/dist/types/skills/memory/memdir.d.ts +8 -0
  85. package/dist/types/skills/memory/task-distillation.d.ts +148 -0
  86. package/dist/types/skills/tools/search-tool.d.ts +6 -0
  87. package/dist/types/skills/tools/shell/task-output.d.ts +2 -0
  88. package/package.json +4 -3
  89. package/dist/types/agent/tool-loop/skill-instruction-policy.d.ts +0 -7
  90. package/dist/types/agent/tool-loop/tool-guardrails.d.ts +0 -24
  91. package/dist/types/cli/turn-skill-autopersist.d.ts +0 -22
@@ -10,6 +10,10 @@ export interface BudgetContinuationPolicyInput {
10
10
  thinkingBlocks: readonly ThinkingBlock[];
11
11
  getBudgetContinuationMessage(usagePct: number, totalUsed: number, tokenBudget?: number): string;
12
12
  log: Pick<AgentLogger, "info">;
13
+ /** The loop's per-turn recovery trace (surfaced on the final `end` event). Stop
14
+ * reasons are recorded here as `budget_continuation_stop:<reason>` so an engine-side
15
+ * end of nudging is visible to callers/UI, not only in the debug log. */
16
+ recoveryTrace?: Map<string, number>;
13
17
  }
14
18
  export interface BudgetContinuationPolicyDecision {
15
19
  messages: unknown[];
@@ -17,7 +17,15 @@ export interface CompletionActionPolicyDecision {
17
17
  transition: ToolLoopTransition;
18
18
  }
19
19
  export declare function findMissingExplicitRequiredFiles(inputMessages: readonly ChatMessage[], messages: unknown[]): string[];
20
- export declare function buildExplicitRequiredFilesFailureContent(input: {
20
+ /**
21
+ * Terminal-path NOTE (not a replacement): when a forced stop ends the turn with
22
+ * explicitly-requested output files still missing, this returns an engine-attributed
23
+ * note to APPEND to whatever the turn is already ending with. It used to return a
24
+ * "<FAIL-marker> ..." string that REPLACED the model's final text — an extraction
25
+ * misfire then handed the user an engine-authored FAIL verdict the model never made
26
+ * (2026-07-07 review, F5). The engine reports evidence; it does not speak as the model.
27
+ */
28
+ export declare function buildMissingRequiredFilesNote(input: {
21
29
  inputMessages: readonly ChatMessage[];
22
30
  messages: unknown[];
23
31
  reason: string;
@@ -30,6 +30,8 @@ export interface CompressionPipelineDeps {
30
30
  turnId: string;
31
31
  };
32
32
  sessionId: string;
33
+ /** Turn workspace/cwd — routes oversized tool-result spillover to the session's reachable data dir. */
34
+ projectRoot: string | undefined;
33
35
  currentModel: string;
34
36
  log: AgentLogger;
35
37
  /** Build + record a recovery event (centralized in the loop's recovery trace). */
@@ -1,5 +1,6 @@
1
1
  import type { ChatMessage } from "../types.js";
2
2
  export { isEmptyToolResult } from "./tool-result-classification.js";
3
+ export declare const OUTPUT_REQUEST_CONTEXT_PATTERN: RegExp;
3
4
  export declare function findLastToolError(messages: unknown[], _toolName: string): string | undefined;
4
5
  export declare function looksLikeBuildRequest(messages?: readonly ChatMessage[]): boolean;
5
6
  export declare function isBareIntentPreamble(text: string): boolean;
@@ -5,7 +5,18 @@ export interface VariantBlockedToolCall {
5
5
  failCount: number;
6
6
  error: string;
7
7
  }
8
- export declare function splitVariantToolCalls(calls: readonly OpenAiToolCall[], toolFailureCounts: ReadonlyMap<string, number>): {
8
+ export declare function splitVariantToolCalls(calls: readonly OpenAiToolCall[], toolFailureCounts: ReadonlyMap<string, number>,
9
+ /**
10
+ * Exact call signatures (name::rawArguments) that were variant-blocked at least once and are
11
+ * eligible for ONE deliberate re-assertion pass. Mutated in place: blocking a call registers
12
+ * its signature; a verbatim re-issue consumes it and runs. The engine cannot tell "another
13
+ * variation of the failed thing" from "a genuinely different task in the same family"
14
+ * (e.g. `pip install A` failing twice must not condemn `pip install C` forever) — so the
15
+ * MODEL's insistence after seeing the warning is the judgment call. A variation-cycling loop
16
+ * never re-issues verbatim, so it stays blocked; verbatim spam is capped separately by the
17
+ * identical-call-repeat guard.
18
+ */
19
+ reassertedSignatures: Set<string>): {
9
20
  allowed: OpenAiToolCall[];
10
21
  blocked: VariantBlockedToolCall[];
11
22
  };
@@ -15,6 +26,7 @@ export declare function recordToolFailureResult(input: {
15
26
  toolName: string;
16
27
  toolArguments?: string;
17
28
  ok: boolean;
29
+ /** True when the tool succeeded but returned an empty/no-match result. Kept for caller clarity. */
18
30
  softEmpty: boolean;
19
31
  }): void;
20
32
  export declare function newVariantFailureNudges(input: {
@@ -39,6 +39,14 @@ export interface ToolLoopParams {
39
39
  modelMaxOutputTokens?: number;
40
40
  /** Tool choice strategy (default "auto") */
41
41
  toolChoice?: "auto" | "none" | "required";
42
+ /**
43
+ * The turn's request demands fresh tool evidence (file read / command run / media generated).
44
+ * The prompt section instructs it; this flag arms the loop's REACTIVE one-shot forced retry
45
+ * when the model answers in prose with zero tool calls anyway. Replaces the retired upstream
46
+ * tool_choice="required" forcing (judgment-over-mechanism: hint first, force only on the
47
+ * observed violation).
48
+ */
49
+ freshEvidenceRequired?: boolean;
42
50
  /**
43
51
  * Build/test verification gate (lever ②). Default true. Set false to disable the
44
52
  * "fix-and-rerun until the test/build passes" recovery — used for A/B measurement.
@@ -124,6 +124,8 @@ export interface TurnConfig {
124
124
  modelMaxOutputTokens?: number;
125
125
  /** Tool choice strategy: "auto" (default), "none", "required" */
126
126
  toolChoice?: "auto" | "none" | "required";
127
+ /** Turn demands fresh tool evidence — arms the loop's reactive one-shot forced retry. */
128
+ freshEvidenceRequired?: boolean;
127
129
  /** Parent fork depth (0 = top-level, default 0). CC: depth tracking for fork recursion limit. */
128
130
  parentDepth?: number;
129
131
  /** Per-turn token budget (prompt + completion). 0 or undefined = unlimited. */
@@ -24,6 +24,12 @@ export interface CredentialSummary {
24
24
  updatedAt: string;
25
25
  /** Secret-free hints for pickers (e.g. apiKey header name, oauth2 scopes). */
26
26
  meta?: Record<string, unknown>;
27
+ /**
28
+ * Set when the on-disk envelope could not be read/parsed. The entry is unusable (get()
29
+ * throws) but stays VISIBLE in list() so the list-driven UI shows the loss instead of the
30
+ * credential silently vanishing; delete works on it.
31
+ */
32
+ corrupt?: true;
27
33
  }
28
34
  /**
29
35
  * Secret payload shapes by type (validated on create):
@@ -4,6 +4,9 @@
4
4
  */
5
5
  import { type ModelPurpose } from "../../runtime/infra/model-registry.js";
6
6
  import { type UnderstandMediaClient, type UnderstandMediaKind } from "../media-understanding.js";
7
+ import { type InstructionFileInfo } from "../../runtime/prompt/instruction-loader.js";
8
+ import type { HookRegistry } from "../../contracts/hooks.js";
9
+ import type { AppendMessageOutcome } from "../../runtime/session/session-transcript-store.js";
7
10
  import type { PermissionMetadataResolver, ToolCatalog } from "../../runtime/ports/index.js";
8
11
  import type { ChatMessage, TokenUsage, ToolDefinition, TurnConfig } from "../../agent/types.js";
9
12
  import type { AgentRpcRequest } from "../../protocol/wire/agent-rpc.js";
@@ -59,6 +62,40 @@ export interface FirstTurnTitleGenerationDeps {
59
62
  log(message: string): void;
60
63
  }
61
64
  export declare function runFirstTurnTitleGeneration(deps: FirstTurnTitleGenerationDeps): Promise<void>;
65
+ /**
66
+ * Loud trace for fire-and-forget background persistence work inside the turn pipeline.
67
+ * Replaces the old silent `.catch(() => {})` pattern (judgment-over-mechanism: a failed write
68
+ * must at least be diagnosable in the engine log, never swallowed).
69
+ */
70
+ export declare function logTurnBackgroundFailure(context: string, err: unknown): void;
71
+ /**
72
+ * Per-turn transcript-persist failure reporter. A lost transcript write means the conversation is
73
+ * missing messages after a reload — that must be VISIBLE: console.error every failure with turn
74
+ * context, and emit ONE `turn.recovery` notification per turn (first failure only) so the user is
75
+ * told without flooding the stream when several writes of the same turn fail.
76
+ * "skipped-deleted" is the legal late-write no-op on a deleted session — not a failure, no trace.
77
+ */
78
+ export declare function createTranscriptPersistFailureReporter(deps: {
79
+ turnId: string;
80
+ sessionId: string;
81
+ sendNotification(method: string, params: Record<string, unknown>): void;
82
+ }): (which: string, outcome: AppendMessageOutcome | {
83
+ rejected: unknown;
84
+ }) => void;
85
+ /**
86
+ * Load the INSTRUCTIONS.md / project-rules block for a turn. A load failure means the WHOLE turn
87
+ * runs without the user's standing rules — the old inline catch called that "non-fatal" and left
88
+ * zero trace. Degrading is still the right call (the turn can proceed), but it must be visible:
89
+ * console.error + a `turn.recovery` note in the turn event stream.
90
+ * `loadInstructions` is injectable so tests can force a failure; defaults to getInstructions.
91
+ */
92
+ export declare function loadInstructionBlockForTurn(deps: {
93
+ cwd: string;
94
+ turnId: string;
95
+ hooks?: HookRegistry;
96
+ sendNotification(method: string, params: Record<string, unknown>): void;
97
+ loadInstructions?(cwd: string, hooks?: HookRegistry): Promise<InstructionFileInfo[]>;
98
+ }): Promise<string | undefined>;
62
99
  export declare function hydrateTurnConfigFromModelMetadata(config: TurnConfig): TurnConfig;
63
100
  export declare function hydrateAttachmentReferenceUrlsForTurn(messages: ChatMessage[]): ChatMessage[];
64
101
  export declare function getFocusedAttachmentToolNamesForTurn(messages: ChatMessage[]): Set<string> | null;
@@ -85,8 +122,20 @@ export declare function augmentLastUserMessageContent(messages: ChatMessage[], m
85
122
  * invisible to those user-intent scans. The original array/objects are never mutated.
86
123
  */
87
124
  export declare function injectSkillContextBeforeLastUser(messages: ChatMessage[], skillContext: string): ChatMessage[];
125
+ /**
126
+ * Insert the per-turn DOMAIN guidance block as a SYSTEM-role message immediately BEFORE the
127
+ * last user message (LLM view only) — the prompt-cache alignment path.
128
+ *
129
+ * Same rationale as injectSkillContextBeforeLastUser: the domain block carries markdown headers
130
+ * ("# Doing Tasks"), the word "artifact", and example file paths — baking it into the user message
131
+ * would poison the user-intent scans (final-marker extraction, artifact counting, round/tool
132
+ * budgets) that read `role === "user"` content. A system message keeps the model bound to the
133
+ * guidance while staying invisible to those scans. Kept out of the system PROMPT so a domain
134
+ * switch never re-encodes the byte-stable prefix or the conversation history. The original
135
+ * array/objects are never mutated.
136
+ */
137
+ export declare function injectDomainGuidanceBeforeLastUser(messages: ChatMessage[], domainGuidance: string): ChatMessage[];
88
138
  export declare function getFocusedAttachmentModelPurposeForTurn(messages: ChatMessage[]): FocusedAttachmentModelPurpose | null;
89
- export declare function requiresPreToolPreambleForTurn(messages: readonly ChatMessage[]): boolean;
90
139
  export declare function refreshPermissionCheckerToolMeta(permissionChecker: PermissionMetadataResolver | null | undefined, tools: ToolDefinition[]): void;
91
140
  export declare function handleUserResponse(this: TurnControlHandlerHost, msg: AgentRpcRequest): void;
92
141
  /**
@@ -152,6 +152,7 @@ export declare function collectActiveIntentWorkflows(this: WorkflowCoordinatorHo
152
152
  trigger: Extract<NonNullable<WorkflowRecord["trigger"]>, {
153
153
  type: "intent";
154
154
  }>;
155
+ sideEffectKinds: string[];
155
156
  }>>;
156
157
  /**
157
158
  * `workflow.intentIndex` — the deterministic-match index the CLIENT consumes (phrases/aliases/
@@ -25,6 +25,10 @@ export interface RegisterMemoryRuntimeHooksDeps {
25
25
  apiKey: string;
26
26
  model: string;
27
27
  } | null;
28
+ /** Part B recall visibility: forwards turn.memory_recall to the client. */
29
+ sendNotification?: (method: string, params: Record<string, unknown>) => void;
30
+ /** V3.2 usage 仪表落盘目录(memory-hooks 记录 procedure 复用维度)。 */
31
+ profileMemoryDir?: () => string;
28
32
  }
29
33
  export declare function registerMemoryRuntimeHooks(deps: RegisterMemoryRuntimeHooksDeps): MemoryProviderState;
30
34
  export interface RegisterMemoryToolDeps {
@@ -23,6 +23,8 @@ export interface PetdexForgeOutput {
23
23
  spritesheet: Buffer;
24
24
  validation: PetdexValidationReport;
25
25
  productionRun?: PetdexProductionRun;
26
+ /** Jobs accepted WITHOUT a working vision-QA verdict (QA call failed → fail-open, but traced). */
27
+ qaSkippedJobs?: string[];
26
28
  mediaUsage?: {
27
29
  provider: string;
28
30
  model: string;
@@ -36,7 +36,18 @@ export type RpcMethodHandler = (msg: AgentRpcRequest) => void;
36
36
  * The pattern mirrors the existing createDreamHandlerHost / createMultiAgentHandlerHost
37
37
  * adapters, just applied uniformly across every RPC domain.
38
38
  */
39
+ export interface TaskDistillationRpcSurface {
40
+ runPass(reason: "manual"): Promise<object>;
41
+ listProposals(): unknown[];
42
+ dismissProposal(id: string): boolean;
43
+ acknowledgeProposal(id: string): boolean;
44
+ getMetrics(): object;
45
+ promote(id: string): Promise<object>;
46
+ demote(id: string): Promise<object>;
47
+ }
39
48
  export interface RpcHandlerHosts {
49
+ /** R3/V3 蒸馏晋升面(惰性:首调时构造 coordinator)。 */
50
+ getTaskDistillation?: () => TaskDistillationRpcSurface;
40
51
  config: ConfigHandlerHost;
41
52
  control: ControlHandlerHost;
42
53
  session: SessionHandlerHost;
@@ -28,6 +28,8 @@ export interface RuntimeHookBootstrapDeps {
28
28
  apiKey: string;
29
29
  };
30
30
  sendNotification?(method: string, params: Record<string, unknown>): void;
31
+ /** V3.2 usage 仪表落盘目录。 */
32
+ profileMemoryDir?: () => string;
31
33
  }
32
34
  export interface RuntimeHookBootstrapResult {
33
35
  hooks: HookRegistry;
@@ -26,3 +26,8 @@ export declare function configureSkillToolsBootstrap(host: SkillToolsHost, deps:
26
26
  * content path, never the raw supporting-file write).
27
27
  */
28
28
  export declare function resolveSupportingFilePath(skillDir: string, filePath: string): string | null;
29
+ /**
30
+ * 读技能文件:ENOENT(文件不存在)→ null(语义 = 技能/文件未安装);其余失败
31
+ * (EPERM/EISDIR 等)抛出真实错误 —— 读失败不能伪装成"技能不存在"。导出仅为单测。
32
+ */
33
+ export declare function readSkillFileOrNull(label: string, filePath: string): Promise<string | null>;
@@ -16,6 +16,7 @@ export type StdioAcpRequestHostSource = Pick<CliAcpRequestHandlerHost, "activeTu
16
16
  petRuntime: unknown;
17
17
  projectMemoryStoreFactory: unknown;
18
18
  toolCatalog: unknown;
19
+ taskDistillation: unknown;
19
20
  cancelBackgroundTasksForSession(sessionId?: string): void;
20
21
  configureTurnMedia(config: Record<string, unknown> | undefined, turnId: string): void;
21
22
  drainPendingTaskNotifications(): string[];
@@ -25,5 +26,5 @@ export type StdioAcpRequestHostSource = Pick<CliAcpRequestHandlerHost, "activeTu
25
26
  };
26
27
  /** Host members the shared turn pipeline reads/writes — keep in sync with
27
28
  * `grep -oE "this\.[a-zA-Z]+" src/cli/handlers/turn-handler.ts | sort -u`. */
28
- export declare const TURN_PIPELINE_HOST_MEMBERS: readonly ["activeTurn", "configureTurnMedia", "currentHooks", "currentModel", "currentTurnId", "drainPendingTaskNotifications", "getActiveProjectRoot", "lastAssistantMessageForExtract", "lastUserMessageForAutoExtract", "log", "mcpReady", "memdir", "pendingAskUser", "permissionChecker", "petRuntime", "projectMemoryStoreFactory", "resolveAgent", "resolveClientForPurpose", "sendNotification", "sendResponse", "sessionHistory", "sessionState", "setActiveWorkdir", "toolCatalog"];
29
+ export declare const TURN_PIPELINE_HOST_MEMBERS: readonly ["activeTurn", "configureTurnMedia", "currentHooks", "currentModel", "currentTurnId", "drainPendingTaskNotifications", "getActiveProjectRoot", "lastAssistantMessageForExtract", "lastUserMessageForAutoExtract", "log", "mcpReady", "memdir", "pendingAskUser", "permissionChecker", "petRuntime", "projectMemoryStoreFactory", "resolveAgent", "resolveClientForPurpose", "sendNotification", "sendResponse", "sessionHistory", "sessionState", "setActiveWorkdir", "taskDistillation", "toolCatalog"];
29
30
  export declare function createStdioAcpRequestHandlerHost(host: StdioAcpRequestHostSource): CliAcpRequestHandlerHost;
@@ -10,6 +10,7 @@ type DirectStdioRpcHost = RpcHandlerHosts["config"] & RpcHandlerHosts["control"]
10
10
  readonly workflowHandlerHost: RpcHandlerHosts["workflow"];
11
11
  };
12
12
  type StdioRpcAdapterSource = DirectStdioRpcHost & {
13
+ ensureTaskDistillation(): import("./rpc-registry.js").TaskDistillationRpcSurface;
13
14
  activeTurn: RpcHandlerHosts["turn"]["activeTurn"];
14
15
  currentSessionId: NonNullable<RpcHandlerHosts["session"]["currentSessionId"]>;
15
16
  currentModel: NonNullable<RpcHandlerHosts["session"]["currentModel"]>;
@@ -8,6 +8,7 @@
8
8
  * Protocol: each message is a single JSON-RPC 2.0 object.
9
9
  * The physical I/O layer is abstracted via the Transport interface.
10
10
  */
11
+ import { TaskDistillationCoordinator } from "./task-distillation-coordinator.js";
11
12
  import type { Transport } from "./transport.js";
12
13
  import type { Agent } from "../agent/agent.js";
13
14
  import type { TurnConfig } from "../agent/types.js";
@@ -195,6 +196,9 @@ export declare class StdioServer {
195
196
  * Opening the DB is cheap and side-effect-free (list() does not embed).
196
197
  */
197
198
  ensureMemoryProvider(): void;
199
+ private _taskDistillation;
200
+ get taskDistillation(): TaskDistillationCoordinator;
201
+ ensureTaskDistillation(): TaskDistillationCoordinator;
198
202
  resolveAgent(config: TurnConfig): Agent | null;
199
203
  private invalidateResolvedLlmCache;
200
204
  /** Emit an `agents.status` notification when a child process state changes. */
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Task distillation coordinator (R3 wiring) — 候选采集/空闲窗蒸馏/晋升通知。
3
+ * 纯逻辑在 skills/memory/task-distillation.ts;本模块只做依赖装配与生命周期:
4
+ * · recordTurn: turn-handler 回合完成处调用(轻量,embedding 异步)
5
+ * · runPass: idle 空闲窗(stdio-server onIdle 并联)与 memory.distill RPC 共用入口
6
+ * · 蒸馏产物: category=procedure 进长期记忆(tag distilled@v1+sig),召回自然带出;
7
+ * LLM 摘要(dream 同款小模型)失败时降级确定性模板 —— 蒸馏永不因模型不可用而丢样本。
8
+ * · 晋升(spec:唯一技能入口): accessCount ≥ 阈值且未被负反馈沉底 → system.activity 推荐。
9
+ */
10
+ import { type PromotionMetrics, type CandidateStoreFile, type PromotionProposal } from "../skills/memory/task-distillation.js";
11
+ export interface TaskDistillationDeps {
12
+ profileMemoryDir: () => string;
13
+ /** 签名 embedding;null=不可用(候选照存但不参与聚类,宁严勿松) */
14
+ embed: (text: string) => Promise<Float32Array | null>;
15
+ /** 落库:返回是否成功(候选只在成功后标 distilled) */
16
+ addProcedure: (text: string, tags: string[]) => Promise<boolean>;
17
+ /** 小模型摘要(dream 同款);null/失败 → 降级模板 */
18
+ llmExtract?: (prompt: string) => Promise<string | null>;
19
+ /** 晋升扫描数据源:全部 distilled 条目 {id,text,accessCount,importance} */
20
+ listDistilled: () => Promise<Array<{
21
+ id: string;
22
+ text: string;
23
+ accessCount: number;
24
+ importance: number;
25
+ }>>;
26
+ /** V3 promote/demote:archive(技能接棒)/unarchive(降格回归) */
27
+ setMemoryArchived: (id: string, archived: boolean) => boolean;
28
+ sendNotification: (method: string, params: Record<string, unknown>) => void;
29
+ log: (message: string) => void;
30
+ }
31
+ export interface RecordTurnInput {
32
+ sessionId: string;
33
+ promptHead: string;
34
+ toolSequence: string[];
35
+ durationMs: number;
36
+ ok: boolean;
37
+ }
38
+ export interface DistillPassResult {
39
+ distilled: number;
40
+ promotionsNotified: number;
41
+ pendingCandidates: number;
42
+ }
43
+ export declare class TaskDistillationCoordinator {
44
+ private readonly deps;
45
+ private readonly turnIndexBySession;
46
+ /** 已通知过晋升的条目(进程内防重复打扰;跨重启重复通知无害) */
47
+ private readonly promotionNotified;
48
+ constructor(deps: TaskDistillationDeps);
49
+ /** 回合完成时采集候选。异步(embedding 网络调用),错误吞掉不碰回合主链。 */
50
+ recordTurn(input: RecordTurnInput): Promise<void>;
51
+ /** 空闲窗/手动共用的蒸馏 pass。 */
52
+ runPass(reason: "idle" | "manual"): Promise<DistillPassResult>;
53
+ private renderProcedure;
54
+ /** 晋升扫描(spec:技能的唯一产生入口):复用达标且未被负反馈沉底 → 写持久提议。
55
+ * V3.1:提议是持久待办(promotion-proposals.json),UI 双入口消费;activity 仅作日志。 */
56
+ private scanPromotions;
57
+ listProposals(): PromotionProposal[];
58
+ /** V3.2 仪表(接受率/降格率/自动档解锁态);技能激活计数由 skill-lifecycle useCount 承载。 */
59
+ getMetrics(): PromotionMetrics;
60
+ /** 自动升格开场确认卡「知道了」。 */
61
+ acknowledgeProposal(procedureId: string): boolean;
62
+ dismissProposal(procedureId: string): boolean;
63
+ /** 升格执行链:配方→SKILL.md(LLM 格式转换,降级模板)→落盘+lifecycle(默认启用)
64
+ * →procedure archive(技能接棒,拍板①)→proposal accepted。 */
65
+ promote(procedureId: string, opts?: {
66
+ auto?: boolean;
67
+ }): Promise<{
68
+ ok: boolean;
69
+ skillName?: string;
70
+ error?: string;
71
+ }>;
72
+ /** 降格(可撤销是信任基础):删技能+unarchive 回 procedure;proposal 置 dismissed(用户明确否定,不再纠缠)。 */
73
+ demote(procedureId: string): Promise<{
74
+ ok: boolean;
75
+ error?: string;
76
+ }>;
77
+ private renderSkillMarkdown;
78
+ }
79
+ export declare function buildCandidateStoreSnapshot(profileMemoryDir: string): CandidateStoreFile;
@@ -32,3 +32,27 @@ export declare function registerLocalCoreTools(context: LocalCoreToolRegistratio
32
32
  export declare function validateExecCommand(command: string, workdir: string, groupMode?: boolean): string | null;
33
33
  /** office/pdf 文档扩展名 → mime;非文档返回 undefined。导出仅为单测。 */
34
34
  export declare function documentMimeForExtension(ext: string): string | undefined;
35
+ export interface RipgrepGrepOutcome {
36
+ matches: Array<{
37
+ path: string;
38
+ line: number;
39
+ text: string;
40
+ }>;
41
+ truncated: boolean;
42
+ /** Model-facing incompleteness note (search tool appends it to content). */
43
+ note?: string;
44
+ }
45
+ /**
46
+ * Map an rg execFile exit to a grep outcome. Returns null for real errors (caller
47
+ * rejects and falls back to native grep). When rg was killed (30s timeout or the
48
+ * 10MB maxBuffer cap) the stdout is a partial result set cut mid-stream: it must be
49
+ * flagged truncated with a model-visible note — otherwise the model treats a
50
+ * mid-flight kill as the complete match set. Exported for unit tests only.
51
+ */
52
+ export declare function resolveRipgrepOutcome(err: (Error & {
53
+ killed?: boolean;
54
+ code?: number | string | null;
55
+ }) | null, stdout: string, options: {
56
+ headLimit?: number;
57
+ offset?: number;
58
+ }): RipgrepGrepOutcome | null;
@@ -27,8 +27,6 @@ export interface TurnCoreAgent {
27
27
  export interface TurnCoreHooks {
28
28
  /** Invoked for every side event handled by `forwardTurnSideEvent` (e.g. tool-call accounting). */
29
29
  onSideEvent?: (event: TurnEvent) => void;
30
- /** Transform assistant content before it is emitted in `turn.end` (e.g. literal-response requirements). */
31
- transformContent?: (content: string) => string;
32
30
  /** Extra work after `turn.end` is emitted (usage tracking, `turn.usage_update`, transcript persistence). */
33
31
  onEnd?: (event: Extract<TurnEvent, {
34
32
  type: "end";
@@ -37,10 +35,6 @@ export interface TurnCoreHooks {
37
35
  onError?: (event: Extract<TurnEvent, {
38
36
  type: "error";
39
37
  }>) => void;
40
- /** Handle a `skill_instruction` event (notify + auto-persist). */
41
- onSkillInstruction?: (event: Extract<TurnEvent, {
42
- type: "skill_instruction";
43
- }>) => void;
44
38
  }
45
39
  export interface TurnCoreResult {
46
40
  content: string;
@@ -13,6 +13,15 @@ export interface TurnProjectRoutingResult {
13
13
  sessionProjectId?: string;
14
14
  projectHintStale: boolean;
15
15
  staleProjectHintContext?: StaleProjectHintContext;
16
+ /**
17
+ * Set when the turn's config CARRIES a projectId that could not be resolved to a registered
18
+ * project. The caller must treat this as fatal for the turn (reject it) — silently falling back
19
+ * to the active project root would run every file read/write of the turn in the WRONG workspace
20
+ * (docs/judgment-over-mechanism.md: failures must be visible, never silently degraded).
21
+ * A session with NO projectId at all (legacy session) is NOT an error — it legitimately anchors
22
+ * to the active project (sessionProjectRoot) and only leaves a host.log trace.
23
+ */
24
+ projectResolutionError?: string;
16
25
  }
17
26
  export declare function routeTurnProjectContext(params: {
18
27
  config?: Record<string, unknown>;
@@ -123,6 +123,9 @@ export interface HookContextMap {
123
123
  };
124
124
  "memory.after_recall": HookTurnContext & {
125
125
  blockCount?: number;
126
+ recalledSummaries?: string[];
127
+ injectedCount?: number;
128
+ droppedCount?: number;
126
129
  };
127
130
  "subagent.started": HookSubagentContext;
128
131
  "subagent.stopped": HookSubagentContext;
@@ -21,6 +21,14 @@ export type SkillInstruction = SkillCreateInstruction | SkillImproveInstruction;
21
21
  export type TurnEvent = {
22
22
  type: "start";
23
23
  turnId: string;
24
+ /**
25
+ * Effective per-turn budgets (rounds / total tool calls) after engine caps and
26
+ * intent-based floors. Echoed at turn start so gateways/UIs can see the ceiling
27
+ * the loop actually runs under — a caller request silently clamped to the hard
28
+ * cap would otherwise be an invisible engine-imposed limit.
29
+ */
30
+ effectiveMaxRounds?: number;
31
+ effectiveMaxToolCalls?: number;
24
32
  } | {
25
33
  type: "delta";
26
34
  turnId: string;
@@ -47,10 +55,6 @@ export type TurnEvent = {
47
55
  error: string;
48
56
  code?: string;
49
57
  usage?: WireTokenUsage;
50
- } | {
51
- type: "skill_instruction";
52
- turnId: string;
53
- instruction: SkillInstruction;
54
58
  } | {
55
59
  type: "tool_result";
56
60
  turnId: string;
@@ -28,10 +28,15 @@ export interface ProductCallbacks {
28
28
  inputTokens: number;
29
29
  outputTokens: number;
30
30
  changedFiles: string[];
31
+ acceptanceUnverified?: boolean;
31
32
  }) => void;
32
33
  onTaskFailed?: (productId: string, taskId: string, error: string) => void;
33
34
  onCheckpointed?: (productId: string, timestamp: string) => void;
34
35
  onBudgetWarning?: (productId: string, usedTokens: number, maxTotalTokens: number, percentage: number) => void;
36
+ /** Budget hard limit hit → the run auto-paused. The 100% counterpart of onBudgetWarning (80%): the
37
+ * warning notified the user while the actual auto-pause was log-only — the strongest budget
38
+ * intervention must be at least as loud as its warning. `reason` says WHICH limit tripped. */
39
+ onBudgetExceeded?: (productId: string, usedTokens: number, maxTotalTokens: number | undefined, reason: string) => void;
35
40
  onCompleted?: (productId: string, summary: string, phase: Extract<ProductPhase, "completed" | "failed">) => void;
36
41
  /** DAG topology resolved and sent to client for visualization. */
37
42
  onDagTopology?: (productId: string, nodes: {
@@ -83,7 +88,12 @@ export declare class ProductOrchestrator {
83
88
  */
84
89
  create(params: ProductCreateParams): Promise<string>;
85
90
  /** Resume a product from persisted state. */
86
- resume(productId: string, cwd?: string): Promise<void>;
91
+ resume(productId: string, cwd?: string, opts?: {
92
+ additionalBudget?: {
93
+ maxTotalTokens?: number;
94
+ maxDuration?: number;
95
+ };
96
+ }): Promise<void>;
87
97
  /**
88
98
  * Pause a running product — the SINGLE pause path (I9).
89
99
  *
@@ -15,3 +15,15 @@ import { type AcpDetector } from "../runtime/infra/acp-detector.js";
15
15
  * if not already in the roster, so the leader always has ≥1 valid assignee even when the user's picks turn
16
16
  * out unready (or when the pool is empty). */
17
17
  export declare function buildAgentRoster(detector: AcpDetector, _configStore: AgentConfigStoreData | null, allowedAgents?: string[]): AgentRosterEntry[];
18
+ /**
19
+ * User-PICKED worker ids that did NOT make it into the roster (unready: not installed / not logged in
20
+ * / not in the catalog). Excludes the leader (always force-included). Empty when nothing was dropped
21
+ * or when the pool was omitted. Callers surface this so a picked worker doesn't vanish silently and
22
+ * collapse the team to just 小智 (honesty over silence — goal used to degrade with no notice).
23
+ */
24
+ export declare function computeUnavailablePicks(allowedAgents: string[] | undefined, rosterIds: readonly string[]): string[];
25
+ /** buildAgentRoster + the diagnostics of which picked workers were dropped as unavailable. */
26
+ export declare function buildAgentRosterWithDiagnostics(detector: AcpDetector, configStore: AgentConfigStoreData | null, allowedAgents?: string[]): {
27
+ roster: AgentRosterEntry[];
28
+ unavailablePicks: string[];
29
+ };
@@ -12,8 +12,6 @@
12
12
  * - Tool delta re-injection (new/removed tools since last compact)
13
13
  */
14
14
  export interface ReactiveCompactConfig {
15
- /** Maximum consecutive auto-compact failures before giving up (CC: 3). */
16
- maxConsecutiveFailures: number;
17
15
  /** Minimum messages to keep after reactive compact. */
18
16
  minMessagesAfterCompact: number;
19
17
  /** Target token usage after compact (percentage of context window). */
@@ -50,8 +48,6 @@ export interface PostCompactRestorationPayload {
50
48
  */
51
49
  export declare function buildPostCompactRestorationMessage(payload: PostCompactRestorationPayload): string | null;
52
50
  export interface ReactiveCompactState {
53
- /** Number of consecutive compact failures. */
54
- consecutiveFailures: number;
55
51
  /** Whether reactive compact has been attempted in this turn. */
56
52
  attemptedThisTurn: boolean;
57
53
  /** Last compact timestamp. */
@@ -61,9 +57,11 @@ export interface ReactiveCompactState {
61
57
  }
62
58
  export declare function createReactiveCompactState(): ReactiveCompactState;
63
59
  /**
64
- * Determine if reactive compact should be attempted.
60
+ * Determine if reactive compact should be attempted. The once-per-turn latch is the
61
+ * real loop guard; there is intentionally no failure counter (a zombie counter that
62
+ * nothing incremented used to live here).
65
63
  */
66
- export declare function shouldAttemptReactiveCompact(state: ReactiveCompactState, config?: ReactiveCompactConfig): boolean;
64
+ export declare function shouldAttemptReactiveCompact(state: ReactiveCompactState): boolean;
67
65
  /**
68
66
  * Calculate the tool delta since last compact.
69
67
  */
@@ -34,6 +34,7 @@ export interface Node {
34
34
  inputTokens?: number;
35
35
  outputTokens?: number;
36
36
  changedFiles?: string[];
37
+ acceptanceUnverified?: boolean;
37
38
  runIndex: number;
38
39
  maxIterations?: number;
39
40
  iteration?: number;
@@ -89,6 +90,7 @@ export declare class DagScheduler {
89
90
  inputTokens?: number;
90
91
  outputTokens?: number;
91
92
  changedFiles?: string[];
93
+ acceptanceUnverified?: boolean;
92
94
  }): void;
93
95
  markFailed(id: string, error: string): void;
94
96
  markPaused(id: string): void;
@@ -188,6 +190,7 @@ export interface SerializedNode {
188
190
  inputTokens?: number;
189
191
  outputTokens?: number;
190
192
  changedFiles?: string[];
193
+ acceptanceUnverified?: boolean;
191
194
  runIndex: number;
192
195
  maxIterations?: number;
193
196
  iteration?: number;
@@ -11,7 +11,7 @@ export interface DelegationDeps {
11
11
  warn(m: string): void;
12
12
  };
13
13
  }
14
- type DelegationStatus = "running" | "completed" | "failed" | "cancelled";
14
+ type DelegationStatus = "running" | "completed" | "failed" | "cancelled" | "timed_out";
15
15
  export declare class DelegationCoordinator {
16
16
  private readonly deps;
17
17
  private readonly active;
@@ -50,6 +50,11 @@ export declare class DelegationCoordinator {
50
50
  delegationId: string;
51
51
  };
52
52
  private run;
53
+ /** Collect a delegation's produced artifacts: the union of the worktree diff (tasks[].changedFiles,
54
+ * omitted by the wire type but carried at runtime) and the mtime-isolated capture of project-root files
55
+ * (for workers that write straight to the workspace), plus the worker task + terminal phase. Shared by
56
+ * the normal terminal path AND the timeout path, so a timed-out run still hands back its partial output. */
57
+ private collectProducts;
53
58
  private settle;
54
59
  }
55
60
  export {};
@@ -1,25 +1,3 @@
1
- export declare function executeBoundedRetryLoop<TResult>(params: {
2
- maxIterations: number;
3
- onRetryLimit: (params: {
4
- iterations: number;
5
- maxIterations: number;
6
- }) => Promise<TResult> | TResult;
7
- executeIteration: (params: {
8
- iteration: number;
9
- }) => Promise<{
10
- kind: "continue";
11
- } | {
12
- kind: "return";
13
- result: TResult;
14
- }>;
15
- }): Promise<TResult>;
16
- export declare function resolveScaledRetryIterations(params: {
17
- candidateCount: number;
18
- baseIterations?: number;
19
- perCandidateIterations?: number;
20
- minIterations?: number;
21
- maxIterations?: number;
22
- }): number;
23
1
  export declare function isForegroundSource(source: string | undefined): boolean;
24
2
  /** Is this a transient capacity error (429 or 529/overloaded)? */
25
3
  export declare function isTransientCapacityError(status: number | undefined): boolean;