qlogicagent 2.24.6 → 2.24.7

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.
@@ -23,7 +23,7 @@ All file paths should be relative to this directory.`:"",r={role:"user",content:
23
23
 
24
24
  You are the "${t.agent.name}" agent.${o}
25
25
 
26
- ${t.taskPrompt}`}]};return n.push(r),n}function Yt(e){return e.map(t=>({role:"tool",tool_call_id:t,content:be}))}function Wt(e,t){if(t.allowedTools&&t.allowedTools.length>0){let n=new Set(t.allowedTools);return e.filter(o=>n.has(o))}if(t.toolCapabilityProfile==="no_tools")return[];if(t.toolCapabilityProfile==="read_tools"){let n=new Set(["file_edit","create_file","write_file","replace_string_in_file","multi_replace_string_in_file","create_directory","delete_file","rename_file","move_file","exec","run_in_terminal","run_command","git_commit","git_push","patch"]);return e.filter(o=>!n.has(o))}return t.canFork?[...e]:e.filter(n=>n!=="agent")}function Xt(e,t,n){let o=Date.now().toString(36);return`${e}:fork:${t}:d${n}:${o}`}var Kt={name:"general",label:"General Purpose",description:"A general-purpose sub-agent that can perform any task with full tool access.",maxTurns:200,toolCapabilityProfile:"all_tools",canFork:!1},Vt={name:"explore",label:"Explore",description:"Fast read-only codebase exploration. Search files, read code, analyze structure. Cannot write or execute.",maxTurns:50,toolCapabilityProfile:"read_tools",allowedTools:["read","search","web_search","web_fetch","memory"],canFork:!1,systemPromptSuffix:"You are READ-ONLY: never attempt to modify files or run mutating commands. Locate and understand code, then report concrete findings with file:line references. Read excerpts rather than whole files; surface conclusions, not raw dumps."},Jt={name:"plan",label:"Plan",description:"Planning mode. Explore, analyze, and produce a structured plan. Cannot write files or execute commands.",maxTurns:80,toolCapabilityProfile:"read_tools",allowedTools:["read","search","web_search","web_fetch","memory","task"],canFork:!1,systemPromptSuffix:"You PLAN but do not execute: never write files or run commands. Investigate enough to ground the plan in the real code, then return a concrete, step-by-step implementation plan naming the specific files and changes involved."},Zt={name:"code",label:"Code",description:"A coding sub-agent with full tool access for implementation tasks.",maxTurns:200,toolCapabilityProfile:"all_tools",canFork:!0,systemPromptSuffix:"Implement the task directly by editing files. Read existing code before changing it, match the surrounding conventions, and verify your change compiles/passes where possible."},Qt={name:"research",label:"Research",description:"Web research and information gathering. Searches the web, fetches pages, and synthesizes findings.",maxTurns:30,toolCapabilityProfile:"read_tools",allowedTools:["web_search","web_fetch","read","search","memory"],canFork:!1,systemPromptSuffix:"Gather information from multiple sources before concluding. Distinguish facts from inferences, cite where each claim comes from, and synthesize \u2014 do not just dump search results."},en={name:"verify",label:"Verify",description:"Verification agent. Runs tests, checks build output, validates changes are correct.",maxTurns:40,toolCapabilityProfile:"all_tools",allowedTools:["exec","read","search","task"],canFork:!1,systemPromptSuffix:"Verify by RUNNING things (tests, builds, type-checks) and reading the actual output \u2014 do not assume. Report a clear verdict (pass/fail) with the evidence that supports it."},Z=[Kt,Vt,Jt,Zt,Qt,en];function tn(){return[...Z]}function nn(e){return Z.find(t=>t.name===e)}function on(e){return Z.some(t=>t.name===e)}function rn(e,t){if(e.allowedTools&&e.allowedTools.length>0){let n=new Set(e.allowedTools);return t.filter(o=>n.has(o))}if(e.toolCapabilityProfile==="no_tools")return[];if(e.toolCapabilityProfile==="read_tools"){let n=new Set(["file_edit","create_file","write_file","replace_string_in_file","multi_replace_string_in_file","create_directory","delete_file","rename_file","move_file","exec","run_in_terminal","run_command","git_commit","git_push","patch"]);return t.filter(o=>!n.has(o))}return e.canFork?[...t]:t.filter(n=>n!=="agent")}function sn(e){return{permissionRole:"worker",isolation:"shared",lifecycle:"pending",depth:0,maxTurns:200,tokenBudget:0,startedAt:Date.now(),...e}}function an(e){let t=Number.isFinite(e.totalPromptTokens)&&(e.totalPromptTokens??0)>0?Math.floor(e.totalPromptTokens):0,n=Number.isFinite(e.promptTokens)&&e.promptTokens>0?Math.floor(e.promptTokens):0,o=Number.isFinite(e.cacheReadTokens)&&(e.cacheReadTokens??0)>0?Math.floor(e.cacheReadTokens):0,r=Number.isFinite(e.cacheCreationTokens)&&(e.cacheCreationTokens??0)>0?Math.floor(e.cacheCreationTokens):0,i=o+r,s=i>n?n+i:n;return Math.max(t,s)}function ln(e){return{promptTokens:0,hasAttemptedReactiveCompact:!1,currentMaxOutputTokens:e.maxOutputTokens,consecutiveTruncations:0,aborted:e.abortSignal?.aborted??!1}}function cn(e,t){if(e.aborted)return{level:"blocking",usagePercent:100,reason:"budget_exhausted"};let n=t.contextWindowTokens-t.responseBufferTokens-e.currentMaxOutputTokens,o=n>0?e.promptTokens/n*100:100;return e.promptTokens>=n?e.hasAttemptedReactiveCompact||!t.reactiveCompactEnabled?{level:"blocking",usagePercent:o,reason:"prompt_too_long"}:{level:"blocking",usagePercent:o,reason:"prompt_too_long"}:o>=85?{level:"warning",usagePercent:o,remainingTokens:n-e.promptTokens}:{level:"ok"}}function un(e,t,n){let o=e.message?.toLowerCase()??"",r=e.status??0;return r===413||o.includes("prompt_too_long")||o.includes("context_length_exceeded")?!t.hasAttemptedReactiveCompact&&n.reactiveCompactEnabled?{action:"reactive_compact"}:{action:"abort",reason:"prompt_too_long_unrecoverable"}:r>=500&&r<600?{action:"retry",reason:`server_error_${r}`}:r===429?{action:"retry",reason:"rate_limited"}:r===401||r===403?{action:"abort",reason:"auth_error"}:r===404?{action:"abort",reason:"model_not_found"}:{action:"abort",reason:o||"unknown_error"}}function pn(e,t,n){if(!t.outputEscalationEnabled)return{shouldEscalate:!1,newMax:e.currentMaxOutputTokens};if(e.consecutiveTruncations>=3)return{shouldEscalate:!1,newMax:e.currentMaxOutputTokens};let o=Math.min(e.currentMaxOutputTokens*2,n);return o<=e.currentMaxOutputTokens?{shouldEscalate:!1,newMax:e.currentMaxOutputTokens}:{shouldEscalate:!0,newMax:o}}function dn(e,t){return e.aborted?!0:t.abortSignal?.aborted?(e.aborted=!0,!0):!1}function mn(e){let t=[];if(e.todoList&&e.todoList.length>0){let n=e.todoList.map(o=>` ${o.status==="completed"?"[x]":o.status==="in-progress"?"[~]":"[ ]"} #${o.id}: ${o.title}`);t.push(`## Active Todo List
26
+ ${t.taskPrompt}`}]};return n.push(r),n}function Yt(e){return e.map(t=>({role:"tool",tool_call_id:t,content:be}))}function Wt(e,t){if(t.allowedTools&&t.allowedTools.length>0){let n=new Set(t.allowedTools);return e.filter(o=>n.has(o))}if(t.toolCapabilityProfile==="no_tools")return[];if(t.toolCapabilityProfile==="read_tools"){let n=new Set(["file_edit","create_file","write_file","replace_string_in_file","multi_replace_string_in_file","create_directory","delete_file","rename_file","move_file","exec","run_in_terminal","run_command","git_commit","git_push","patch"]);return e.filter(o=>!n.has(o))}return t.canFork?[...e]:e.filter(n=>n!=="agent")}function Xt(e,t,n){let o=Date.now().toString(36);return`${e}:fork:${t}:d${n}:${o}`}var Kt={name:"general",label:"General Purpose",description:"A general-purpose sub-agent that can perform any task with full tool access.",maxTurns:200,toolCapabilityProfile:"all_tools",canFork:!1},Vt={name:"explore",label:"Explore",description:"Fast read-only codebase exploration. Search files, read code, analyze structure. Cannot write or execute.",maxTurns:50,toolCapabilityProfile:"read_tools",allowedTools:["read","search","web_search","web_fetch","memory"],canFork:!1,systemPromptSuffix:"You are READ-ONLY: never attempt to modify files or run mutating commands. Locate and understand code, then report concrete findings with file:line references. Read excerpts rather than whole files; surface conclusions, not raw dumps."},Jt={name:"plan",label:"Plan",description:"Planning mode. Explore, analyze, and produce a structured plan. Cannot write files or execute commands.",maxTurns:80,toolCapabilityProfile:"read_tools",allowedTools:["read","search","web_search","web_fetch","memory","task"],canFork:!1,systemPromptSuffix:"You PLAN but do not execute: never write files or run commands. Investigate enough to ground the plan in the real code, then return a concrete, step-by-step implementation plan naming the specific files and changes involved."},Zt={name:"code",label:"Code",description:"A coding sub-agent with full tool access for implementation tasks.",maxTurns:200,toolCapabilityProfile:"all_tools",canFork:!0,systemPromptSuffix:"Implement the task directly by editing files. Read existing code before changing it, match the surrounding conventions, and verify your change compiles/passes where possible."},Qt={name:"research",label:"Research",description:"Web research and information gathering. Searches the web, fetches pages, and synthesizes findings.",maxTurns:30,toolCapabilityProfile:"read_tools",allowedTools:["web_search","web_fetch","read","search","memory"],canFork:!1,systemPromptSuffix:"Gather information from multiple sources before concluding. Distinguish facts from inferences, cite where each claim comes from, and synthesize \u2014 do not just dump search results."},en={name:"verify",label:"Verify",description:"Verification agent. Runs tests, checks build output, validates changes are correct.",maxTurns:40,toolCapabilityProfile:"all_tools",allowedTools:["exec","read","search","task"],canFork:!1,systemPromptSuffix:"Verify by RUNNING things (tests, builds, type-checks) and reading the actual output \u2014 do not assume. Report a clear verdict (pass/fail) with the evidence that supports it."},Z=[Kt,Vt,Jt,Zt,Qt,en];function tn(){return[...Z]}function nn(e){return Z.find(t=>t.name===e)}function on(e){return Z.some(t=>t.name===e)}function rn(e,t){if(e.allowedTools&&e.allowedTools.length>0){let n=new Set(e.allowedTools);return t.filter(o=>n.has(o))}if(e.toolCapabilityProfile==="no_tools")return[];if(e.toolCapabilityProfile==="read_tools"){let n=new Set(["file_edit","create_file","write_file","replace_string_in_file","multi_replace_string_in_file","create_directory","delete_file","rename_file","move_file","exec","run_in_terminal","run_command","git_commit","git_push","patch"]);return t.filter(o=>!n.has(o))}return e.canFork?[...t]:t.filter(n=>n!=="agent")}function sn(e){return{permissionRole:"worker",isolation:"shared",lifecycle:"pending",depth:0,maxTurns:200,tokenBudget:0,startedAt:Date.now(),...e}}function an(e){let t=Number.isFinite(e.totalPromptTokens)&&(e.totalPromptTokens??0)>0?Math.floor(e.totalPromptTokens):0,n=Number.isFinite(e.promptTokens)&&e.promptTokens>0?Math.floor(e.promptTokens):0,o=Number.isFinite(e.cacheReadTokens)&&(e.cacheReadTokens??0)>0?Math.floor(e.cacheReadTokens):0,r=Number.isFinite(e.cacheCreationTokens)&&(e.cacheCreationTokens??0)>0?Math.floor(e.cacheCreationTokens):0,i=o+r,s=i>n?n+i:n;return Math.max(t,s)}function ln(e){return{promptTokens:0,hasAttemptedReactiveCompact:!1,currentMaxOutputTokens:e.maxOutputTokens,consecutiveTruncations:0,aborted:e.abortSignal?.aborted??!1}}function cn(e,t){let n=t.contextWindowTokens-t.responseBufferTokens-e.currentMaxOutputTokens,o=n>0?e.promptTokens/n*100:100;return o>=85?{level:"warning",usagePercent:o,remainingTokens:Math.max(0,n-e.promptTokens)}:{level:"ok"}}function un(e,t,n){let o=e.message?.toLowerCase()??"",r=e.status??0;return r===413||o.includes("prompt_too_long")||o.includes("context_length_exceeded")?!t.hasAttemptedReactiveCompact&&n.reactiveCompactEnabled?{action:"reactive_compact"}:{action:"abort",reason:"prompt_too_long_unrecoverable"}:r>=500&&r<600?{action:"retry",reason:`server_error_${r}`}:r===429?{action:"retry",reason:"rate_limited"}:r===401||r===403?{action:"abort",reason:"auth_error"}:r===404?{action:"abort",reason:"model_not_found"}:{action:"abort",reason:o||"unknown_error"}}function pn(e,t,n){if(!t.outputEscalationEnabled)return{shouldEscalate:!1,newMax:e.currentMaxOutputTokens};if(e.consecutiveTruncations>=3)return{shouldEscalate:!1,newMax:e.currentMaxOutputTokens};let o=Math.min(e.currentMaxOutputTokens*2,n);return o<=e.currentMaxOutputTokens?{shouldEscalate:!1,newMax:e.currentMaxOutputTokens}:{shouldEscalate:!0,newMax:o}}function dn(e,t){return e.aborted?!0:t.abortSignal?.aborted?(e.aborted=!0,!0):!1}function mn(e){let t=[];if(e.todoList&&e.todoList.length>0){let n=e.todoList.map(o=>` ${o.status==="completed"?"[x]":o.status==="in-progress"?"[~]":"[ ]"} #${o.id}: ${o.title}`);t.push(`## Active Todo List
27
27
  ${n.join(`
28
28
  `)}`)}if(e.activeSkillContext&&t.push(`## Active Skill: ${e.activeSkillContext.name}
29
29
  Step ${e.activeSkillContext.step}:
@@ -148,6 +148,13 @@ export declare const NO_PROGRESS_TARGET_THRESHOLD = 4;
148
148
  * etc.). Exported for testing.
149
149
  */
150
150
  export declare function noProgressTargetKey(toolName: string, rawArguments: string): string | null;
151
+ /**
152
+ * Remove presentation-only churn from an observation. Time passing, elapsed counters, and package
153
+ * manager lock markers do not prove that the observed task made progress.
154
+ */
155
+ export declare function normalizeProgressObservation(content: string): string;
156
+ /** Stable identity for observation-style successes. null means the success itself proves progress. */
157
+ export declare function toolProgressIdentity(toolName: string, details: unknown, content: string): string | null;
151
158
  export declare function buildLongHorizonStateMaintenanceInstruction(documents: ReadonlyMap<string, MaintainedDocumentIndex>, turn: number): string | null;
152
159
  export declare function longHorizonStateMaintenanceWriteValidation(maintainedDocuments: ReadonlyMap<string, MaintainedDocumentIndex>, filePath: string, rawArguments: string): {
153
160
  ok: true;
@@ -4,6 +4,7 @@ import type { Transport } from "./transport.js";
4
4
  /** Owns one ordinary ACP server connection. */
5
5
  export declare class StdioAcpProtocolCoordinator {
6
6
  private server;
7
+ private readonly textStateBySession;
7
8
  get active(): boolean;
8
9
  init(transport: Transport, handler: AcpRequestHandler, options: {
9
10
  verbose: boolean;
@@ -16,5 +17,7 @@ export declare class StdioAcpProtocolCoordinator {
16
17
  requestPermission: AcpServer["requestPermission"];
17
18
  } | undefined;
18
19
  dispose(_reason?: string): void;
20
+ private textState;
21
+ private flushCommittedProgress;
19
22
  emitUpdate<M extends NotificationMethod>(sessionId: string, method: M, params: NotificationMethodMap[M]): boolean;
20
23
  }
@@ -1,9 +1,9 @@
1
1
  /**
2
- * Turn Loop Guard — Abort signal + token budget warning for preventive termination.
2
+ * Turn Loop Guard — Abort signal + advisory token usage warning.
3
3
  *
4
4
  * Aligned with Claude Code's multi-condition termination:
5
5
  * 1. AbortSignal from user cancellation
6
- * 2. Token budget pre-check (don't send API call if over budget)
6
+ * 2. Token usage warning (the provider remains authoritative for its context window)
7
7
  * 3. max_output_tokens escalation on truncation
8
8
  * 4. Prompt-too-long reactive compact trigger
9
9
  */
@@ -27,10 +27,6 @@ export type TokenWarningState = {
27
27
  level: "warning";
28
28
  usagePercent: number;
29
29
  remainingTokens: number;
30
- } | {
31
- level: "blocking";
32
- usagePercent: number;
33
- reason: "prompt_too_long" | "budget_exhausted";
34
30
  };
35
31
  export interface TurnLoopGuardState {
36
32
  /** Current accumulated prompt tokens. */
@@ -60,8 +56,11 @@ export declare function resolvePromptContextTokens(usage: PromptContextUsage): n
60
56
  /** Initial guard state. */
61
57
  export declare function createTurnLoopGuardState(config: TurnLoopGuardConfig): TurnLoopGuardState;
62
58
  /**
63
- * Calculate token warning state before making an API call.
64
- * If level is "blocking", do NOT send the API call.
59
+ * Calculate advisory token usage before making an API call.
60
+ *
61
+ * The local count can lag the next prompt and model metadata can lag the
62
+ * provider. It must therefore never terminate a turn. A real provider context
63
+ * error is handled by resolveApiErrorRecovery after the request.
65
64
  */
66
65
  export declare function calculateTokenWarningState(state: TurnLoopGuardState, config: TurnLoopGuardConfig): TokenWarningState;
67
66
  /**
@@ -11,6 +11,12 @@ export interface TurnDeltaNotification {
11
11
  turnId: string;
12
12
  text: string;
13
13
  }
14
+ /** Adapter-local rollback signal. It is consumed before standard ACP projection. */
15
+ export interface TurnTextRollbackNotification {
16
+ turnId: string;
17
+ keepLength: number;
18
+ reason: string;
19
+ }
14
20
  export interface TurnEndNotification {
15
21
  turnId: string;
16
22
  content: string;
@@ -57,6 +63,7 @@ export interface TurnMediaResultNotification {
57
63
  }
58
64
  export interface NotificationMethodMap {
59
65
  "turn.delta": TurnDeltaNotification;
66
+ "turn.text_rollback": TurnTextRollbackNotification;
60
67
  "turn.end": TurnEndNotification;
61
68
  "turn.reasoning_delta": TurnReasoningDeltaNotification;
62
69
  "turn.tool_call": TurnToolCallNotification;
@@ -65,6 +65,8 @@ export interface RegisterBashTaskOptions {
65
65
  }
66
66
  export interface TaskOutputSnapshot {
67
67
  task: TaskState;
68
+ /** Monotonic task-state identity from TaskStore. Live output has its own digest at the tool boundary. */
69
+ stateRevision: number;
68
70
  /** Current output: final result for terminal tasks, live tail for running bash tasks. */
69
71
  output: string;
70
72
  running: boolean;
@@ -22,6 +22,7 @@ export declare function generateTaskId(type: TaskType): string;
22
22
  */
23
23
  export declare class TaskStore {
24
24
  private tasks;
25
+ private revisions;
25
26
  private listeners;
26
27
  private hooks;
27
28
  private sessionId;
@@ -46,6 +47,8 @@ export declare class TaskStore {
46
47
  * Get a task by ID.
47
48
  */
48
49
  getTask(taskId: string): TaskState | undefined;
50
+ /** Monotonic identity for material state changes; elapsed time is deliberately excluded. */
51
+ getRevision(taskId: string): number | undefined;
49
52
  /**
50
53
  * Get all running tasks.
51
54
  */
@@ -13,6 +13,7 @@ export interface TaskRuntimeAccess {
13
13
  task: RuntimeTaskView;
14
14
  output: string;
15
15
  running: boolean;
16
+ stateRevision?: number;
16
17
  } | null>;
17
18
  cancelTask(taskId: string): boolean;
18
19
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "qlogicagent",
3
- "version": "2.24.6",
3
+ "version": "2.24.7",
4
4
  "packageManager": "pnpm@10.23.0",
5
5
  "description": "XiaozhiClaw standard ACP Agent adapter",
6
6
  "type": "module",
@@ -79,7 +79,7 @@
79
79
  "@agentclientprotocol/sdk": "^0.25.0",
80
80
  "@napi-rs/canvas": "0.1.100",
81
81
  "@xiaozhiclaw/module-sdk": "0.4.4",
82
- "@xiaozhiclaw/provider-core": "0.1.39",
82
+ "@xiaozhiclaw/provider-core": "0.1.40",
83
83
  "ajv": "8.20.0",
84
84
  "better-sqlite3": "^12.10.0",
85
85
  "dotenv": "^17.3.1",