qlogicagent 2.10.49 → 2.11.1

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.
Files changed (44) hide show
  1. package/dist/cli.js +321 -362
  2. package/dist/index.js +321 -362
  3. package/dist/pet-contracts.js +1 -0
  4. package/dist/protocol.js +1 -1
  5. package/dist/types/cli/acp-commands.d.ts +32 -0
  6. package/dist/types/cli/acp-session-handlers.d.ts +36 -25
  7. package/dist/types/cli/acp-session-host.d.ts +24 -0
  8. package/dist/types/cli/handlers/memory-handler.d.ts +10 -1
  9. package/dist/types/cli/handlers/pet-handler.d.ts +5 -11
  10. package/dist/types/cli/media-runtime-facade.d.ts +9 -1
  11. package/dist/types/cli/memory-candidate-service.d.ts +10 -1
  12. package/dist/types/cli/pet-runtime.d.ts +28 -6
  13. package/dist/types/cli/provider-core-facade.d.ts +3 -0
  14. package/dist/types/pet-contracts.d.ts +1 -0
  15. package/dist/types/protocol/methods.d.ts +1 -38
  16. package/dist/types/protocol/wire/acp-protocol.d.ts +64 -162
  17. package/dist/types/protocol/wire/agent-events.d.ts +2 -2
  18. package/dist/types/protocol/wire/agent-methods.d.ts +1 -30
  19. package/dist/types/protocol/wire/agent-rpc.d.ts +0 -15
  20. package/dist/types/protocol/wire/chat-types.d.ts +3 -3
  21. package/dist/types/protocol/wire/gateway-rpc.d.ts +30 -0
  22. package/dist/types/protocol/wire/index.d.ts +3 -3
  23. package/dist/types/protocol/wire/notification-payloads.d.ts +39 -5
  24. package/dist/types/protocol/wire/pet-contracts.d.ts +75 -2
  25. package/dist/types/protocol/wire/thread-protocol.d.ts +0 -12
  26. package/dist/types/runtime/infra/acp-detector.d.ts +5 -0
  27. package/dist/types/runtime/infra/acp-host-handler.d.ts +23 -0
  28. package/dist/types/runtime/pet/index.d.ts +4 -4
  29. package/dist/types/runtime/pet/pet-file-loader.d.ts +4 -61
  30. package/dist/types/runtime/pet/pet-profile-service.d.ts +51 -10
  31. package/dist/types/runtime/pet/petdex-asset.d.ts +138 -0
  32. package/dist/types/runtime/pet/petdex-forge-service.d.ts +110 -0
  33. package/dist/types/runtime/ports/memory-provider.d.ts +35 -0
  34. package/dist/types/skills/memory/local-memory-provider.d.ts +25 -0
  35. package/dist/types/skills/memory/local-store.d.ts +48 -0
  36. package/dist/types/skills/memory/memory-attachment-store.d.ts +62 -0
  37. package/dist/types/skills/memory/memory-consolidation.d.ts +2 -0
  38. package/dist/types/skills/memory/memory-db-path.d.ts +6 -0
  39. package/dist/types/skills/memory/sqlite-memory-schema.d.ts +1 -1
  40. package/dist/types/skills/tools/petdex-create-tool.d.ts +61 -0
  41. package/dist/types/transport/acp-server.d.ts +26 -8
  42. package/package.json +11 -2
  43. package/dist/types/runtime/pet/pet-consistency.d.ts +0 -79
  44. package/dist/types/runtime/pet/pet-skeleton.d.ts +0 -70
