qlogicagent 2.20.8 → 2.20.10

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.
@@ -20,6 +20,8 @@ export interface RecallMemoriesDeps {
20
20
  turnId: string;
21
21
  /** Last user message (already truncated by the caller). */
22
22
  query: string;
23
+ /** Turn lifetime. Aborted recall must not be reported or injected as consumed. */
24
+ signal?: AbortSignal;
23
25
  }
24
26
  /**
25
27
  * Recall long-term memories for this turn and build the system-message content
@@ -1,7 +1,7 @@
1
1
  import type { ChatMessage, ToolCallExecutionEvidence } from "../types.js";
2
2
  export { isEmptyToolResult } from "./tool-result-classification.js";
3
3
  export declare const OUTPUT_REQUEST_CONTEXT_PATTERN: RegExp;
4
- export declare function findLastToolError(messages: unknown[], _toolName: string): string | undefined;
4
+ export declare function findLastToolError(messages: unknown[], toolName: string, toolArguments?: string): string | undefined;
5
5
  export declare function looksLikeBuildRequest(messages?: readonly ChatMessage[]): boolean;
6
6
  export declare function isCapabilityDenial(text: string): boolean;
7
7
  export declare function resolveToolLoopBudget(requested?: number, messages?: readonly ChatMessage[]): number;
@@ -13,7 +13,10 @@ export interface SessionRuntimeState {
13
13
  hooks: HookRegistry;
14
14
  permission: PermissionState;
15
15
  }
16
+ export declare const MCP_TOOL_SNAPSHOT_TTL_MS = 30000;
16
17
  export declare class AgentRuntimeSessionState {
18
+ private readonly now;
19
+ private readonly mcpToolSnapshotTtlMs;
17
20
  private readonly runtimeBySession;
18
21
  private readonly permissionLeaseCountBySession;
19
22
  private readonly retiredPermissionUnregisterBySession;
@@ -23,6 +26,7 @@ export declare class AgentRuntimeSessionState {
23
26
  memoryProvider: MemoryHandlerProvider | null;
24
27
  memoryDreamProvider: MemoryDreamRuntimeProvider | null;
25
28
  memoryUserId: string;
29
+ constructor(now?: () => number, mcpToolSnapshotTtlMs?: number);
26
30
  getPluginSkills(): ReturnType<PluginLoader["getPluginSkills"]>;
27
31
  applyBootstrap(sessionId: string, result: AgentRuntimeBootstrapResult): void;
28
32
  withPermissionLease<T>(sessionId: string, action: () => Promise<T>): Promise<T>;
@@ -1,8 +1,10 @@
1
1
  import type { FinalAnswerEvidence, ToolCallExecutionEvidence } from "../protocol/wire/notification-payloads.js";
2
+ export declare function isFreshEvidenceToolCall(call: Pick<ToolCallExecutionEvidence, "identity">): boolean;
3
+ export declare function hasSuccessfulFreshToolEvidence(toolCalls: readonly ToolCallExecutionEvidence[]): boolean;
2
4
  export declare function classifyToolFailureKind(result: {
3
5
  blocked?: boolean;
4
6
  blockReason?: string;
5
7
  error?: string;
6
8
  details?: Record<string, unknown>;
7
9
  }): ToolCallExecutionEvidence["failureKind"];
8
- export declare function buildFinalAnswerEvidence(freshEvidenceRequired: boolean, toolCalls: readonly ToolCallExecutionEvidence[]): FinalAnswerEvidence;
10
+ export declare function buildFinalAnswerEvidence(freshEvidenceRequired: boolean, toolCalls: readonly ToolCallExecutionEvidence[], requiredSuccessfulLogicalToolNames?: readonly string[]): FinalAnswerEvidence;
@@ -61,6 +61,7 @@ type SkillReadinessSet = {
61
61
  };
62
62
  type PendingSkillReadinessSet = SkillReadinessSet & {
63
63
  readPaths: Set<string>;
64
+ readCallIds: Set<string>;
64
65
  nextSets: SkillReadinessSet[];
65
66
  };
66
67
  type SkillReadinessActivation = {
@@ -73,6 +74,15 @@ export type PersistedToolResult = {
73
74
  preview: string;
74
75
  hasMore: boolean;
75
76
  };
77
+ export type CompleteToolResultEvidence = {
78
+ schemaVersion: 1;
79
+ complete: true;
80
+ storage: "session-tool-result";
81
+ artifactPath: string;
82
+ contentSha256: string;
83
+ contentBytes: number;
84
+ contentChars: number;
85
+ };
76
86
  export declare function createContentReplacementState(): ContentReplacementState;
77
87
  export declare function toolResultContextPolicy(details: Record<string, unknown> | undefined): ToolResultContextPolicy;
78
88
  export declare function toolResultContextBudget(policy: ToolResultContextPolicy): ToolResultContextBudget;
@@ -93,6 +103,7 @@ export declare function generatePreview(content: string, maxBytes: number): {
93
103
  hasMore: boolean;
94
104
  };
95
105
  export declare function persistToolResult(content: string, toolCallId: string, sessionId: string, projectRoot: string | undefined): Promise<PersistedToolResult | null>;
106
+ export declare function persistCompleteToolResultEvidence(content: string, toolCallId: string, sessionId: string, projectRoot: string | undefined): Promise<CompleteToolResultEvidence | undefined>;
96
107
  /**
97
108
  * Build a reference message for large tool results (CC buildLargeToolResultMessage parity).
98
109
  */
