qlogicagent 2.7.0 → 2.9.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/dist/agent.js +18 -18
- package/dist/cli.js +353 -413
- package/dist/index.js +373 -433
- package/dist/orchestration.js +6 -6
- package/dist/protocol.js +1 -1
- package/dist/types/agent/agent.d.ts +1 -1
- package/dist/types/agent/tool-loop.d.ts +1 -1
- package/dist/types/agent/tunable-defaults.d.ts +4 -0
- package/dist/types/agent/types.d.ts +7 -18
- package/dist/types/cli/handlers/agents-handler.d.ts +19 -0
- package/dist/types/cli/handlers/config-handler.d.ts +17 -0
- package/dist/types/cli/handlers/dream-handler.d.ts +5 -0
- package/dist/types/cli/handlers/files-handler.d.ts +15 -0
- package/dist/types/cli/handlers/media-handler.d.ts +13 -0
- package/dist/types/cli/handlers/memory-handler.d.ts +11 -0
- package/dist/types/cli/handlers/pet-handler.d.ts +21 -0
- package/dist/types/cli/handlers/product-handler.d.ts +32 -0
- package/dist/types/cli/handlers/project-handler.d.ts +19 -0
- package/dist/types/cli/handlers/session-handler.d.ts +38 -0
- package/dist/types/cli/handlers/settings-handler.d.ts +24 -0
- package/dist/types/cli/handlers/skills-handler.d.ts +20 -0
- package/dist/types/cli/handlers/solo-handler.d.ts +15 -0
- package/dist/types/cli/handlers/turn-handler.d.ts +17 -0
- package/dist/types/cli/main.d.ts +2 -2
- package/dist/types/cli/stdio-server.d.ts +64 -106
- package/dist/types/cli/tool-bootstrap.d.ts +4 -3
- package/dist/types/config/config.d.ts +1 -1
- package/dist/types/index.d.ts +2 -2
- package/dist/types/llm/index.d.ts +1 -31
- package/dist/types/orchestration/tool-cascade.d.ts +2 -2
- package/dist/types/protocol/methods.d.ts +153 -5
- package/dist/types/protocol/wire/agent-events.d.ts +2 -2
- package/dist/types/protocol/wire/agent-methods.d.ts +5 -3
- package/dist/types/protocol/wire/gateway-rpc.d.ts +77 -4
- package/dist/types/protocol/wire/index.d.ts +1 -1
- package/dist/types/protocol/wire/notification-payloads.d.ts +72 -1
- package/dist/types/runtime/execution/dream-agent.d.ts +1 -1
- package/dist/types/runtime/execution/forked-agent.d.ts +1 -1
- package/dist/types/runtime/hooks/context-compression.d.ts +1 -1
- package/dist/types/runtime/hooks/memory-hooks.d.ts +1 -1
- package/dist/types/runtime/infra/acp-types.d.ts +4 -0
- package/dist/types/runtime/infra/agent-paths.d.ts +22 -25
- package/dist/types/runtime/infra/agent-process.d.ts +1 -1
- package/dist/types/runtime/infra/builtin-providers.d.ts +36 -0
- package/dist/types/runtime/infra/checkpoint-backend.d.ts +1 -1
- package/dist/types/runtime/infra/index.d.ts +1 -2
- package/dist/types/runtime/infra/key-pool.d.ts +120 -0
- package/dist/types/runtime/infra/media-persistence.d.ts +26 -15
- package/dist/types/runtime/infra/model-registry.d.ts +187 -0
- package/dist/types/runtime/infra/project-instructions-store.d.ts +3 -3
- package/dist/types/runtime/infra/project-store.d.ts +3 -0
- package/dist/types/runtime/infra/token-budget.d.ts +2 -2
- package/dist/types/runtime/infra/worktree-backend.d.ts +1 -1
- package/dist/types/runtime/pet/index.d.ts +8 -0
- package/dist/types/runtime/pet/pet-context-injection.d.ts +8 -0
- package/dist/types/runtime/pet/pet-file-loader.d.ts +62 -0
- package/dist/types/runtime/pet/pet-growth-engine.d.ts +60 -0
- package/dist/types/runtime/pet/pet-reaction-service.d.ts +33 -0
- package/dist/types/runtime/pet/pet-soul-service.d.ts +71 -0
- package/dist/types/runtime/session/group-session-split.d.ts +38 -0
- package/dist/types/runtime/session/index.d.ts +4 -2
- package/dist/types/runtime/session/session-locator.d.ts +24 -0
- package/dist/types/runtime/session/session-memory.d.ts +4 -4
- package/dist/types/runtime/session/session-persistence.d.ts +47 -46
- package/dist/types/runtime/session/session-state.d.ts +3 -5
- package/dist/types/skills/memory/local-memory-provider.d.ts +1 -1
- package/dist/types/skills/memory/local-store.d.ts +3 -2
- package/dist/types/skills/memory/memdir.d.ts +7 -4
- package/dist/types/skills/memory/memory-provider-factory.d.ts +2 -8
- package/dist/types/skills/permissions/denial-audit-log.d.ts +1 -1
- package/dist/types/skills/permissions/permission-classifier.d.ts +1 -1
- package/dist/types/skills/tools/search-tool.d.ts +1 -1
- package/dist/types/skills/tools.d.ts +3 -3
- package/dist/types/transport/acp-event-emitter.d.ts +1 -1
- package/dist/types/transport/acp-server.d.ts +2 -2
- package/package.json +2 -1
- package/dist/types/llm/adapters/aliyun-oss-file-upload-adapter.d.ts +0 -44
- package/dist/types/llm/adapters/gemini-file-upload-adapter.d.ts +0 -26
- package/dist/types/llm/adapters/hub-oss-file-upload-adapter.d.ts +0 -29
- package/dist/types/llm/adapters/index.d.ts +0 -10
- package/dist/types/llm/adapters/openai-file-upload-adapter.d.ts +0 -38
- package/dist/types/llm/adapters/volcengine-file-upload-adapter.d.ts +0 -24
- package/dist/types/llm/builtin-providers.d.ts +0 -10
- package/dist/types/llm/debug-transport.d.ts +0 -12
- package/dist/types/llm/file-upload-service.d.ts +0 -68
- package/dist/types/llm/gemini-schema-utils.d.ts +0 -17
- package/dist/types/llm/llm-client.d.ts +0 -43
- package/dist/types/llm/media-client.d.ts +0 -42
- package/dist/types/llm/media-transport.d.ts +0 -176
- package/dist/types/llm/model-catalog.d.ts +0 -82
- package/dist/types/llm/model-detection.d.ts +0 -22
- package/dist/types/llm/provider-def.d.ts +0 -203
- package/dist/types/llm/provider-registry.d.ts +0 -59
- package/dist/types/llm/provider-tool-api.d.ts +0 -44
- package/dist/types/llm/retry.d.ts +0 -37
- package/dist/types/llm/transport.d.ts +0 -281
- package/dist/types/llm/transports/anthropic-messages.d.ts +0 -65
- package/dist/types/llm/transports/gemini-cache-api.d.ts +0 -86
- package/dist/types/llm/transports/gemini-file-api.d.ts +0 -90
- package/dist/types/llm/transports/gemini-generatecontent.d.ts +0 -56
- package/dist/types/llm/transports/gemini-lyria-realtime.d.ts +0 -117
- package/dist/types/llm/transports/gemini-media.d.ts +0 -53
- package/dist/types/llm/transports/media-resolve.d.ts +0 -50
- package/dist/types/llm/transports/minimax-media.d.ts +0 -55
- package/dist/types/llm/transports/openai-chat.d.ts +0 -81
- package/dist/types/llm/transports/openai-media.d.ts +0 -24
- package/dist/types/llm/transports/openai-responses.d.ts +0 -63
- package/dist/types/llm/transports/qwen-media.d.ts +0 -50
- package/dist/types/llm/transports/realtime-transport.d.ts +0 -183
- package/dist/types/llm/transports/volcengine-grounding.d.ts +0 -58
- package/dist/types/llm/transports/volcengine-media.d.ts +0 -93
- package/dist/types/llm/transports/volcengine-responses.d.ts +0 -64
- package/dist/types/llm/transports/zhipu-media.d.ts +0 -82
- package/dist/types/llm/transports/zhipu-tool-api.d.ts +0 -35
- package/dist/types/runtime/infra/project-plan-store.d.ts +0 -27
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pet File Loader — loads, validates, and sanitizes .pet bundles.
|
|
3
|
+
*
|
|
4
|
+
* Design §14.2: .pet is a zip file containing manifest.json + SVG states + thumbnail.
|
|
5
|
+
* Design §16.2: Security — SVG sanitize (remove scripts, foreign objects, event handlers).
|
|
6
|
+
*
|
|
7
|
+
* This module handles:
|
|
8
|
+
* - Zip extraction
|
|
9
|
+
* - Manifest JSON Schema validation
|
|
10
|
+
* - SVG sanitization (whitelist-based)
|
|
11
|
+
* - File size enforcement
|
|
12
|
+
*/
|
|
13
|
+
export interface PetManifest {
|
|
14
|
+
version: number;
|
|
15
|
+
name: string;
|
|
16
|
+
author: string;
|
|
17
|
+
created: string;
|
|
18
|
+
generator?: string;
|
|
19
|
+
source?: {
|
|
20
|
+
type: "image" | "text" | "dialogue";
|
|
21
|
+
prompt?: string;
|
|
22
|
+
};
|
|
23
|
+
dimensions: {
|
|
24
|
+
width: number;
|
|
25
|
+
height: number;
|
|
26
|
+
};
|
|
27
|
+
states: Record<string, {
|
|
28
|
+
file: string;
|
|
29
|
+
loop: boolean;
|
|
30
|
+
duration?: number;
|
|
31
|
+
}>;
|
|
32
|
+
eyeTracking?: {
|
|
33
|
+
enabled: boolean;
|
|
34
|
+
pupils: string[];
|
|
35
|
+
maxOffset: number;
|
|
36
|
+
};
|
|
37
|
+
colors?: {
|
|
38
|
+
primary: string;
|
|
39
|
+
secondary?: string;
|
|
40
|
+
accent?: string;
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
export interface PetFileBundle {
|
|
44
|
+
manifest: PetManifest;
|
|
45
|
+
svgs: Record<string, string>;
|
|
46
|
+
thumbnail?: string;
|
|
47
|
+
hash: string;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Load and validate a .pet file from disk.
|
|
51
|
+
* Returns a PetFileBundle with sanitized SVGs, or throws on validation failure.
|
|
52
|
+
*/
|
|
53
|
+
export declare function loadPetFile(filePath: string): Promise<PetFileBundle>;
|
|
54
|
+
/**
|
|
55
|
+
* Validate manifest structure. Throws on invalid.
|
|
56
|
+
*/
|
|
57
|
+
export declare function validatePetManifest(manifest: unknown): asserts manifest is PetManifest;
|
|
58
|
+
/**
|
|
59
|
+
* Sanitize SVG content — remove dangerous elements and attributes.
|
|
60
|
+
* Whitelist-based approach (design §16.2).
|
|
61
|
+
*/
|
|
62
|
+
export declare function sanitizeSvg(svgContent: string): string;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PetGrowthEngine — handles pet leveling, molting (脱壳升级), and ability unlocks.
|
|
3
|
+
*
|
|
4
|
+
* Design §13: Growth system
|
|
5
|
+
* - XP curve: level * 100 (linear P0, polynomial later)
|
|
6
|
+
* - Molting: every 5 levels triggers a "molt" event with visual upgrade
|
|
7
|
+
* - Abilities: unlocked at specific levels
|
|
8
|
+
* - Stats growth: each level-up slightly boosts one stat
|
|
9
|
+
*/
|
|
10
|
+
import type { PetStats, PetSoul } from "./pet-soul-service.js";
|
|
11
|
+
export interface PetAbility {
|
|
12
|
+
id: string;
|
|
13
|
+
name: string;
|
|
14
|
+
description: string;
|
|
15
|
+
unlockedAtLevel: number;
|
|
16
|
+
}
|
|
17
|
+
export interface GrowthEvent {
|
|
18
|
+
type: "level_up" | "molt" | "ability_unlock";
|
|
19
|
+
level: number;
|
|
20
|
+
ability?: PetAbility;
|
|
21
|
+
moltStage?: number;
|
|
22
|
+
}
|
|
23
|
+
export interface MoltResult {
|
|
24
|
+
stage: number;
|
|
25
|
+
description: string;
|
|
26
|
+
statBoost: Partial<PetStats>;
|
|
27
|
+
}
|
|
28
|
+
export declare class PetGrowthEngine {
|
|
29
|
+
/**
|
|
30
|
+
* Calculate XP needed for next level.
|
|
31
|
+
* P0: linear 100*level
|
|
32
|
+
*/
|
|
33
|
+
static xpForLevel(level: number): number;
|
|
34
|
+
/**
|
|
35
|
+
* Process XP gain and return all triggered growth events.
|
|
36
|
+
* Does NOT mutate the soul — caller is responsible for persisting.
|
|
37
|
+
*/
|
|
38
|
+
static processXpGain(soul: PetSoul, xpGain: number): {
|
|
39
|
+
newLevel: number;
|
|
40
|
+
newXp: number;
|
|
41
|
+
events: GrowthEvent[];
|
|
42
|
+
statBoosts: Partial<PetStats>;
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* Get molt result for a given stage.
|
|
46
|
+
*/
|
|
47
|
+
static getMoltResult(stage: number, currentStats: PetStats): MoltResult;
|
|
48
|
+
/**
|
|
49
|
+
* Get all unlocked abilities for a given level.
|
|
50
|
+
*/
|
|
51
|
+
static getUnlockedAbilities(level: number): PetAbility[];
|
|
52
|
+
/**
|
|
53
|
+
* Get next upcoming ability.
|
|
54
|
+
*/
|
|
55
|
+
static getNextAbility(level: number): PetAbility | null;
|
|
56
|
+
/**
|
|
57
|
+
* XP gain rules for different events.
|
|
58
|
+
*/
|
|
59
|
+
static xpForEvent(event: string): number;
|
|
60
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PetReactionService — probabilistic reaction generation after turns.
|
|
3
|
+
*
|
|
4
|
+
* P0: Local template pools (no LLM).
|
|
5
|
+
* P1+: LLM-generated personalized reactions via small model.
|
|
6
|
+
*/
|
|
7
|
+
import type { PetSoul } from "./pet-soul-service.js";
|
|
8
|
+
export type ReactionPool = "greeting" | "completion" | "error" | "curiosity" | "bored" | "memory" | "tool_success";
|
|
9
|
+
export type ReactionStyle = "normal" | "thinking" | "excited" | "sleepy";
|
|
10
|
+
/**
|
|
11
|
+
* Determine whether a reaction should fire, and if so, return it.
|
|
12
|
+
* P0: uses local template pools.
|
|
13
|
+
*/
|
|
14
|
+
export declare function maybeGenerateReaction(eventMethod: string): {
|
|
15
|
+
text: string;
|
|
16
|
+
style: ReactionStyle;
|
|
17
|
+
} | null;
|
|
18
|
+
export interface LLMReactionContext {
|
|
19
|
+
turnSummary: string;
|
|
20
|
+
soul: PetSoul;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Generate a personalized reaction via small LLM call.
|
|
24
|
+
* Returns null on failure or timeout (graceful degradation to template pool).
|
|
25
|
+
* Max 50 tokens, under 2s.
|
|
26
|
+
*
|
|
27
|
+
* @param ctx Context for the reaction
|
|
28
|
+
* @param llmGenerate External function to call LLM (injected to avoid coupling)
|
|
29
|
+
*/
|
|
30
|
+
export declare function generateLLMReaction(ctx: LLMReactionContext, llmGenerate: (prompt: string, maxTokens: number) => Promise<string | null>): Promise<{
|
|
31
|
+
text: string;
|
|
32
|
+
style: ReactionStyle;
|
|
33
|
+
} | null>;
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PetSoulService — manages pet identity (hatching, persistence, stats).
|
|
3
|
+
*
|
|
4
|
+
* Hatching: deterministic identity via hash(userId) + LLM-generated soul.
|
|
5
|
+
* Persistence: stored in project workspace under .qlogicagent/pet/soul.json
|
|
6
|
+
*/
|
|
7
|
+
export interface PetStats {
|
|
8
|
+
grip: number;
|
|
9
|
+
patience: number;
|
|
10
|
+
curiosity: number;
|
|
11
|
+
appetite: number;
|
|
12
|
+
humor: number;
|
|
13
|
+
}
|
|
14
|
+
export interface PetSoul {
|
|
15
|
+
name: string;
|
|
16
|
+
species: string;
|
|
17
|
+
personality: string;
|
|
18
|
+
catchphrase: string;
|
|
19
|
+
stats: PetStats;
|
|
20
|
+
rarity: string;
|
|
21
|
+
breed?: string;
|
|
22
|
+
breedColors?: {
|
|
23
|
+
primary: string;
|
|
24
|
+
secondary: string;
|
|
25
|
+
};
|
|
26
|
+
level: number;
|
|
27
|
+
experience: number;
|
|
28
|
+
hatchedAt: string;
|
|
29
|
+
}
|
|
30
|
+
/** Breed system (design §6.2): 7 breeds with deterministic hash selection. */
|
|
31
|
+
export interface PetBreed {
|
|
32
|
+
name: string;
|
|
33
|
+
colors: {
|
|
34
|
+
primary: string;
|
|
35
|
+
secondary: string;
|
|
36
|
+
};
|
|
37
|
+
rarity: string;
|
|
38
|
+
}
|
|
39
|
+
export declare class PetSoulService {
|
|
40
|
+
private workspaceDir;
|
|
41
|
+
private soul;
|
|
42
|
+
private storagePath;
|
|
43
|
+
constructor(workspaceDir: string);
|
|
44
|
+
/**
|
|
45
|
+
* Load existing soul from disk. Returns null if not hatched.
|
|
46
|
+
*/
|
|
47
|
+
load(): PetSoul | null;
|
|
48
|
+
/**
|
|
49
|
+
* Hatch a new pet soul. Uses LLM for name/personality/catchphrase.
|
|
50
|
+
* If generateSoul is provided, uses it; otherwise falls back to defaults.
|
|
51
|
+
*/
|
|
52
|
+
hatch(userId: string, generateSoul?: (rarity: string, stats: PetStats) => Promise<{
|
|
53
|
+
name: string;
|
|
54
|
+
personality: string;
|
|
55
|
+
catchphrase: string;
|
|
56
|
+
}>): Promise<PetSoul>;
|
|
57
|
+
/**
|
|
58
|
+
* Add experience points. Returns true if leveled up.
|
|
59
|
+
*/
|
|
60
|
+
addExperience(xp: number): {
|
|
61
|
+
leveledUp: boolean;
|
|
62
|
+
level: number;
|
|
63
|
+
experience: number;
|
|
64
|
+
};
|
|
65
|
+
getSoul(): PetSoul | null;
|
|
66
|
+
/**
|
|
67
|
+
* Update soul (e.g., after growth/stat changes) and persist.
|
|
68
|
+
*/
|
|
69
|
+
updateSoul(soul: PetSoul): void;
|
|
70
|
+
private persist;
|
|
71
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Group Session Auto-Split — detects idle group sessions and creates successor sessions.
|
|
3
|
+
*
|
|
4
|
+
* When a group chat message arrives and the last session activity was > N hours ago,
|
|
5
|
+
* the old session is sealed and a new session is created with:
|
|
6
|
+
* - previousSessionId linking to the predecessor
|
|
7
|
+
* - carryoverSummary (from predecessor's taskSummary or last messages)
|
|
8
|
+
* - Same groupKey, groupName, groupPlatform, projectId
|
|
9
|
+
*
|
|
10
|
+
* This prevents unbounded context growth in long-lived group chats.
|
|
11
|
+
*/
|
|
12
|
+
import { type SessionMetadata } from "./session-persistence.js";
|
|
13
|
+
export interface GroupSplitResult {
|
|
14
|
+
/** Whether a split occurred */
|
|
15
|
+
split: boolean;
|
|
16
|
+
/** The session ID to use for the current turn (new or existing) */
|
|
17
|
+
activeSessionId: string;
|
|
18
|
+
/** If split, the sealed predecessor session ID */
|
|
19
|
+
sealedSessionId?: string;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Check whether a group session should be auto-split due to idle timeout.
|
|
23
|
+
* If yes, seal the old session and create a new successor.
|
|
24
|
+
*
|
|
25
|
+
* @param currentSession - The existing group session metadata
|
|
26
|
+
* @param projectRoot - The project workspace directory
|
|
27
|
+
* @returns Split result with the session ID to use
|
|
28
|
+
*/
|
|
29
|
+
export declare function maybeAutoSplitGroupSession(currentSession: SessionMetadata, projectRoot: string): Promise<GroupSplitResult>;
|
|
30
|
+
/**
|
|
31
|
+
* Check whether a group session has exceeded MAX_TURNS hard limit.
|
|
32
|
+
* Called AFTER turn.end — soft-splits without interrupting the current turn.
|
|
33
|
+
*
|
|
34
|
+
* @param currentSession - The session that just finished a turn
|
|
35
|
+
* @param projectRoot - The project workspace directory
|
|
36
|
+
* @returns Split result (new session ready for next message, or no-op)
|
|
37
|
+
*/
|
|
38
|
+
export declare function maybeHardLimitSplit(currentSession: SessionMetadata, projectRoot: string): Promise<GroupSplitResult>;
|
|
@@ -1,2 +1,4 @@
|
|
|
1
|
-
export { SessionState, type SessionUsageSnapshot
|
|
2
|
-
export {
|
|
1
|
+
export { SessionState, type SessionUsageSnapshot } from "./session-state.js";
|
|
2
|
+
export { SessionLocator } from "./session-locator.js";
|
|
3
|
+
export { appendMessage, saveSessionState, updateSessionMetadata, getSessionMetadata, loadSessionForResume, listSessions, deleteSession, pruneOldSessions, shouldGenerateTaskSummary, maybeGenerateTaskSummary, type SessionMetadata, type PersistedSession, type SessionListEntry, type TaskSummaryDeps, } from "./session-persistence.js";
|
|
4
|
+
export { maybeAutoSplitGroupSession, type GroupSplitResult } from "./group-session-split.js";
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SessionLocator — resolves session storage paths from projectId.
|
|
3
|
+
*
|
|
4
|
+
* Every session operation uses this locator to determine the correct
|
|
5
|
+
* filesystem path based on the session's owning projectId.
|
|
6
|
+
* When projectId is missing, falls back to scanning all projects.
|
|
7
|
+
*/
|
|
8
|
+
export declare class SessionLocator {
|
|
9
|
+
/** Get sessions root directory for a given projectId. */
|
|
10
|
+
getSessionsRoot(projectId: string): string;
|
|
11
|
+
/** Get the workspace dir for a project. */
|
|
12
|
+
getProjectWorkspaceDir(projectId: string): string;
|
|
13
|
+
/** Get the session directory path for a given projectId + sessionId. */
|
|
14
|
+
getSessionDir(projectId: string, sessionId: string): string;
|
|
15
|
+
/**
|
|
16
|
+
* Resolve the workspaceDir for a session given its projectId.
|
|
17
|
+
* If projectId is not provided, scans all projects for the session directory.
|
|
18
|
+
*/
|
|
19
|
+
resolveWorkspaceDir(sessionId: string, projectId?: string): string;
|
|
20
|
+
/** Get the active project's workspace dir (for new session creation when no projectId specified). */
|
|
21
|
+
getActiveProjectWorkspaceDir(): string;
|
|
22
|
+
/** Get the active project's ID. */
|
|
23
|
+
getActiveProjectId(): string;
|
|
24
|
+
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* SessionMemoryIn-memory session message store with JSONL persistence.
|
|
3
3
|
*
|
|
4
4
|
* CC alignment: messages live in memory during the session lifetime.
|
|
5
5
|
* JSONL is the sole persistent source of truth (for crash recovery).
|
|
6
|
-
* Gateway never owns message
|
|
6
|
+
* Gateway never owns message dataAgent is the single authority.
|
|
7
7
|
*
|
|
8
8
|
* Design:
|
|
9
9
|
* - Map<sessionId, ChatMessage[]> holds active session messages
|
|
@@ -15,7 +15,7 @@ import type { ChatMessage } from "../../protocol/wire/index.js";
|
|
|
15
15
|
export declare class SessionMemory {
|
|
16
16
|
private sessions;
|
|
17
17
|
private projectRoot;
|
|
18
|
-
constructor(projectRoot
|
|
18
|
+
constructor(projectRoot: string);
|
|
19
19
|
setProjectRoot(projectRoot: string): void;
|
|
20
20
|
/**
|
|
21
21
|
* Get messages for a session. Lazy-loads from JSONL on first access.
|
|
@@ -35,7 +35,7 @@ export declare class SessionMemory {
|
|
|
35
35
|
initSession(sessionId: string): void;
|
|
36
36
|
/**
|
|
37
37
|
* Drop a session from memory (e.g., on session.ended).
|
|
38
|
-
* Does NOT delete
|
|
38
|
+
* Does NOT delete JSONLdata persists for future resume.
|
|
39
39
|
*/
|
|
40
40
|
evictSession(sessionId: string): void;
|
|
41
41
|
/**
|
|
@@ -1,113 +1,113 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Session Persistence
|
|
2
|
+
* Session Persistence — CC sessionRestore.ts + conversationRecovery.ts parity.
|
|
3
3
|
*
|
|
4
4
|
* Enables conversation resume by persisting:
|
|
5
5
|
* 1. Message transcript (JSONL-based, append-only)
|
|
6
|
-
* 2.
|
|
7
|
-
* 3. Session metadata (model, cwd, agent mode)
|
|
6
|
+
* 2. Session metadata (flat JSON, atomic write)
|
|
8
7
|
*
|
|
9
|
-
* Storage layout:
|
|
10
|
-
* <project>/.qlogicagent/sessions/<session-id>/
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* state.json 鈥?cost snapshot + metadata
|
|
8
|
+
* Storage layout (ALL data lives under project workspace, NEVER global):
|
|
9
|
+
* <project>/.qlogicagent/sessions/<session-id>/
|
|
10
|
+
* transcript.jsonl — append-only message log
|
|
11
|
+
* metadata.json — flat session metadata + usage stats
|
|
14
12
|
*
|
|
15
13
|
* Resume flow (CC processResumedConversation parity):
|
|
16
|
-
* 1. loadSessionForResume(sessionId)
|
|
17
|
-
* 2. Restore
|
|
14
|
+
* 1. loadSessionForResume(sessionId) → messages + metadata
|
|
15
|
+
* 2. Restore usage state into SessionState
|
|
18
16
|
* 3. Feed messages as initial context to agent
|
|
19
|
-
*
|
|
20
|
-
* Reference: claude-code src/utils/sessionRestore.ts
|
|
21
|
-
* claude-code src/utils/conversationRecovery.ts
|
|
22
17
|
*/
|
|
23
18
|
import type { ChatMessage } from "../../protocol/wire/index.js";
|
|
24
|
-
import type {
|
|
19
|
+
import type { SessionUsageSnapshot } from "./session-state.js";
|
|
25
20
|
export interface SessionMetadata {
|
|
26
21
|
sessionId: string;
|
|
27
|
-
|
|
28
|
-
|
|
22
|
+
projectId: string;
|
|
23
|
+
createdAt: string;
|
|
24
|
+
lastActiveAt: string;
|
|
29
25
|
model?: string;
|
|
30
26
|
cwd?: string;
|
|
31
27
|
turnCount: number;
|
|
32
28
|
messageCount: number;
|
|
33
|
-
/** Title / description (auto-generated or user-set) */
|
|
34
29
|
title?: string;
|
|
35
|
-
/** Task summary generated by LLM (CC maybeGenerateTaskSummary parity) */
|
|
36
30
|
taskSummary?: string;
|
|
37
|
-
/** Timestamp of last task summary generation */
|
|
38
31
|
taskSummaryGeneratedAt?: number;
|
|
39
|
-
/** ISO timestamp 鈥?session pinned in UI */
|
|
40
32
|
pinnedAt?: string;
|
|
41
|
-
/** ISO timestamp 鈥?session archived (soft-deleted) */
|
|
42
33
|
archivedAt?: string;
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
34
|
+
sealedAt?: string;
|
|
35
|
+
previousSessionId?: string;
|
|
36
|
+
carryoverSummary?: string;
|
|
46
37
|
type?: "personal" | "group";
|
|
47
|
-
/** Owner user ID */
|
|
48
38
|
ownerId?: string;
|
|
49
|
-
/** Group key for group sessions */
|
|
50
39
|
groupKey?: string;
|
|
51
|
-
/** Group display name */
|
|
52
40
|
groupName?: string;
|
|
53
|
-
/** Group platform (wechat, dingtalk, etc.) */
|
|
54
41
|
groupPlatform?: string;
|
|
42
|
+
totalInputTokens?: number;
|
|
43
|
+
totalOutputTokens?: number;
|
|
55
44
|
}
|
|
56
45
|
export interface PersistedSession {
|
|
57
46
|
metadata: SessionMetadata;
|
|
58
47
|
messages: ChatMessage[];
|
|
59
|
-
costSnapshot?: SessionCostSnapshot;
|
|
60
48
|
}
|
|
61
49
|
export interface SessionListEntry {
|
|
62
50
|
sessionId: string;
|
|
63
51
|
title?: string;
|
|
64
|
-
lastActiveAt:
|
|
52
|
+
lastActiveAt: string;
|
|
65
53
|
messageCount: number;
|
|
66
54
|
model?: string;
|
|
67
55
|
pinnedAt?: string;
|
|
68
56
|
archivedAt?: string;
|
|
69
|
-
|
|
57
|
+
sealedAt?: string;
|
|
58
|
+
projectId: string;
|
|
70
59
|
type?: "personal" | "group";
|
|
71
|
-
createdAt
|
|
60
|
+
createdAt: string;
|
|
61
|
+
groupKey?: string;
|
|
62
|
+
previousSessionId?: string;
|
|
63
|
+
carryoverSummary?: string | null;
|
|
72
64
|
}
|
|
65
|
+
/**
|
|
66
|
+
* Load session metadata only (lightweight — no transcript loading).
|
|
67
|
+
* Returns null if session doesn't exist or metadata is unreadable.
|
|
68
|
+
*/
|
|
69
|
+
export declare function getSessionMetadata(sessionId: string, projectRoot: string): SessionMetadata | null;
|
|
73
70
|
/**
|
|
74
71
|
* Append a message to the session transcript.
|
|
75
72
|
* Creates the session directory if it doesn't exist.
|
|
76
73
|
* When turnId is provided, it acts as a per-turn boundary marker enabling
|
|
77
74
|
* reconciliation with Gateway's token_usage records.
|
|
75
|
+
*
|
|
76
|
+
* Robustness: catches disk-full and I/O errors without crashing the agent.
|
|
77
|
+
* Returns false if the write fails.
|
|
78
78
|
*/
|
|
79
|
-
export declare function appendMessage(sessionId: string, message: ChatMessage, projectRoot
|
|
79
|
+
export declare function appendMessage(sessionId: string, message: ChatMessage, projectRoot: string, turnId?: string): Promise<boolean>;
|
|
80
80
|
/**
|
|
81
|
-
* Save session
|
|
81
|
+
* Save session metadata + usage stats atomically (flat structure).
|
|
82
82
|
*/
|
|
83
|
-
export declare function saveSessionState(sessionId: string,
|
|
83
|
+
export declare function saveSessionState(sessionId: string, usageSnapshot: SessionUsageSnapshot, metadata: Partial<SessionMetadata>, projectRoot: string): Promise<void>;
|
|
84
84
|
/**
|
|
85
85
|
* Update specific metadata fields of a session without touching cost data.
|
|
86
86
|
* Used by session CRUD RPC (rename, pin, archive, move-to-project).
|
|
87
87
|
*/
|
|
88
|
-
export declare function updateSessionMetadata(sessionId: string, patch: Partial<SessionMetadata
|
|
88
|
+
export declare function updateSessionMetadata(sessionId: string, patch: Partial<Record<keyof SessionMetadata, SessionMetadata[keyof SessionMetadata] | null>>, projectRoot: string): Promise<SessionMetadata | null>;
|
|
89
89
|
/**
|
|
90
|
-
* Load a persisted session for resume
|
|
90
|
+
* Load a persisted session for resume — CC loadConversationForResume parity.
|
|
91
91
|
*
|
|
92
92
|
* Returns null if the session doesn't exist or is corrupted.
|
|
93
93
|
*/
|
|
94
|
-
export declare function loadSessionForResume(sessionId: string, projectRoot
|
|
94
|
+
export declare function loadSessionForResume(sessionId: string, projectRoot: string): Promise<PersistedSession | null>;
|
|
95
95
|
/**
|
|
96
|
-
* List available sessions for resume
|
|
96
|
+
* List available sessions for resume CC ResumeConversation picker.
|
|
97
97
|
* Returns most-recent-first, up to `limit` entries.
|
|
98
98
|
*/
|
|
99
|
-
export declare function listSessions(limit
|
|
99
|
+
export declare function listSessions(limit: number | undefined, projectRoot: string): Promise<SessionListEntry[]>;
|
|
100
100
|
/**
|
|
101
101
|
* Delete a session (cleanup).
|
|
102
102
|
*/
|
|
103
|
-
export declare function deleteSession(sessionId: string, projectRoot
|
|
103
|
+
export declare function deleteSession(sessionId: string, projectRoot: string): Promise<void>;
|
|
104
104
|
/**
|
|
105
105
|
* Prune old sessions beyond MAX_SESSIONS limit.
|
|
106
106
|
* Deletes oldest sessions first.
|
|
107
107
|
*/
|
|
108
|
-
export declare function pruneOldSessions(projectRoot
|
|
108
|
+
export declare function pruneOldSessions(projectRoot: string): Promise<number>;
|
|
109
109
|
export interface TaskSummaryDeps {
|
|
110
|
-
transport: import("
|
|
110
|
+
transport: import("@qlogic/provider-core").LLMTransport;
|
|
111
111
|
apiKey: string;
|
|
112
112
|
model: string;
|
|
113
113
|
}
|
|
@@ -117,7 +117,8 @@ export interface TaskSummaryDeps {
|
|
|
117
117
|
*/
|
|
118
118
|
export declare function shouldGenerateTaskSummary(metadata: SessionMetadata): boolean;
|
|
119
119
|
/**
|
|
120
|
-
* Generate
|
|
121
|
-
*
|
|
120
|
+
* Generate a concise session title from the user's first message.
|
|
121
|
+
* Lightweight LLM call — one-shot, no tool loop.
|
|
122
122
|
*/
|
|
123
|
-
export declare function
|
|
123
|
+
export declare function generateSessionTitle(userMessage: string, deps: TaskSummaryDeps): Promise<string | null>;
|
|
124
|
+
export declare function maybeGenerateTaskSummary(sessionId: string, metadata: SessionMetadata, recentMessages: ChatMessage[], deps: TaskSummaryDeps, projectRoot: string): Promise<string | null>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Session State
|
|
2
|
+
* Session State CC session state parity.
|
|
3
3
|
*
|
|
4
4
|
* Unified state container for a single agent session:
|
|
5
5
|
* - Token usage / cost accumulation across turns
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* Reference: claude-code src/bootstrap/state.ts, src/cost-tracker.ts
|
|
15
15
|
*/
|
|
16
16
|
import type { WireTokenUsage as TokenUsage } from "../../protocol/wire/index.js";
|
|
17
|
-
/** Per-model usage accumulation
|
|
17
|
+
/** Per-model usage accumulation CC modelUsage parity */
|
|
18
18
|
export interface ModelUsage {
|
|
19
19
|
inputTokens: number;
|
|
20
20
|
outputTokens: number;
|
|
@@ -36,8 +36,6 @@ export interface SessionUsageSnapshot {
|
|
|
36
36
|
turnCount: number;
|
|
37
37
|
lastSavedAt: number;
|
|
38
38
|
}
|
|
39
|
-
/** @deprecated Use SessionUsageSnapshot. Kept for persistence compat. */
|
|
40
|
-
export type SessionCostSnapshot = SessionUsageSnapshot;
|
|
41
39
|
export declare class SessionState {
|
|
42
40
|
readonly sessionId: string;
|
|
43
41
|
private _trustAccepted;
|
|
@@ -59,7 +57,7 @@ export declare class SessionState {
|
|
|
59
57
|
/** Get all model usages as a plain object */
|
|
60
58
|
getAllModelUsage(): Record<string, ModelUsage>;
|
|
61
59
|
/**
|
|
62
|
-
* Add usage from an API response
|
|
60
|
+
* Add usage from an API response CC addToTotalSessionCost() parity.
|
|
63
61
|
* Tracks token counts only; pricing is handled by Hub/Admin.
|
|
64
62
|
*
|
|
65
63
|
* @param usage - Token counts from the API response
|
|
@@ -21,7 +21,7 @@ export interface ExtractedMemoryItem {
|
|
|
21
21
|
tags?: string[];
|
|
22
22
|
}
|
|
23
23
|
export interface LocalMemoryProviderConfig {
|
|
24
|
-
/**
|
|
24
|
+
/** Not used for L2 vector memory (always global). Kept for interface compat. */
|
|
25
25
|
projectRoot?: string;
|
|
26
26
|
/** Embedding configuration. If omitted, uses FTS-only search. */
|
|
27
27
|
embedding?: LocalEmbeddingConfig;
|
|
@@ -249,6 +249,7 @@ export declare class LocalMemoryStore {
|
|
|
249
249
|
close(): void;
|
|
250
250
|
}
|
|
251
251
|
/**
|
|
252
|
-
* Resolve the database file path for
|
|
252
|
+
* Resolve the database file path for L2 vector memory storage.
|
|
253
|
+
* L2 vector memory is GLOBAL (cross-project knowledge), stored at ~/.qlogicagent/memory/.
|
|
253
254
|
*/
|
|
254
|
-
export declare function resolveMemoryDbPath(
|
|
255
|
+
export declare function resolveMemoryDbPath(): string;
|
|
@@ -4,10 +4,10 @@ export declare const INDEX_MAX_CHARS = 12288;
|
|
|
4
4
|
export declare const INDEX_MAX_LINES = 200;
|
|
5
5
|
/** Max chars for a single topic file. */
|
|
6
6
|
export declare const TOPIC_FILE_MAX_CHARS = 8192;
|
|
7
|
-
/** Root directory:
|
|
8
|
-
export declare function getMemdirPath(): string;
|
|
7
|
+
/** Root directory: <project>/.qlogicagent/memory/ */
|
|
8
|
+
export declare function getMemdirPath(projectRoot: string): string;
|
|
9
9
|
/** Full path to INDEX.md */
|
|
10
|
-
export declare function getIndexPath(): string;
|
|
10
|
+
export declare function getIndexPath(projectRoot: string): string;
|
|
11
11
|
export interface MemdirFileInfo {
|
|
12
12
|
name: string;
|
|
13
13
|
/** Size in bytes */
|
|
@@ -29,7 +29,7 @@ export declare function isMemoryContentSafe(text: string): boolean;
|
|
|
29
29
|
export declare class Memdir {
|
|
30
30
|
private readonly root;
|
|
31
31
|
private indexCache;
|
|
32
|
-
constructor(
|
|
32
|
+
constructor(projectRoot: string);
|
|
33
33
|
/** Get the root directory path of this MEMDIR. */
|
|
34
34
|
getRootPath(): string;
|
|
35
35
|
/** Ensure memdir exists with a default INDEX.md if missing. */
|
|
@@ -52,6 +52,9 @@ export declare class Memdir {
|
|
|
52
52
|
/**
|
|
53
53
|
* Auto-compact INDEX.md by removing oldest non-structural entries to make room.
|
|
54
54
|
* Returns the compacted content with the new entry appended, or null if impossible.
|
|
55
|
+
*
|
|
56
|
+
* Entry-aware: removes complete logical entries (a non-indented line plus its
|
|
57
|
+
* continuation lines that start with whitespace/'-') to avoid half-entries.
|
|
55
58
|
*/
|
|
56
59
|
private autoCompactIndex;
|
|
57
60
|
/** Replace text in INDEX.md (str_replace semantics). */
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
import type { LocalEmbeddingConfig } from "./local-embedding.js";
|
|
8
8
|
import type { LocalMemoryProvider } from "./local-memory-provider.js";
|
|
9
9
|
export interface MemoryProviderFactoryConfig {
|
|
10
|
-
/**
|
|
10
|
+
/** Not used for L2 vector DB (always global). Kept for config compat. */
|
|
11
11
|
projectRoot?: string;
|
|
12
12
|
/** User ID prefix. */
|
|
13
13
|
userIdPrefix?: string;
|
|
@@ -44,11 +44,5 @@ export declare function createMemoryProvider(config: MemoryProviderFactoryConfig
|
|
|
44
44
|
* Layer 3: FTS5 pure text (NullEmbeddingProvider)
|
|
45
45
|
*
|
|
46
46
|
* @param projectRoot — Project root for local storage path
|
|
47
|
-
* @param embeddingOverride — TurnConfig.embeddingModel override (takes priority over env vars)
|
|
48
47
|
*/
|
|
49
|
-
export declare function resolveMemoryConfigFromEnv(projectRoot?: string
|
|
50
|
-
provider?: string;
|
|
51
|
-
model?: string;
|
|
52
|
-
apiKey?: string;
|
|
53
|
-
baseUrl?: string;
|
|
54
|
-
}): MemoryProviderFactoryConfig;
|
|
48
|
+
export declare function resolveMemoryConfigFromEnv(projectRoot?: string): MemoryProviderFactoryConfig;
|
|
@@ -38,7 +38,7 @@ export interface DenialAuditEntry {
|
|
|
38
38
|
export declare class DenialAuditLogger {
|
|
39
39
|
private filePath;
|
|
40
40
|
private writeQueue;
|
|
41
|
-
constructor(projectRoot
|
|
41
|
+
constructor(projectRoot: string);
|
|
42
42
|
/**
|
|
43
43
|
* Append a denial event to the audit log.
|
|
44
44
|
* Non-blocking; errors are swallowed to avoid disrupting agent flow.
|
|
@@ -6,7 +6,7 @@ export interface ClassifierResult {
|
|
|
6
6
|
durationMs: number;
|
|
7
7
|
}
|
|
8
8
|
/**
|
|
9
|
-
* LLM call
|
|
9
|
+
* LLM call interfaceinjected by the host so the classifier
|
|
10
10
|
* doesn't depend on a specific LLM client.
|
|
11
11
|
*/
|
|
12
12
|
export interface ClassifierLLMCall {
|
|
@@ -87,7 +87,7 @@ export interface SearchToolDeps {
|
|
|
87
87
|
* The implementation may use ripgrep, native grep, or a custom engine.
|
|
88
88
|
* Returns match records.
|
|
89
89
|
* The host SHOULD auto-exclude VCS directories (.git, .svn, .hg, .bzr)
|
|
90
|
-
* and
|
|
90
|
+
* and enforcemax-columns 500 to avoid minified file noise.
|
|
91
91
|
*/
|
|
92
92
|
grep(pattern: string, options: {
|
|
93
93
|
cwd: string;
|