@@ -0,0 +1,62 @@
1
+ /**
2
+ * MemoryAttachmentStore — persistent attachment storage for long-term memory.
3
+ *
4
+ * Files live beside the memory DB, with no expiry:
5
+ * ~/.qlogicagent/profiles/<owner>/memory/attachments/<id><ext>
6
+ * The DB (`memory_attachments` table, via LocalMemoryStore) is the index;
7
+ * this class owns the on-disk bytes + ties index rows to files.
8
+ *
9
+ * Lifecycle: an attachment is `adopt`ed at upload time (orphan, memory_id=''),
10
+ * then `link`ed to a memory at commit; on memory delete the files+rows are
11
+ * removed; long-orphaned uploads are purged.
12
+ */
13
+ import type { LocalMemoryStore, MemoryAttachmentRef, MemoryAttachmentRow } from "./local-store.js";
14
+ export declare const MAX_ATTACHMENT_BYTES: number;
15
+ export type AttachmentKind = "image" | "audio" | "video" | "doc" | "file";
16
+ export declare function attachmentKindFromMime(mimeType: string, filename?: string): AttachmentKind;
17
+ export interface AdoptedAttachment {
18
+ id: string;
19
+ kind: AttachmentKind;
20
+ filename: string;
21
+ mimeType: string;
22
+ size: number;
23
+ url: string;
24
+ }
25
+ export interface AdoptInput {
26
+ /** Raw bytes (preferred). */
27
+ data?: Buffer;
28
+ /** Or a URL the store fetches (e.g. the gateway's temp MediaStore url). */
29
+ sourceUrl?: string;
30
+ filename: string;
31
+ mimeType: string;
32
+ userId: string;
33
+ }
34
+ export declare class MemoryAttachmentStore {
35
+ private readonly store;
36
+ private readonly dir;
37
+ constructor(store: LocalMemoryStore, dir: string);
38
+ urlFor(id: string): string;
39
+ toRef(row: MemoryAttachmentRow): MemoryAttachmentRef;
40
+ /** Persist an uploaded file + create an orphan index row (memory_id=''). */
41
+ adopt(input: AdoptInput): Promise<AdoptedAttachment>;
42
+ /** Read an attachment's bytes + mime (for multimodal understanding). */
43
+ readBytes(id: string): Promise<{
44
+ bytes: Buffer;
45
+ mimeType: string;
46
+ } | null>;
47
+ /** Resolve an attachment to an absolute on-disk path (for serving). Guards traversal. */
48
+ locate(id: string): Promise<{
49
+ absPath: string;
50
+ mimeType: string;
51
+ filename: string;
52
+ } | null>;
53
+ link(memoryId: string, attachmentIds: string[], userId: string): number;
54
+ setExtractedText(id: string, text: string): void;
55
+ refsForMemory(memoryId: string): MemoryAttachmentRef[];
56
+ /** Map of memoryId → refs, for atlas windows. */
57
+ refsForMemories(memoryIds: string[]): Map<string, MemoryAttachmentRef[]>;
58
+ /** Remove all files + index rows for a deleted memory. */
59
+ removeByMemoryId(memoryId: string): Promise<void>;
60
+ /** Purge uploads that were never linked to a saved memory. */
61
+ purgeOrphans(olderThanMs?: number): Promise<void>;
62
+ }
@@ -7,6 +7,8 @@ export interface ExtractedMemoryItem {
7
7
  speaker?: string;
8
8
  event_date?: string;
9
9
  tags?: string[];
10
+ /** Ids of already-uploaded attachments to link to this memory on commit. */
11
+ attachmentIds?: string[];
10
12
  }