@@ -1,5 +1,4 @@
1
- import type { FreshWorkspaceEvidencePolicy } from "./fresh-workspace-evidence.js";
2
- export type CapabilityRoutingOwner = "structured-planner" | "direct-response" | "mcp-capability" | "typed-builtin" | "pinned-skill" | "host-skill-discovery";
1
+ export type CapabilityRoutingOwner = "structured-planner" | "direct-response" | "mcp-capability" | "pinned-skill" | "host-skill-discovery";
3
2
  /**
4
3
  * Resolves exclusive capability ownership before any semantic Skill classification.
5
4
  * A lower-specificity route must never steal a turn already owned by a typed policy.
@@ -8,6 +7,5 @@ export declare function resolveCapabilityRoutingOwner(input: {
8
7
  structuredPlannerTurn: boolean;
9
8
  directResponse: boolean;
10
9
  mcpCapabilitySelection: boolean;
11
- freshEvidencePolicy: FreshWorkspaceEvidencePolicy;
12
10
  pinnedSkillCount: number;
13
11
  }): CapabilityRoutingOwner;
@@ -1,43 +1,20 @@
1
1
  /**
2
- * Task Domain Detection selects which system prompt guidance is injected.
3
- *
4
- * qlogicagent handles coding, office, AND creative tasks; a coding-only prompt
5
- * hurts non-coding performance, so the per-domain CONTENT blocks are kept.
6
- *
7
- * Resolution is STATELESS and recomputed every turn (CC-aligned — no hidden
8
- * session/disk state, no stickiness latch, no auto-persisted guesses):
9
- * 1. Host override: `config.taskDomain` from thread.turn params (explicit).
10
- * 2. Auto-detect: keyword match on the current user message; "general" if ambiguous.
11
- *
12
- * The universal BEHAVIORAL rules (answer-directly, tools-not-default, conciseness)
13
- * live in universalGuidance() and apply in every domain, so misclassifying a turn
14
- * as "general" degrades only the domain-tailored content, never the core behavior.
15
- */
16
- /**
17
- * Task domain determines which system prompt sections are injected.
18
- *
19
- * - "coding" — software engineering: bug fixes, refactoring, code gen, etc.
20
- * - "office" — data analysis, reports, documents, spreadsheets, emails
21
- * - "creative" — writing, copywriting, marketing, storytelling, brainstorming
22
- * - "general" — undetectable or mixed domain, uses universal guidance
2
+ * Task-domain guidance is a Host-owned typed choice, not a language classifier.
3
+ * User text is intentionally not inspected for keywords or regular expressions.
23
4
  */
