promptpilot 0.1.0 → 0.1.2

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/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli.ts","../src/errors.ts","../src/storage/fileSessionStore.ts","../src/utils/validation.ts","../src/storage/sqliteSessionStore.ts","../src/utils/logger.ts","../src/utils/json.ts","../src/core/ollamaClient.ts","../src/core/systemPrompt.ts","../src/core/tokenEstimator.ts","../src/core/contextCompressor.ts","../src/core/contextManager.ts","../src/core/modelSelector.ts","../src/core/optimizer.ts","../src/index.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { pathToFileURL } from \"node:url\";\n\nimport { createOptimizer } from \"./index.js\";\nimport { toPrettyJson } from \"./utils/json.js\";\nimport { createLogger } from \"./utils/logger.js\";\n\ntype CliWriter = {\n write(message: string): void;\n};\n\ninterface CliIO {\n stdout: CliWriter;\n stderr: CliWriter;\n stdin?: NodeJS.ReadStream;\n}\n\ninterface CliDependencies {\n createOptimizer: typeof createOptimizer;\n readStdin: (stdin?: NodeJS.ReadStream) => Promise<string>;\n}\n\nexport async function runCli(\n argv: string[],\n io: CliIO = { stdout: process.stdout, stderr: process.stderr, stdin: process.stdin },\n dependencies: CliDependencies = { createOptimizer, readStdin }\n): Promise<number> {\n const [command, ...rest] = argv;\n\n if (!command || command === \"--help\" || command === \"-h\") {\n io.stdout.write(`${getHelpText()}\\n`);\n return 0;\n }\n\n if (command !== \"optimize\") {\n io.stderr.write(`Unknown command: ${command}\\n`);\n io.stderr.write(`${getHelpText()}\\n`);\n return 1;\n }\n\n const parsed = parseOptimizeArgs(rest);\n if (parsed.help) {\n io.stdout.write(`${getHelpText()}\\n`);\n return 0;\n }\n\n if (!parsed.sessionId && parsed.clearSession) {\n io.stderr.write(\"--clear-session requires --session <id>.\\n\");\n return 1;\n }\n\n const optimizer = dependencies.createOptimizer({\n provider: \"ollama\",\n ollamaModel: parsed.model,\n host: parsed.host,\n contextStore: parsed.contextStore,\n storageDir: parsed.storageDir,\n sqlitePath: parsed.sqlitePath,\n timeoutMs: parsed.timeoutMs,\n logger: createLogger(parsed.debug)\n });\n\n if (parsed.clearSession && parsed.sessionId) {\n await optimizer.clearContext(parsed.sessionId);\n if (!parsed.prompt) {\n io.stdout.write(`Cleared session ${parsed.sessionId}\\n`);\n return 0;\n }\n }\n\n if (!parsed.prompt) {\n const stdinPrompt = await dependencies.readStdin(io.stdin);\n parsed.prompt = stdinPrompt.trim() || undefined;\n }\n\n if (!parsed.prompt) {\n io.stderr.write(\"A prompt is required.\\n\");\n return 1;\n }\n\n try {\n const result = await optimizer.optimize({\n prompt: parsed.prompt,\n task: parsed.task,\n tone: parsed.tone,\n mode: parsed.mode,\n preset: parsed.preset,\n sessionId: parsed.sessionId,\n saveContext: parsed.saveContext,\n useContext: parsed.useContext,\n targetModel: parsed.targetModel ?? \"claude\",\n outputFormat: parsed.outputFormat,\n maxLength: parsed.maxLength,\n tags: parsed.tags,\n pinnedConstraints: parsed.pinnedConstraints,\n debug: parsed.debug,\n plainOutput: parsed.plain,\n maxTotalTokens: parsed.maxTotalTokens,\n maxContextTokens: parsed.maxContextTokens,\n maxInputTokens: parsed.maxInputTokens,\n timeoutMs: parsed.timeoutMs,\n bypassOptimization: parsed.bypassOptimization\n });\n\n if (parsed.json) {\n io.stdout.write(`${toPrettyJson(result)}\\n`);\n return 0;\n }\n\n if (parsed.plain) {\n io.stdout.write(`${result.finalPrompt}\\n`);\n return 0;\n }\n\n io.stdout.write(`${result.finalPrompt}\\n\\n`);\n io.stdout.write(`provider=${result.provider} model=${result.model} tokens=${result.estimatedTokensAfter.total} savings=${result.tokenSavings}\\n`);\n if (result.warnings.length > 0) {\n io.stdout.write(`warnings=${result.warnings.join(\" | \")}\\n`);\n }\n return 0;\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Unknown CLI error.\";\n io.stderr.write(`${message}\\n`);\n return 1;\n }\n}\n\nfunction parseOptimizeArgs(args: string[]) {\n const parsed: {\n prompt?: string;\n sessionId?: string;\n model?: string;\n mode?: any;\n task?: string;\n tone?: string;\n preset?: any;\n targetModel?: string;\n outputFormat?: string;\n maxLength?: number;\n tags: string[];\n pinnedConstraints: string[];\n host?: string;\n contextStore?: \"local\" | \"sqlite\";\n storageDir?: string;\n sqlitePath?: string;\n plain: boolean;\n json: boolean;\n debug: boolean;\n saveContext?: boolean;\n useContext?: boolean;\n clearSession: boolean;\n maxTotalTokens?: number;\n maxContextTokens?: number;\n maxInputTokens?: number;\n timeoutMs?: number;\n bypassOptimization: boolean;\n help: boolean;\n } = {\n plain: false,\n json: false,\n debug: false,\n clearSession: false,\n useContext: true,\n bypassOptimization: false,\n help: false,\n tags: [],\n pinnedConstraints: []\n };\n\n const positionals: string[] = [];\n\n for (let index = 0; index < args.length; index += 1) {\n const arg = args[index];\n switch (arg) {\n case \"--session\":\n parsed.sessionId = args[++index];\n break;\n case \"--model\":\n parsed.model = args[++index];\n break;\n case \"--mode\":\n parsed.mode = args[++index];\n break;\n case \"--task\":\n parsed.task = args[++index];\n break;\n case \"--tone\":\n parsed.tone = args[++index];\n break;\n case \"--preset\":\n parsed.preset = args[++index];\n break;\n case \"--target-model\":\n parsed.targetModel = args[++index];\n break;\n case \"--output-format\":\n parsed.outputFormat = args[++index];\n break;\n case \"--max-length\":\n parsed.maxLength = Number(args[++index]);\n break;\n case \"--tag\":\n parsed.tags.push(args[++index]);\n break;\n case \"--pin-constraint\":\n parsed.pinnedConstraints.push(args[++index]);\n break;\n case \"--host\":\n parsed.host = args[++index];\n break;\n case \"--store\":\n parsed.contextStore = args[++index] as \"local\" | \"sqlite\";\n break;\n case \"--storage-dir\":\n parsed.storageDir = args[++index];\n break;\n case \"--sqlite-path\":\n parsed.sqlitePath = args[++index];\n break;\n case \"--plain\":\n parsed.plain = true;\n break;\n case \"--json\":\n parsed.json = true;\n break;\n case \"--debug\":\n parsed.debug = true;\n break;\n case \"--save-context\":\n parsed.saveContext = true;\n break;\n case \"--no-context\":\n parsed.useContext = false;\n break;\n case \"--clear-session\":\n parsed.clearSession = true;\n break;\n case \"--max-total-tokens\":\n parsed.maxTotalTokens = Number(args[++index]);\n break;\n case \"--max-context-tokens\":\n parsed.maxContextTokens = Number(args[++index]);\n break;\n case \"--max-input-tokens\":\n parsed.maxInputTokens = Number(args[++index]);\n break;\n case \"--timeout\":\n parsed.timeoutMs = Number(args[++index]);\n break;\n case \"--bypass-optimization\":\n parsed.bypassOptimization = true;\n break;\n case \"--help\":\n case \"-h\":\n parsed.help = true;\n break;\n default:\n positionals.push(arg);\n }\n }\n\n parsed.prompt = positionals.join(\" \").trim() || undefined;\n return parsed;\n}\n\nfunction getHelpText(): string {\n return [\n \"promptpilot optimize <prompt> [options]\",\n \"\",\n \"Options:\",\n \" --session <id>\",\n \" --model <name> Override auto-selected local Ollama model\",\n \" --mode <mode>\",\n \" --task <task>\",\n \" --tone <tone>\",\n \" --preset <preset>\",\n \" --target-model <name>\",\n \" --output-format <text>\",\n \" --max-length <n>\",\n \" --tag <value> Repeatable\",\n \" --pin-constraint <text> Repeatable\",\n \" --host <url>\",\n \" --store <local|sqlite>\",\n \" --storage-dir <path>\",\n \" --sqlite-path <path>\",\n \" --plain\",\n \" --json\",\n \" --debug\",\n \" --save-context\",\n \" --no-context\",\n \" --clear-session\",\n \" --max-total-tokens <n>\",\n \" --max-context-tokens <n>\",\n \" --max-input-tokens <n>\",\n \" --timeout <ms>\",\n \" --bypass-optimization\"\n ].join(\"\\n\");\n}\n\nasync function readStdin(stdin: NodeJS.ReadStream | undefined = process.stdin): Promise<string> {\n if (!stdin || stdin.isTTY) {\n return \"\";\n }\n\n return new Promise((resolve, reject) => {\n let data = \"\";\n stdin.setEncoding(\"utf8\");\n stdin.on(\"data\", (chunk) => {\n data += chunk;\n });\n stdin.on(\"end\", () => resolve(data));\n stdin.on(\"error\", reject);\n });\n}\n\nif (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {\n runCli(process.argv.slice(2)).then((code) => {\n process.exit(code);\n });\n}\n","export class InvalidPromptError extends Error {\n constructor(message = \"Prompt must be a non-empty string.\") {\n super(message);\n this.name = \"InvalidPromptError\";\n }\n}\n\nexport class OllamaUnavailableError extends Error {\n constructor(message = \"Ollama is unavailable or returned an invalid response.\") {\n super(message);\n this.name = \"OllamaUnavailableError\";\n }\n}\n\nexport class ContextStoreError extends Error {\n constructor(message = \"Context store operation failed.\") {\n super(message);\n this.name = \"ContextStoreError\";\n }\n}\n\nexport class TokenBudgetExceededError extends Error {\n constructor(message = \"Final prompt could not be reduced to fit within the configured token budget.\") {\n super(message);\n this.name = \"TokenBudgetExceededError\";\n }\n}\n","import { mkdir, readFile, rm, writeFile } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\n\nimport { ContextStoreError } from \"../errors.js\";\nimport type { SessionData, SessionStore } from \"../types.js\";\nimport { sanitizeSessionId } from \"../utils/validation.js\";\n\nexport class FileSessionStore implements SessionStore {\n private readonly rootDir: string;\n\n constructor(rootDir = join(homedir(), \".promptpilot\", \"sessions\")) {\n this.rootDir = rootDir;\n }\n\n async loadSession(sessionId: string): Promise<SessionData> {\n const filePath = this.getFilePath(sessionId);\n\n try {\n const contents = await readFile(filePath, \"utf8\");\n const parsed = JSON.parse(contents) as SessionData;\n return parsed;\n } catch (error) {\n const code = (error as NodeJS.ErrnoException).code;\n if (code === \"ENOENT\") {\n return this.createEmptySession(sessionId);\n }\n\n throw new ContextStoreError(`Failed to load session \"${sessionId}\".`);\n }\n }\n\n async saveSession(session: SessionData): Promise<void> {\n const filePath = this.getFilePath(session.sessionId);\n\n try {\n await mkdir(dirname(filePath), { recursive: true });\n await writeFile(filePath, JSON.stringify(session, null, 2), \"utf8\");\n } catch {\n throw new ContextStoreError(`Failed to save session \"${session.sessionId}\".`);\n }\n }\n\n async clearSession(sessionId: string): Promise<void> {\n const filePath = this.getFilePath(sessionId);\n\n try {\n await rm(filePath, { force: true });\n } catch {\n throw new ContextStoreError(`Failed to clear session \"${sessionId}\".`);\n }\n }\n\n private getFilePath(sessionId: string): string {\n return join(this.rootDir, `${sanitizeSessionId(sessionId)}.json`);\n }\n\n private createEmptySession(sessionId: string): SessionData {\n const now = new Date().toISOString();\n return {\n sessionId,\n entries: [],\n summaries: [],\n createdAt: now,\n updatedAt: now\n };\n }\n}\n","import { InvalidPromptError } from \"../errors.js\";\n\nexport function normalizeWhitespace(value: string): string {\n return value\n .replace(/\\r\\n/g, \"\\n\")\n .replace(/[ \\t]+\\n/g, \"\\n\")\n .replace(/\\n{3,}/g, \"\\n\\n\")\n .trim();\n}\n\nexport function validatePrompt(prompt: string): string {\n if (typeof prompt !== \"string\" || normalizeWhitespace(prompt).length === 0) {\n throw new InvalidPromptError();\n }\n\n return normalizeWhitespace(prompt);\n}\n\nexport function sanitizeSessionId(sessionId: string): string {\n return sessionId.trim().replace(/[^a-zA-Z0-9._-]/g, \"-\");\n}\n","import { dirname, join } from \"node:path\";\nimport { mkdir } from \"node:fs/promises\";\n\nimport { ContextStoreError } from \"../errors.js\";\nimport type { SessionData, SessionStore } from \"../types.js\";\n\ntype DatabaseAdapter = {\n prepare(sql: string): {\n get(param?: string): { data?: string } | undefined;\n run(...params: unknown[]): void;\n };\n exec(sql: string): void;\n};\n\nexport class SQLiteSessionStore implements SessionStore {\n private dbPromise: Promise<DatabaseAdapter>;\n\n constructor(private readonly dbPath = join(process.cwd(), \".promptpilot\", \"promptpilot.db\")) {\n this.dbPromise = this.openDatabase();\n }\n\n async loadSession(sessionId: string): Promise<SessionData> {\n const db = await this.dbPromise;\n const row = db.prepare(\"SELECT data FROM sessions WHERE id = ?\").get(sessionId);\n if (!row?.data) {\n return createEmptySession(sessionId);\n }\n\n return JSON.parse(row.data) as SessionData;\n }\n\n async saveSession(session: SessionData): Promise<void> {\n const db = await this.dbPromise;\n db.prepare(\"INSERT OR REPLACE INTO sessions (id, data) VALUES (?, ?)\").run(\n session.sessionId,\n JSON.stringify(session)\n );\n }\n\n async clearSession(sessionId: string): Promise<void> {\n const db = await this.dbPromise;\n db.prepare(\"DELETE FROM sessions WHERE id = ?\").run(sessionId);\n }\n\n private async openDatabase(): Promise<DatabaseAdapter> {\n try {\n await mkdir(dirname(this.dbPath), { recursive: true });\n const nodeSqliteName = \"node:sqlite\";\n const nodeSqlite = await import(nodeSqliteName).catch(() => null);\n\n if (nodeSqlite?.DatabaseSync) {\n const db = new nodeSqlite.DatabaseSync(this.dbPath) as DatabaseAdapter;\n db.exec(\"CREATE TABLE IF NOT EXISTS sessions (id TEXT PRIMARY KEY, data TEXT NOT NULL)\");\n return db;\n }\n\n const betterSqliteName = \"better-sqlite3\";\n const betterSqlite = await import(betterSqliteName).catch(() => null);\n if (betterSqlite?.default) {\n const db = new betterSqlite.default(this.dbPath) as DatabaseAdapter;\n db.exec(\"CREATE TABLE IF NOT EXISTS sessions (id TEXT PRIMARY KEY, data TEXT NOT NULL)\");\n return db;\n }\n\n throw new ContextStoreError(\n \"SQLite store requires node:sqlite support or the better-sqlite3 package.\"\n );\n } catch (error) {\n if (error instanceof ContextStoreError) {\n throw error;\n }\n\n throw new ContextStoreError(\"Failed to initialize SQLite session store.\");\n }\n }\n}\n\nfunction createEmptySession(sessionId: string): SessionData {\n const now = new Date().toISOString();\n return {\n sessionId,\n entries: [],\n summaries: [],\n createdAt: now,\n updatedAt: now\n };\n}\n","import type { Logger } from \"../types.js\";\n\nexport const noopLogger: Logger = {\n debug: () => undefined,\n info: () => undefined,\n warn: () => undefined,\n error: () => undefined\n};\n\nexport function createLogger(debugEnabled = false): Logger {\n return {\n debug(message, meta) {\n if (debugEnabled) {\n console.debug(`[promptpilot] ${message}`, meta ?? \"\");\n }\n },\n info(message, meta) {\n if (debugEnabled) {\n console.info(`[promptpilot] ${message}`, meta ?? \"\");\n }\n },\n warn(message, meta) {\n if (debugEnabled) {\n console.warn(`[promptpilot] ${message}`, meta ?? \"\");\n }\n },\n error(message, meta) {\n if (debugEnabled) {\n console.error(`[promptpilot] ${message}`, meta ?? \"\");\n }\n }\n };\n}\n","export function safeJsonParse<T>(value: string): T | null {\n try {\n return JSON.parse(value) as T;\n } catch {\n return null;\n }\n}\n\nexport function extractFirstJsonObject(value: string): string | null {\n const start = value.indexOf(\"{\");\n if (start === -1) {\n return null;\n }\n\n let depth = 0;\n let inString = false;\n let escaped = false;\n\n for (let index = start; index < value.length; index += 1) {\n const char = value[index];\n\n if (escaped) {\n escaped = false;\n continue;\n }\n\n if (char === \"\\\\\") {\n escaped = true;\n continue;\n }\n\n if (char === \"\\\"\") {\n inString = !inString;\n continue;\n }\n\n if (inString) {\n continue;\n }\n\n if (char === \"{\") {\n depth += 1;\n } else if (char === \"}\") {\n depth -= 1;\n if (depth === 0) {\n return value.slice(start, index + 1);\n }\n }\n }\n\n return null;\n}\n\nexport function toPrettyJson(value: unknown): string {\n return JSON.stringify(value, null, 2);\n}\n","import { OllamaUnavailableError } from \"../errors.js\";\nimport type { Logger, OllamaClientLike, OllamaGenerateOptions, OllamaModelInfo } from \"../types.js\";\nimport { extractFirstJsonObject, safeJsonParse } from \"../utils/json.js\";\nimport { noopLogger } from \"../utils/logger.js\";\n\ninterface OllamaClientConfig {\n host?: string;\n model?: string;\n timeoutMs?: number;\n temperature?: number;\n logger?: Logger;\n}\n\nexport class OllamaClient implements OllamaClientLike {\n readonly host: string;\n readonly model: string;\n readonly timeoutMs: number;\n readonly temperature: number;\n readonly logger: Logger;\n\n constructor(config: OllamaClientConfig = {}) {\n this.host = config.host ?? \"http://localhost:11434\";\n this.model = config.model ?? \"qwen2.5:3b\";\n this.timeoutMs = config.timeoutMs ?? 30000;\n this.temperature = config.temperature ?? 0.1;\n this.logger = config.logger ?? noopLogger;\n }\n\n async isAvailable(): Promise<boolean> {\n try {\n const response = await fetch(new URL(\"/api/tags\", this.host), {\n method: \"GET\"\n });\n\n return response.ok;\n } catch {\n return false;\n }\n }\n\n async listModels(): Promise<OllamaModelInfo[]> {\n try {\n const response = await fetch(new URL(\"/api/tags\", this.host), {\n method: \"GET\"\n });\n\n if (!response.ok) {\n throw new OllamaUnavailableError(`Ollama tags request failed with status ${response.status}.`);\n }\n\n const data = (await response.json()) as {\n models?: Array<{\n name?: string;\n size?: number;\n modified_at?: string;\n details?: {\n family?: string;\n parameter_size?: string;\n };\n }>;\n };\n\n return (data.models ?? [])\n .filter((model) => typeof model.name === \"string\" && model.name.length > 0)\n .map((model) => ({\n name: model.name as string,\n sizeBytes: model.size,\n family: model.details?.family,\n parameterSize: model.details?.parameter_size,\n modifiedAt: model.modified_at\n }));\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Unknown Ollama tags error.\";\n this.logger.warn(\"ollama.list_models.failed\", { message });\n throw new OllamaUnavailableError(message);\n }\n }\n\n async generate(options: OllamaGenerateOptions): Promise<string> {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), options.timeoutMs ?? this.timeoutMs);\n\n try {\n const response = await fetch(new URL(\"/api/generate\", this.host), {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\"\n },\n body: JSON.stringify({\n model: options.model ?? this.model,\n system: options.systemPrompt,\n prompt: options.prompt,\n stream: false,\n format: options.format === \"json\" ? \"json\" : undefined,\n options: {\n temperature: options.temperature ?? this.temperature\n }\n }),\n signal: controller.signal\n });\n\n if (!response.ok) {\n throw new OllamaUnavailableError(`Ollama request failed with status ${response.status}.`);\n }\n\n const data = (await response.json()) as { response?: string };\n if (!data.response || typeof data.response !== \"string\") {\n throw new OllamaUnavailableError(\"Ollama did not return a text response.\");\n }\n\n return data.response.trim();\n } catch (error) {\n if (error instanceof OllamaUnavailableError) {\n throw error;\n }\n\n const message = error instanceof Error ? error.message : \"Unknown Ollama error.\";\n this.logger.warn(\"ollama.generate.failed\", { message });\n throw new OllamaUnavailableError(message);\n } finally {\n clearTimeout(timeout);\n }\n }\n\n async generateJson<T>(options: OllamaGenerateOptions): Promise<T> {\n const raw = await this.generate({\n ...options,\n format: \"json\"\n });\n\n const direct = safeJsonParse<T>(raw);\n if (direct) {\n return direct;\n }\n\n const extracted = extractFirstJsonObject(raw);\n if (extracted) {\n const parsed = safeJsonParse<T>(extracted);\n if (parsed) {\n return parsed;\n }\n }\n\n throw new OllamaUnavailableError(\"Ollama returned JSON that could not be parsed.\");\n }\n}\n","import type { OptimizationMode, OptimizePromptInput, PromptPreset } from \"../types.js\";\n\nconst modeGuidance: Record<OptimizationMode, string> = {\n clarity: \"Improve clarity, remove ambiguity, and keep the request easy for a downstream model to follow.\",\n concise: \"Minimize token count while preserving user intent, constraints, and expected output.\",\n detailed: \"Make the request explicit and complete, including structure and success criteria.\",\n structured: \"Organize the request into clean sections with compact headings and bullet points where helpful.\",\n persuasive: \"Refine wording so the request is compelling and likely to elicit a thoughtful response.\",\n compress: \"Aggressively compress redundant wording while preserving the meaning and critical constraints.\",\n claude_cli: \"Optimize specifically for Claude CLI: compact sections, direct instructions, and minimal boilerplate.\"\n};\n\nconst presetGuidance: Record<PromptPreset, string> = {\n code: \"Favor precise technical requirements, edge cases, and expected output format for code tasks.\",\n email: \"Preserve the sender's goal, tone, and audience; aim for a realistic and usable writing request.\",\n essay: \"Preserve thesis, structure, and voice guidance while making the prompt clearer.\",\n support: \"Favor concise issue context, user impact, and desired resolution details.\",\n summarization: \"Favor strong compression while retaining key facts, structure, and takeaways.\",\n chat: \"Keep the prompt natural and conversational while preserving instructions and context.\"\n};\n\nexport function getOptimizationSystemPrompt(mode: OptimizationMode, preset?: PromptPreset): string {\n return [\n \"You are PromptPilot, a local prompt optimizer for downstream LLM workflows.\",\n \"Return strict JSON only with this shape:\",\n \"{\\\"optimizedPrompt\\\":\\\"string\\\",\\\"constraints\\\":[\\\"string\\\"],\\\"changes\\\":[\\\"string\\\"],\\\"warnings\\\":[\\\"string\\\"]}\",\n \"Rules:\",\n \"- Do not change the user's intent.\",\n \"- Do not invent new requirements.\",\n \"- Preserve critical constraints and task goals.\",\n \"- Improve clarity, structure, and downstream usefulness.\",\n \"- Keep the result compact when the mode requests compression.\",\n `Mode guidance: ${modeGuidance[mode]}`,\n preset ? `Preset guidance: ${presetGuidance[preset]}` : \"Preset guidance: none\"\n ].join(\"\\n\");\n}\n\nexport function buildOptimizationPrompt(\n input: OptimizePromptInput,\n relevantContext: string,\n extractedConstraints: string[]\n): string {\n const payload = {\n prompt: input.prompt,\n task: input.task ?? null,\n tone: input.tone ?? null,\n targetModel: input.targetModel ?? \"claude\",\n outputFormat: input.outputFormat ?? null,\n maxLength: input.maxLength ?? null,\n mode: input.mode ?? \"claude_cli\",\n preset: input.preset ?? null,\n pinnedConstraints: input.pinnedConstraints ?? [],\n extractedConstraints,\n relevantContext\n };\n\n return `Optimize this prompt payload for a downstream LLM.\\n${JSON.stringify(payload, null, 2)}`;\n}\n","import type { TokenUsageEstimate } from \"../types.js\";\nimport { normalizeWhitespace } from \"../utils/validation.js\";\n\nexport class TokenEstimator {\n estimateText(text: string): number {\n const normalized = normalizeWhitespace(text);\n if (!normalized) {\n return 0;\n }\n\n const wordCount = normalized.split(/\\s+/).length;\n const charCount = normalized.length;\n return Math.max(1, Math.ceil(wordCount * 1.3), Math.ceil(charCount / 4));\n }\n\n estimateUsage(input: { prompt: string; context?: string }): TokenUsageEstimate {\n const prompt = this.estimateText(input.prompt);\n const context = this.estimateText(input.context ?? \"\");\n return {\n prompt,\n context,\n total: prompt + context\n };\n }\n\n truncateToBudget(text: string, tokenBudget: number): string {\n const normalized = normalizeWhitespace(text);\n if (tokenBudget <= 0 || !normalized) {\n return \"\";\n }\n\n if (this.estimateText(normalized) <= tokenBudget) {\n return normalized;\n }\n\n const words = normalized.split(/\\s+/);\n const selected: string[] = [];\n\n for (const word of words) {\n const candidate = [...selected, word].join(\" \");\n if (this.estimateText(candidate) > tokenBudget) {\n break;\n }\n\n selected.push(word);\n }\n\n return selected.join(\" \").trim();\n }\n}\n","import { randomUUID } from \"node:crypto\";\n\nimport type { ContextEntry, ContextSummary, Logger, OllamaClientLike } from \"../types.js\";\nimport { TokenEstimator } from \"./tokenEstimator.js\";\nimport { getOptimizationSystemPrompt } from \"./systemPrompt.js\";\nimport { noopLogger } from \"../utils/logger.js\";\n\ninterface SummarizeContextOptions {\n sessionId: string;\n entries: ContextEntry[];\n prompt: string;\n task?: string;\n budgetTokens: number;\n timeoutMs?: number;\n}\n\ninterface ContextSummaryJson {\n optimizedPrompt: string;\n constraints?: string[];\n changes?: string[];\n}\n\nexport class ContextCompressor {\n constructor(\n private readonly estimator: TokenEstimator,\n private readonly client?: OllamaClientLike,\n private readonly logger: Logger = noopLogger\n ) {}\n\n async summarizeEntries(options: SummarizeContextOptions): Promise<ContextSummary | null> {\n if (options.entries.length === 0 || options.budgetTokens <= 0) {\n return null;\n }\n\n const ollamaSummary = await this.tryOllamaSummary(options);\n if (ollamaSummary) {\n return ollamaSummary;\n }\n\n return this.heuristicSummary(options);\n }\n\n private async tryOllamaSummary(options: SummarizeContextOptions): Promise<ContextSummary | null> {\n if (!this.client || options.entries.length < 3) {\n return null;\n }\n\n try {\n const source = options.entries\n .slice(-8)\n .map((entry) => [\n `Timestamp: ${entry.timestamp}`,\n entry.task ? `Task: ${entry.task}` : \"\",\n entry.constraints?.length ? `Constraints: ${entry.constraints.join(\"; \")}` : \"\",\n `Prompt: ${entry.rawPrompt ?? entry.text}`\n ].filter(Boolean).join(\"\\n\"))\n .join(\"\\n\\n\");\n\n const response = await this.client.generateJson<ContextSummaryJson>({\n systemPrompt: getOptimizationSystemPrompt(\"compress\"),\n prompt: `Summarize this stored prompt context for reuse in later turns.\\nPrompt: ${options.prompt}\\nTask: ${options.task ?? \"unknown\"}\\nBudget tokens: ${options.budgetTokens}\\n\\n${source}`,\n timeoutMs: options.timeoutMs,\n format: \"json\"\n });\n\n const summaryText = this.estimator.truncateToBudget(response.optimizedPrompt ?? \"\", options.budgetTokens);\n if (!summaryText) {\n return null;\n }\n\n return {\n id: randomUUID(),\n sessionId: options.sessionId,\n text: summaryText,\n createdAt: new Date().toISOString(),\n sourceEntryIds: options.entries.map((entry) => entry.id),\n tokenEstimate: this.estimator.estimateText(summaryText),\n kind: \"ollama\"\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Unknown summary failure\";\n this.logger.debug(\"context.summary.ollama_fallback\", { message });\n return null;\n }\n }\n\n private heuristicSummary(options: SummarizeContextOptions): ContextSummary {\n const constraints = Array.from(\n new Set(options.entries.flatMap((entry) => entry.constraints ?? []).filter(Boolean))\n ).slice(0, 6);\n\n const recentPrompts = options.entries\n .slice(-4)\n .map((entry) => `- ${truncateLine(entry.rawPrompt ?? entry.text, 120)}`);\n\n const lines = [\n constraints.length ? `Key constraints: ${constraints.join(\"; \")}` : \"\",\n recentPrompts.length ? `Recent focus:\\n${recentPrompts.join(\"\\n\")}` : \"\"\n ].filter(Boolean);\n\n const summaryText = this.estimator.truncateToBudget(lines.join(\"\\n\\n\"), options.budgetTokens);\n\n return {\n id: randomUUID(),\n sessionId: options.sessionId,\n text: summaryText,\n createdAt: new Date().toISOString(),\n sourceEntryIds: options.entries.map((entry) => entry.id),\n tokenEstimate: this.estimator.estimateText(summaryText),\n kind: \"heuristic\"\n };\n }\n}\n\nfunction truncateLine(value: string, maxLength: number): string {\n if (value.length <= maxLength) {\n return value;\n }\n\n return `${value.slice(0, maxLength - 3).trim()}...`;\n}\n","import { randomUUID } from \"node:crypto\";\n\nimport type {\n ContextEntry,\n ContextSummary,\n Logger,\n OptimizePromptInput,\n RelevantContextResult,\n SessionStore\n} from \"../types.js\";\nimport { TokenEstimator } from \"./tokenEstimator.js\";\nimport { ContextCompressor } from \"./contextCompressor.js\";\nimport { noopLogger } from \"../utils/logger.js\";\n\ninterface GetRelevantContextOptions {\n sessionId: string;\n prompt: string;\n task?: string;\n tags?: string[];\n pinnedConstraints?: string[];\n maxContextTokens: number;\n timeoutMs?: number;\n}\n\ninterface SaveContextOptions {\n sessionId: string;\n input: OptimizePromptInput;\n optimizedPrompt: string;\n finalPrompt: string;\n contextSummary: ContextSummary | null;\n}\n\nexport class ContextManager {\n constructor(\n private readonly store: SessionStore,\n private readonly estimator: TokenEstimator,\n private readonly compressor: ContextCompressor,\n private readonly logger: Logger = noopLogger\n ) {}\n\n async loadContext(sessionId: string) {\n return this.store.loadSession(sessionId);\n }\n\n async clearContext(sessionId: string): Promise<void> {\n await this.store.clearSession(sessionId);\n }\n\n async saveContext(options: SaveContextOptions): Promise<void> {\n const session = await this.store.loadSession(options.sessionId);\n const timestamp = new Date().toISOString();\n const constraints = Array.from(\n new Set([\n ...extractConstraints(options.input.prompt),\n ...(options.input.pinnedConstraints ?? [])\n ])\n );\n const entry: ContextEntry = {\n id: randomUUID(),\n sessionId: options.sessionId,\n text: options.optimizedPrompt,\n rawPrompt: options.input.prompt,\n optimizedPrompt: options.optimizedPrompt,\n finalPrompt: options.finalPrompt,\n task: options.input.task,\n tone: options.input.tone,\n tags: options.input.tags ?? [],\n constraints,\n entities: extractEntities(options.input.prompt),\n pinned: (options.input.pinnedConstraints?.length ?? 0) > 0,\n timestamp,\n tokenEstimate: this.estimator.estimateText(options.finalPrompt)\n };\n\n session.entries.push(entry);\n if (session.entries.length > 100) {\n session.entries = session.entries.slice(-100);\n }\n\n if (options.contextSummary) {\n session.summaries.push(options.contextSummary);\n if (session.summaries.length > 10) {\n session.summaries = session.summaries.slice(-10);\n }\n }\n\n session.updatedAt = timestamp;\n await this.store.saveSession(session);\n }\n\n async summarizeContext(\n sessionId: string,\n prompt: string,\n task: string | undefined,\n budgetTokens: number,\n timeoutMs?: number\n ): Promise<ContextSummary | null> {\n const session = await this.store.loadSession(sessionId);\n if (session.entries.length === 0) {\n return null;\n }\n\n return this.compressor.summarizeEntries({\n sessionId,\n entries: session.entries,\n prompt,\n task,\n budgetTokens,\n timeoutMs\n });\n }\n\n async getRelevantContext(options: GetRelevantContextOptions): Promise<RelevantContextResult> {\n const session = await this.store.loadSession(options.sessionId);\n if (session.entries.length === 0 && session.summaries.length === 0) {\n return {\n usedEntries: [],\n summary: null,\n warnings: [],\n debugInfo: { scores: [] }\n };\n }\n\n const scores = session.entries.map((entry, index) => ({\n entry,\n score: scoreEntry({\n entry,\n prompt: options.prompt,\n task: options.task,\n tags: options.tags,\n pinnedConstraints: options.pinnedConstraints,\n index,\n total: session.entries.length\n })\n }));\n\n const selected: ContextEntry[] = [];\n const seenFingerprints = new Set<string>();\n let selectedTokens = 0;\n\n for (const scored of scores.sort((left, right) => right.score - left.score)) {\n if (selected.find((entry) => entry.id === scored.entry.id)) {\n continue;\n }\n\n const fingerprint = createFingerprint(scored.entry);\n if (seenFingerprints.has(fingerprint)) {\n continue;\n }\n\n if (selectedTokens + scored.entry.tokenEstimate > options.maxContextTokens) {\n continue;\n }\n\n selected.push(scored.entry);\n seenFingerprints.add(fingerprint);\n selectedTokens += scored.entry.tokenEstimate;\n }\n\n const remainder = session.entries.filter(\n (entry) => !selected.find((selectedEntry) => selectedEntry.id === entry.id)\n );\n\n let summary: ContextSummary | null = null;\n if (remainder.length > 1 && selectedTokens < Math.floor(options.maxContextTokens * 0.8)) {\n summary = await this.compressor.summarizeEntries({\n sessionId: options.sessionId,\n entries: remainder,\n prompt: options.prompt,\n task: options.task,\n budgetTokens: Math.max(80, options.maxContextTokens - selectedTokens),\n timeoutMs: options.timeoutMs\n });\n } else if (session.summaries.length > 0) {\n const latest = session.summaries.at(-1) ?? null;\n if (latest && latest.tokenEstimate <= options.maxContextTokens - selectedTokens) {\n summary = latest;\n }\n }\n\n const warnings: string[] = [];\n if (remainder.length > 0) {\n warnings.push(`Dropped ${remainder.length} lower-value context item(s) to fit the token budget.`);\n }\n\n return {\n usedEntries: selected.sort((left, right) => left.timestamp.localeCompare(right.timestamp)),\n summary,\n warnings,\n debugInfo: {\n scores: scores\n .sort((left, right) => right.score - left.score)\n .map(({ entry, score }) => ({ id: entry.id, score, task: entry.task, timestamp: entry.timestamp }))\n }\n };\n }\n}\n\nfunction scoreEntry(input: {\n entry: ContextEntry;\n prompt: string;\n task?: string;\n tags?: string[];\n pinnedConstraints?: string[];\n index: number;\n total: number;\n}): number {\n const promptTerms = tokenize(input.prompt);\n const promptEntities = new Set(extractEntities(input.prompt).map((entity) => entity.toLowerCase()));\n const entryTerms = tokenize(\n [input.entry.rawPrompt, input.entry.optimizedPrompt, input.entry.constraints?.join(\" \")].filter(Boolean).join(\" \")\n );\n const entryEntities = new Set((input.entry.entities ?? []).map((entity) => entity.toLowerCase()));\n\n const overlap = Array.from(promptTerms).filter((term) => entryTerms.has(term)).length;\n const entityOverlap = Array.from(promptEntities).filter((entity) => entryEntities.has(entity)).length;\n const taskMatch = input.task && input.entry.task === input.task ? 2 : 0;\n const pinned = input.entry.pinned ? 3 : 0;\n const pinnedConstraintMatch = Array.from(new Set(input.pinnedConstraints ?? [])).filter((constraint) =>\n (input.entry.constraints ?? []).includes(constraint)\n ).length;\n const tagOverlap = Array.from(new Set(input.tags ?? [])).filter((tag) => (input.entry.tags ?? []).includes(tag)).length;\n const constraintBonus = (input.entry.constraints?.length ?? 0) > 0 ? 0.75 : 0;\n const recency = (input.index + 1) / input.total;\n\n return overlap * 0.8 + entityOverlap * 1.2 + taskMatch + pinned + pinnedConstraintMatch * 2 + tagOverlap + constraintBonus + recency;\n}\n\nfunction tokenize(value: string): Set<string> {\n return new Set(\n value\n .toLowerCase()\n .split(/[^a-z0-9]+/i)\n .filter((token) => token.length > 2)\n );\n}\n\nexport function extractConstraints(value: string): string[] {\n return value\n .split(/\\n+/)\n .map((line) => line.trim())\n .filter((line) => /(must|should|avoid|do not|don't|never|exactly|at most|under|limit|max)/i.test(line))\n .slice(0, 8);\n}\n\nexport function extractEntities(value: string): string[] {\n return Array.from(\n new Set(value.match(/\\b[A-Z][a-zA-Z0-9._-]+\\b/g) ?? [])\n ).slice(0, 12);\n}\n\nfunction createFingerprint(entry: ContextEntry): string {\n return [entry.task ?? \"\", entry.rawPrompt ?? entry.text]\n .join(\"::\")\n .toLowerCase()\n .replace(/\\s+/g, \" \")\n .trim();\n}\n","import type { OllamaModelInfo, OptimizationMode, PromptPreset } from \"../types.js\";\n\nconst DEFAULT_SMALL_MODEL_PREFERENCES = [\n \"qwen2.5:3b\",\n \"phi3:mini\",\n \"llama3.2:3b\",\n \"qwen2.5:1.5b\"\n];\n\nexport interface ModelSelectionInput {\n installedModels: OllamaModelInfo[];\n mode: OptimizationMode;\n preset: PromptPreset;\n task?: string;\n preferredModels?: string[];\n}\n\nexport interface ModelSelectionResult {\n model: string;\n reason: string;\n suitableForAutoUse: boolean;\n}\n\nexport function getDefaultPreferredModels(): string[] {\n return [...DEFAULT_SMALL_MODEL_PREFERENCES];\n}\n\nexport function selectOllamaModel(input: ModelSelectionInput): ModelSelectionResult {\n const preferred = buildPreferredOrder(input);\n const smallCandidates = input.installedModels.filter((model) => isSuitableSmallModel(model));\n const preferredMatch = findPreferredMatch(smallCandidates, preferred);\n if (preferredMatch) {\n return {\n model: preferredMatch,\n reason: `Selected installed model \"${preferredMatch}\" from the preferred low-memory order.`,\n suitableForAutoUse: true\n };\n }\n\n const ranked = [...smallCandidates]\n .filter((model) => isUsefulGenerationModel(model.name))\n .map((model) => ({ model, score: scoreModel(model.name, input.preset, input.mode, input.task) }))\n .sort((left, right) => right.score - left.score);\n\n if (ranked[0]) {\n return {\n model: ranked[0].model.name,\n reason: `Selected installed model \"${ranked[0].model.name}\" using task-aware ranking.`,\n suitableForAutoUse: true\n };\n }\n\n const oversizedRanked = [...input.installedModels]\n .filter((model) => isUsefulGenerationModel(model.name))\n .map((model) => ({ model, score: scoreModel(model.name, input.preset, input.mode, input.task) }))\n .sort((left, right) => right.score - left.score);\n\n if (oversizedRanked[0]) {\n return {\n model: oversizedRanked[0].model.name,\n reason: `Installed model \"${oversizedRanked[0].model.name}\" was detected, but it is larger than the preferred low-memory range for auto-use.`,\n suitableForAutoUse: false\n };\n }\n\n return {\n model: preferred[0] ?? \"qwen2.5:3b\",\n reason: \"No installed Ollama models were discovered, so the default small-model preference was used.\",\n suitableForAutoUse: false\n };\n}\n\nfunction buildPreferredOrder(input: ModelSelectionInput): string[] {\n const taskContext = `${input.task ?? \"\"} ${input.preset} ${input.mode}`.toLowerCase();\n const configured = (input.preferredModels ?? []).map((model) => model.toLowerCase());\n\n if (taskContext.includes(\"code\")) {\n return uniqueModels([\n ...configured,\n \"qwen2.5-coder:3b\",\n \"qwen2.5:3b\",\n \"phi3:mini\",\n \"llama3.2:3b\",\n \"qwen2.5:1.5b\"\n ]);\n }\n\n if (taskContext.includes(\"compress\") || taskContext.includes(\"summar\")) {\n return uniqueModels([\n ...configured,\n \"qwen2.5:3b\",\n \"qwen2.5:1.5b\",\n \"phi3:mini\",\n \"llama3.2:3b\"\n ]);\n }\n\n return uniqueModels([...configured, ...DEFAULT_SMALL_MODEL_PREFERENCES]);\n}\n\nfunction uniqueModels(models: string[]): string[] {\n return Array.from(new Set(models));\n}\n\nfunction findPreferredMatch(installedModels: OllamaModelInfo[], preferred: string[]): string | null {\n const installedNames = installedModels.map((model) => model.name);\n\n for (const preferredName of preferred) {\n const direct = installedNames.find((name) => name.toLowerCase() === preferredName);\n if (direct) {\n return direct;\n }\n }\n\n return null;\n}\n\nfunction scoreModel(modelName: string, preset: PromptPreset, mode: OptimizationMode, task?: string): number {\n const lower = modelName.toLowerCase();\n let score = 0;\n\n if (!isUsefulGenerationModel(lower)) {\n return -100;\n }\n\n if (lower.includes(\"qwen2.5\")) {\n score += 4;\n } else if (lower.includes(\"phi3\")) {\n score += 3.5;\n } else if (lower.includes(\"llama3.2\")) {\n score += 3;\n } else if (lower.includes(\"mistral\")) {\n score += 2;\n }\n\n const parameterSize = extractBillions(lower);\n if (parameterSize !== null) {\n if (parameterSize <= 4) {\n score += 4;\n } else if (parameterSize <= 8) {\n score += 1;\n } else {\n score -= 4;\n }\n }\n\n if (lower.includes(\"mini\")) {\n score += 2;\n }\n\n if (lower.includes(\"instruct\") || lower.includes(\"chat\")) {\n score += 1;\n }\n\n const taskContext = `${task ?? \"\"} ${preset} ${mode}`.toLowerCase();\n if (taskContext.includes(\"code\") && lower.includes(\"coder\")) {\n score += 3;\n }\n\n if ((taskContext.includes(\"compress\") || taskContext.includes(\"summar\")) && lower.includes(\"qwen2.5\")) {\n score += 1;\n }\n\n return score;\n}\n\nfunction extractBillions(modelName: string): number | null {\n const match = modelName.match(/(\\d+(?:\\.\\d+)?)b/);\n if (!match) {\n return null;\n }\n\n return Number.parseFloat(match[1]);\n}\n\nfunction isUsefulGenerationModel(modelName: string): boolean {\n const lower = modelName.toLowerCase();\n return ![\n \"embed\",\n \"embedding\",\n \"whisper\",\n \"vision\",\n \"diffusion\",\n \"tts\",\n \"bge\",\n \"nomic-embed\"\n ].some((blocked) => lower.includes(blocked));\n}\n\nfunction isSuitableSmallModel(model: OllamaModelInfo): boolean {\n if (!isUsefulGenerationModel(model.name)) {\n return false;\n }\n\n const byParameter = extractBillions(`${model.parameterSize ?? \"\"} ${model.name}`);\n if (byParameter !== null) {\n return byParameter <= 4;\n }\n\n if (typeof model.sizeBytes === \"number\") {\n return model.sizeBytes <= 5_500_000_000;\n }\n\n return /mini|1\\.5b|2b|3b|4b/i.test(model.name);\n}\n","import type {\n ContextEntry,\n ContextSummary,\n OptimizationMode,\n OptimizePromptInput,\n OptimizePromptResult,\n OptimizerConfig,\n PromptPreset,\n ProviderType,\n RelevantContextResult,\n SessionStore\n} from \"../types.js\";\nimport { TokenBudgetExceededError } from \"../errors.js\";\nimport { FileSessionStore } from \"../storage/fileSessionStore.js\";\nimport { SQLiteSessionStore } from \"../storage/sqliteSessionStore.js\";\nimport { createLogger, noopLogger } from \"../utils/logger.js\";\nimport { normalizeWhitespace, validatePrompt } from \"../utils/validation.js\";\nimport { OllamaClient } from \"./ollamaClient.js\";\nimport { getOptimizationSystemPrompt, buildOptimizationPrompt } from \"./systemPrompt.js\";\nimport { TokenEstimator } from \"./tokenEstimator.js\";\nimport { ContextCompressor } from \"./contextCompressor.js\";\nimport { ContextManager, extractConstraints } from \"./contextManager.js\";\nimport { getDefaultPreferredModels, selectOllamaModel } from \"./modelSelector.js\";\n\ninterface OptimizationResponse {\n optimizedPrompt?: string;\n constraints?: string[];\n changes?: string[];\n warnings?: string[];\n}\n\nconst DEFAULT_MODE: OptimizationMode = \"claude_cli\";\nconst DEFAULT_PRESET: PromptPreset = \"chat\";\nconst DEFAULT_PROVIDER: ProviderType = \"ollama\";\nconst DEFAULT_MAX_INPUT_TOKENS = 1200;\nconst DEFAULT_MAX_CONTEXT_TOKENS = 800;\nconst DEFAULT_MAX_TOTAL_TOKENS = 2200;\n\nexport class PromptOptimizer {\n readonly config: OptimizerConfig & {\n host: string;\n timeoutMs: number;\n temperature: number;\n preferredModels: string[];\n };\n\n private readonly logger;\n private readonly estimator;\n private readonly client;\n private readonly compressor;\n private readonly contextManager;\n\n constructor(config: OptimizerConfig = {}) {\n this.logger = config.logger ?? noopLogger;\n this.estimator = new TokenEstimator();\n this.client =\n config.ollamaClient ??\n new OllamaClient({\n host: config.host,\n model: config.ollamaModel,\n timeoutMs: config.timeoutMs,\n temperature: config.temperature,\n logger: this.logger\n });\n\n const store = resolveSessionStore(config);\n this.compressor = new ContextCompressor(this.estimator, this.client, this.logger);\n this.contextManager = new ContextManager(store, this.estimator, this.compressor, this.logger);\n\n this.config = {\n ...config,\n host: config.host ?? \"http://localhost:11434\",\n ollamaModel: config.ollamaModel,\n preferredModels: config.preferredModels ?? getDefaultPreferredModels(),\n timeoutMs: config.timeoutMs ?? 30000,\n temperature: config.temperature ?? 0.1\n };\n }\n\n async optimize(input: OptimizePromptInput): Promise<OptimizePromptResult> {\n const originalPrompt = validatePrompt(input.prompt);\n const mode = input.mode ?? this.config.defaultMode ?? DEFAULT_MODE;\n const preset = input.preset ?? this.config.defaultPreset ?? DEFAULT_PRESET;\n const maxInputTokens = input.maxInputTokens ?? this.config.maxInputTokens ?? DEFAULT_MAX_INPUT_TOKENS;\n const maxContextTokens = input.maxContextTokens ?? this.config.maxContextTokens ?? DEFAULT_MAX_CONTEXT_TOKENS;\n const maxTotalTokens = input.maxTotalTokens ?? this.config.maxTotalTokens ?? DEFAULT_MAX_TOTAL_TOKENS;\n const warnings: string[] = [];\n const changes: string[] = [];\n\n const useContext = input.useContext !== false && Boolean(input.sessionId);\n const saveContext = input.saveContext ?? Boolean(input.sessionId);\n const relevantContext = useContext && input.sessionId\n ? await this.contextManager.getRelevantContext({\n sessionId: input.sessionId,\n prompt: originalPrompt,\n task: input.task,\n tags: input.tags,\n pinnedConstraints: input.pinnedConstraints,\n maxContextTokens,\n timeoutMs: input.timeoutMs ?? this.config.timeoutMs\n })\n : emptyRelevantContext();\n\n warnings.push(...relevantContext.warnings);\n\n const contextBlock = formatContextBlock(relevantContext);\n const estimatedTokensBefore = this.estimator.estimateUsage({\n prompt: originalPrompt,\n context: contextBlock\n });\n\n if (estimatedTokensBefore.prompt > maxInputTokens) {\n warnings.push(\n `Raw prompt estimate (${estimatedTokensBefore.prompt}) exceeds maxInputTokens (${maxInputTokens}).`\n );\n }\n\n const extractedConstraints = Array.from(\n new Set([...extractConstraints(originalPrompt), ...(input.pinnedConstraints ?? [])])\n );\n\n let provider: ProviderType = input.bypassOptimization ? \"heuristic\" : this.config.provider ?? DEFAULT_PROVIDER;\n let model = provider === \"ollama\" ? this.config.ollamaModel ?? \"auto\" : \"heuristic\";\n\n let optimizedPrompt = originalPrompt;\n let providerWarnings: string[] = [];\n let providerChanges: string[] = [];\n\n if (provider === \"ollama\") {\n const modelSelection = await this.resolveOllamaModel({\n mode,\n preset,\n task: input.task\n });\n model = modelSelection.model;\n providerWarnings.push(...modelSelection.warnings);\n if (input.debug) {\n changes.push(modelSelection.reason);\n }\n\n if (modelSelection.forceHeuristic) {\n provider = \"heuristic\";\n model = \"heuristic\";\n }\n\n const ollamaResult = provider === \"ollama\"\n ? await this.tryOllamaOptimization({\n input: {\n ...input,\n prompt: originalPrompt,\n mode,\n preset\n },\n model,\n extractedConstraints,\n relevantContext: contextBlock\n })\n : null;\n\n if (ollamaResult) {\n optimizedPrompt = ollamaResult.optimizedPrompt;\n providerWarnings = ollamaResult.warnings;\n providerChanges = ollamaResult.changes;\n } else if (provider === \"ollama\") {\n provider = \"heuristic\";\n model = \"heuristic\";\n providerWarnings = [\n `Ollama was unavailable. Falling back to deterministic local prompt shaping.`\n ];\n }\n }\n\n if (provider === \"heuristic\") {\n const fallback = this.heuristicOptimize({\n input: {\n ...input,\n prompt: originalPrompt,\n mode,\n preset\n },\n context: relevantContext,\n constraints: extractedConstraints\n });\n optimizedPrompt = fallback.optimizedPrompt;\n providerChanges = [...providerChanges, ...fallback.changes];\n providerWarnings = [...providerWarnings, ...fallback.warnings];\n }\n\n warnings.push(...providerWarnings);\n changes.push(...providerChanges);\n\n let finalPrompt = composeFinalPrompt({\n optimizedPrompt,\n input: {\n ...input,\n prompt: originalPrompt,\n mode,\n preset\n },\n context: relevantContext\n });\n\n let estimatedTokensAfter = {\n prompt: this.estimator.estimateText(optimizedPrompt),\n context: this.estimator.estimateText(formatContextBlock(relevantContext)),\n total: this.estimator.estimateText(finalPrompt)\n };\n\n if (estimatedTokensAfter.total > maxTotalTokens) {\n const reduced = await this.reduceToBudget({\n input: {\n ...input,\n prompt: originalPrompt,\n mode,\n preset\n },\n optimizedPrompt,\n context: relevantContext,\n maxTotalTokens\n });\n\n finalPrompt = reduced.finalPrompt;\n estimatedTokensAfter = reduced.estimatedTokensAfter;\n if (reduced.warning) {\n warnings.push(reduced.warning);\n }\n }\n\n if (estimatedTokensAfter.total > maxTotalTokens) {\n throw new TokenBudgetExceededError();\n }\n\n if (saveContext && input.sessionId) {\n await this.contextManager.saveContext({\n sessionId: input.sessionId,\n input: {\n ...input,\n prompt: originalPrompt\n },\n optimizedPrompt,\n finalPrompt,\n contextSummary: relevantContext.summary\n });\n }\n\n return {\n originalPrompt,\n optimizedPrompt,\n finalPrompt,\n usedContext: relevantContext.usedEntries,\n contextSummary: relevantContext.summary,\n estimatedTokensBefore,\n estimatedTokensAfter,\n tokenSavings: Math.max(0, estimatedTokensBefore.total - estimatedTokensAfter.total),\n mode,\n provider,\n model,\n warnings,\n changes,\n debugInfo: input.debug\n ? {\n context: relevantContext.debugInfo,\n estimatedTokensBefore,\n estimatedTokensAfter,\n extractedConstraints,\n preset,\n selectedModel: model\n }\n : undefined\n };\n }\n\n async clearContext(sessionId: string): Promise<void> {\n await this.contextManager.clearContext(sessionId);\n }\n\n async loadContext(sessionId: string) {\n return this.contextManager.loadContext(sessionId);\n }\n\n async summarizeContext(sessionId: string, prompt: string, task?: string, budgetTokens = 200) {\n return this.contextManager.summarizeContext(sessionId, prompt, task, budgetTokens, this.config.timeoutMs);\n }\n\n async getRelevantContext(sessionId: string, prompt: string, task?: string, maxContextTokens?: number) {\n return this.contextManager.getRelevantContext({\n sessionId,\n prompt,\n task,\n maxContextTokens: maxContextTokens ?? this.config.maxContextTokens ?? DEFAULT_MAX_CONTEXT_TOKENS,\n timeoutMs: this.config.timeoutMs\n });\n }\n\n private async tryOllamaOptimization(options: {\n input: OptimizePromptInput & { mode: OptimizationMode; preset: PromptPreset };\n model: string;\n extractedConstraints: string[];\n relevantContext: string;\n }): Promise<{ optimizedPrompt: string; changes: string[]; warnings: string[] } | null> {\n try {\n if (!(await this.client.isAvailable())) {\n return null;\n }\n\n const response = await this.client.generateJson<OptimizationResponse>({\n systemPrompt: getOptimizationSystemPrompt(options.input.mode, options.input.preset),\n prompt: buildOptimizationPrompt(options.input, options.relevantContext, options.extractedConstraints),\n timeoutMs: options.input.timeoutMs ?? this.config.timeoutMs,\n model: options.model,\n temperature: this.config.temperature,\n format: \"json\"\n });\n\n const optimizedPrompt = normalizeWhitespace(response.optimizedPrompt ?? \"\");\n if (!optimizedPrompt) {\n return null;\n }\n\n return {\n optimizedPrompt,\n changes: response.changes ?? [`Applied Ollama optimization with ${options.model}.`],\n warnings: response.warnings ?? []\n };\n } catch {\n return null;\n }\n }\n\n private async resolveOllamaModel(options: {\n mode: OptimizationMode;\n preset: PromptPreset;\n task?: string;\n }): Promise<{ model: string; warnings: string[]; reason: string; forceHeuristic: boolean }> {\n if (this.config.ollamaModel) {\n return {\n model: this.config.ollamaModel,\n warnings: [],\n reason: `Using explicitly configured model \"${this.config.ollamaModel}\".`,\n forceHeuristic: false\n };\n }\n\n if (!this.client.listModels) {\n const fallback = this.config.preferredModels[0] ?? \"qwen2.5:3b\";\n return {\n model: fallback,\n warnings: [`Model auto-selection is unavailable in the current Ollama client, so \"${fallback}\" was assumed.`],\n reason: `Assumed default model \"${fallback}\" because model discovery is unsupported.`,\n forceHeuristic: false\n };\n }\n\n try {\n const installedModels = await this.client.listModels();\n const selection = selectOllamaModel({\n installedModels,\n mode: options.mode,\n preset: options.preset,\n task: options.task,\n preferredModels: this.config.preferredModels\n });\n\n if (!selection.suitableForAutoUse) {\n return {\n model: selection.model,\n warnings: [\n `No suitable small Ollama model was found for auto-use. Falling back to heuristic optimization. Install one of: ${this.config.preferredModels.join(\", \")}.`,\n selection.reason\n ],\n reason: selection.reason,\n forceHeuristic: true\n };\n }\n\n return {\n model: selection.model,\n warnings: installedModels.length === 0\n ? [`No installed Ollama models were reported, so \"${selection.model}\" was chosen as the default preference.`]\n : [],\n reason: selection.reason,\n forceHeuristic: false\n };\n } catch {\n const fallback = this.config.preferredModels[0] ?? \"qwen2.5:3b\";\n return {\n model: fallback,\n warnings: [`Failed to inspect local Ollama models, so \"${fallback}\" was chosen as the default preference.`],\n reason: `Fell back to default model \"${fallback}\" because model discovery failed.`,\n forceHeuristic: false\n };\n }\n }\n\n private heuristicOptimize(options: {\n input: OptimizePromptInput & { mode: OptimizationMode; preset: PromptPreset };\n context: RelevantContextResult;\n constraints: string[];\n }): { optimizedPrompt: string; changes: string[]; warnings: string[] } {\n const lines = [\n `Request: ${options.input.prompt}`,\n options.input.task ? `Task type: ${options.input.task}` : \"\",\n options.input.tone ? `Tone: ${options.input.tone}` : \"\",\n options.input.outputFormat ? `Output format: ${options.input.outputFormat}` : \"\",\n options.input.maxLength ? `Maximum length: ${options.input.maxLength}` : \"\",\n options.constraints.length ? `Critical constraints: ${options.constraints.join(\"; \")}` : \"\"\n ].filter(Boolean);\n\n const optimizedPrompt = lines.join(\"\\n\");\n const changes = [\"Normalized prompt structure for downstream model consumption.\"];\n if (options.input.mode === \"compress\" || options.input.mode === \"concise\") {\n changes.push(\"Applied concise formatting to reduce token usage.\");\n }\n\n return {\n optimizedPrompt,\n changes,\n warnings: []\n };\n }\n\n private async reduceToBudget(options: {\n input: OptimizePromptInput & { mode: OptimizationMode; preset: PromptPreset };\n optimizedPrompt: string;\n context: RelevantContextResult;\n maxTotalTokens: number;\n }): Promise<{ finalPrompt: string; estimatedTokensAfter: { prompt: number; context: number; total: number }; warning?: string }> {\n const summaryBudget = Math.max(80, Math.floor(options.maxTotalTokens * 0.2));\n const summary = options.input.sessionId\n ? await this.summarizeContext(options.input.sessionId, options.input.prompt, options.input.task, summaryBudget)\n : null;\n\n const compactContext: RelevantContextResult = {\n ...options.context,\n usedEntries: [],\n summary\n };\n\n const finalPrompt = composeFinalPrompt({\n optimizedPrompt: this.estimator.truncateToBudget(options.optimizedPrompt, Math.floor(options.maxTotalTokens * 0.5)),\n input: options.input,\n context: compactContext\n });\n\n return {\n finalPrompt,\n estimatedTokensAfter: {\n prompt: this.estimator.estimateText(options.optimizedPrompt),\n context: this.estimator.estimateText(formatContextBlock(compactContext)),\n total: this.estimator.estimateText(finalPrompt)\n },\n warning: \"Summarized stored context further to stay within the total token budget.\"\n };\n }\n}\n\nfunction resolveSessionStore(config: OptimizerConfig): SessionStore {\n if (typeof config.contextStore === \"object\" && config.contextStore !== null) {\n return config.contextStore;\n }\n\n if (config.contextStore === \"sqlite\") {\n return new SQLiteSessionStore(config.sqlitePath);\n }\n\n return new FileSessionStore(config.storageDir);\n}\n\nfunction composeFinalPrompt(input: {\n optimizedPrompt: string;\n input: OptimizePromptInput & { mode: OptimizationMode; preset: PromptPreset };\n context: RelevantContextResult;\n}): string {\n const sections: string[] = [];\n\n sections.push(`Task:\\n${input.optimizedPrompt}`);\n\n const contextBlock = formatContextBlock(input.context);\n if (contextBlock) {\n sections.push(`Relevant context:\\n${contextBlock}`);\n }\n\n const constraints = Array.from(\n new Set([\n ...(input.input.pinnedConstraints ?? []),\n ...extractConstraints(input.input.prompt),\n input.input.maxLength ? `Keep the response within ${input.input.maxLength} units if possible.` : \"\",\n input.input.tone ? `Maintain a ${input.input.tone} tone.` : \"\",\n input.input.outputFormat ? `Return the output as ${input.input.outputFormat}.` : \"\"\n ].filter(Boolean))\n );\n\n if (constraints.length > 0) {\n sections.push(`Constraints:\\n- ${constraints.join(\"\\n- \")}`);\n }\n\n const desiredOutput = [\n input.input.targetModel ? `Target model: ${input.input.targetModel}` : \"Target model: claude\",\n `Mode: ${input.input.mode}`,\n `Preset: ${input.input.preset}`\n ];\n\n sections.push(`Desired output:\\n- ${desiredOutput.join(\"\\n- \")}`);\n\n return sections.join(\"\\n\\n\").trim();\n}\n\nfunction formatContextBlock(context: RelevantContextResult): string {\n const lines: string[] = [];\n\n if (context.summary?.text) {\n lines.push(`Summary: ${context.summary.text}`);\n }\n\n for (const entry of context.usedEntries.slice(-4)) {\n lines.push(`- ${entry.optimizedPrompt ?? entry.rawPrompt ?? entry.text}`);\n }\n\n return normalizeWhitespace(lines.join(\"\\n\"));\n}\n\nfunction emptyRelevantContext(): RelevantContextResult {\n return {\n usedEntries: [],\n summary: null,\n warnings: [],\n debugInfo: {}\n };\n}\n","import type { OptimizePromptInput, OptimizerConfig } from \"./types.js\";\nimport { PromptOptimizer } from \"./core/optimizer.js\";\n\nexport * from \"./types.js\";\nexport * from \"./errors.js\";\nexport { PromptOptimizer } from \"./core/optimizer.js\";\nexport { OllamaClient } from \"./core/ollamaClient.js\";\nexport { TokenEstimator } from \"./core/tokenEstimator.js\";\nexport { ContextManager } from \"./core/contextManager.js\";\nexport { ContextCompressor } from \"./core/contextCompressor.js\";\nexport { selectOllamaModel, getDefaultPreferredModels } from \"./core/modelSelector.js\";\nexport { FileSessionStore } from \"./storage/fileSessionStore.js\";\nexport { SQLiteSessionStore } from \"./storage/sqliteSessionStore.js\";\n\nexport function createOptimizer(config: OptimizerConfig = {}) {\n return new PromptOptimizer(config);\n}\n\nexport async function optimizePrompt(input: OptimizePromptInput, config: OptimizerConfig = {}) {\n const optimizer = createOptimizer(config);\n return optimizer.optimize(input);\n}\n"],"mappings":"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","names":["dirname","join","mkdir","join","mkdir","dirname","randomUUID","randomUUID"]}
1
+ {"version":3,"sources":["../src/cli.ts","../src/errors.ts","../src/storage/fileSessionStore.ts","../src/utils/validation.ts","../src/storage/sqliteSessionStore.ts","../src/utils/logger.ts","../src/utils/json.ts","../src/core/ollamaClient.ts","../src/core/systemPrompt.ts","../src/core/tokenEstimator.ts","../src/core/contextCompressor.ts","../src/core/contextManager.ts","../src/core/modelSelector.ts","../src/core/optimizer.ts","../src/index.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { realpathSync } from \"node:fs\";\nimport { fileURLToPath } from \"node:url\";\n\nimport { createOptimizer } from \"./index.js\";\nimport { toPrettyJson } from \"./utils/json.js\";\nimport { createLogger } from \"./utils/logger.js\";\n\ntype CliWriter = {\n write(message: string): void;\n};\n\ninterface CliIO {\n stdout: CliWriter;\n stderr: CliWriter;\n stdin?: NodeJS.ReadStream;\n}\n\ninterface CliDependencies {\n createOptimizer: typeof createOptimizer;\n readStdin: (stdin?: NodeJS.ReadStream) => Promise<string>;\n}\n\nexport async function runCli(\n argv: string[],\n io: CliIO = { stdout: process.stdout, stderr: process.stderr, stdin: process.stdin },\n dependencies: CliDependencies = { createOptimizer, readStdin }\n): Promise<number> {\n const [command, ...rest] = argv;\n\n if (!command || command === \"--help\" || command === \"-h\") {\n io.stdout.write(`${getHelpText()}\\n`);\n return 0;\n }\n\n if (command !== \"optimize\") {\n io.stderr.write(`Unknown command: ${command}\\n`);\n io.stderr.write(`${getHelpText()}\\n`);\n return 1;\n }\n\n const parsed = parseOptimizeArgs(rest);\n if (parsed.help) {\n io.stdout.write(`${getHelpText()}\\n`);\n return 0;\n }\n\n if (!parsed.sessionId && parsed.clearSession) {\n io.stderr.write(\"--clear-session requires --session <id>.\\n\");\n return 1;\n }\n\n const optimizer = dependencies.createOptimizer({\n provider: \"ollama\",\n ollamaModel: parsed.model,\n host: parsed.host,\n contextStore: parsed.contextStore,\n storageDir: parsed.storageDir,\n sqlitePath: parsed.sqlitePath,\n timeoutMs: parsed.timeoutMs,\n logger: createLogger(parsed.debug)\n });\n\n if (parsed.clearSession && parsed.sessionId) {\n await optimizer.clearContext(parsed.sessionId);\n if (!parsed.prompt) {\n io.stdout.write(`Cleared session ${parsed.sessionId}\\n`);\n return 0;\n }\n }\n\n if (!parsed.prompt) {\n const stdinPrompt = await dependencies.readStdin(io.stdin);\n parsed.prompt = stdinPrompt.trim() || undefined;\n }\n\n if (!parsed.prompt) {\n io.stderr.write(\"A prompt is required.\\n\");\n return 1;\n }\n\n try {\n const result = await optimizer.optimize({\n prompt: parsed.prompt,\n task: parsed.task,\n tone: parsed.tone,\n mode: parsed.mode,\n preset: parsed.preset,\n sessionId: parsed.sessionId,\n saveContext: parsed.saveContext,\n useContext: parsed.useContext,\n targetModel: parsed.targetModel ?? \"claude\",\n outputFormat: parsed.outputFormat,\n maxLength: parsed.maxLength,\n tags: parsed.tags,\n pinnedConstraints: parsed.pinnedConstraints,\n debug: parsed.debug,\n plainOutput: parsed.plain,\n maxTotalTokens: parsed.maxTotalTokens,\n maxContextTokens: parsed.maxContextTokens,\n maxInputTokens: parsed.maxInputTokens,\n timeoutMs: parsed.timeoutMs,\n bypassOptimization: parsed.bypassOptimization\n });\n\n if (parsed.json) {\n io.stdout.write(`${toPrettyJson(result)}\\n`);\n return 0;\n }\n\n if (parsed.plain) {\n io.stdout.write(`${result.finalPrompt}\\n`);\n return 0;\n }\n\n io.stdout.write(`${result.finalPrompt}\\n\\n`);\n io.stdout.write(`provider=${result.provider} model=${result.model} tokens=${result.estimatedTokensAfter.total} savings=${result.tokenSavings}\\n`);\n if (result.warnings.length > 0) {\n io.stdout.write(`warnings=${result.warnings.join(\" | \")}\\n`);\n }\n return 0;\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Unknown CLI error.\";\n io.stderr.write(`${message}\\n`);\n return 1;\n }\n}\n\nfunction parseOptimizeArgs(args: string[]) {\n const parsed: {\n prompt?: string;\n sessionId?: string;\n model?: string;\n mode?: any;\n task?: string;\n tone?: string;\n preset?: any;\n targetModel?: string;\n outputFormat?: string;\n maxLength?: number;\n tags: string[];\n pinnedConstraints: string[];\n host?: string;\n contextStore?: \"local\" | \"sqlite\";\n storageDir?: string;\n sqlitePath?: string;\n plain: boolean;\n json: boolean;\n debug: boolean;\n saveContext?: boolean;\n useContext?: boolean;\n clearSession: boolean;\n maxTotalTokens?: number;\n maxContextTokens?: number;\n maxInputTokens?: number;\n timeoutMs?: number;\n bypassOptimization: boolean;\n help: boolean;\n } = {\n plain: false,\n json: false,\n debug: false,\n clearSession: false,\n useContext: true,\n bypassOptimization: false,\n help: false,\n tags: [],\n pinnedConstraints: []\n };\n\n const positionals: string[] = [];\n\n for (let index = 0; index < args.length; index += 1) {\n const arg = args[index];\n switch (arg) {\n case \"--session\":\n parsed.sessionId = args[++index];\n break;\n case \"--model\":\n parsed.model = args[++index];\n break;\n case \"--mode\":\n parsed.mode = args[++index];\n break;\n case \"--task\":\n parsed.task = args[++index];\n break;\n case \"--tone\":\n parsed.tone = args[++index];\n break;\n case \"--preset\":\n parsed.preset = args[++index];\n break;\n case \"--target-model\":\n parsed.targetModel = args[++index];\n break;\n case \"--output-format\":\n parsed.outputFormat = args[++index];\n break;\n case \"--max-length\":\n parsed.maxLength = Number(args[++index]);\n break;\n case \"--tag\":\n parsed.tags.push(args[++index]);\n break;\n case \"--pin-constraint\":\n parsed.pinnedConstraints.push(args[++index]);\n break;\n case \"--host\":\n parsed.host = args[++index];\n break;\n case \"--store\":\n parsed.contextStore = args[++index] as \"local\" | \"sqlite\";\n break;\n case \"--storage-dir\":\n parsed.storageDir = args[++index];\n break;\n case \"--sqlite-path\":\n parsed.sqlitePath = args[++index];\n break;\n case \"--plain\":\n parsed.plain = true;\n break;\n case \"--json\":\n parsed.json = true;\n break;\n case \"--debug\":\n parsed.debug = true;\n break;\n case \"--save-context\":\n parsed.saveContext = true;\n break;\n case \"--no-context\":\n parsed.useContext = false;\n break;\n case \"--clear-session\":\n parsed.clearSession = true;\n break;\n case \"--max-total-tokens\":\n parsed.maxTotalTokens = Number(args[++index]);\n break;\n case \"--max-context-tokens\":\n parsed.maxContextTokens = Number(args[++index]);\n break;\n case \"--max-input-tokens\":\n parsed.maxInputTokens = Number(args[++index]);\n break;\n case \"--timeout\":\n parsed.timeoutMs = Number(args[++index]);\n break;\n case \"--bypass-optimization\":\n parsed.bypassOptimization = true;\n break;\n case \"--help\":\n case \"-h\":\n parsed.help = true;\n break;\n default:\n positionals.push(arg);\n }\n }\n\n parsed.prompt = positionals.join(\" \").trim() || undefined;\n return parsed;\n}\n\nfunction getHelpText(): string {\n return [\n \"promptpilot optimize <prompt> [options]\",\n \"\",\n \"Options:\",\n \" --session <id>\",\n \" --model <name> Override auto-selected local Ollama model\",\n \" --mode <mode>\",\n \" --task <task>\",\n \" --tone <tone>\",\n \" --preset <preset>\",\n \" --target-model <name>\",\n \" --output-format <text>\",\n \" --max-length <n>\",\n \" --tag <value> Repeatable\",\n \" --pin-constraint <text> Repeatable\",\n \" --host <url>\",\n \" --store <local|sqlite>\",\n \" --storage-dir <path>\",\n \" --sqlite-path <path>\",\n \" --plain\",\n \" --json\",\n \" --debug\",\n \" --save-context\",\n \" --no-context\",\n \" --clear-session\",\n \" --max-total-tokens <n>\",\n \" --max-context-tokens <n>\",\n \" --max-input-tokens <n>\",\n \" --timeout <ms>\",\n \" --bypass-optimization\"\n ].join(\"\\n\");\n}\n\nasync function readStdin(stdin: NodeJS.ReadStream | undefined = process.stdin): Promise<string> {\n if (!stdin || stdin.isTTY) {\n return \"\";\n }\n\n return new Promise((resolve, reject) => {\n let data = \"\";\n stdin.setEncoding(\"utf8\");\n stdin.on(\"data\", (chunk) => {\n data += chunk;\n });\n stdin.on(\"end\", () => resolve(data));\n stdin.on(\"error\", reject);\n });\n}\n\nif (isMainModule()) {\n runCli(process.argv.slice(2)).then(\n (code) => {\n process.exit(code);\n },\n (error: unknown) => {\n const message = error instanceof Error ? error.message : String(error);\n process.stderr.write(`${message}\\n`);\n process.exit(1);\n }\n );\n}\n\nfunction isMainModule(): boolean {\n if (!process.argv[1]) {\n return false;\n }\n\n try {\n const entryPath = realpathSync(process.argv[1]);\n const thisPath = realpathSync(fileURLToPath(import.meta.url));\n return entryPath === thisPath;\n } catch {\n return false;\n }\n}\n","export class InvalidPromptError extends Error {\n constructor(message = \"Prompt must be a non-empty string.\") {\n super(message);\n this.name = \"InvalidPromptError\";\n }\n}\n\nexport class OllamaUnavailableError extends Error {\n constructor(message = \"Ollama is unavailable or returned an invalid response.\") {\n super(message);\n this.name = \"OllamaUnavailableError\";\n }\n}\n\nexport class ContextStoreError extends Error {\n constructor(message = \"Context store operation failed.\") {\n super(message);\n this.name = \"ContextStoreError\";\n }\n}\n\nexport class TokenBudgetExceededError extends Error {\n constructor(message = \"Final prompt could not be reduced to fit within the configured token budget.\") {\n super(message);\n this.name = \"TokenBudgetExceededError\";\n }\n}\n","import { mkdir, readFile, rm, writeFile } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\n\nimport { ContextStoreError } from \"../errors.js\";\nimport type { SessionData, SessionStore } from \"../types.js\";\nimport { sanitizeSessionId } from \"../utils/validation.js\";\n\nexport class FileSessionStore implements SessionStore {\n private readonly rootDir: string;\n\n constructor(rootDir = join(homedir(), \".promptpilot\", \"sessions\")) {\n this.rootDir = rootDir;\n }\n\n async loadSession(sessionId: string): Promise<SessionData> {\n const filePath = this.getFilePath(sessionId);\n\n try {\n const contents = await readFile(filePath, \"utf8\");\n const parsed = JSON.parse(contents) as SessionData;\n return parsed;\n } catch (error) {\n const code = (error as NodeJS.ErrnoException).code;\n if (code === \"ENOENT\") {\n return this.createEmptySession(sessionId);\n }\n\n throw new ContextStoreError(`Failed to load session \"${sessionId}\".`);\n }\n }\n\n async saveSession(session: SessionData): Promise<void> {\n const filePath = this.getFilePath(session.sessionId);\n\n try {\n await mkdir(dirname(filePath), { recursive: true });\n await writeFile(filePath, JSON.stringify(session, null, 2), \"utf8\");\n } catch {\n throw new ContextStoreError(`Failed to save session \"${session.sessionId}\".`);\n }\n }\n\n async clearSession(sessionId: string): Promise<void> {\n const filePath = this.getFilePath(sessionId);\n\n try {\n await rm(filePath, { force: true });\n } catch {\n throw new ContextStoreError(`Failed to clear session \"${sessionId}\".`);\n }\n }\n\n private getFilePath(sessionId: string): string {\n return join(this.rootDir, `${sanitizeSessionId(sessionId)}.json`);\n }\n\n private createEmptySession(sessionId: string): SessionData {\n const now = new Date().toISOString();\n return {\n sessionId,\n entries: [],\n summaries: [],\n createdAt: now,\n updatedAt: now\n };\n }\n}\n","import { InvalidPromptError } from \"../errors.js\";\n\nexport function normalizeWhitespace(value: string): string {\n return value\n .replace(/\\r\\n/g, \"\\n\")\n .replace(/[ \\t]+\\n/g, \"\\n\")\n .replace(/\\n{3,}/g, \"\\n\\n\")\n .trim();\n}\n\nexport function validatePrompt(prompt: string): string {\n if (typeof prompt !== \"string\" || normalizeWhitespace(prompt).length === 0) {\n throw new InvalidPromptError();\n }\n\n return normalizeWhitespace(prompt);\n}\n\nexport function sanitizeSessionId(sessionId: string): string {\n return sessionId.trim().replace(/[^a-zA-Z0-9._-]/g, \"-\");\n}\n","import { dirname, join } from \"node:path\";\nimport { mkdir } from \"node:fs/promises\";\n\nimport { ContextStoreError } from \"../errors.js\";\nimport type { SessionData, SessionStore } from \"../types.js\";\n\ntype DatabaseAdapter = {\n prepare(sql: string): {\n get(param?: string): { data?: string } | undefined;\n run(...params: unknown[]): void;\n };\n exec(sql: string): void;\n};\n\nexport class SQLiteSessionStore implements SessionStore {\n private dbPromise: Promise<DatabaseAdapter>;\n\n constructor(private readonly dbPath = join(process.cwd(), \".promptpilot\", \"promptpilot.db\")) {\n this.dbPromise = this.openDatabase();\n }\n\n async loadSession(sessionId: string): Promise<SessionData> {\n const db = await this.dbPromise;\n const row = db.prepare(\"SELECT data FROM sessions WHERE id = ?\").get(sessionId);\n if (!row?.data) {\n return createEmptySession(sessionId);\n }\n\n return JSON.parse(row.data) as SessionData;\n }\n\n async saveSession(session: SessionData): Promise<void> {\n const db = await this.dbPromise;\n db.prepare(\"INSERT OR REPLACE INTO sessions (id, data) VALUES (?, ?)\").run(\n session.sessionId,\n JSON.stringify(session)\n );\n }\n\n async clearSession(sessionId: string): Promise<void> {\n const db = await this.dbPromise;\n db.prepare(\"DELETE FROM sessions WHERE id = ?\").run(sessionId);\n }\n\n private async openDatabase(): Promise<DatabaseAdapter> {\n try {\n await mkdir(dirname(this.dbPath), { recursive: true });\n const nodeSqliteName = \"node:sqlite\";\n const nodeSqlite = await import(nodeSqliteName).catch(() => null);\n\n if (nodeSqlite?.DatabaseSync) {\n const db = new nodeSqlite.DatabaseSync(this.dbPath) as DatabaseAdapter;\n db.exec(\"CREATE TABLE IF NOT EXISTS sessions (id TEXT PRIMARY KEY, data TEXT NOT NULL)\");\n return db;\n }\n\n const betterSqliteName = \"better-sqlite3\";\n const betterSqlite = await import(betterSqliteName).catch(() => null);\n if (betterSqlite?.default) {\n const db = new betterSqlite.default(this.dbPath) as DatabaseAdapter;\n db.exec(\"CREATE TABLE IF NOT EXISTS sessions (id TEXT PRIMARY KEY, data TEXT NOT NULL)\");\n return db;\n }\n\n throw new ContextStoreError(\n \"SQLite store requires node:sqlite support or the better-sqlite3 package.\"\n );\n } catch (error) {\n if (error instanceof ContextStoreError) {\n throw error;\n }\n\n throw new ContextStoreError(\"Failed to initialize SQLite session store.\");\n }\n }\n}\n\nfunction createEmptySession(sessionId: string): SessionData {\n const now = new Date().toISOString();\n return {\n sessionId,\n entries: [],\n summaries: [],\n createdAt: now,\n updatedAt: now\n };\n}\n","import type { Logger } from \"../types.js\";\n\nexport const noopLogger: Logger = {\n debug: () => undefined,\n info: () => undefined,\n warn: () => undefined,\n error: () => undefined\n};\n\nexport function createLogger(debugEnabled = false): Logger {\n return {\n debug(message, meta) {\n if (debugEnabled) {\n console.debug(`[promptpilot] ${message}`, meta ?? \"\");\n }\n },\n info(message, meta) {\n if (debugEnabled) {\n console.info(`[promptpilot] ${message}`, meta ?? \"\");\n }\n },\n warn(message, meta) {\n if (debugEnabled) {\n console.warn(`[promptpilot] ${message}`, meta ?? \"\");\n }\n },\n error(message, meta) {\n if (debugEnabled) {\n console.error(`[promptpilot] ${message}`, meta ?? \"\");\n }\n }\n };\n}\n","export function safeJsonParse<T>(value: string): T | null {\n try {\n return JSON.parse(value) as T;\n } catch {\n return null;\n }\n}\n\nexport function extractFirstJsonObject(value: string): string | null {\n const start = value.indexOf(\"{\");\n if (start === -1) {\n return null;\n }\n\n let depth = 0;\n let inString = false;\n let escaped = false;\n\n for (let index = start; index < value.length; index += 1) {\n const char = value[index];\n\n if (escaped) {\n escaped = false;\n continue;\n }\n\n if (char === \"\\\\\") {\n escaped = true;\n continue;\n }\n\n if (char === \"\\\"\") {\n inString = !inString;\n continue;\n }\n\n if (inString) {\n continue;\n }\n\n if (char === \"{\") {\n depth += 1;\n } else if (char === \"}\") {\n depth -= 1;\n if (depth === 0) {\n return value.slice(start, index + 1);\n }\n }\n }\n\n return null;\n}\n\nexport function toPrettyJson(value: unknown): string {\n return JSON.stringify(value, null, 2);\n}\n","import { OllamaUnavailableError } from \"../errors.js\";\nimport type { Logger, OllamaClientLike, OllamaGenerateOptions, OllamaModelInfo } from \"../types.js\";\nimport { extractFirstJsonObject, safeJsonParse } from \"../utils/json.js\";\nimport { noopLogger } from \"../utils/logger.js\";\n\ninterface OllamaClientConfig {\n host?: string;\n model?: string;\n timeoutMs?: number;\n temperature?: number;\n logger?: Logger;\n}\n\nexport class OllamaClient implements OllamaClientLike {\n readonly host: string;\n readonly model: string;\n readonly timeoutMs: number;\n readonly temperature: number;\n readonly logger: Logger;\n\n constructor(config: OllamaClientConfig = {}) {\n this.host = config.host ?? \"http://localhost:11434\";\n this.model = config.model ?? \"qwen2.5:3b\";\n this.timeoutMs = config.timeoutMs ?? 30000;\n this.temperature = config.temperature ?? 0.1;\n this.logger = config.logger ?? noopLogger;\n }\n\n async isAvailable(): Promise<boolean> {\n try {\n const response = await fetch(new URL(\"/api/tags\", this.host), {\n method: \"GET\"\n });\n\n return response.ok;\n } catch {\n return false;\n }\n }\n\n async listModels(): Promise<OllamaModelInfo[]> {\n try {\n const response = await fetch(new URL(\"/api/tags\", this.host), {\n method: \"GET\"\n });\n\n if (!response.ok) {\n throw new OllamaUnavailableError(`Ollama tags request failed with status ${response.status}.`);\n }\n\n const data = (await response.json()) as {\n models?: Array<{\n name?: string;\n size?: number;\n modified_at?: string;\n details?: {\n family?: string;\n parameter_size?: string;\n };\n }>;\n };\n\n return (data.models ?? [])\n .filter((model) => typeof model.name === \"string\" && model.name.length > 0)\n .map((model) => ({\n name: model.name as string,\n sizeBytes: model.size,\n family: model.details?.family,\n parameterSize: model.details?.parameter_size,\n modifiedAt: model.modified_at\n }));\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Unknown Ollama tags error.\";\n this.logger.warn(\"ollama.list_models.failed\", { message });\n throw new OllamaUnavailableError(message);\n }\n }\n\n async generate(options: OllamaGenerateOptions): Promise<string> {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), options.timeoutMs ?? this.timeoutMs);\n\n try {\n const response = await fetch(new URL(\"/api/generate\", this.host), {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\"\n },\n body: JSON.stringify({\n model: options.model ?? this.model,\n system: options.systemPrompt,\n prompt: options.prompt,\n stream: false,\n format: options.format === \"json\" ? \"json\" : undefined,\n options: {\n temperature: options.temperature ?? this.temperature\n }\n }),\n signal: controller.signal\n });\n\n if (!response.ok) {\n throw new OllamaUnavailableError(`Ollama request failed with status ${response.status}.`);\n }\n\n const data = (await response.json()) as { response?: string };\n if (!data.response || typeof data.response !== \"string\") {\n throw new OllamaUnavailableError(\"Ollama did not return a text response.\");\n }\n\n return data.response.trim();\n } catch (error) {\n if (error instanceof OllamaUnavailableError) {\n throw error;\n }\n\n const message = error instanceof Error ? error.message : \"Unknown Ollama error.\";\n this.logger.warn(\"ollama.generate.failed\", { message });\n throw new OllamaUnavailableError(message);\n } finally {\n clearTimeout(timeout);\n }\n }\n\n async generateJson<T>(options: OllamaGenerateOptions): Promise<T> {\n const raw = await this.generate({\n ...options,\n format: \"json\"\n });\n\n const direct = safeJsonParse<T>(raw);\n if (direct) {\n return direct;\n }\n\n const extracted = extractFirstJsonObject(raw);\n if (extracted) {\n const parsed = safeJsonParse<T>(extracted);\n if (parsed) {\n return parsed;\n }\n }\n\n throw new OllamaUnavailableError(\"Ollama returned JSON that could not be parsed.\");\n }\n}\n","import type { OptimizationMode, OptimizePromptInput, PromptPreset } from \"../types.js\";\n\nconst modeGuidance: Record<OptimizationMode, string> = {\n clarity: \"Improve clarity, remove ambiguity, and keep the request easy for a downstream model to follow.\",\n concise: \"Minimize token count while preserving user intent, constraints, and expected output.\",\n detailed: \"Make the request explicit and complete, including structure and success criteria.\",\n structured: \"Organize the request into clean sections with compact headings and bullet points where helpful.\",\n persuasive: \"Refine wording so the request is compelling and likely to elicit a thoughtful response.\",\n compress: \"Aggressively compress redundant wording while preserving the meaning and critical constraints.\",\n claude_cli: \"Optimize specifically for Claude CLI: compact sections, direct instructions, and minimal boilerplate.\"\n};\n\nconst presetGuidance: Record<PromptPreset, string> = {\n code: \"Favor precise technical requirements, edge cases, and expected output format for code tasks.\",\n email: \"Preserve the sender's goal, tone, and audience; aim for a realistic and usable writing request.\",\n essay: \"Preserve thesis, structure, and voice guidance while making the prompt clearer.\",\n support: \"Favor concise issue context, user impact, and desired resolution details.\",\n summarization: \"Favor strong compression while retaining key facts, structure, and takeaways.\",\n chat: \"Keep the prompt natural and conversational while preserving instructions and context.\"\n};\n\nexport function getOptimizationSystemPrompt(mode: OptimizationMode, preset?: PromptPreset): string {\n return [\n \"You are PromptPilot, a local prompt optimizer for downstream LLM workflows.\",\n \"Return strict JSON only with this shape:\",\n \"{\\\"optimizedPrompt\\\":\\\"string\\\",\\\"constraints\\\":[\\\"string\\\"],\\\"changes\\\":[\\\"string\\\"],\\\"warnings\\\":[\\\"string\\\"]}\",\n \"Rules:\",\n \"- Do not change the user's intent.\",\n \"- Do not invent new requirements.\",\n \"- Preserve critical constraints and task goals.\",\n \"- Improve clarity, structure, and downstream usefulness.\",\n \"- Keep the result compact when the mode requests compression.\",\n `Mode guidance: ${modeGuidance[mode]}`,\n preset ? `Preset guidance: ${presetGuidance[preset]}` : \"Preset guidance: none\"\n ].join(\"\\n\");\n}\n\nexport function buildOptimizationPrompt(\n input: OptimizePromptInput,\n relevantContext: string,\n extractedConstraints: string[]\n): string {\n const payload = {\n prompt: input.prompt,\n task: input.task ?? null,\n tone: input.tone ?? null,\n targetModel: input.targetModel ?? \"claude\",\n outputFormat: input.outputFormat ?? null,\n maxLength: input.maxLength ?? null,\n mode: input.mode ?? \"claude_cli\",\n preset: input.preset ?? null,\n pinnedConstraints: input.pinnedConstraints ?? [],\n extractedConstraints,\n relevantContext\n };\n\n return `Optimize this prompt payload for a downstream LLM.\\n${JSON.stringify(payload, null, 2)}`;\n}\n","import type { TokenUsageEstimate } from \"../types.js\";\nimport { normalizeWhitespace } from \"../utils/validation.js\";\n\nexport class TokenEstimator {\n estimateText(text: string): number {\n const normalized = normalizeWhitespace(text);\n if (!normalized) {\n return 0;\n }\n\n const wordCount = normalized.split(/\\s+/).length;\n const charCount = normalized.length;\n return Math.max(1, Math.ceil(wordCount * 1.3), Math.ceil(charCount / 4));\n }\n\n estimateUsage(input: { prompt: string; context?: string }): TokenUsageEstimate {\n const prompt = this.estimateText(input.prompt);\n const context = this.estimateText(input.context ?? \"\");\n return {\n prompt,\n context,\n total: prompt + context\n };\n }\n\n truncateToBudget(text: string, tokenBudget: number): string {\n const normalized = normalizeWhitespace(text);\n if (tokenBudget <= 0 || !normalized) {\n return \"\";\n }\n\n if (this.estimateText(normalized) <= tokenBudget) {\n return normalized;\n }\n\n const words = normalized.split(/\\s+/);\n const selected: string[] = [];\n\n for (const word of words) {\n const candidate = [...selected, word].join(\" \");\n if (this.estimateText(candidate) > tokenBudget) {\n break;\n }\n\n selected.push(word);\n }\n\n return selected.join(\" \").trim();\n }\n}\n","import { randomUUID } from \"node:crypto\";\n\nimport type { ContextEntry, ContextSummary, Logger, OllamaClientLike } from \"../types.js\";\nimport { TokenEstimator } from \"./tokenEstimator.js\";\nimport { getOptimizationSystemPrompt } from \"./systemPrompt.js\";\nimport { noopLogger } from \"../utils/logger.js\";\n\ninterface SummarizeContextOptions {\n sessionId: string;\n entries: ContextEntry[];\n prompt: string;\n task?: string;\n budgetTokens: number;\n timeoutMs?: number;\n}\n\ninterface ContextSummaryJson {\n optimizedPrompt: string;\n constraints?: string[];\n changes?: string[];\n}\n\nexport class ContextCompressor {\n constructor(\n private readonly estimator: TokenEstimator,\n private readonly client?: OllamaClientLike,\n private readonly logger: Logger = noopLogger\n ) {}\n\n async summarizeEntries(options: SummarizeContextOptions): Promise<ContextSummary | null> {\n if (options.entries.length === 0 || options.budgetTokens <= 0) {\n return null;\n }\n\n const ollamaSummary = await this.tryOllamaSummary(options);\n if (ollamaSummary) {\n return ollamaSummary;\n }\n\n return this.heuristicSummary(options);\n }\n\n private async tryOllamaSummary(options: SummarizeContextOptions): Promise<ContextSummary | null> {\n if (!this.client || options.entries.length < 3) {\n return null;\n }\n\n try {\n const source = options.entries\n .slice(-8)\n .map((entry) => [\n `Timestamp: ${entry.timestamp}`,\n entry.task ? `Task: ${entry.task}` : \"\",\n entry.constraints?.length ? `Constraints: ${entry.constraints.join(\"; \")}` : \"\",\n `Prompt: ${entry.rawPrompt ?? entry.text}`\n ].filter(Boolean).join(\"\\n\"))\n .join(\"\\n\\n\");\n\n const response = await this.client.generateJson<ContextSummaryJson>({\n systemPrompt: getOptimizationSystemPrompt(\"compress\"),\n prompt: `Summarize this stored prompt context for reuse in later turns.\\nPrompt: ${options.prompt}\\nTask: ${options.task ?? \"unknown\"}\\nBudget tokens: ${options.budgetTokens}\\n\\n${source}`,\n timeoutMs: options.timeoutMs,\n format: \"json\"\n });\n\n const summaryText = this.estimator.truncateToBudget(response.optimizedPrompt ?? \"\", options.budgetTokens);\n if (!summaryText) {\n return null;\n }\n\n return {\n id: randomUUID(),\n sessionId: options.sessionId,\n text: summaryText,\n createdAt: new Date().toISOString(),\n sourceEntryIds: options.entries.map((entry) => entry.id),\n tokenEstimate: this.estimator.estimateText(summaryText),\n kind: \"ollama\"\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Unknown summary failure\";\n this.logger.debug(\"context.summary.ollama_fallback\", { message });\n return null;\n }\n }\n\n private heuristicSummary(options: SummarizeContextOptions): ContextSummary {\n const constraints = Array.from(\n new Set(options.entries.flatMap((entry) => entry.constraints ?? []).filter(Boolean))\n ).slice(0, 6);\n\n const recentPrompts = options.entries\n .slice(-4)\n .map((entry) => `- ${truncateLine(entry.rawPrompt ?? entry.text, 120)}`);\n\n const lines = [\n constraints.length ? `Key constraints: ${constraints.join(\"; \")}` : \"\",\n recentPrompts.length ? `Recent focus:\\n${recentPrompts.join(\"\\n\")}` : \"\"\n ].filter(Boolean);\n\n const summaryText = this.estimator.truncateToBudget(lines.join(\"\\n\\n\"), options.budgetTokens);\n\n return {\n id: randomUUID(),\n sessionId: options.sessionId,\n text: summaryText,\n createdAt: new Date().toISOString(),\n sourceEntryIds: options.entries.map((entry) => entry.id),\n tokenEstimate: this.estimator.estimateText(summaryText),\n kind: \"heuristic\"\n };\n }\n}\n\nfunction truncateLine(value: string, maxLength: number): string {\n if (value.length <= maxLength) {\n return value;\n }\n\n return `${value.slice(0, maxLength - 3).trim()}...`;\n}\n","import { randomUUID } from \"node:crypto\";\n\nimport type {\n ContextEntry,\n ContextSummary,\n Logger,\n OptimizePromptInput,\n RelevantContextResult,\n SessionStore\n} from \"../types.js\";\nimport { TokenEstimator } from \"./tokenEstimator.js\";\nimport { ContextCompressor } from \"./contextCompressor.js\";\nimport { noopLogger } from \"../utils/logger.js\";\n\ninterface GetRelevantContextOptions {\n sessionId: string;\n prompt: string;\n task?: string;\n tags?: string[];\n pinnedConstraints?: string[];\n maxContextTokens: number;\n timeoutMs?: number;\n}\n\ninterface SaveContextOptions {\n sessionId: string;\n input: OptimizePromptInput;\n optimizedPrompt: string;\n finalPrompt: string;\n contextSummary: ContextSummary | null;\n}\n\nexport class ContextManager {\n constructor(\n private readonly store: SessionStore,\n private readonly estimator: TokenEstimator,\n private readonly compressor: ContextCompressor,\n private readonly logger: Logger = noopLogger\n ) {}\n\n async loadContext(sessionId: string) {\n return this.store.loadSession(sessionId);\n }\n\n async clearContext(sessionId: string): Promise<void> {\n await this.store.clearSession(sessionId);\n }\n\n async saveContext(options: SaveContextOptions): Promise<void> {\n const session = await this.store.loadSession(options.sessionId);\n const timestamp = new Date().toISOString();\n const constraints = Array.from(\n new Set([\n ...extractConstraints(options.input.prompt),\n ...(options.input.pinnedConstraints ?? [])\n ])\n );\n const entry: ContextEntry = {\n id: randomUUID(),\n sessionId: options.sessionId,\n text: options.optimizedPrompt,\n rawPrompt: options.input.prompt,\n optimizedPrompt: options.optimizedPrompt,\n finalPrompt: options.finalPrompt,\n task: options.input.task,\n tone: options.input.tone,\n tags: options.input.tags ?? [],\n constraints,\n entities: extractEntities(options.input.prompt),\n pinned: (options.input.pinnedConstraints?.length ?? 0) > 0,\n timestamp,\n tokenEstimate: this.estimator.estimateText(options.finalPrompt)\n };\n\n session.entries.push(entry);\n if (session.entries.length > 100) {\n session.entries = session.entries.slice(-100);\n }\n\n if (options.contextSummary) {\n session.summaries.push(options.contextSummary);\n if (session.summaries.length > 10) {\n session.summaries = session.summaries.slice(-10);\n }\n }\n\n session.updatedAt = timestamp;\n await this.store.saveSession(session);\n this.logger.debug(\"context saved\", {\n sessionId: options.sessionId,\n entryCount: session.entries.length,\n summaryCount: session.summaries.length\n });\n }\n\n async summarizeContext(\n sessionId: string,\n prompt: string,\n task: string | undefined,\n budgetTokens: number,\n timeoutMs?: number\n ): Promise<ContextSummary | null> {\n const session = await this.store.loadSession(sessionId);\n if (session.entries.length === 0) {\n return null;\n }\n\n return this.compressor.summarizeEntries({\n sessionId,\n entries: session.entries,\n prompt,\n task,\n budgetTokens,\n timeoutMs\n });\n }\n\n async getRelevantContext(options: GetRelevantContextOptions): Promise<RelevantContextResult> {\n const session = await this.store.loadSession(options.sessionId);\n if (session.entries.length === 0 && session.summaries.length === 0) {\n return {\n usedEntries: [],\n summary: null,\n warnings: [],\n debugInfo: { scores: [] }\n };\n }\n\n const scores = session.entries.map((entry, index) => ({\n entry,\n score: scoreEntry({\n entry,\n prompt: options.prompt,\n task: options.task,\n tags: options.tags,\n pinnedConstraints: options.pinnedConstraints,\n index,\n total: session.entries.length\n })\n }));\n\n const selected: ContextEntry[] = [];\n const seenFingerprints = new Set<string>();\n let selectedTokens = 0;\n\n for (const scored of scores.sort((left, right) => right.score - left.score)) {\n if (selected.find((entry) => entry.id === scored.entry.id)) {\n continue;\n }\n\n const fingerprint = createFingerprint(scored.entry);\n if (seenFingerprints.has(fingerprint)) {\n continue;\n }\n\n if (selectedTokens + scored.entry.tokenEstimate > options.maxContextTokens) {\n continue;\n }\n\n selected.push(scored.entry);\n seenFingerprints.add(fingerprint);\n selectedTokens += scored.entry.tokenEstimate;\n }\n\n const remainder = session.entries.filter(\n (entry) => !selected.find((selectedEntry) => selectedEntry.id === entry.id)\n );\n\n let summary: ContextSummary | null = null;\n if (remainder.length > 1 && selectedTokens < Math.floor(options.maxContextTokens * 0.8)) {\n summary = await this.compressor.summarizeEntries({\n sessionId: options.sessionId,\n entries: remainder,\n prompt: options.prompt,\n task: options.task,\n budgetTokens: Math.max(80, options.maxContextTokens - selectedTokens),\n timeoutMs: options.timeoutMs\n });\n } else if (session.summaries.length > 0) {\n const latest = session.summaries.at(-1) ?? null;\n if (latest && latest.tokenEstimate <= options.maxContextTokens - selectedTokens) {\n summary = latest;\n }\n }\n\n const warnings: string[] = [];\n if (remainder.length > 0) {\n warnings.push(`Dropped ${remainder.length} lower-value context item(s) to fit the token budget.`);\n }\n\n return {\n usedEntries: selected.sort((left, right) => left.timestamp.localeCompare(right.timestamp)),\n summary,\n warnings,\n debugInfo: {\n scores: scores\n .sort((left, right) => right.score - left.score)\n .map(({ entry, score }) => ({ id: entry.id, score, task: entry.task, timestamp: entry.timestamp }))\n }\n };\n }\n}\n\nfunction scoreEntry(input: {\n entry: ContextEntry;\n prompt: string;\n task?: string;\n tags?: string[];\n pinnedConstraints?: string[];\n index: number;\n total: number;\n}): number {\n const promptTerms = tokenize(input.prompt);\n const promptEntities = new Set(extractEntities(input.prompt).map((entity) => entity.toLowerCase()));\n const entryTerms = tokenize(\n [input.entry.rawPrompt, input.entry.optimizedPrompt, input.entry.constraints?.join(\" \")].filter(Boolean).join(\" \")\n );\n const entryEntities = new Set((input.entry.entities ?? []).map((entity) => entity.toLowerCase()));\n\n const overlap = Array.from(promptTerms).filter((term) => entryTerms.has(term)).length;\n const entityOverlap = Array.from(promptEntities).filter((entity) => entryEntities.has(entity)).length;\n const taskMatch = input.task && input.entry.task === input.task ? 2 : 0;\n const pinned = input.entry.pinned ? 3 : 0;\n const pinnedConstraintMatch = Array.from(new Set(input.pinnedConstraints ?? [])).filter((constraint) =>\n (input.entry.constraints ?? []).includes(constraint)\n ).length;\n const tagOverlap = Array.from(new Set(input.tags ?? [])).filter((tag) => (input.entry.tags ?? []).includes(tag)).length;\n const constraintBonus = (input.entry.constraints?.length ?? 0) > 0 ? 0.75 : 0;\n const recency = (input.index + 1) / input.total;\n\n return overlap * 0.8 + entityOverlap * 1.2 + taskMatch + pinned + pinnedConstraintMatch * 2 + tagOverlap + constraintBonus + recency;\n}\n\nfunction tokenize(value: string): Set<string> {\n return new Set(\n value\n .toLowerCase()\n .split(/[^a-z0-9]+/i)\n .filter((token) => token.length > 2)\n );\n}\n\nexport function extractConstraints(value: string): string[] {\n return value\n .split(/\\n+/)\n .map((line) => line.trim())\n .filter((line) => /(must|should|avoid|do not|don't|never|exactly|at most|under|limit|max)/i.test(line))\n .slice(0, 8);\n}\n\nexport function extractEntities(value: string): string[] {\n return Array.from(\n new Set(value.match(/\\b[A-Z][a-zA-Z0-9._-]+\\b/g) ?? [])\n ).slice(0, 12);\n}\n\nfunction createFingerprint(entry: ContextEntry): string {\n return [entry.task ?? \"\", entry.rawPrompt ?? entry.text]\n .join(\"::\")\n .toLowerCase()\n .replace(/\\s+/g, \" \")\n .trim();\n}\n","import type { OllamaModelInfo, OptimizationMode, PromptPreset } from \"../types.js\";\n\nconst DEFAULT_SMALL_MODEL_PREFERENCES = [\n \"qwen2.5:3b\",\n \"phi3:mini\",\n \"llama3.2:3b\",\n \"qwen2.5:1.5b\"\n];\n\nexport interface ModelSelectionInput {\n installedModels: OllamaModelInfo[];\n mode: OptimizationMode;\n preset: PromptPreset;\n task?: string;\n preferredModels?: string[];\n}\n\nexport interface ModelSelectionResult {\n model: string;\n reason: string;\n suitableForAutoUse: boolean;\n}\n\nexport function getDefaultPreferredModels(): string[] {\n return [...DEFAULT_SMALL_MODEL_PREFERENCES];\n}\n\nexport function getSuitableAutoModels(installedModels: OllamaModelInfo[]): OllamaModelInfo[] {\n return installedModels.filter((model) => isSuitableSmallModel(model));\n}\n\nexport function getQwenRouterModel(\n installedModels: OllamaModelInfo[],\n explicitRouterModel?: string\n): string | null {\n if (explicitRouterModel) {\n const match = installedModels.find((model) => model.name === explicitRouterModel);\n return match?.name ?? null;\n }\n\n const qwenRouters = getSuitableAutoModels(installedModels)\n .filter((model) => /qwen/i.test(model.name))\n .sort((left, right) => scoreRouterModel(right) - scoreRouterModel(left));\n\n return qwenRouters[0]?.name ?? null;\n}\n\nexport function selectOllamaModel(input: ModelSelectionInput): ModelSelectionResult {\n const smallCandidates = getSuitableAutoModels(input.installedModels);\n if (smallCandidates.length === 1) {\n return {\n model: smallCandidates[0].name,\n reason: `Selected installed model \"${smallCandidates[0].name}\" because it is the only suitable small local model available.`,\n suitableForAutoUse: true\n };\n }\n\n if (smallCandidates.length > 1) {\n return {\n model: \"\",\n reason: `Multiple suitable small local models are available (${smallCandidates.map((model) => model.name).join(\", \")}), so a Qwen router must choose between them.`,\n suitableForAutoUse: false\n };\n }\n\n const oversizedRanked = [...input.installedModels]\n .filter((model) => isUsefulGenerationModel(model.name))\n .sort((left, right) => compareModelNames(left.name, right.name));\n\n if (oversizedRanked[0]) {\n return {\n model: oversizedRanked[0].name,\n reason: `Installed model \"${oversizedRanked[0].name}\" was detected, but it is larger than the preferred low-memory range for auto-use.`,\n suitableForAutoUse: false\n };\n }\n\n return {\n model: \"\",\n reason: \"No suitable local generation models were discovered for automatic routing.\",\n suitableForAutoUse: false\n };\n}\n\nfunction extractBillions(modelName: string): number | null {\n const match = modelName.match(/(\\d+(?:\\.\\d+)?)b/);\n if (!match) {\n return null;\n }\n\n return Number.parseFloat(match[1]);\n}\n\nfunction isUsefulGenerationModel(modelName: string): boolean {\n const lower = modelName.toLowerCase();\n return ![\n \"embed\",\n \"embedding\",\n \"whisper\",\n \"vision\",\n \"diffusion\",\n \"tts\",\n \"bge\",\n \"nomic-embed\"\n ].some((blocked) => lower.includes(blocked));\n}\n\nfunction isSuitableSmallModel(model: OllamaModelInfo): boolean {\n if (!isUsefulGenerationModel(model.name)) {\n return false;\n }\n\n const byParameter = extractBillions(`${model.parameterSize ?? \"\"} ${model.name}`);\n if (byParameter !== null) {\n return byParameter <= 4;\n }\n\n if (typeof model.sizeBytes === \"number\") {\n return model.sizeBytes <= 5_500_000_000;\n }\n\n return /mini|1\\.5b|2b|3b|4b/i.test(model.name);\n}\n\nfunction scoreRouterModel(model: OllamaModelInfo): number {\n const lower = model.name.toLowerCase();\n let score = 0;\n if (lower.includes(\"qwen2.5\")) {\n score += 3;\n }\n if (lower.includes(\"3b\")) {\n score += 2;\n } else if (lower.includes(\"1.5b\")) {\n score += 1;\n }\n if (lower.includes(\"coder\")) {\n score -= 1;\n }\n return score;\n}\n\nfunction compareModelNames(left: string, right: string): number {\n return left.localeCompare(right);\n}\n","import type {\n OptimizationMode,\n OptimizePromptInput,\n OptimizePromptResult,\n OptimizerConfig,\n PromptPreset,\n ProviderType,\n RelevantContextResult,\n SessionStore\n} from \"../types.js\";\nimport { TokenBudgetExceededError } from \"../errors.js\";\nimport { FileSessionStore } from \"../storage/fileSessionStore.js\";\nimport { SQLiteSessionStore } from \"../storage/sqliteSessionStore.js\";\nimport { noopLogger } from \"../utils/logger.js\";\nimport { normalizeWhitespace, validatePrompt } from \"../utils/validation.js\";\nimport { OllamaClient } from \"./ollamaClient.js\";\nimport { getOptimizationSystemPrompt, buildOptimizationPrompt } from \"./systemPrompt.js\";\nimport { TokenEstimator } from \"./tokenEstimator.js\";\nimport { ContextCompressor } from \"./contextCompressor.js\";\nimport { ContextManager, extractConstraints } from \"./contextManager.js\";\nimport {\n getDefaultPreferredModels,\n getQwenRouterModel,\n getSuitableAutoModels,\n selectOllamaModel\n} from \"./modelSelector.js\";\n\ninterface OptimizationResponse {\n optimizedPrompt?: string;\n constraints?: string[];\n changes?: string[];\n warnings?: string[];\n}\n\ninterface ModelRoutingResponse {\n selectedModel?: string;\n reason?: string;\n}\n\nconst DEFAULT_MODE: OptimizationMode = \"claude_cli\";\nconst DEFAULT_PRESET: PromptPreset = \"chat\";\nconst DEFAULT_PROVIDER: ProviderType = \"ollama\";\nconst DEFAULT_MAX_INPUT_TOKENS = 1200;\nconst DEFAULT_MAX_CONTEXT_TOKENS = 800;\nconst DEFAULT_MAX_TOTAL_TOKENS = 2200;\n\nexport class PromptOptimizer {\n readonly config: OptimizerConfig & {\n host: string;\n timeoutMs: number;\n temperature: number;\n preferredModels: string[];\n modelRoutingStrategy: \"qwen\";\n };\n\n private readonly logger;\n private readonly estimator;\n private readonly client;\n private readonly compressor;\n private readonly contextManager;\n\n constructor(config: OptimizerConfig = {}) {\n this.logger = config.logger ?? noopLogger;\n this.estimator = new TokenEstimator();\n this.client =\n config.ollamaClient ??\n new OllamaClient({\n host: config.host,\n model: config.ollamaModel,\n timeoutMs: config.timeoutMs,\n temperature: config.temperature,\n logger: this.logger\n });\n\n const store = resolveSessionStore(config);\n this.compressor = new ContextCompressor(this.estimator, this.client, this.logger);\n this.contextManager = new ContextManager(store, this.estimator, this.compressor, this.logger);\n\n this.config = {\n ...config,\n host: config.host ?? \"http://localhost:11434\",\n ollamaModel: config.ollamaModel,\n preferredModels: config.preferredModels ?? getDefaultPreferredModels(),\n modelRoutingStrategy: \"qwen\",\n timeoutMs: config.timeoutMs ?? 30000,\n temperature: config.temperature ?? 0.1\n };\n }\n\n async optimize(input: OptimizePromptInput): Promise<OptimizePromptResult> {\n const originalPrompt = validatePrompt(input.prompt);\n const mode = input.mode ?? this.config.defaultMode ?? DEFAULT_MODE;\n const preset = input.preset ?? this.config.defaultPreset ?? DEFAULT_PRESET;\n const maxInputTokens = input.maxInputTokens ?? this.config.maxInputTokens ?? DEFAULT_MAX_INPUT_TOKENS;\n const maxContextTokens = input.maxContextTokens ?? this.config.maxContextTokens ?? DEFAULT_MAX_CONTEXT_TOKENS;\n const maxTotalTokens = input.maxTotalTokens ?? this.config.maxTotalTokens ?? DEFAULT_MAX_TOTAL_TOKENS;\n const warnings: string[] = [];\n const changes: string[] = [];\n\n const useContext = input.useContext !== false && Boolean(input.sessionId);\n const saveContext = input.saveContext ?? Boolean(input.sessionId);\n const relevantContext = useContext && input.sessionId\n ? await this.contextManager.getRelevantContext({\n sessionId: input.sessionId,\n prompt: originalPrompt,\n task: input.task,\n tags: input.tags,\n pinnedConstraints: input.pinnedConstraints,\n maxContextTokens,\n timeoutMs: input.timeoutMs ?? this.config.timeoutMs\n })\n : emptyRelevantContext();\n\n warnings.push(...relevantContext.warnings);\n\n const contextBlock = formatContextBlock(relevantContext);\n const estimatedTokensBefore = this.estimator.estimateUsage({\n prompt: originalPrompt,\n context: contextBlock\n });\n\n if (estimatedTokensBefore.prompt > maxInputTokens) {\n warnings.push(\n `Raw prompt estimate (${estimatedTokensBefore.prompt}) exceeds maxInputTokens (${maxInputTokens}).`\n );\n }\n\n const extractedConstraints = Array.from(\n new Set([...extractConstraints(originalPrompt), ...(input.pinnedConstraints ?? [])])\n );\n\n let provider: ProviderType = input.bypassOptimization ? \"heuristic\" : this.config.provider ?? DEFAULT_PROVIDER;\n let model = provider === \"ollama\" ? this.config.ollamaModel ?? \"auto\" : \"heuristic\";\n\n let optimizedPrompt = originalPrompt;\n let providerWarnings: string[] = [];\n let providerChanges: string[] = [];\n\n if (provider === \"ollama\") {\n const modelSelection = await this.resolveOllamaModel({\n prompt: originalPrompt,\n mode,\n preset,\n task: input.task\n });\n model = modelSelection.model;\n providerWarnings.push(...modelSelection.warnings);\n if (input.debug) {\n changes.push(modelSelection.reason);\n }\n\n if (modelSelection.forceHeuristic) {\n provider = \"heuristic\";\n model = \"heuristic\";\n }\n\n const ollamaResult = provider === \"ollama\"\n ? await this.tryOllamaOptimization({\n input: {\n ...input,\n prompt: originalPrompt,\n mode,\n preset\n },\n model,\n extractedConstraints,\n relevantContext: contextBlock\n })\n : null;\n\n if (ollamaResult) {\n optimizedPrompt = ollamaResult.optimizedPrompt;\n providerWarnings = ollamaResult.warnings;\n providerChanges = ollamaResult.changes;\n } else if (provider === \"ollama\") {\n provider = \"heuristic\";\n model = \"heuristic\";\n providerWarnings = [\n `Ollama was unavailable. Falling back to deterministic local prompt shaping.`\n ];\n }\n }\n\n if (provider === \"heuristic\") {\n const fallback = this.heuristicOptimize({\n input: {\n ...input,\n prompt: originalPrompt,\n mode,\n preset\n },\n context: relevantContext,\n constraints: extractedConstraints\n });\n optimizedPrompt = fallback.optimizedPrompt;\n providerChanges = [...providerChanges, ...fallback.changes];\n providerWarnings = [...providerWarnings, ...fallback.warnings];\n }\n\n warnings.push(...providerWarnings);\n changes.push(...providerChanges);\n\n let finalPrompt = composeFinalPrompt({\n optimizedPrompt,\n input: {\n ...input,\n prompt: originalPrompt,\n mode,\n preset\n },\n context: relevantContext\n });\n\n let estimatedTokensAfter = {\n prompt: this.estimator.estimateText(optimizedPrompt),\n context: this.estimator.estimateText(formatContextBlock(relevantContext)),\n total: this.estimator.estimateText(finalPrompt)\n };\n\n if (estimatedTokensAfter.total > maxTotalTokens) {\n const reduced = await this.reduceToBudget({\n input: {\n ...input,\n prompt: originalPrompt,\n mode,\n preset\n },\n optimizedPrompt,\n context: relevantContext,\n maxTotalTokens\n });\n\n finalPrompt = reduced.finalPrompt;\n estimatedTokensAfter = reduced.estimatedTokensAfter;\n if (reduced.warning) {\n warnings.push(reduced.warning);\n }\n }\n\n if (estimatedTokensAfter.total > maxTotalTokens) {\n throw new TokenBudgetExceededError();\n }\n\n if (saveContext && input.sessionId) {\n await this.contextManager.saveContext({\n sessionId: input.sessionId,\n input: {\n ...input,\n prompt: originalPrompt\n },\n optimizedPrompt,\n finalPrompt,\n contextSummary: relevantContext.summary\n });\n }\n\n return {\n originalPrompt,\n optimizedPrompt,\n finalPrompt,\n usedContext: relevantContext.usedEntries,\n contextSummary: relevantContext.summary,\n estimatedTokensBefore,\n estimatedTokensAfter,\n tokenSavings: Math.max(0, estimatedTokensBefore.total - estimatedTokensAfter.total),\n mode,\n provider,\n model,\n warnings,\n changes,\n debugInfo: input.debug\n ? {\n context: relevantContext.debugInfo,\n estimatedTokensBefore,\n estimatedTokensAfter,\n extractedConstraints,\n preset,\n selectedModel: model\n }\n : undefined\n };\n }\n\n async clearContext(sessionId: string): Promise<void> {\n await this.contextManager.clearContext(sessionId);\n }\n\n async loadContext(sessionId: string) {\n return this.contextManager.loadContext(sessionId);\n }\n\n async summarizeContext(sessionId: string, prompt: string, task?: string, budgetTokens = 200) {\n return this.contextManager.summarizeContext(sessionId, prompt, task, budgetTokens, this.config.timeoutMs);\n }\n\n async getRelevantContext(sessionId: string, prompt: string, task?: string, maxContextTokens?: number) {\n return this.contextManager.getRelevantContext({\n sessionId,\n prompt,\n task,\n maxContextTokens: maxContextTokens ?? this.config.maxContextTokens ?? DEFAULT_MAX_CONTEXT_TOKENS,\n timeoutMs: this.config.timeoutMs\n });\n }\n\n private async tryOllamaOptimization(options: {\n input: OptimizePromptInput & { mode: OptimizationMode; preset: PromptPreset };\n model: string;\n extractedConstraints: string[];\n relevantContext: string;\n }): Promise<{ optimizedPrompt: string; changes: string[]; warnings: string[] } | null> {\n try {\n if (!(await this.client.isAvailable())) {\n return null;\n }\n\n const response = await this.client.generateJson<OptimizationResponse>({\n systemPrompt: getOptimizationSystemPrompt(options.input.mode, options.input.preset),\n prompt: buildOptimizationPrompt(options.input, options.relevantContext, options.extractedConstraints),\n timeoutMs: options.input.timeoutMs ?? this.config.timeoutMs,\n model: options.model,\n temperature: this.config.temperature,\n format: \"json\"\n });\n\n const optimizedPrompt = normalizeWhitespace(response.optimizedPrompt ?? \"\");\n if (!optimizedPrompt) {\n return null;\n }\n\n return {\n optimizedPrompt,\n changes: response.changes ?? [`Applied Ollama optimization with ${options.model}.`],\n warnings: response.warnings ?? []\n };\n } catch {\n return null;\n }\n }\n\n private async resolveOllamaModel(options: {\n prompt: string;\n mode: OptimizationMode;\n preset: PromptPreset;\n task?: string;\n }): Promise<{ model: string; warnings: string[]; reason: string; forceHeuristic: boolean }> {\n if (this.config.ollamaModel) {\n return {\n model: this.config.ollamaModel,\n warnings: [],\n reason: `Using explicitly configured model \"${this.config.ollamaModel}\".`,\n forceHeuristic: false\n };\n }\n\n if (!this.client.listModels) {\n return {\n model: \"heuristic\",\n warnings: [\n \"Model auto-selection is unavailable in the current Ollama client, so prompt optimization is falling back to deterministic heuristic formatting.\"\n ],\n reason: \"Model discovery is unsupported, so Qwen-based model routing could not run.\",\n forceHeuristic: true\n };\n }\n\n try {\n const installedModels = await this.client.listModels();\n const suitableModels = getSuitableAutoModels(installedModels);\n const selection = selectOllamaModel({\n installedModels,\n mode: options.mode,\n preset: options.preset,\n task: options.task,\n preferredModels: this.config.preferredModels\n });\n\n if (suitableModels.length === 0) {\n return {\n model: selection.model,\n warnings: [\n `No suitable small Ollama model was found for auto-use. Falling back to heuristic optimization. Install one of: ${this.config.preferredModels.join(\", \")}.`,\n selection.reason\n ],\n reason: selection.reason,\n forceHeuristic: true\n };\n }\n\n if (suitableModels.length === 1) {\n return {\n model: selection.model,\n warnings: [],\n reason: selection.reason,\n forceHeuristic: false\n };\n }\n\n if (this.config.modelRoutingStrategy === \"qwen\") {\n const routed = await this.tryQwenModelRouting({\n prompt: options.prompt,\n task: options.task,\n mode: options.mode,\n preset: options.preset,\n installedModels,\n candidateModels: suitableModels.map((model) => model.name),\n fallbackModel: selection.model\n });\n\n return {\n model: routed.model,\n warnings: routed.warnings,\n reason: routed.reason,\n forceHeuristic: routed.model === \"heuristic\"\n };\n }\n\n return {\n model: \"heuristic\",\n warnings: [\"Qwen model routing is required but was disabled, so prompt optimization is falling back to deterministic heuristic formatting.\"],\n reason: \"Qwen model routing is required but was disabled.\",\n forceHeuristic: true\n };\n } catch {\n return {\n model: \"heuristic\",\n warnings: [\n \"Failed to inspect local Ollama models, so prompt optimization is falling back to deterministic heuristic formatting.\"\n ],\n reason: \"Local Ollama model discovery failed, so Qwen-based model routing could not run.\",\n forceHeuristic: true\n };\n }\n }\n\n private async tryQwenModelRouting(options: {\n prompt: string;\n task?: string;\n mode: OptimizationMode;\n preset: PromptPreset;\n installedModels: { name: string }[];\n candidateModels: string[];\n fallbackModel: string;\n }): Promise<{ model: string; warnings: string[]; reason: string }> {\n const routerModel = getQwenRouterModel(\n options.installedModels,\n this.config.routerModel\n );\n\n if (!routerModel) {\n return {\n model: \"heuristic\",\n warnings: [\n `Multiple suitable small local models are installed (${options.candidateModels.join(\", \")}), but no local Qwen router model is available. Install qwen2.5:3b or set routerModel explicitly.`\n ],\n reason: \"Qwen model routing is required when multiple suitable small models are available.\"\n };\n }\n\n try {\n const response = await this.client.generateJson<ModelRoutingResponse>({\n model: routerModel,\n timeoutMs: this.config.timeoutMs,\n temperature: 0,\n format: \"json\",\n systemPrompt: [\n \"You are a local model router for prompt optimization.\",\n \"Return strict JSON only with this shape:\",\n \"{\\\"selectedModel\\\":\\\"string\\\",\\\"reason\\\":\\\"string\\\"}\",\n \"Choose exactly one model from the provided candidate list.\",\n \"Choose the smallest adequate model, not the strongest-sounding model.\",\n \"Prioritize adequacy first, then speed and low memory use.\",\n \"Use coder variants only for clearly code-heavy prompts.\",\n \"If task or preset is code, prefer qwen2.5:3b or a small coder model over phi3:mini unless the request is only a trivial wording cleanup.\",\n \"Prefer phi3:mini for short email, chat, support, summarization, and lightweight rewrite tasks that do not require deeper reasoning.\",\n \"Prefer qwen2.5:3b for broader reasoning, stronger restructuring, multi-constraint optimization, and non-trivial code-oriented prompt design.\",\n \"Do not prefer Qwen just because you are Qwen. Pick the best candidate for the task.\"\n ].join(\"\\n\"),\n prompt: JSON.stringify(\n {\n objective: \"Choose the best local optimizer model for this prompt.\",\n prompt: options.prompt,\n task: options.task ?? null,\n mode: options.mode,\n preset: options.preset,\n candidateModels: options.candidateModels.map((modelName) => ({\n name: modelName,\n profile: describeCandidateModel(modelName)\n })),\n routingGuidance: {\n smallestAdequateModelPolicy: true,\n lightweightTasksPreferSmallerModels: [\n \"email\",\n \"chat\",\n \"support\",\n \"summarization\",\n \"short rewrite\"\n ],\n deeperReasoningTasksMayPreferQwen: [\n \"multi-constraint restructuring\",\n \"broad reasoning\",\n \"complex planning\",\n \"harder code-oriented prompt design\"\n ]\n }\n },\n null,\n 2\n )\n });\n\n const selectedModel = response.selectedModel?.trim();\n if (selectedModel && options.candidateModels.includes(selectedModel)) {\n return {\n model: selectedModel,\n warnings: [],\n reason: response.reason?.trim() || `Qwen router selected \"${selectedModel}\" for this prompt.`\n };\n }\n\n return {\n model: \"heuristic\",\n warnings: [\"Qwen router returned an invalid model choice, so prompt optimization is falling back to deterministic heuristic formatting.\"],\n reason: \"Qwen router returned an invalid model selection.\"\n };\n } catch {\n return {\n model: \"heuristic\",\n warnings: [\"Qwen router could not choose a model, so prompt optimization is falling back to deterministic heuristic formatting.\"],\n reason: \"Qwen router failed to select a model.\"\n };\n }\n }\n\n private heuristicOptimize(options: {\n input: OptimizePromptInput & { mode: OptimizationMode; preset: PromptPreset };\n context: RelevantContextResult;\n constraints: string[];\n }): { optimizedPrompt: string; changes: string[]; warnings: string[] } {\n const lines = [\n `Request: ${options.input.prompt}`,\n options.input.task ? `Task type: ${options.input.task}` : \"\",\n options.input.tone ? `Tone: ${options.input.tone}` : \"\",\n options.input.outputFormat ? `Output format: ${options.input.outputFormat}` : \"\",\n options.input.maxLength ? `Maximum length: ${options.input.maxLength}` : \"\",\n options.constraints.length ? `Critical constraints: ${options.constraints.join(\"; \")}` : \"\"\n ].filter(Boolean);\n\n const optimizedPrompt = lines.join(\"\\n\");\n const changes = [\"Normalized prompt structure for downstream model consumption.\"];\n if (options.input.mode === \"compress\" || options.input.mode === \"concise\") {\n changes.push(\"Applied concise formatting to reduce token usage.\");\n }\n\n return {\n optimizedPrompt,\n changes,\n warnings: []\n };\n }\n\n private async reduceToBudget(options: {\n input: OptimizePromptInput & { mode: OptimizationMode; preset: PromptPreset };\n optimizedPrompt: string;\n context: RelevantContextResult;\n maxTotalTokens: number;\n }): Promise<{ finalPrompt: string; estimatedTokensAfter: { prompt: number; context: number; total: number }; warning?: string }> {\n const summaryBudget = Math.max(80, Math.floor(options.maxTotalTokens * 0.2));\n const summary = options.input.sessionId\n ? await this.summarizeContext(options.input.sessionId, options.input.prompt, options.input.task, summaryBudget)\n : null;\n\n const compactContext: RelevantContextResult = {\n ...options.context,\n usedEntries: [],\n summary\n };\n\n const finalPrompt = composeFinalPrompt({\n optimizedPrompt: this.estimator.truncateToBudget(options.optimizedPrompt, Math.floor(options.maxTotalTokens * 0.5)),\n input: options.input,\n context: compactContext\n });\n\n return {\n finalPrompt,\n estimatedTokensAfter: {\n prompt: this.estimator.estimateText(options.optimizedPrompt),\n context: this.estimator.estimateText(formatContextBlock(compactContext)),\n total: this.estimator.estimateText(finalPrompt)\n },\n warning: \"Summarized stored context further to stay within the total token budget.\"\n };\n }\n}\n\nfunction describeCandidateModel(modelName: string): string {\n const lower = modelName.toLowerCase();\n\n if (lower.includes(\"phi3:mini\")) {\n return \"Very small and fast. Good for short rewrites, lightweight email/chat tasks, and simple prompt cleanup.\";\n }\n\n if (lower.includes(\"qwen2.5:3b\")) {\n return \"Small general-purpose model with stronger reasoning and restructuring than ultra-light models. Better for broader or more complex prompt optimization.\";\n }\n\n if (lower.includes(\"coder\")) {\n return \"Code-specialized model. Use only when the prompt is clearly code-heavy or refactor-oriented.\";\n }\n\n if (lower.includes(\"llama3.2:3b\")) {\n return \"Small general chat/rewrite model. Reasonable middle option for general tasks.\";\n }\n\n return \"Local candidate model for prompt optimization.\";\n}\n\nfunction resolveSessionStore(config: OptimizerConfig): SessionStore {\n if (typeof config.contextStore === \"object\" && config.contextStore !== null) {\n return config.contextStore;\n }\n\n if (config.contextStore === \"sqlite\") {\n return new SQLiteSessionStore(config.sqlitePath);\n }\n\n return new FileSessionStore(config.storageDir);\n}\n\nfunction composeFinalPrompt(input: {\n optimizedPrompt: string;\n input: OptimizePromptInput & { mode: OptimizationMode; preset: PromptPreset };\n context: RelevantContextResult;\n}): string {\n const sections: string[] = [];\n\n sections.push(`Task:\\n${input.optimizedPrompt}`);\n\n const contextBlock = formatContextBlock(input.context);\n if (contextBlock) {\n sections.push(`Relevant context:\\n${contextBlock}`);\n }\n\n const constraints = Array.from(\n new Set([\n ...(input.input.pinnedConstraints ?? []),\n ...extractConstraints(input.input.prompt),\n input.input.maxLength ? `Keep the response within ${input.input.maxLength} units if possible.` : \"\",\n input.input.tone ? `Maintain a ${input.input.tone} tone.` : \"\",\n input.input.outputFormat ? `Return the output as ${input.input.outputFormat}.` : \"\"\n ].filter(Boolean))\n );\n\n if (constraints.length > 0) {\n sections.push(`Constraints:\\n- ${constraints.join(\"\\n- \")}`);\n }\n\n const desiredOutput = [\n input.input.targetModel ? `Target model: ${input.input.targetModel}` : \"Target model: claude\",\n `Mode: ${input.input.mode}`,\n `Preset: ${input.input.preset}`\n ];\n\n sections.push(`Desired output:\\n- ${desiredOutput.join(\"\\n- \")}`);\n\n return sections.join(\"\\n\\n\").trim();\n}\n\nfunction formatContextBlock(context: RelevantContextResult): string {\n const lines: string[] = [];\n\n if (context.summary?.text) {\n lines.push(`Summary: ${context.summary.text}`);\n }\n\n for (const entry of context.usedEntries.slice(-4)) {\n lines.push(`- ${entry.optimizedPrompt ?? entry.rawPrompt ?? entry.text}`);\n }\n\n return normalizeWhitespace(lines.join(\"\\n\"));\n}\n\nfunction emptyRelevantContext(): RelevantContextResult {\n return {\n usedEntries: [],\n summary: null,\n warnings: [],\n debugInfo: {}\n };\n}\n","import type { OptimizePromptInput, OptimizerConfig } from \"./types.js\";\nimport { PromptOptimizer } from \"./core/optimizer.js\";\n\nexport * from \"./types.js\";\nexport * from \"./errors.js\";\nexport { PromptOptimizer } from \"./core/optimizer.js\";\nexport { OllamaClient } from \"./core/ollamaClient.js\";\nexport { TokenEstimator } from \"./core/tokenEstimator.js\";\nexport { ContextManager } from \"./core/contextManager.js\";\nexport { ContextCompressor } from \"./core/contextCompressor.js\";\nexport { selectOllamaModel, getDefaultPreferredModels } from \"./core/modelSelector.js\";\nexport { FileSessionStore } from \"./storage/fileSessionStore.js\";\nexport { SQLiteSessionStore } from \"./storage/sqliteSessionStore.js\";\n\nexport function createOptimizer(config: OptimizerConfig = {}) {\n return new PromptOptimizer(config);\n}\n\nexport async function optimizePrompt(input: OptimizePromptInput, config: OptimizerConfig = {}) {\n const optimizer = createOptimizer(config);\n return optimizer.optimize(input);\n}\n"],"mappings":"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","names":["dirname","join","mkdir","join","mkdir","dirname","randomUUID","randomUUID"]}
package/dist/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  type ProviderType = "ollama" | "heuristic";
2
2
  type OptimizationMode = "clarity" | "concise" | "detailed" | "structured" | "persuasive" | "compress" | "claude_cli";