11
13
  export interface MemoryConsolidationOptions {
12
14
  source?: string;
@@ -5,3 +5,9 @@ import type { PathService } from "../../runtime/ports/index.js";
5
5
  * profile at ~/.qlogicagent/profiles/<owner_user_id>/memory/.
6
6
  */
7
7
  export declare function resolveMemoryDbPath(ownerUserId?: string, pathService?: PathService): string;
8
+ /**
9
+ * Persistent attachment directory for long-term memory, beside the memory DB:
10
+ * ~/.qlogicagent/profiles/<owner_user_id>/memory/attachments/
11
+ * Files here live as long as the memories that reference them (no expiry).
12
+ */
13
+ export declare function resolveMemoryAttachmentsDir(ownerUserId?: string, pathService?: PathService): string;
@@ -1,3 +1,3 @@
1
1
  import type { SqliteDatabase } from "./local-store-records.js";
2
- export declare const MEMORY_SCHEMA_SQL = "\nCREATE TABLE IF NOT EXISTS memories (\n id TEXT PRIMARY KEY,\n text TEXT NOT NULL,\n user_id TEXT NOT NULL,\n category TEXT NOT NULL DEFAULT 'general',\n importance REAL NOT NULL DEFAULT 0.5,\n confidence REAL NOT NULL DEFAULT 1.0,\n source TEXT NOT NULL DEFAULT 'agent',\n session_id TEXT NOT NULL DEFAULT '',\n event_date TEXT NOT NULL DEFAULT '',\n tags TEXT NOT NULL DEFAULT '[]',\n embedding BLOB,\n created_at INTEGER NOT NULL,\n updated_at INTEGER NOT NULL,\n access_count INTEGER NOT NULL DEFAULT 0,\n last_accessed_at INTEGER NOT NULL DEFAULT 0,\n is_archived INTEGER NOT NULL DEFAULT 0\n);\n\nCREATE INDEX IF NOT EXISTS idx_memories_user ON memories(user_id);\nCREATE INDEX IF NOT EXISTS idx_memories_user_category ON memories(user_id, category);\nCREATE INDEX IF NOT EXISTS idx_memories_user_importance ON memories(user_id, importance DESC);\nCREATE INDEX IF NOT EXISTS idx_memories_created ON memories(created_at DESC);\n\nCREATE TABLE IF NOT EXISTS memory_observations (\n id TEXT PRIMARY KEY,\n user_id TEXT NOT NULL,\n text TEXT NOT NULL,\n source TEXT NOT NULL,\n source_priority INTEGER NOT NULL DEFAULT 0,\n session_id TEXT NOT NULL DEFAULT '',\n evidence_type TEXT NOT NULL DEFAULT 'text',\n payload TEXT NOT NULL DEFAULT '{}',\n created_at INTEGER NOT NULL\n);\n\nCREATE INDEX IF NOT EXISTS idx_memory_observations_user_created ON memory_observations(user_id, created_at DESC);\nCREATE INDEX IF NOT EXISTS idx_memory_observations_source ON memory_observations(user_id, source);\n\nCREATE TABLE IF NOT EXISTS memory_proposals (\n id TEXT PRIMARY KEY,\n user_id TEXT NOT NULL,\n observation_ids TEXT NOT NULL DEFAULT '[]',\n text TEXT NOT NULL,\n category TEXT NOT NULL DEFAULT 'general',\n importance REAL NOT NULL DEFAULT 0.5,\n confidence REAL NOT NULL DEFAULT 0.5,\n source TEXT NOT NULL DEFAULT 'agent',\n source_priority INTEGER NOT NULL DEFAULT 0,\n entity TEXT NOT NULL DEFAULT '',\n predicate TEXT NOT NULL DEFAULT '',\n value_json TEXT NOT NULL DEFAULT '{}',\n valid_time TEXT NOT NULL DEFAULT '',\n tags TEXT NOT NULL DEFAULT '[]',\n status TEXT NOT NULL DEFAULT 'pending',\n related_claim_ids TEXT NOT NULL DEFAULT '[]',\n created_at INTEGER NOT NULL,\n updated_at INTEGER NOT NULL\n);\n\nCREATE INDEX IF NOT EXISTS idx_memory_proposals_user_status ON memory_proposals(user_id, status);\nCREATE INDEX IF NOT EXISTS idx_memory_proposals_fact ON memory_proposals(user_id, entity, predicate, valid_time);\n\nCREATE TABLE IF NOT EXISTS memory_claims (\n id TEXT PRIMARY KEY,\n memory_id TEXT NOT NULL DEFAULT '',\n user_id TEXT NOT NULL,\n entity TEXT NOT NULL DEFAULT '',\n predicate TEXT NOT NULL DEFAULT '',\n value_json TEXT NOT NULL DEFAULT '{}',\n text TEXT NOT NULL,\n category TEXT NOT NULL DEFAULT 'general',\n importance REAL NOT NULL DEFAULT 0.5,\n confidence REAL NOT NULL DEFAULT 0.5,\n source TEXT NOT NULL DEFAULT 'agent',\n source_priority INTEGER NOT NULL DEFAULT 0,\n status TEXT NOT NULL DEFAULT 'active',\n valid_time TEXT NOT NULL DEFAULT '',\n evidence_ids TEXT NOT NULL DEFAULT '[]',\n supersedes_claim_id TEXT NOT NULL DEFAULT '',\n conflict_group_id TEXT NOT NULL DEFAULT '',\n created_at INTEGER NOT NULL,\n updated_at INTEGER NOT NULL\n);\n\nCREATE INDEX IF NOT EXISTS idx_memory_claims_user_status ON memory_claims(user_id, status);\nCREATE INDEX IF NOT EXISTS idx_memory_claims_memory ON memory_claims(memory_id);\nCREATE INDEX IF NOT EXISTS idx_memory_claims_fact ON memory_claims(user_id, entity, predicate, valid_time);\n\nCREATE TABLE IF NOT EXISTS memory_conflicts (\n id TEXT PRIMARY KEY,\n user_id TEXT NOT NULL,\n claim_a_id TEXT NOT NULL,\n claim_b_id TEXT NOT NULL,\n reason TEXT NOT NULL,\n status TEXT NOT NULL DEFAULT 'open',\n created_at INTEGER NOT NULL,\n updated_at INTEGER NOT NULL\n);\n\nCREATE INDEX IF NOT EXISTS idx_memory_conflicts_user_status ON memory_conflicts(user_id, status);\n\nCREATE VIRTUAL TABLE IF NOT EXISTS memories_fts USING fts5(\n id UNINDEXED,\n user_id UNINDEXED,\n text,\n category,\n tags,\n content=memories,\n content_rowid=rowid,\n tokenize='unicode61 remove_diacritics 2'\n);\n\nCREATE TRIGGER IF NOT EXISTS memories_ai AFTER INSERT ON memories BEGIN\n INSERT INTO memories_fts(rowid, id, user_id, text, category, tags)\n VALUES (new.rowid, new.id, new.user_id, new.text, new.category, new.tags);\nEND;\n\nCREATE TRIGGER IF NOT EXISTS memories_ad AFTER DELETE ON memories BEGIN\n INSERT INTO memories_fts(memories_fts, rowid, id, user_id, text, category, tags)\n VALUES ('delete', old.rowid, old.id, old.user_id, old.text, old.category, old.tags);\nEND;\n\nCREATE TRIGGER IF NOT EXISTS memories_au AFTER UPDATE ON memories BEGIN\n INSERT INTO memories_fts(memories_fts, rowid, id, user_id, text, category, tags)\n VALUES ('delete', old.rowid, old.id, old.user_id, old.text, old.category, old.tags);\n INSERT INTO memories_fts(rowid, id, user_id, text, category, tags)\n VALUES (new.rowid, new.id, new.user_id, new.text, new.category, new.tags);\nEND;\n";
2
+ export declare const MEMORY_SCHEMA_SQL = "\nCREATE TABLE IF NOT EXISTS memories (\n id TEXT PRIMARY KEY,\n text TEXT NOT NULL,\n user_id TEXT NOT NULL,\n category TEXT NOT NULL DEFAULT 'general',\n importance REAL NOT NULL DEFAULT 0.5,\n confidence REAL NOT NULL DEFAULT 1.0,\n source TEXT NOT NULL DEFAULT 'agent',\n session_id TEXT NOT NULL DEFAULT '',\n event_date TEXT NOT NULL DEFAULT '',\n tags TEXT NOT NULL DEFAULT '[]',\n embedding BLOB,\n created_at INTEGER NOT NULL,\n updated_at INTEGER NOT NULL,\n access_count INTEGER NOT NULL DEFAULT 0,\n last_accessed_at INTEGER NOT NULL DEFAULT 0,\n is_archived INTEGER NOT NULL DEFAULT 0\n);\n\nCREATE INDEX IF NOT EXISTS idx_memories_user ON memories(user_id);\nCREATE INDEX IF NOT EXISTS idx_memories_user_category ON memories(user_id, category);\nCREATE INDEX IF NOT EXISTS idx_memories_user_importance ON memories(user_id, importance DESC);\nCREATE INDEX IF NOT EXISTS idx_memories_created ON memories(created_at DESC);\n\nCREATE TABLE IF NOT EXISTS memory_observations (\n id TEXT PRIMARY KEY,\n user_id TEXT NOT NULL,\n text TEXT NOT NULL,\n source TEXT NOT NULL,\n source_priority INTEGER NOT NULL DEFAULT 0,\n session_id TEXT NOT NULL DEFAULT '',\n evidence_type TEXT NOT NULL DEFAULT 'text',\n payload TEXT NOT NULL DEFAULT '{}',\n created_at INTEGER NOT NULL\n);\n\nCREATE INDEX IF NOT EXISTS idx_memory_observations_user_created ON memory_observations(user_id, created_at DESC);\nCREATE INDEX IF NOT EXISTS idx_memory_observations_source ON memory_observations(user_id, source);\n\nCREATE TABLE IF NOT EXISTS memory_proposals (\n id TEXT PRIMARY KEY,\n user_id TEXT NOT NULL,\n observation_ids TEXT NOT NULL DEFAULT '[]',\n text TEXT NOT NULL,\n category TEXT NOT NULL DEFAULT 'general',\n importance REAL NOT NULL DEFAULT 0.5,\n confidence REAL NOT NULL DEFAULT 0.5,\n source TEXT NOT NULL DEFAULT 'agent',\n source_priority INTEGER NOT NULL DEFAULT 0,\n entity TEXT NOT NULL DEFAULT '',\n predicate TEXT NOT NULL DEFAULT '',\n value_json TEXT NOT NULL DEFAULT '{}',\n valid_time TEXT NOT NULL DEFAULT '',\n tags TEXT NOT NULL DEFAULT '[]',\n status TEXT NOT NULL DEFAULT 'pending',\n related_claim_ids TEXT NOT NULL DEFAULT '[]',\n created_at INTEGER NOT NULL,\n updated_at INTEGER NOT NULL\n);\n\nCREATE INDEX IF NOT EXISTS idx_memory_proposals_user_status ON memory_proposals(user_id, status);\nCREATE INDEX IF NOT EXISTS idx_memory_proposals_fact ON memory_proposals(user_id, entity, predicate, valid_time);\n\nCREATE TABLE IF NOT EXISTS memory_claims (\n id TEXT PRIMARY KEY,\n memory_id TEXT NOT NULL DEFAULT '',\n user_id TEXT NOT NULL,\n entity TEXT NOT NULL DEFAULT '',\n predicate TEXT NOT NULL DEFAULT '',\n value_json TEXT NOT NULL DEFAULT '{}',\n text TEXT NOT NULL,\n category TEXT NOT NULL DEFAULT 'general',\n importance REAL NOT NULL DEFAULT 0.5,\n confidence REAL NOT NULL DEFAULT 0.5,\n source TEXT NOT NULL DEFAULT 'agent',\n source_priority INTEGER NOT NULL DEFAULT 0,\n status TEXT NOT NULL DEFAULT 'active',\n valid_time TEXT NOT NULL DEFAULT '',\n evidence_ids TEXT NOT NULL DEFAULT '[]',\n supersedes_claim_id TEXT NOT NULL DEFAULT '',\n conflict_group_id TEXT NOT NULL DEFAULT '',\n created_at INTEGER NOT NULL,\n updated_at INTEGER NOT NULL\n);\n\nCREATE INDEX IF NOT EXISTS idx_memory_claims_user_status ON memory_claims(user_id, status);\nCREATE INDEX IF NOT EXISTS idx_memory_claims_memory ON memory_claims(memory_id);\nCREATE INDEX IF NOT EXISTS idx_memory_claims_fact ON memory_claims(user_id, entity, predicate, valid_time);\n\nCREATE TABLE IF NOT EXISTS memory_conflicts (\n id TEXT PRIMARY KEY,\n user_id TEXT NOT NULL,\n claim_a_id TEXT NOT NULL,\n claim_b_id TEXT NOT NULL,\n reason TEXT NOT NULL,\n status TEXT NOT NULL DEFAULT 'open',\n created_at INTEGER NOT NULL,\n updated_at INTEGER NOT NULL\n);\n\nCREATE INDEX IF NOT EXISTS idx_memory_conflicts_user_status ON memory_conflicts(user_id, status);\n\nCREATE TABLE IF NOT EXISTS memory_attachments (\n id TEXT PRIMARY KEY,\n memory_id TEXT NOT NULL DEFAULT '',\n user_id TEXT NOT NULL,\n kind TEXT NOT NULL DEFAULT 'file',\n filename TEXT NOT NULL DEFAULT '',\n mime_type TEXT NOT NULL DEFAULT '',\n size INTEGER NOT NULL DEFAULT 0,\n rel_path TEXT NOT NULL,\n extracted_text TEXT NOT NULL DEFAULT '',\n created_at INTEGER NOT NULL\n);\n\nCREATE INDEX IF NOT EXISTS idx_memory_attachments_memory ON memory_attachments(memory_id);\nCREATE INDEX IF NOT EXISTS idx_memory_attachments_orphan ON memory_attachments(user_id, memory_id, created_at);\n\nCREATE VIRTUAL TABLE IF NOT EXISTS memories_fts USING fts5(\n id UNINDEXED,\n user_id UNINDEXED,\n text,\n category,\n tags,\n content=memories,\n content_rowid=rowid,\n tokenize='unicode61 remove_diacritics 2'\n);\n\nCREATE TRIGGER IF NOT EXISTS memories_ai AFTER INSERT ON memories BEGIN\n INSERT INTO memories_fts(rowid, id, user_id, text, category, tags)\n VALUES (new.rowid, new.id, new.user_id, new.text, new.category, new.tags);\nEND;\n\nCREATE TRIGGER IF NOT EXISTS memories_ad AFTER DELETE ON memories BEGIN\n INSERT INTO memories_fts(memories_fts, rowid, id, user_id, text, category, tags)\n VALUES ('delete', old.rowid, old.id, old.user_id, old.text, old.category, old.tags);\nEND;\n\nCREATE TRIGGER IF NOT EXISTS memories_au AFTER UPDATE ON memories BEGIN\n INSERT INTO memories_fts(memories_fts, rowid, id, user_id, text, category, tags)\n VALUES ('delete', old.rowid, old.id, old.user_id, old.text, old.category, old.tags);\n INSERT INTO memories_fts(rowid, id, user_id, text, category, tags)\n VALUES (new.rowid, new.id, new.user_id, new.text, new.category, new.tags);\nEND;\n";
3
3
  export declare function initializeMemorySchema(db: SqliteDatabase): void;
@@ -0,0 +1,61 @@
1
+ import type { PortableTool } from "../portable-tool.js";
2
+ import { type GeneratePetdexImage, type UploadPetdexReferenceImage } from "../../runtime/pet/petdex-forge-service.js";
3
+ export declare const PETDEX_CREATE_TOOL_NAME: "petdex_create";
4
+ export interface PetdexCreateToolParams {
5
+ name?: string;
6
+ description: string;
7
+ prompt?: string;
8
+ reference_image_url?: string;
9
+ base_spritesheet_path?: string;
10
+ refine_animation_id?: string;
11
+ refine_frame_indexes?: number[];
12
+ output_dir?: string;
13
+ }
14
+ export interface PetdexCreateToolDeps {
15
+ generateImage: GeneratePetdexImage;
16
+ uploadReferenceImage?: UploadPetdexReferenceImage;
17
+ resolveOutputDir(outputDir?: string): string;
18
+ }
19
+ export declare const PETDEX_CREATE_TOOL_SCHEMA: {
20
+ readonly type: "object";
21
+ readonly properties: {
22
+ readonly name: {
23
+ readonly type: "string";
24
+ readonly description: "Short display name for the generated desktop pet. Defaults to a short name derived from description.";
25
+ };
26
+ readonly description: {
27
+ readonly type: "string";
28
+ readonly description: "Canonical character description for the Petdex desktop pet.";
29
+ };
30
+ readonly prompt: {
31
+ readonly type: "string";
32
+ readonly description: "Optional extra visual direction. The tool will embed it into a strict Petdex 8x9 atlas prompt.";
33
+ };
34
+ readonly reference_image_url: {
35
+ readonly type: "string";
36
+ readonly description: "Optional publicly accessible HTTP/HTTPS reference image URL for image-to-image generation.";
37
+ };
38
+ readonly base_spritesheet_path: {
39
+ readonly type: "string";
40
+ readonly description: "Optional existing spritesheet.webp path for targeted row/frame refinement.";
41
+ };
42
+ readonly refine_animation_id: {
43
+ readonly type: "string";
44
+ readonly enum: readonly ["idle", "thinking", "working", "done", "happy", "error", "attention", "dragging", "sleeping"];
45
+ readonly description: "Optional canonical animation id to regenerate against base_spritesheet_path.";
46
+ };
47
+ readonly refine_frame_indexes: {
48
+ readonly type: "array";
49
+ readonly items: {
50
+ readonly type: "number";
51
+ };
52
+ readonly description: "Optional frame indexes to replace for targeted refinement. Accepts row-local 0..7, global 0..71, or global 1..72.";
53
+ };
54
+ readonly output_dir: {
55
+ readonly type: "string";
56
+ readonly description: "Optional output directory. Defaults to the workspace Petdex asset output directory.";
57
+ };
58
+ };
59
+ readonly required: readonly ["description"];
60
+ };
61
+ export declare function createPetdexCreateTool(deps: PetdexCreateToolDeps): PortableTool<PetdexCreateToolParams>;
@@ -7,7 +7,7 @@
7
7
  * Protocol: ACP v1 over JSON-RPC 2.0 / stdio (line-delimited JSON).
8
8
  *
9
9
  * Responsibilities:
10
- * - Accepts ACP standard methods: initialize, session/new, session/prompt, session/end
10
+ * - Accepts ACP standard methods: initialize, session/new, session/prompt, session/close
11
11
  * - Accepts x/ extended methods: x/abort, x/dream, x/solo.*, x/product.*
12
12
  * - Emits ACP session/update notifications (standard + x_ extended)
13
13
  * - Translates host permission responses back to the agent
@@ -17,7 +17,7 @@
17
17
  * existing internal handlers.
18
18
  */
19
19
  import type { Transport } from "./io-transport.js";
20
- import { type AcpInitializeParams, type AcpInitializeResult, type AcpSessionNewParams, type AcpSessionNewResult, type AcpSessionPromptParams, type AcpSessionPromptResult, type AcpSessionEndParams, type AcpSessionSetConfigParams, type AcpSessionUpdateType, type AcpPermissionRequestParams, type AcpPermissionRequestResult } from "../protocol/wire/index.js";
20
+ import { type AcpInitializeParams, type AcpInitializeResult, type AcpSessionNewParams, type AcpSessionLoadParams, type AcpSessionNewResult, type AcpSessionPromptParams, type AcpSessionPromptResult, type AcpSessionCloseParams, type AcpSessionSetConfigParams, type AcpSessionUpdateType, type AcpPermissionRequestParams, type AcpPermissionRequestResult } from "../protocol/wire/index.js";
21
21
  export declare const ACP_ERROR_CODES: {
22
22
  readonly PARSE_ERROR: -32700;
23
23
  readonly INVALID_REQUEST: -32600;
@@ -39,10 +39,26 @@ export interface AcpRequestHandler {
39
39
  handleAcpInitialize(params: AcpInitializeParams): Promise<AcpInitializeResult>;
40
40
  handleAcpSessionNew(params: AcpSessionNewParams): Promise<AcpSessionNewResult>;
41
41
  handleAcpSessionPrompt(params: AcpSessionPromptParams): Promise<AcpSessionPromptResult>;
42
- handleAcpSessionEnd(params: AcpSessionEndParams): Promise<void>;
42
+ handleAcpSessionClose(params: AcpSessionCloseParams): Promise<void>;
43
43
  handleAcpSessionSetConfig(params: AcpSessionSetConfigParams): Promise<void>;
44
44
  handleAcpSessionSetModel(sessionId: string, model: string): Promise<void>;
45
- handleAcpSessionSetMode(sessionId: string, mode: string): Promise<void>;
45
+ handleAcpSessionSetMode(sessionId: string, modeId: string): Promise<string>;
46
+ handleAcpSessionLoad(params: AcpSessionLoadParams): Promise<{
47
+ replay: Array<{
48
+ type: "user_message_chunk" | "agent_message_chunk";
49
+ content: string;
50
+ }>;
51
+ }>;
52
+ /** Single source of truth for advertised slash commands (also summarized by /help). */
53
+ buildAvailableCommands(): Array<{
54
+ name: string;
55
+ description?: string;
56
+ }>;
57
+ /** Pre-prompt slash-command intercept. Returns {handled,reply}; server emits + acks. */
58
+ tryDispatchCommand(params: AcpSessionPromptParams): Promise<{
59
+ handled: boolean;
60
+ reply?: string;
61
+ }>;
46
62
  handleAcpPermissionResponse(permissionId: string, optionId: string): void;
47
63
  handleAcpAbort(params: {
48
64
  sessionId: string;
@@ -86,7 +102,7 @@ export interface AcpServerConfig {
86
102
  * 2. Host sends `initialize` -> agent responds with capabilities
87
103
  * 3. Host sends `session/new` -> session created
88
104
  * 4. Host sends `session/prompt` -> agent runs turn, emits session/update notifications
89
- * 5. Host sends `session/end` -> session cleaned up
105
+ * 5. Host sends `session/close` -> session cleaned up
90
106
  */
91
107
  export declare class AcpServer {
92
108
  private transport;
@@ -113,8 +129,8 @@ export declare class AcpServer {
113
129
  dispatchMessage(raw: unknown): boolean;
114
130
  /**
115
131
  * Emit an ACP session/update notification to the host.
116
- * Standard update types are always sent; x_ types only if host declared
117
- * capabilities.extendedEvents = true.
132
+ * Standard update types are always sent; x_ types only if the host declared
133
+ * the qlogicagent capability with events enabled.
118
134
  */
119
135
  emitSessionUpdate(sessionId: string, type: AcpSessionUpdateType, payload: Record<string, unknown>): void;
120
136
  /**
@@ -133,9 +149,11 @@ export declare class AcpServer {
133
149
  private handleResponse;
134
150
  private onInitialize;
135
151
  private onSessionNew;
152
+ private onSessionLoad;
136
153
  private onSessionPrompt;
137
- private onSessionEnd;
154
+ private onSessionClose;
138
155
  private onSessionSetConfig;
156
+ private onSessionSetMode;
139
157
  private onAbort;
140
158
  private onCancel;
141
159
  private onDream;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "qlogicagent",
3
- "version": "2.10.49",
3
+ "version": "2.11.1",
4
4
  "description": "XiaozhiClaw Agent CLI — subprocess architecture (JSON-RPC over stdio)",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -31,6 +31,10 @@
31
31
  "./permissions": {
32
32
  "types": "./dist/types/permissions.d.ts",
33
33
  "default": "./dist/permissions.js"
34
+ },
35
+ "./pet-contracts": {
36
+ "types": "./dist/types/pet-contracts.d.ts",
37
+ "default": "./dist/pet-contracts.js"
34
38
  }
35
39
  },
36
40
  "files": [
@@ -52,6 +56,9 @@
52
56
  ],
53
57
  "permissions": [
54
58
  "./dist/types/permissions.d.ts"
59
+ ],
60
+ "pet-contracts": [
61
+ "./dist/types/pet-contracts.d.ts"
55
62
  ]
56
63
  }
57
64
  },
@@ -78,7 +85,8 @@
78
85
  "node": ">=22.0.0"
79
86
  },
80
87
  "dependencies": {
81
- "@xiaozhiclaw/provider-core": "^0.1.1",
88
+ "@napi-rs/canvas": "0.1.100",
89
+ "@xiaozhiclaw/provider-core": "0.1.2",
82
90
  "better-sqlite3": "^12.10.0",
83
91
  "dotenv": "^17.3.1",
84
92
  "nanoid": "^5.1.5",
@@ -88,6 +96,7 @@
88
96
  "devDependencies": {
89
97
  "@types/better-sqlite3": "^7.6.13",
90
98
  "@types/node": "^22.15.0",
99
+ "@zed-industries/agent-client-protocol": "0.4.5",
91
100
  "esbuild": "^0.28.0",
92
101
  "oxlint": "1.67.0",
93
102
  "tsx": "^4.19.0",
@@ -1,79 +0,0 @@
1
- /**
2
- * Pet Consistency Scorer — Vision model evaluation for character consistency (design §14.4).
3
- *
4
- * After generating SVGs (via skeleton or direct LLM), this module:
5
- * 1. Renders each SVG state to compare against the reference/base
6
- * 2. Uses Vision model to score visual consistency (0-10)
7
- * 3. Retries generation if score < threshold
8
- *
9
- * Strategies used:
10
- * - Structured Prompt: fixed character description + only vary action
11
- * - Post-processing validation: Vision model scores after generation
12
- * - Part presence check: verify required DOM structure exists
13
- */
14
- export interface ConsistencyResult {
15
- state: string;
16
- score: number;
17
- passed: boolean;
18
- feedback?: string;
19
- }
20
- export interface ConsistencyReport {
21
- overallScore: number;
22
- results: ConsistencyResult[];
23
- passedAll: boolean;
24
- retryStates: string[];
25
- }
26
- export interface ConsistencyOptions {
27
- /** Minimum score to pass (0-10). Default: 6 */
28
- threshold?: number;
29
- /** Max retries per state. Default: 2 */
30
- maxRetries?: number;
31
- /** Reference SVG (base/idle state) to compare against */
32
- referenceSvg: string;
33
- /** Character description for context */
34
- characterDesc: string;
35
- }
36
- declare const DEFAULT_THRESHOLD = 6;
37
- declare const DEFAULT_MAX_RETRIES = 2;
38
- /**
39
- * Quick structural check: verify the SVG has consistent DOM structure.
40
- * Returns a score 0-10 based on structural similarity to reference.
41
- */
42
- export declare function structuralConsistencyScore(referenceSvg: string, candidateSvg: string): number;
43
- /**
44
- * Build the Vision model prompt for consistency scoring.
45
- */
46
- export declare function buildConsistencyPrompt(characterDesc: string, stateName: string): string;
47
- /**
48
- * Parse Vision model response to extract score and feedback.
49
- */
50
- export declare function parseConsistencyResponse(response: string): {
51
- score: number;
52
- feedback: string;
53
- };
54
- /**
55
- * Run the full consistency check pipeline.
56
- * Takes generated SVGs, scores each against reference, returns report.
57
- *
58
- * The `visionScore` callback is optional — if not provided, only structural
59
- * scoring is used (faster, no LLM cost, but less accurate).
60
- */
61
- export declare function evaluateConsistency(referenceSvg: string, stateSvgs: Record<string, string>, options?: {
62
- threshold?: number;
63
- }): ConsistencyReport;
64
- /**
65
- * Async consistency evaluation using Vision model for high-accuracy scoring.
66
- * Falls back to structural scoring if Vision call fails.
67
- */
68
- export declare function evaluateConsistencyWithVision(referenceSvg: string, stateSvgs: Record<string, string>, visionScore: (referenceSvg: string, candidateSvg: string, state: string) => Promise<{
69
- score: number;
70
- feedback: string;
71
- }>, options?: {
72
- threshold?: number;
73
- }): Promise<ConsistencyReport>;
74
- /**
75
- * Retry strategy: regenerate failed states with enhanced prompt.
76
- * Returns a prompt modifier string that emphasizes consistency.
77
- */
78
- export declare function buildRetryPrompt(characterDesc: string, state: string, feedback: string, attempt: number): string;
79
- export { DEFAULT_THRESHOLD, DEFAULT_MAX_RETRIES };
@@ -1,70 +0,0 @@
1
- /**
2
- * PetSkeleton — SVG skeleton parameterization system (design §14.3 Plan A).
3
- *
4
- * Core idea: generate ONE base skeleton via LLM, then render each state by
5
- * only varying animation parameters (pose, expression, effects).
6
- * This ensures visual consistency across states without repeated LLM calls.
7
- *
8
- * Pipeline:
9
- * 1. LLM generates a base SVG skeleton with labeled parts
10
- * 2. We parse and decompose it into movable parts
11
- * 3. Each state applies different CSS @keyframes to the same skeleton
12
- */
13
- export interface PetSkeleton {
14
- /** Raw SVG of the base pose (idle-like neutral pose) */
15
- baseSvg: string;
16
- /** Extracted part IDs found in the SVG */
17
- parts: SkeletonPart[];
18
- /** Color palette extracted from the base SVG */
19
- colors: {
20
- primary: string;
21
- secondary: string;
22
- accent?: string;
23
- };
24
- /** Character description used to generate this skeleton */
25
- characterDesc: string;
26
- }
27
- export interface SkeletonPart {
28
- id: string;
29
- type: "body" | "head" | "left-eye" | "right-eye" | "left-arm" | "right-arm" | "accessory" | "effect";
30
- /** CSS selector for this part within the SVG */
31
- selector: string;
32
- }
33
- export interface StateAnimationParams {
34
- body: BodyAnimation;
35
- eyes: EyeExpression;
36
- arms: ArmPose;
37
- effects?: EffectOverlay[];
38
- }
39
- export type BodyAnimation = "breathe" | "sway" | "lean" | "tilt" | "shrink" | "bounce" | "still" | "float";
40
- export type EyeExpression = "blink" | "lookup" | "focus" | "closed" | "wide" | "sparkle" | "dizzy" | "sleepy";
41
- export type ArmPose = "sway" | "still" | "hammer" | "wave" | "raised" | "covering" | "hold" | "eat";
42
- export type EffectOverlay = "zzz" | "sparkle" | "sweat" | "question" | "ellipsis" | "heart" | "exclaim" | "music";
43
- export declare const STATE_ANIMATION_MAP: Record<string, StateAnimationParams>;
44
- /**
45
- * Generate the base skeleton prompt for LLM.
46
- * The LLM generates ONE SVG with labeled groups that we can animate differently per state.
47
- */
48
- export declare function buildSkeletonPrompt(characterDesc: string): string;
49
- /**
50
- * Parse a skeleton SVG and identify parts.
51
- */
52
- export declare function parseSkeleton(svgText: string): SkeletonPart[];
53
- /**
54
- * Render a specific state by injecting CSS animations into the skeleton SVG.
55
- * The skeleton remains identical — only the <style> block changes.
56
- */
57
- export declare function renderState(skeleton: PetSkeleton, state: string): string;
58
- /**
59
- * Extract primary/secondary colors from an SVG string.
60
- * Looks for fill/stop-color attributes and picks the two most frequent.
61
- */
62
- export declare function extractColors(svgText: string): {
63
- primary: string;
64
- secondary: string;
65
- };
66
- /**
67
- * Validate that a skeleton SVG has the required part structure.
68
- * Returns list of missing parts (empty = valid).
69
- */
70
- export declare function validateSkeleton(svgText: string): string[];