qlogicagent 2.0.0 → 2.1.0
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.
- package/README.md +8 -8
- package/dist/agent.js +8 -8
- package/dist/cli.js +238 -208
- package/dist/index.js +237 -207
- package/dist/types/cli/stdio-server.d.ts +9 -8
- package/dist/types/contracts/hooks.d.ts +3 -0
- package/dist/types/llm/transports/media-resolve.d.ts +25 -0
- package/dist/types/runtime/execution/dream-agent.d.ts +2 -0
- package/dist/types/runtime/execution/dream-category-context.d.ts +47 -0
- package/dist/types/runtime/execution/dream-category-context.test.d.ts +1 -0
- package/dist/types/runtime/execution/index.d.ts +1 -0
- package/dist/types/runtime/execution/memory-decay.d.ts +57 -0
- package/dist/types/runtime/execution/memory-decay.test.d.ts +1 -0
- package/dist/types/runtime/hooks/index.d.ts +1 -0
- package/dist/types/runtime/hooks/memory-hooks.d.ts +20 -0
- package/dist/types/runtime/hooks/skill-recall-hooks.d.ts +36 -0
- package/dist/types/runtime/infra/agent-paths.d.ts +14 -2
- package/dist/types/runtime/infra/disk-storage.d.ts +0 -16
- package/dist/types/runtime/infra/index.d.ts +2 -2
- package/dist/types/runtime/session/session-persistence.d.ts +3 -1
- package/dist/types/skills/index.d.ts +5 -5
- package/dist/types/skills/memory/find-relevant-memories.d.ts +70 -0
- package/dist/types/skills/memory/memdir.d.ts +80 -0
- package/dist/types/skills/memory/memory-tool.d.ts +16 -44
- package/dist/types/skills/memory/memory-write-gate.d.ts +46 -0
- package/dist/types/skills/memory/memory-write-hook.d.ts +44 -0
- package/dist/types/skills/memory/qmemory-adapter.d.ts +12 -0
- package/dist/types/skills/memory/recall-category-filter.d.ts +54 -0
- package/dist/types/skills/tools/skill-tool.d.ts +16 -3
- package/package.json +1 -1
- package/dist/types/skills/memory/memory-store.d.ts +0 -86
- package/dist/types/skills/tools/skill-invoke-tool.d.ts +0 -46
- package/dist/types/skills/tools/skill-list-tool.d.ts +0 -33
- package/dist/types/skills/tools/skill-manage-tool.d.ts +0 -73
- package/dist/types/skills/tools/skill-view-tool.d.ts +0 -37
|
@@ -46,8 +46,10 @@ export declare class StdioServer {
|
|
|
46
46
|
/** QMemory adapter (when QMEMORY_BASE_URL env is set). Used by Dream hippocampus bridge. */
|
|
47
47
|
private qmemoryAdapter;
|
|
48
48
|
private qmemoryUserId;
|
|
49
|
-
/**
|
|
50
|
-
private
|
|
49
|
+
/** MEMDIR file-based memory (CC memdir parity). */
|
|
50
|
+
private memdir;
|
|
51
|
+
/** Memory write gate state (P2+P3: category gate + supersedes). */
|
|
52
|
+
private memoryWriteState;
|
|
51
53
|
private fileWatcher;
|
|
52
54
|
/** Pending ask_user requests waiting for host response */
|
|
53
55
|
private pendingAskUser;
|
|
@@ -123,15 +125,15 @@ export declare class StdioServer {
|
|
|
123
125
|
*/
|
|
124
126
|
private handleSessionGetInfo;
|
|
125
127
|
/**
|
|
126
|
-
* `memory.list` — Enumerate available memory sources (
|
|
128
|
+
* `memory.list` — Enumerate available memory sources (memdir + qmemory).
|
|
127
129
|
*/
|
|
128
130
|
private handleMemoryList;
|
|
129
131
|
/**
|
|
130
|
-
* `memory.read` — Read memory content from
|
|
132
|
+
* `memory.read` — Read memory content from memdir (INDEX.md or topic file).
|
|
131
133
|
*/
|
|
132
134
|
private handleMemoryRead;
|
|
133
135
|
/**
|
|
134
|
-
* `memory.write` — Write memory content to
|
|
136
|
+
* `memory.write` — Write memory content to memdir (INDEX.md or topic file).
|
|
135
137
|
*/
|
|
136
138
|
private handleMemoryWrite;
|
|
137
139
|
/**
|
|
@@ -176,12 +178,11 @@ export declare class StdioServer {
|
|
|
176
178
|
*/
|
|
177
179
|
private handleTodosList;
|
|
178
180
|
/**
|
|
179
|
-
* `memory.search` —
|
|
180
|
-
* Powers the memory page's search feature.
|
|
181
|
+
* `memory.search` — Search memory via QMemory (vector) or memdir (local keyword).
|
|
181
182
|
*/
|
|
182
183
|
private handleMemorySearch;
|
|
183
184
|
/**
|
|
184
|
-
* `memory.delete` — Remove
|
|
185
|
+
* `memory.delete` — Remove memory entry from memdir (INDEX.md line) or QMemory (by ID).
|
|
185
186
|
*/
|
|
186
187
|
private handleMemoryDelete;
|
|
187
188
|
/**
|
|
@@ -114,7 +114,10 @@ export interface HookContextMap {
|
|
|
114
114
|
recalledMemories?: Array<{
|
|
115
115
|
text: string;
|
|
116
116
|
score?: number;
|
|
117
|
+
category?: string | null;
|
|
117
118
|
}>;
|
|
119
|
+
preferredCategories?: string[];
|
|
120
|
+
deprioritizedCategories?: string[];
|
|
118
121
|
};
|
|
119
122
|
"memory.after_recall": HookTurnContext & {
|
|
120
123
|
blockCount?: number;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Media URL Resolution — converts local/private URLs to inline base64 data URLs.
|
|
3
|
+
*
|
|
4
|
+
* Cloud LLM APIs (OpenAI, Anthropic, DeepSeek) cannot fetch content from
|
|
5
|
+
* localhost or private networks. This utility detects such URLs and resolves
|
|
6
|
+
* them to base64 data URLs that can be sent inline.
|
|
7
|
+
*
|
|
8
|
+
* URL-first design: the gateway stores media as HTTP URLs; this layer handles
|
|
9
|
+
* the last-mile transformation before sending to provider APIs.
|
|
10
|
+
*/
|
|
11
|
+
/** Check if a URL points to a local/private address that cloud APIs cannot reach. */
|
|
12
|
+
export declare function isLocalUrl(url: string): boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Resolve a URL to a base64 data URL if it's a local address.
|
|
15
|
+
* Public URLs are returned as-is (the LLM API can fetch them directly).
|
|
16
|
+
*
|
|
17
|
+
* Returns the original URL for non-local addresses.
|
|
18
|
+
* Returns a `data:<mime>;base64,...` string for local addresses.
|
|
19
|
+
*/
|
|
20
|
+
export declare function resolveMediaUrl(url: string, fallbackMime?: string): Promise<string>;
|
|
21
|
+
/**
|
|
22
|
+
* Batch-resolve multiple URLs. Returns array in same order.
|
|
23
|
+
* Failures are logged and the original URL is kept (best-effort).
|
|
24
|
+
*/
|
|
25
|
+
export declare function resolveMediaUrls(urls: string[], fallbackMime?: string): Promise<string[]>;
|
|
@@ -72,9 +72,11 @@ export declare function canUseDreamTool(memoryRoot: string, restriction: DreamTo
|
|
|
72
72
|
* Build the 4-phase memory consolidation prompt.
|
|
73
73
|
*
|
|
74
74
|
* Adapted from CC's consolidationPrompt.ts with our project context.
|
|
75
|
+
* P5: Enhanced with category-aware merge rules from write gate taxonomy.
|
|
75
76
|
*/
|
|
76
77
|
export declare function buildConsolidationPrompt(memoryRoot: string, transcriptDir: string, sessionIds: string[], opts?: {
|
|
77
78
|
hasQMemory?: boolean;
|
|
79
|
+
categoryContext?: string;
|
|
78
80
|
}): string;
|
|
79
81
|
/**
|
|
80
82
|
* Check whether dream consolidation should run.
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { QMemoryCategory } from "../../skills/memory/memory-write-gate.js";
|
|
2
|
+
/** A memory file with its inferred category and metadata. */
|
|
3
|
+
export interface CategorizedMemoryFile {
|
|
4
|
+
filename: string;
|
|
5
|
+
category: QMemoryCategory | "uncategorized";
|
|
6
|
+
/** First line description. */
|
|
7
|
+
description: string;
|
|
8
|
+
/** File size bytes. */
|
|
9
|
+
sizeBytes: number;
|
|
10
|
+
/** Count of entries/bullets in the file. */
|
|
11
|
+
entryCount: number;
|
|
12
|
+
}
|
|
13
|
+
/** Category statistics for the dream prompt. */
|
|
14
|
+
export interface CategoryManifest {
|
|
15
|
+
/** Per-category file groups. */
|
|
16
|
+
categories: Record<string, CategorizedMemoryFile[]>;
|
|
17
|
+
/** Total files scanned. */
|
|
18
|
+
totalFiles: number;
|
|
19
|
+
/** Files that couldn't be classified. */
|
|
20
|
+
uncategorizedCount: number;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Scan MEMDIR and classify all topic files by category.
|
|
24
|
+
*
|
|
25
|
+
* @param memoryRoot - The MEMDIR root directory
|
|
26
|
+
* @returns Category manifest with grouped files
|
|
27
|
+
*/
|
|
28
|
+
export declare function scanCategoryManifest(memoryRoot: string): Promise<CategoryManifest>;
|
|
29
|
+
/**
|
|
30
|
+
* Category-specific merge/conflict rules for the dream prompt.
|
|
31
|
+
*
|
|
32
|
+
* These rules tell the dream agent how to handle each category:
|
|
33
|
+
* - facts: supersede (newer replaces older when same topic)
|
|
34
|
+
* - lessons: accumulate (append new insights, don't delete old)
|
|
35
|
+
* - preferences: overwrite (latest preference wins)
|
|
36
|
+
* - patterns: merge (consolidate duplicates into one authoritative entry)
|
|
37
|
+
* - decisions: update (add "update" section if decision changed)
|
|
38
|
+
*/
|
|
39
|
+
export declare const CATEGORY_MERGE_RULES: Record<QMemoryCategory | "uncategorized", string>;
|
|
40
|
+
/**
|
|
41
|
+
* Format the category manifest and merge rules as an injection block
|
|
42
|
+
* for the dream consolidation prompt.
|
|
43
|
+
*
|
|
44
|
+
* This replaces the blind "grep transcripts" approach with structured
|
|
45
|
+
* guidance about what exists and how to handle each category.
|
|
46
|
+
*/
|
|
47
|
+
export declare function formatCategoryContextBlock(manifest: CategoryManifest): string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -3,4 +3,5 @@ export { createContentReplacementState, enforceToolResultBudget, maybePersistLar
|
|
|
3
3
|
export { resolveToolEligibility, type ToolEligibilityContext, type ToolEligibilityResult } from "./tool-eligibility.js";
|
|
4
4
|
export { runForkedAgent, type ForkedAgentParams, type CanUseToolFn } from "./forked-agent.js";
|
|
5
5
|
export { runDream, type DreamRunDeps } from "./dream-agent.js";
|
|
6
|
+
export { runDecayCycle, shouldTriggerDecay, markDecayComplete, type DecayCycleDeps, type DecayCycleResult, type DecayConfig } from "./memory-decay.js";
|
|
6
7
|
export { createProgressTracker, updateProgressFromUsage, recordToolUse, getProgressUpdate, type AgentProgress, } from "./progress-tracker.js";
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import type { DecayOptions, DecayResult } from "../../skills/memory/qmemory-adapter.js";
|
|
2
|
+
export interface DecayConfig {
|
|
3
|
+
/** Minimum hours between decay cycles. Default: 24. */
|
|
4
|
+
minIntervalHours: number;
|
|
5
|
+
/** Enable temporal expiry (event/plan memories past grace period). Default: true. */
|
|
6
|
+
temporalExpiry: boolean;
|
|
7
|
+
/** Enable staleness decay (reduce importance of unaccessed memories). Default: true. */
|
|
8
|
+
stalenessDecay: boolean;
|
|
9
|
+
/** Enable noise archival (archive memories below threshold). Default: true. */
|
|
10
|
+
noiseArchival: boolean;
|
|
11
|
+
}
|
|
12
|
+
export declare const DEFAULT_DECAY_CONFIG: DecayConfig;
|
|
13
|
+
/**
|
|
14
|
+
* Check whether enough time has elapsed since last decay.
|
|
15
|
+
* Returns true if decay should run.
|
|
16
|
+
*/
|
|
17
|
+
export declare function shouldTriggerDecay(memoryRoot: string, config?: Partial<DecayConfig>): Promise<boolean>;
|
|
18
|
+
/**
|
|
19
|
+
* Mark decay as having just run (persist timestamp).
|
|
20
|
+
*/
|
|
21
|
+
export declare function markDecayComplete(memoryRoot: string): Promise<void>;
|
|
22
|
+
export interface DecayCycleDeps {
|
|
23
|
+
/** QMemory adapter with triggerDecay method. */
|
|
24
|
+
adapter: {
|
|
25
|
+
triggerDecay(userId: string, options?: DecayOptions): Promise<DecayResult>;
|
|
26
|
+
};
|
|
27
|
+
/** User ID for QMemory operations. */
|
|
28
|
+
userId: string;
|
|
29
|
+
/** Memory root directory (for gate marker). */
|
|
30
|
+
memoryRoot: string;
|
|
31
|
+
/** Decay configuration overrides. */
|
|
32
|
+
config?: Partial<DecayConfig>;
|
|
33
|
+
/** Logger. */
|
|
34
|
+
log?: {
|
|
35
|
+
info(msg: string): void;
|
|
36
|
+
debug?(msg: string): void;
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
export interface DecayCycleResult {
|
|
40
|
+
/** Whether decay actually ran (false = skipped by gate). */
|
|
41
|
+
ran: boolean;
|
|
42
|
+
/** Number of memories whose importance was reduced. */
|
|
43
|
+
decayed: number;
|
|
44
|
+
/** Number of memories archived (below threshold). */
|
|
45
|
+
archived: number;
|
|
46
|
+
/** Duration in ms. */
|
|
47
|
+
durationMs: number;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Run a full decay cycle with gate check.
|
|
51
|
+
*
|
|
52
|
+
* Lifecycle:
|
|
53
|
+
* 1. Check time gate (24h default)
|
|
54
|
+
* 2. Call QMemory /v1/admin/decay
|
|
55
|
+
* 3. Mark completion timestamp
|
|
56
|
+
*/
|
|
57
|
+
export declare function runDecayCycle(deps: DecayCycleDeps): Promise<DecayCycleResult>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
export { createHookRegistry, type RuntimeLogger } from "./hook-registry.js";
|
|
2
2
|
export { registerMemoryHooks, createMemoryPrefetchState, type MemoryHooksDeps, type MemoryPrefetchState, MEMORY_PREFETCH_CONFIG, } from "./memory-hooks.js";
|
|
3
3
|
export { registerContextCompressionHook, compressMessages } from "./context-compression.js";
|
|
4
|
+
export { registerSkillRecallHooks, detectRetrospectiveTrigger, invalidateSkillRecallCache, type SkillRecallHooksDeps, SKILL_RECALL_CONFIG, } from "./skill-recall-hooks.js";
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { HookRegistry } from "../../contracts/hooks.js";
|
|
2
2
|
import type { MemoryProvider } from "qlogicagent-runtime-contracts";
|
|
3
|
+
import type { Memdir } from "../../skills/memory/memdir.js";
|
|
3
4
|
export declare const MEMORY_PREFETCH_CONFIG: {
|
|
4
5
|
/** Max bytes of memory content to inject per session (CC: 60KB) */
|
|
5
6
|
readonly MAX_SESSION_BYTES: number;
|
|
@@ -47,3 +48,22 @@ export declare function createMemoryPrefetchState(): MemoryPrefetchState;
|
|
|
47
48
|
export declare function registerMemoryHooks(hooks: HookRegistry, deps: MemoryHooksDeps,
|
|
48
49
|
/** Shared state — pass the same object across hook re-registrations in a session. */
|
|
49
50
|
prefetchState?: MemoryPrefetchState): () => void;
|
|
51
|
+
export interface MemdirRecallHookDeps {
|
|
52
|
+
/** MEMDIR instance (lazy: may be null at registration time). */
|
|
53
|
+
getMemdir: () => Memdir | null;
|
|
54
|
+
/** Logger. */
|
|
55
|
+
log: {
|
|
56
|
+
debug(msg: string): void;
|
|
57
|
+
warn(msg: string): void;
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Register the MEMDIR cross-file recall hook on `memory.before_recall`.
|
|
62
|
+
*
|
|
63
|
+
* - Priority 40 (before QMemory at 50)
|
|
64
|
+
* - Scans topic files, selects top-5 relevant
|
|
65
|
+
* - Injects content into recalledMemories (merged with QMemory results)
|
|
66
|
+
* - Respects session byte budget from shared MemoryPrefetchState
|
|
67
|
+
* - Dedup via surfacedPaths (shared with QMemory hook)
|
|
68
|
+
*/
|
|
69
|
+
export declare function registerMemdirRecallHook(hooks: HookRegistry, deps: MemdirRecallHookDeps, prefetchState?: MemoryPrefetchState): () => void;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { HookRegistry } from "../../contracts/hooks.js";
|
|
2
|
+
export declare const SKILL_RECALL_CONFIG: {
|
|
3
|
+
/** Max number of cross-project skills to inject per turn. */
|
|
4
|
+
readonly MAX_RECALLED_SKILLS: 3;
|
|
5
|
+
/** Max chars of skill content to include in recall context. */
|
|
6
|
+
readonly MAX_SKILL_CONTENT_CHARS: 800;
|
|
7
|
+
/** Cache TTL for known project skill index (ms). */
|
|
8
|
+
readonly CACHE_TTL_MS: number;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Detect whether user message contains retrospective/cross-reference semantics.
|
|
12
|
+
* Returns extracted keywords for skill matching if triggered, or null.
|
|
13
|
+
*/
|
|
14
|
+
export declare function detectRetrospectiveTrigger(message: string): string[] | null;
|
|
15
|
+
export interface SkillRecallHooksDeps {
|
|
16
|
+
/** Current project cwd (to exclude from cross-project search). */
|
|
17
|
+
currentCwd?: string;
|
|
18
|
+
/** Logger. */
|
|
19
|
+
log: {
|
|
20
|
+
debug(msg: string): void;
|
|
21
|
+
warn(msg: string): void;
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Register the cross-project skill recall hook on `memory.before_recall`.
|
|
26
|
+
* Runs at lower priority (60) than QMemory prefetch (50) so it supplements,
|
|
27
|
+
* not replaces, the standard memory recall.
|
|
28
|
+
*
|
|
29
|
+
* When triggered, injects cross-project skill metadata into recalledMemories.
|
|
30
|
+
*/
|
|
31
|
+
export declare function registerSkillRecallHooks(hooks: HookRegistry, deps: SkillRecallHooksDeps): () => void;
|
|
32
|
+
/**
|
|
33
|
+
* Invalidate the cross-project skill index cache.
|
|
34
|
+
* Call when skills are created/deleted/promoted to refresh.
|
|
35
|
+
*/
|
|
36
|
+
export declare function invalidateSkillRecallCache(): void;
|
|
@@ -59,7 +59,19 @@ export declare function getProjectSessionsRoot(cwd: string): string;
|
|
|
59
59
|
export declare function getProjectSessionDir(cwd: string, sessionId: string): string;
|
|
60
60
|
/** `<cwd>/.qlogicagent/checkpoints/` or `<cwd>/.qlogicagent/checkpoints/{sessionId}` */
|
|
61
61
|
export declare function getProjectCheckpointsDir(cwd: string, sessionId?: string): string;
|
|
62
|
-
/** `<cwd>/.qlogicagent/memory.json` */
|
|
63
|
-
export declare function getProjectMemoryPath(cwd: string): string;
|
|
64
62
|
/** `<gitRoot>/.qlogicagent/hooks/` */
|
|
65
63
|
export declare function getGitRootHooksDir(gitRoot: string): string;
|
|
64
|
+
/**
|
|
65
|
+
* Discover all known project directories from session history.
|
|
66
|
+
* Scans `~/.qlogicagent/sessions/` metadata to extract unique `cwd` paths.
|
|
67
|
+
* Used for cross-project skill recall (read-only, never writes to foreign projects).
|
|
68
|
+
*
|
|
69
|
+
* @param excludeCwd - Current project cwd to exclude from results
|
|
70
|
+
* @returns Array of absolute paths to project roots that have been worked on
|
|
71
|
+
*/
|
|
72
|
+
export declare function getKnownProjectDirs(excludeCwd?: string): string[];
|
|
73
|
+
/**
|
|
74
|
+
* Get skill directories from all known projects (excluding current).
|
|
75
|
+
* Returns paths to `<project>/.qlogicagent/skills/` for recall-only access.
|
|
76
|
+
*/
|
|
77
|
+
export declare function getAllProjectSkillDirs(excludeCwd?: string): string[];
|
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
* Provides:
|
|
5
5
|
* - Atomic write (tmp + rename) with dir auto-creation
|
|
6
6
|
* - JSON read/write helpers
|
|
7
|
-
* - MemoryStore disk persistence (auto-save on mutation)
|
|
8
7
|
*/
|
|
9
8
|
/**
|
|
10
9
|
* Write data atomically: write to a temp file in the same directory,
|
|
@@ -19,18 +18,3 @@ export declare function readJsonFile<T = unknown>(filePath: string): Promise<T |
|
|
|
19
18
|
* Write a JSON file atomically.
|
|
20
19
|
*/
|
|
21
20
|
export declare function writeJsonFile(filePath: string, data: unknown): Promise<void>;
|
|
22
|
-
/** Path to user-level memory file: `~/.qlogicagent/memory.json` */
|
|
23
|
-
export declare function getMemoryFilePath(): string;
|
|
24
|
-
export interface PersistedMemory {
|
|
25
|
-
memory: string;
|
|
26
|
-
user: string;
|
|
27
|
-
/** ISO 8601 timestamp of last save. */
|
|
28
|
-
savedAt: string;
|
|
29
|
-
}
|
|
30
|
-
/** Load persisted memory from disk. Returns undefined if no file exists. */
|
|
31
|
-
export declare function loadPersistedMemory(): Promise<PersistedMemory | undefined>;
|
|
32
|
-
/** Save memory to disk atomically. */
|
|
33
|
-
export declare function savePersistedMemory(data: {
|
|
34
|
-
memory: string;
|
|
35
|
-
user: string;
|
|
36
|
-
}): Promise<void>;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
export { AGENT_DOT_DIR, getUserAgentHome, getUserSessionDir, getUserCredentialsPath, getUserPluginsDir, getUserSkillsDir, getUserSettingsPath, getUserCacheDir, getUserDebugLogsDir, getUserCheckpointsDir, getUserPluginCacheDir, getUserMcpConfigPath, getUserMarketplaceConfigPath, getUserWorkflowsDir, getUserInstructionsPath, getProjectAgentDir, getProjectWorkflowsDir, getProjectPluginsDir, getProjectSkillsDir, getProjectSettingsPath, getProjectInstructionsPath, getProjectRulesDir, getGitRootHooksDir, } from "./agent-paths.js";
|
|
1
|
+
export { AGENT_DOT_DIR, getUserAgentHome, getUserSessionDir, getUserCredentialsPath, getUserPluginsDir, getUserSkillsDir, getUserSettingsPath, getUserCacheDir, getUserDebugLogsDir, getUserCheckpointsDir, getUserPluginCacheDir, getUserMcpConfigPath, getUserMarketplaceConfigPath, getUserWorkflowsDir, getUserInstructionsPath, getProjectAgentDir, getProjectWorkflowsDir, getProjectPluginsDir, getProjectSkillsDir, getProjectSettingsPath, getProjectInstructionsPath, getProjectRulesDir, getGitRootHooksDir, getKnownProjectDirs, getAllProjectSkillDirs, } from "./agent-paths.js";
|
|
2
2
|
export { getBudgetContinuationMessage } from "./token-budget.js";
|
|
3
3
|
export { type SecureStorage, saveApiKey, loadApiKey } from "./secure-storage.js";
|
|
4
4
|
export { createFileWatcher, FileWatcher } from "./file-watcher.js";
|
|
5
5
|
export { TaskStore } from "./task-runtime.js";
|
|
6
6
|
export { createWorktreeBackend } from "./worktree-backend.js";
|
|
7
7
|
export { registerCleanup, runCleanupFunctions } from "./cleanup-registry.js";
|
|
8
|
-
export { atomicWriteFile, readJsonFile, writeJsonFile,
|
|
8
|
+
export { atomicWriteFile, readJsonFile, writeJsonFile, } from "./disk-storage.js";
|
|
9
9
|
export { AcpDetector, ACP_BACKENDS } from "./acp-detector.js";
|
|
10
10
|
export { AcpProtocolAdapter, type TranslatedNotification, type AcpHostRequestHandler } from "./acp-protocol-adapter.js";
|
|
11
11
|
export { AcpUsageTracker, type AccumulatedUsage } from "./acp-usage-tracker.js";
|
|
@@ -52,8 +52,10 @@ export interface SessionListEntry {
|
|
|
52
52
|
/**
|
|
53
53
|
* Append a message to the session transcript.
|
|
54
54
|
* Creates the session directory if it doesn't exist.
|
|
55
|
+
* When turnId is provided, it acts as a per-turn boundary marker enabling
|
|
56
|
+
* reconciliation with Gateway's token_usage records.
|
|
55
57
|
*/
|
|
56
|
-
export declare function appendMessage(sessionId: string, message: ChatMessage, projectRoot?: string): Promise<void>;
|
|
58
|
+
export declare function appendMessage(sessionId: string, message: ChatMessage, projectRoot?: string, turnId?: string): Promise<void>;
|
|
57
59
|
/**
|
|
58
60
|
* Save session state (cost + metadata) atomically.
|
|
59
61
|
*/
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
export type { PortableTool, PortableToolResult, ToolContentBlock, } from "./portable-tool.js";
|
|
2
2
|
export { setToolPool, addTool, addTools, removeTool, findTool, hasTool, getToolNames, getToolCount, executeTool, getToolManifest, getTools, activateTool, isToolActivated, clearActivatedTools, AGENT_DISALLOWED_TOOLS, CUSTOM_AGENT_DISALLOWED_TOOLS, filterToolsForAgent, } from "./tools.js";
|
|
3
|
-
export { MEMORY_TOOL_NAME,
|
|
4
|
-
export type { MemoryToolAction, MemoryToolParams, MemoryToolResult, MemoryToolExecutorDeps,
|
|
5
|
-
export {
|
|
6
|
-
export type {
|
|
3
|
+
export { MEMORY_TOOL_NAME, MEMORY_TOOL_ACTIONS, MEMORY_TOOL_SCHEMA, MEMORY_TOOL_DESCRIPTION, MEMORY_TOOL_LABEL, isMemoryContentSafe, executeMemoryTool, } from "./memory/memory-tool.js";
|
|
4
|
+
export type { MemoryToolAction, MemoryToolParams, MemoryToolResult, MemoryToolExecutorDeps, } from "./memory/memory-tool.js";
|
|
5
|
+
export { Memdir, getMemdirPath, getIndexPath } from "./memory/memdir.js";
|
|
6
|
+
export type { MemdirFileInfo, MemdirResult } from "./memory/memdir.js";
|
|
7
7
|
export { createQMemoryAdapter } from "./memory/qmemory-adapter.js";
|
|
8
|
-
export type { QMemoryAdapterConfig, QMemoryHealthStatus, ExtractedMemoryItem } from "./memory/qmemory-adapter.js";
|
|
8
|
+
export type { QMemoryAdapterConfig, QMemoryHealthStatus, ExtractedMemoryItem, DecayOptions, DecayResult } from "./memory/qmemory-adapter.js";
|
|
9
9
|
export { THINK_TOOL_NAME, THINK_TOOL_SCHEMA, createThinkTool } from "./think-tool.js";
|
|
10
10
|
export type { ThinkToolParams } from "./think-tool.js";
|
|
11
11
|
export { TODO_TOOL_NAME, TODO_TOOL_SCHEMA, TODO_ACTIONS, createTodoTool } from "./todo-tool.js";
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
export declare const RELEVANT_MEMORIES_CONFIG: {
|
|
2
|
+
/** Max topic files to consider during scan. */
|
|
3
|
+
readonly MAX_SCAN_FILES: 100;
|
|
4
|
+
/** Max files to surface per turn. */
|
|
5
|
+
readonly MAX_SELECTED: 5;
|
|
6
|
+
/** Max bytes per surfaced file (CC: 4096). */
|
|
7
|
+
readonly MAX_FILE_BYTES: 4096;
|
|
8
|
+
/** Max total bytes for all surfaced files combined. */
|
|
9
|
+
readonly MAX_TOTAL_BYTES: number;
|
|
10
|
+
/** Minimum score to be selected (0.0-1.0). */
|
|
11
|
+
readonly MIN_SCORE: 0.2;
|
|
12
|
+
/** Lines to read for header/description extraction. */
|
|
13
|
+
readonly HEADER_LINES: 10;
|
|
14
|
+
/** Recency boost: files modified within this many days get a bonus. */
|
|
15
|
+
readonly RECENCY_DAYS: 7;
|
|
16
|
+
/** Recency boost amount. */
|
|
17
|
+
readonly RECENCY_BOOST: 0.15;
|
|
18
|
+
};
|
|
19
|
+
/** Scanned memory file header (CC MemoryHeader parity). */
|
|
20
|
+
export interface MemoryFileHeader {
|
|
21
|
+
/** Filename (e.g. "lesson-docker.md") */
|
|
22
|
+
filename: string;
|
|
23
|
+
/** Absolute path */
|
|
24
|
+
filePath: string;
|
|
25
|
+
/** Last modified timestamp (ms since epoch) */
|
|
26
|
+
mtimeMs: number;
|
|
27
|
+
/** File size in bytes */
|
|
28
|
+
sizeBytes: number;
|
|
29
|
+
/** Description extracted from first non-heading line */
|
|
30
|
+
description: string | null;
|
|
31
|
+
/** Category inferred from filename prefix */
|
|
32
|
+
category: string | null;
|
|
33
|
+
}
|
|
34
|
+
/** A selected relevant memory with content loaded. */
|
|
35
|
+
export interface RelevantMemory {
|
|
36
|
+
/** Filename */
|
|
37
|
+
filename: string;
|
|
38
|
+
/** Full file path */
|
|
39
|
+
filePath: string;
|
|
40
|
+
/** Last modified timestamp */
|
|
41
|
+
mtimeMs: number;
|
|
42
|
+
/** Relevance score (0.0 - 1.0) */
|
|
43
|
+
score: number;
|
|
44
|
+
/** Content (possibly truncated) */
|
|
45
|
+
content: string;
|
|
46
|
+
/** Whether content was truncated */
|
|
47
|
+
truncated: boolean;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Find memory files relevant to a user query.
|
|
51
|
+
*
|
|
52
|
+
* CC parity: scans topic files, scores by keyword + filename + recency,
|
|
53
|
+
* selects top-N, loads content. No LLM needed (unlike CC's Sonnet call).
|
|
54
|
+
*
|
|
55
|
+
* @param query - User query text
|
|
56
|
+
* @param memoryDir - Root of the MEMDIR directory (~/.qlogicagent/memory/)
|
|
57
|
+
* @param alreadySurfaced - Paths already shown in prior turns (for dedup)
|
|
58
|
+
* @returns Relevant memories with content, sorted by score
|
|
59
|
+
*/
|
|
60
|
+
export declare function findRelevantMemories(query: string, memoryDir: string, alreadySurfaced?: ReadonlySet<string>): Promise<RelevantMemory[]>;
|
|
61
|
+
/**
|
|
62
|
+
* Scan memory directory for topic files (excludes INDEX.md).
|
|
63
|
+
* Returns headers sorted by modification time (newest first).
|
|
64
|
+
*/
|
|
65
|
+
export declare function scanMemoryHeaders(memoryDir: string): Promise<MemoryFileHeader[]>;
|
|
66
|
+
/**
|
|
67
|
+
* Format relevant memories as a single block for system prompt injection.
|
|
68
|
+
* CC parity: includes freshness header per file.
|
|
69
|
+
*/
|
|
70
|
+
export declare function formatRelevantMemoriesBlock(memories: RelevantMemory[]): string;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/** Max chars for INDEX.md to inject into system prompt (CC uses 25KB, we use 12KB). */
|
|
2
|
+
export declare const INDEX_MAX_CHARS = 12288;
|
|
3
|
+
/** Max lines for INDEX.md injection. */
|
|
4
|
+
export declare const INDEX_MAX_LINES = 200;
|
|
5
|
+
/** Max chars for a single topic file. */
|
|
6
|
+
export declare const TOPIC_FILE_MAX_CHARS = 8192;
|
|
7
|
+
/** Root directory: ~/.qlogicagent/memory/ */
|
|
8
|
+
export declare function getMemdirPath(): string;
|
|
9
|
+
/** Full path to INDEX.md */
|
|
10
|
+
export declare function getIndexPath(): string;
|
|
11
|
+
export interface MemdirFileInfo {
|
|
12
|
+
name: string;
|
|
13
|
+
/** Size in bytes */
|
|
14
|
+
size: number;
|
|
15
|
+
/** Last modified ISO timestamp */
|
|
16
|
+
modifiedAt: string;
|
|
17
|
+
/** First non-empty line (preview) */
|
|
18
|
+
preview?: string;
|
|
19
|
+
}
|
|
20
|
+
export interface MemdirResult {
|
|
21
|
+
ok: boolean;
|
|
22
|
+
message: string;
|
|
23
|
+
/** File path relative to memdir */
|
|
24
|
+
file?: string;
|
|
25
|
+
/** Current INDEX.md char usage */
|
|
26
|
+
indexUsage?: string;
|
|
27
|
+
}
|
|
28
|
+
export declare function isMemoryContentSafe(text: string): boolean;
|
|
29
|
+
export declare class Memdir {
|
|
30
|
+
private readonly root;
|
|
31
|
+
private indexCache;
|
|
32
|
+
constructor(root?: string);
|
|
33
|
+
/** Get the root directory path of this MEMDIR. */
|
|
34
|
+
getRootPath(): string;
|
|
35
|
+
/** Ensure memdir exists with a default INDEX.md if missing. */
|
|
36
|
+
ensureInitialized(): void;
|
|
37
|
+
/**
|
|
38
|
+
* Get INDEX.md content for system prompt injection.
|
|
39
|
+
* Truncated to INDEX_MAX_CHARS / INDEX_MAX_LINES.
|
|
40
|
+
*/
|
|
41
|
+
getIndexForPrompt(): string;
|
|
42
|
+
/** Get raw INDEX.md content (untruncated). */
|
|
43
|
+
getIndexRaw(): string;
|
|
44
|
+
/** Get INDEX.md usage stats. */
|
|
45
|
+
getIndexUsage(): {
|
|
46
|
+
chars: number;
|
|
47
|
+
lines: number;
|
|
48
|
+
percent: number;
|
|
49
|
+
};
|
|
50
|
+
/** Append a line/entry to INDEX.md. */
|
|
51
|
+
addToIndex(content: string): Promise<MemdirResult>;
|
|
52
|
+
/** Replace text in INDEX.md (str_replace semantics). */
|
|
53
|
+
replaceInIndex(oldText: string, newText: string): Promise<MemdirResult>;
|
|
54
|
+
/** Remove text from INDEX.md. */
|
|
55
|
+
removeFromIndex(oldText: string): Promise<MemdirResult>;
|
|
56
|
+
/** List all memory files (excluding INDEX.md). */
|
|
57
|
+
listFiles(): Promise<MemdirFileInfo[]>;
|
|
58
|
+
/** Create a new topic file. Fails if it already exists. */
|
|
59
|
+
createFile(name: string, content: string): Promise<MemdirResult>;
|
|
60
|
+
/** Write/overwrite a topic file. */
|
|
61
|
+
writeFile(name: string, content: string): Promise<MemdirResult>;
|
|
62
|
+
/** Read a topic file. */
|
|
63
|
+
readFile(name: string): Promise<{
|
|
64
|
+
ok: boolean;
|
|
65
|
+
content?: string;
|
|
66
|
+
message: string;
|
|
67
|
+
}>;
|
|
68
|
+
/** Delete a topic file. INDEX.md cannot be deleted. */
|
|
69
|
+
deleteFile(name: string): Promise<MemdirResult>;
|
|
70
|
+
/** Search all memory files for keyword matches. Returns matching snippets. */
|
|
71
|
+
searchLocal(query: string): Promise<Array<{
|
|
72
|
+
file: string;
|
|
73
|
+
snippet: string;
|
|
74
|
+
score: number;
|
|
75
|
+
}>>;
|
|
76
|
+
private writeIndex;
|
|
77
|
+
private ensureDir;
|
|
78
|
+
/** Append an entry to the file listing section of INDEX.md (idempotent). */
|
|
79
|
+
private appendIndexEntry;
|
|
80
|
+
}
|
|
@@ -1,16 +1,8 @@
|
|
|
1
1
|
import type { MemoryProvider, MemorySearchResult } from "qlogicagent-runtime-contracts";
|
|
2
|
-
import type {
|
|
3
|
-
export interface MediaPreferencesSummary {
|
|
4
|
-
imageStyle?: string;
|
|
5
|
-
videoStyle?: string;
|
|
6
|
-
musicGenre?: string;
|
|
7
|
-
musicMood?: string;
|
|
8
|
-
primaryPurpose?: string;
|
|
9
|
-
colorPreference?: string;
|
|
10
|
-
}
|
|
2
|
+
import type { Memdir } from "./memdir.js";
|
|
11
3
|
export declare const MEMORY_TOOL_NAME: "memory";
|
|
12
|
-
export declare const
|
|
13
|
-
export declare const MEMORY_TOOL_ACTIONS: readonly ["add", "replace", "remove", "search"];
|
|
4
|
+
export declare const MEMORY_TOOL_LABEL = "Memory";
|
|
5
|
+
export declare const MEMORY_TOOL_ACTIONS: readonly ["add", "replace", "remove", "create_file", "write_file", "read_file", "delete_file", "list_files", "search"];
|
|
14
6
|
export type MemoryToolAction = (typeof MEMORY_TOOL_ACTIONS)[number];
|
|
15
7
|
export declare const MEMORY_TOOL_SCHEMA: {
|
|
16
8
|
readonly type: "object";
|
|
@@ -20,68 +12,48 @@ export declare const MEMORY_TOOL_SCHEMA: {
|
|
|
20
12
|
readonly enum: string[];
|
|
21
13
|
readonly description: string;
|
|
22
14
|
};
|
|
23
|
-
readonly target: {
|
|
24
|
-
readonly type: "string";
|
|
25
|
-
readonly enum: readonly ["memory", "user"];
|
|
26
|
-
readonly description: string;
|
|
27
|
-
};
|
|
28
15
|
readonly content: {
|
|
29
16
|
readonly type: "string";
|
|
30
17
|
readonly description: string;
|
|
31
18
|
};
|
|
32
19
|
readonly old_text: {
|
|
33
20
|
readonly type: "string";
|
|
34
|
-
readonly description: "
|
|
21
|
+
readonly description: "For 'replace'/'remove': the exact text to find in INDEX.md.";
|
|
35
22
|
};
|
|
36
|
-
readonly
|
|
23
|
+
readonly new_text: {
|
|
37
24
|
readonly type: "string";
|
|
38
|
-
readonly description: "
|
|
25
|
+
readonly description: "For 'replace': the replacement text.";
|
|
39
26
|
};
|
|
40
|
-
readonly
|
|
27
|
+
readonly file: {
|
|
41
28
|
readonly type: "string";
|
|
42
|
-
readonly
|
|
43
|
-
|
|
29
|
+
readonly description: "Filename for file operations (e.g. 'project-notes.md', 'lesson-esbuild.md'). Must be kebab-case .md.";
|
|
30
|
+
};
|
|
31
|
+
readonly query: {
|
|
32
|
+
readonly type: "string";
|
|
33
|
+
readonly description: "For 'search': natural language query to find relevant memories.";
|
|
44
34
|
};
|
|
45
35
|
};
|
|
46
36
|
readonly required: readonly ["action"];
|
|
47
37
|
};
|
|
48
38
|
export declare const MEMORY_TOOL_DESCRIPTION: string;
|
|
49
|
-
export declare const MEMORY_TOOL_LABEL = "Memory";
|
|
50
39
|
export declare function isMemoryContentSafe(text: string): boolean;
|
|
51
40
|
export interface MemoryToolParams {
|
|
52
41
|
action: MemoryToolAction;
|
|
53
|
-
target?: MemoryStoreTarget;
|
|
54
42
|
content?: string;
|
|
55
43
|
old_text?: string;
|
|
44
|
+
new_text?: string;
|
|
45
|
+
file?: string;
|
|
56
46
|
query?: string;
|
|
57
|
-
category?: "profile" | "facts" | "media" | "projects";
|
|
58
47
|
}
|
|
59
48
|
export interface MemoryToolResult {
|
|
60
49
|
ok: boolean;
|
|
61
50
|
message: string;
|
|
62
51
|
action: string;
|
|
63
|
-
/** For MD store operations: live entry count */
|
|
64
|
-
entryCount?: number;
|
|
65
|
-
/** For MD store operations: usage string */
|
|
66
|
-
usage?: string;
|
|
67
|
-
/** For search: qmemory results */
|
|
68
52
|
results?: MemorySearchResult[];
|
|
69
|
-
/** Indicates MD store was mutated (consumer should persist) */
|
|
70
|
-
storeModified?: boolean;
|
|
71
|
-
errorCode?: string;
|
|
72
53
|
}
|
|
73
54
|
export interface MemoryToolExecutorDeps {
|
|
74
|
-
|
|
75
|
-
provider
|
|
76
|
-
/** Local MD memory store for notes. */
|
|
77
|
-
store?: MemoryStore;
|
|
55
|
+
memdir: Memdir;
|
|
56
|
+
provider?: MemoryProvider;
|
|
78
57
|
userId: string;
|
|
79
|
-
sessionId?: string;
|
|
80
|
-
/** Query recalled facts/memories by natural language. */
|
|
81
|
-
queryGraph?: (query: string, userId: string) => string[];
|
|
82
|
-
/** Retrieve user profile summary. */
|
|
83
|
-
getProfileSummary?: (userId: string) => string | null;
|
|
84
|
-
/** Retrieve media preferences. */
|
|
85
|
-
getMediaPreferences?: (userId: string) => MediaPreferencesSummary | null;
|
|
86
58
|
}
|
|
87
59
|
export declare function executeMemoryTool(params: MemoryToolParams, deps: MemoryToolExecutorDeps): Promise<MemoryToolResult>;
|