3
3
  type PromptPreset = "code" | "email" | "essay" | "support" | "summarization" | "chat";
4
+ type ModelRoutingStrategy = "qwen";
4
5
  interface ContextEntry {
5
6
  id: string;
6
7
  sessionId: string;
@@ -113,6 +114,8 @@ interface OptimizerConfig {
113
114
  host?: string;
114
115
  ollamaModel?: string;
115
116
  preferredModels?: string[];
117
+ modelRoutingStrategy?: ModelRoutingStrategy;
118
+ routerModel?: string;
116
119
  timeoutMs?: number;
117
120
  temperature?: number;
118
121
  contextStore?: "local" | "sqlite" | SessionStore;
@@ -139,6 +142,7 @@ declare class PromptOptimizer {
139
142
  timeoutMs: number;
140
143
  temperature: number;
141
144
  preferredModels: string[];
145
+ modelRoutingStrategy: "qwen";
142
146
  };
143
147
  private readonly logger;
144
148
  private readonly estimator;
@@ -153,6 +157,7 @@ declare class PromptOptimizer {
153
157
  getRelevantContext(sessionId: string, prompt: string, task?: string, maxContextTokens?: number): Promise<RelevantContextResult>;
154
158
  private tryOllamaOptimization;
155
159
  private resolveOllamaModel;
160
+ private tryQwenModelRouting;
156
161
  private heuristicOptimize;
157
162
  private reduceToBudget;
158
163
  }
@@ -284,4 +289,4 @@ declare class SQLiteSessionStore implements SessionStore {
284
289
  declare function createOptimizer(config?: OptimizerConfig): PromptOptimizer;
285
290
  declare function optimizePrompt(input: OptimizePromptInput, config?: OptimizerConfig): Promise<OptimizePromptResult>;
286
291
 
287
- export { ContextCompressor, type ContextEntry, ContextManager, ContextStoreError, type ContextSummary, FileSessionStore, InvalidPromptError, type Logger, OllamaClient, type OllamaClientLike, type OllamaGenerateOptions, type OllamaModelInfo, OllamaUnavailableError, type OptimizationMode, type OptimizePromptInput, type OptimizePromptResult, type OptimizerConfig, PromptOptimizer, type PromptPreset, type ProviderType, type RelevantContextResult, SQLiteSessionStore, type SessionData, type SessionStore, TokenBudgetExceededError, TokenEstimator, type TokenUsageEstimate, createOptimizer, getDefaultPreferredModels, optimizePrompt, selectOllamaModel };
292
+ export { ContextCompressor, type ContextEntry, ContextManager, ContextStoreError, type ContextSummary, FileSessionStore, InvalidPromptError, type Logger, type ModelRoutingStrategy, OllamaClient, type OllamaClientLike, type OllamaGenerateOptions, type OllamaModelInfo, OllamaUnavailableError, type OptimizationMode, type OptimizePromptInput, type OptimizePromptResult, type OptimizerConfig, PromptOptimizer, type PromptPreset, type ProviderType, type RelevantContextResult, SQLiteSessionStore, type SessionData, type SessionStore, TokenBudgetExceededError, TokenEstimator, type TokenUsageEstimate, createOptimizer, getDefaultPreferredModels, optimizePrompt, selectOllamaModel };