qlogicagent 2.18.5 → 2.18.6

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.
@@ -78,6 +78,13 @@ export interface ToolLoopParams {
78
78
  * the next LLM call, steering the run without waiting for the turn to finish.
79
79
  */
80
80
  drainPendingGuidance?: () => string[];
81
+ /**
82
+ * Sanitize a tool-result message's media the MAIN model can't consume (e.g. the `read` tool
83
+ * returning an image for a text-only model → provider closes the stream, -32603): route it to
84
+ * the understanding model + fold the description into the message text, dropping the raw media.
85
+ * Mutates in place; called before each tool result enters the model context.
86
+ */
87
+ sanitizeToolResultMedia?: (message: Record<string, unknown>) => Promise<void>;
81
88
  /**
82
89
  * Post-sampling hooks -fire-and-forget after LLM response completes (CC executePostSamplingHooks parity).
83
90
  * Cannot modify messages. Used for background tasks (memory extraction, skill learning, etc.).
@@ -93,6 +93,12 @@ export interface TurnRequest {
93
93
  * tool-loop round; returned strings become user messages before the next LLM call.
94
94
  */
95
95
  drainPendingGuidance?: () => string[];
96
+ /**
97
+ * Route media a tool returns that the MAIN model can't consume (e.g. `read` returning an image
98
+ * for a text-only model) to the understanding model; folds the description into the message text
99
+ * and drops the raw media. Forwarded to the tool loop; mutates the message in place.
100
+ */
101
+ sanitizeToolResultMedia?: (message: Record<string, unknown>) => Promise<void>;
96
102
  systemPrompt?: string;
97
103
  config?: TurnConfig;
98
104
  }