24
5
  export type TaskDomain = "coding" | "office" | "creative" | "general";
25
6
  /**
26
- * Detect task domain from user message text. Keyword matching fast, no LLM call.
7
+ * Kept as a compatibility-neutral pure function for callers that only have text.
8
+ * Without a typed Host decision the safe domain is always general.
27
9
  */
28
- export declare function detectTaskDomain(userText: string): TaskDomain;
10
+ export declare function detectTaskDomain(_userText: string): TaskDomain;
29
11
  export interface DomainResolutionContext {
30
- /** Host-provided override from config.taskDomain (explicit, per-request). */
12
+ /** Host-provided typed override from thread.turn params. */
31
13
  hostOverride?: TaskDomain;
32
- /** Current turn's user message text. */
14
+ /** Current user text is accepted for API stability but never classified. */
33
15
  userText: string;
34
16
  }
35
- /**
36
- * Resolve task domain, stateless and per-turn: explicit host override, else fresh
37
- * keyword auto-detect on this turn's message. No project file, no session stickiness,
38
- * no disk persistence.
39
- */
40
17
  export declare function resolveTaskDomain(ctx: DomainResolutionContext): {
41
18
  domain: TaskDomain;
42
- source: "host-override" | "auto-detect";
19
+ source: "host-override" | "default";
43
20
  };
@@ -61,6 +61,7 @@ export interface McpManagerConfig {
61
61
  toolCatalog?: ToolRegistryLike;
62
62
  }
63
63
  export declare function resolveMcpCallTimeoutMs(value: number | undefined): number;
64
+ export declare function withMcpDeadline<T>(operation: Promise<T>, timeoutMs: number, label: string): Promise<T>;
64
65
  /**
65
66
  * Run `attempt` up to `options.attempts` times, backing off `baseDelayMs * n`
66
67
  * between tries. Returns the first success; rethrows the last error if every
package/package.json CHANGED
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "name": "qlogicagent",
3
- "version": "2.20.8",
3
+ "version": "2.20.10",
4
+ "packageManager": "pnpm@10.23.0",
4
5
  "description": "XiaozhiClaw Agent CLI — subprocess architecture (JSON-RPC over stdio)",
5
6
  "type": "module",
6
7
  "main": "dist/index.js",
@@ -140,6 +141,10 @@
140
141
  "test:watch": "vitest",
141
142
  "benchmark:hermes-superiority": "tsx benchmarks/hermes-superiority/runner.ts",
142
143
  "benchmark:product-blackbox": "tsx benchmarks/product-blackbox/runner.ts",
144
+ "benchmark:product-blind-preflight": "tsx benchmarks/product-blackbox/runner.ts blind-preflight",
145
+ "benchmark:product-blind-calibration": "tsx benchmarks/product-blackbox/runner.ts prepare-blind-calibration",
146
+ "benchmark:product-blind-score": "tsx benchmarks/product-blackbox/runner.ts score-blind-calibration",
147
+ "benchmark:capability-state-fixtures": "tsx benchmarks/product-blackbox/run-capability-state-fixtures.ts",
143
148
  "lint": "oxlint .",
144
149
  "check:encoding-corruption": "node scripts/check-encoding-corruption.mjs",
145
150
  "check:mechanical-rules": "node scripts/check-mechanical-rules.mjs",
@@ -160,13 +165,13 @@
160
165
  "release": "node scripts/release.mjs"
161
166
  },
162
167
  "engines": {
163
- "node": ">=22.0.0"
168
+ "node": ">=24.0.0 <25"
164
169
  },
165
170
  "dependencies": {
166
171
  "@agentclientprotocol/sdk": "^0.25.0",
167
172
  "@napi-rs/canvas": "0.1.100",
168
- "@xiaozhiclaw/module-sdk": "0.2.4",
169
- "@xiaozhiclaw/provider-core": "^0.1.30",
173
+ "@xiaozhiclaw/module-sdk": "0.2.5",
174
+ "@xiaozhiclaw/provider-core": "0.1.31",
170
175
  "better-sqlite3": "^12.10.0",
171
176
  "dotenv": "^17.3.1",
172
177
  "ioredis": "^5.11.1",
@@ -1,38 +0,0 @@
1
- import { type SystemPromptSection } from "./system-prompt-sections.js";
2
- export interface PromptMessageLike {
3
- role?: string;
4
- content?: unknown;
5
- }
6
- export interface ToolNameLike {
7
- function?: {
8
- name?: string;
9
- };
10
- name?: string;
11
- }
12
- export interface FreshWorkspaceEvidencePolicy {
13
- requiresFreshTool: boolean;
14
- reason?: "file-read" | "memory-mutation" | "media-generation" | "media-understanding" | "directory-list" | "content-search" | "shell" | "web";
15
- mediaKind?: "image" | "video" | "tts" | "music";
16
- allowedToolNames: string[];
17
- /** When true, the typed route is an execution boundary rather than prompt guidance. */
18
- enforceAllowedToolNames?: boolean;
19
- }
20
- export declare function getFreshWorkspaceEvidencePolicy(messages: readonly PromptMessageLike[] | string): FreshWorkspaceEvidencePolicy;
21
- export declare function isLightweightChatTurn(messages: readonly PromptMessageLike[] | string): boolean;
22
- export declare function isExplicitNoToolTurn(messages: readonly PromptMessageLike[] | string): boolean;
23
- /**
24
- * Apply a hard allowlist only for deterministic Host-owned operations such as
25
- * media generation/understanding. Other evidence policies keep the complete
26
- * turn surface so ordinary engineering and orchestration work is not narrowed
27
- * merely because its wording resembles an evidence request. Namespaced Host
28
- * tools are matched by their local MCP tool name.
29
- */
30
- export declare function selectFreshWorkspaceEvidenceTools<TTool extends ToolNameLike>(tools: readonly TTool[], policy: FreshWorkspaceEvidencePolicy): TTool[];
31
- /**
32
- * Prompt notice for an explicit "don't use tools" instruction. This INFORMS the
33
- * model and leaves the judgment to it — the engine no longer strips the tool list
34
- * (toolChoice="none"), which also silently disabled the reactive guards and
35
- * misfired on quoted/reported speech ("he said don't use tools").
36
- */
37
- export declare function createExplicitNoToolNoticeSection(): SystemPromptSection;
38
- export declare function createFreshWorkspaceEvidenceSection(policy: FreshWorkspaceEvidencePolicy, availableToolNames?: readonly string[]): SystemPromptSection | null;
@@ -1,12 +0,0 @@
1
- import type { FreshWorkspaceEvidencePolicy } from "./fresh-workspace-evidence.js";
2
- /**
3
- * Typed, conservative pre-tool routing for requests whose complete input is already
4
- * present in the latest user message. This is intentionally an operation taxonomy,
5
- * not a benchmark phrase list: every admitted class is closed over supplied text or
6
- * scalar values and therefore cannot gain correctness from filesystem, shell or MCP.
7
- */
8
- export interface ToolNecessityPolicy {
9
- mode: "model-tools" | "direct-response";
10
- reason?: "scalar-computation" | "text-transformation" | "structured-data-inspection" | "inline-classification" | "url-component-extraction";
11
- }
12
- export declare function resolveToolNecessityPolicy(text: string, evidencePolicy: FreshWorkspaceEvidencePolicy): ToolNecessityPolicy;