@@ -10,6 +10,7 @@ export interface DreamHostAdapterDeps {
10
10
  getCurrentHooks(): DreamHandlerHost["currentHooks"];
11
11
  getMemoryProvider(): DreamHandlerHost["memoryProvider"];
12
12
  getMemoryUserId(): string;
13
+ ensureMemoryProvider(): void;
13
14
  getToolCatalog(): DreamHandlerHost["toolCatalog"];
14
15
  getTaskStore(): DreamHandlerHost["taskStore"];
15
16
  getVerbose(): boolean;
@@ -17,6 +17,10 @@ export interface DreamHandlerHost {
17
17
  currentHooks?: DreamRunDeps["hooks"] | null;
18
18
  memoryProvider?: DreamMemoryProvider | null;
19
19
  memoryUserId?: string;
20
+ /** Lazy read-path init for the L2 memory provider (cheap, side-effect-free DB open). Consumers
21
+ * that can run before any turn (goal planning's orchestration memory context, memory.atlas)
22
+ * must call this before reading memoryProvider — on a cold process nothing else has built it. */
23
+ ensureMemoryProvider?(): void;
20
24
  toolCatalog: ToolCatalog;
21
25
  taskStore: TaskStore;
22
26
  verbose?: boolean;
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Resolve a media reference into a form a REMOTE model can consume, by rewriting a LOCAL file path to
3
+ * the gateway's `/api/media/local?src=file://…` proxy URL.
4
+ *
5
+ * Why the proxy URL (not a raw path, not base64, not the provider file-API upload):
6
+ * - A tool result (e.g. the `read` tool reading a workspace image) carries a RAW local path
7
+ * (`C:\…\assets\images\x.jpg`) a remote model cannot fetch → the understanding model returns empty.
8
+ * - A base64 `data:` URL blows past the LLM gateway's request-size limit → HTTP 413.
9
+ * - The provider file-API upload (media-file-api-service) needs a Files-API provider that isn't always
10
+ * configured → "no provider".
11
+ * - The `127.0.0.1/api/media/local` proxy URL is exactly what user-attachments use: provider-core's
12
+ * FileUploadAdapter (given QLOGICAGENT_HUB_URL) relays it to hub OSS → a small public URL. Proven path.
13
+ *
14
+ * Remote (`http`/`https`/`data`/`blob`) URLs, non-media extensions, and missing files pass through
15
+ * unchanged. Never throws.
16
+ */
17
+ export declare function resolveLocalMediaForModel(url: string): string;
@@ -18,6 +18,8 @@ export interface TurnCoreRequest {
18
18
  refreshTools?: () => ToolDefinition[];
19
19
  /** Mid-turn guidance drain (运行中引导) — forwarded to the tool loop. */
20
20
  drainPendingGuidance?: () => string[];
21
+ /** Sanitize tool-result media the main model can't consume — forwarded to the tool loop. */
22
+ sanitizeToolResultMedia?: (message: Record<string, unknown>) => Promise<void>;
21
23
  systemPrompt: string;
22
24
  config: TurnConfig;
23
25
  }
@@ -1,6 +1,18 @@
1
1
  import type { SessionListEntry } from "./session-types.js";
2
2
  export declare function listSessions(limit: number | undefined, projectRoot: string): Promise<SessionListEntry[]>;
3
3
  export declare function deleteSession(sessionId: string, projectRoot: string): Promise<void>;
4
+ /**
5
+ * Authoritative "already ours" id set for the lazy-migration discovery scan: every session id and
6
+ * bound native id recorded for `agentId` in this project — including ARCHIVED records, which the
7
+ * list pipeline filters out of its window.
8
+ *
9
+ * listSessions' windowed result must NOT be used for discovery dedup: it truncates (limit) and
10
+ * post-filters (archived), so an adopted session pushed out of the window would be "re-discovered"
11
+ * as a second entry — and a resume on that duplicate would fork a second canonical record for the
12
+ * same native conversation. This enumerates metadata.json only (no transcript counting), and
13
+ * callers only pay for it when the scan actually yielded candidates.
14
+ */
15
+ export declare function collectAdoptedNativeIds(agentId: string, projectRoot: string): Promise<Set<string>>;
4
16
  /**
5
17
  * ⚠️ Destructive cascade with NO user-visible confirmation: every pruned session goes through
6
18
  * deleteSession, which permanently removes its transcript + metadata + checkpoints + uploads.
@@ -11,6 +11,6 @@
11
11
  export { appendMessage } from "./session-transcript-store.js";
12
12
  export { getSessionMetadata, readSessionMetadata, saveSessionState, updateSessionMetadata, } from "./session-metadata-store.js";
13
13
  export { loadSessionForResume } from "./session-resume.js";
14
- export { deleteSession, listSessions, pruneOldSessions } from "./session-catalog.js";
14
+ export { collectAdoptedNativeIds, deleteSession, listSessions, pruneOldSessions } from "./session-catalog.js";
15
15
  export { generateSessionTitle, maybeGenerateTaskSummary, shouldGenerateTaskSummary, } from "./session-summary.js";
16
16
  export { SESSION_SCHEMA_VERSION, type MessageDisplayMetadata, type PersistedChatMessage, type PersistedSession, type SessionListEntry, type SessionMetadata, type TaskSummaryDeps, } from "./session-types.js";
@@ -229,7 +229,7 @@ export declare class LocalMemoryProvider implements MemoryProvider {
229
229
  activeOnly?: boolean;
230
230
  }): import("./local-store-records.js").MemoryAtlasResult;
231
231
  /** Complete tag-scoped listing (resident refresh / onboarding purge) — see store.listByTag. */
232
- listMemoriesByTag(userId: string, tag: string, limit?: number): import("./local-store-records.js").MemoryRecord[];
232
+ listMemoriesByTag(userId: string, tag: string): import("./local-store-records.js").MemoryRecord[];
233
233
  /**
234
234
  * Find related memories (event continuity detection).
235
235
  * Given a new memory, finds existing memories that are semantically related
@@ -96,9 +96,12 @@ export declare class LocalMemoryStore {
96
96
  * All active memories carrying a tag (LIKE match on the quoted JSON-array
97
97
  * element). Tag consumers (resident refresh / onboarding replace-purge) need
98
98
  * the COMPLETE tag set regardless of age — the windowed atlas read silently
99
- * truncated them once history outgrew one page/time window.
99
+ * truncated them once history outgrew one page/time window. No LIMIT by
100
+ * design: a capped "complete" read is the same bug at a higher threshold
101
+ * (a purge that misses rows resurrects stale memories). Tag sets are small
102
+ * (one origin/resident group), and this is not a hot path.
100
103
  */
101
- listByTag(userId: string, tag: string, limit?: number): MemoryRecord[];
104
+ listByTag(userId: string, tag: string): MemoryRecord[];
102
105
  /**
103
106
  * Return a windowed atlas payload for large-history visualization.
104
107
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "qlogicagent",
3
- "version": "2.18.5",
3
+ "version": "2.18.6",
4
4
  "description": "XiaozhiClaw Agent CLI — subprocess architecture (JSON-RPC over stdio)",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",