@avasis-ai/synthcode 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +292 -0
- package/dist/chunk-53ZOIXM4.js +624 -0
- package/dist/chunk-53ZOIXM4.js.map +1 -0
- package/dist/chunk-BWXHO6UJ.js +115 -0
- package/dist/chunk-BWXHO6UJ.js.map +1 -0
- package/dist/chunk-CARUMOML.js +123 -0
- package/dist/chunk-CARUMOML.js.map +1 -0
- package/dist/chunk-DGUM43GV.js +11 -0
- package/dist/chunk-DGUM43GV.js.map +1 -0
- package/dist/chunk-F34HO4RA.js +487 -0
- package/dist/chunk-F34HO4RA.js.map +1 -0
- package/dist/chunk-FK7S2S7V.js +132 -0
- package/dist/chunk-FK7S2S7V.js.map +1 -0
- package/dist/chunk-MQ7XP6VT.js +174 -0
- package/dist/chunk-MQ7XP6VT.js.map +1 -0
- package/dist/chunk-TLPOO6C3.js +176 -0
- package/dist/chunk-TLPOO6C3.js.map +1 -0
- package/dist/chunk-W6OLZ2OI.js +56 -0
- package/dist/chunk-W6OLZ2OI.js.map +1 -0
- package/dist/cli/index.cjs +151 -0
- package/dist/cli/index.cjs.map +1 -0
- package/dist/cli/index.d.cts +1 -0
- package/dist/cli/index.d.ts +1 -0
- package/dist/cli/index.js +8 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/run.cjs +128 -0
- package/dist/cli/run.cjs.map +1 -0
- package/dist/cli/run.d.cts +1 -0
- package/dist/cli/run.d.ts +1 -0
- package/dist/cli/run.js +126 -0
- package/dist/cli/run.js.map +1 -0
- package/dist/index-D-K6sx8s.d.cts +8 -0
- package/dist/index-D-K6sx8s.d.ts +8 -0
- package/dist/index.cjs +2909 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +274 -0
- package/dist/index.d.ts +274 -0
- package/dist/index.js +1048 -0
- package/dist/index.js.map +1 -0
- package/dist/llm/index.cjs +531 -0
- package/dist/llm/index.cjs.map +1 -0
- package/dist/llm/index.d.cts +70 -0
- package/dist/llm/index.d.ts +70 -0
- package/dist/llm/index.js +24 -0
- package/dist/llm/index.js.map +1 -0
- package/dist/mcp/index.cjs +323 -0
- package/dist/mcp/index.cjs.map +1 -0
- package/dist/mcp/index.d.cts +39 -0
- package/dist/mcp/index.d.ts +39 -0
- package/dist/mcp/index.js +11 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/memory/index.cjs +146 -0
- package/dist/memory/index.cjs.map +1 -0
- package/dist/memory/index.d.cts +51 -0
- package/dist/memory/index.d.ts +51 -0
- package/dist/memory/index.js +10 -0
- package/dist/memory/index.js.map +1 -0
- package/dist/tools/fuzzy-edit.cjs +200 -0
- package/dist/tools/fuzzy-edit.cjs.map +1 -0
- package/dist/tools/fuzzy-edit.d.cts +9 -0
- package/dist/tools/fuzzy-edit.d.ts +9 -0
- package/dist/tools/fuzzy-edit.js +12 -0
- package/dist/tools/fuzzy-edit.js.map +1 -0
- package/dist/tools/index.cjs +1032 -0
- package/dist/tools/index.cjs.map +1 -0
- package/dist/tools/index.d.cts +4 -0
- package/dist/tools/index.d.ts +4 -0
- package/dist/tools/index.js +39 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/types-C11cw5ZD.d.cts +177 -0
- package/dist/types-C11cw5ZD.d.ts +177 -0
- package/dist/utils-TF4TBXQJ.js +10 -0
- package/dist/utils-TF4TBXQJ.js.map +1 -0
- package/dist/web-fetch-B42QzYD2.d.cts +85 -0
- package/dist/web-fetch-EDdhxmEf.d.ts +85 -0
- package/package.json +134 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/tools/orchestrator.ts","../src/tools/registry.ts","../src/tools/bash.ts","../src/tools/file-read.ts","../src/tools/file-write.ts","../src/tools/file-edit.ts","../src/tools/glob.ts","../src/tools/grep.ts","../src/tools/web-fetch.ts"],"sourcesContent":["import type { ToolContext, ToolUseBlock } from '../types.js';\nimport type { Tool } from './tool.js';\nimport { ToolRegistry } from './registry.js';\n\n/** Result of a single tool execution. */\nexport interface ToolExecutionResult {\n id: string;\n name: string;\n output: string;\n isError: boolean;\n durationMs: number;\n}\n\nclass Semaphore {\n private current = 0;\n private queue: (() => void)[] = [];\n\n constructor(private readonly max: number) {}\n\n acquire(): Promise<void> {\n if (this.current < this.max) {\n this.current++;\n return Promise.resolve();\n }\n return new Promise<void>((resolve) => {\n this.queue.push(resolve);\n });\n }\n\n release(): void {\n this.current--;\n const next = this.queue.shift();\n if (next) {\n this.current++;\n next();\n }\n }\n}\n\nfunction partitionToolCalls(\n toolCalls: ToolUseBlock[],\n registry: ToolRegistry,\n): ToolUseBlock[][] {\n const batches: ToolUseBlock[][] = [];\n let currentBatch: ToolUseBlock[] = [];\n let currentBatchIsConcurrent = false;\n\n for (const call of toolCalls) {\n const tool = registry.get(call.name);\n const isConcurrent = tool ? tool.isReadOnly && tool.isConcurrencySafe : false;\n\n if (isConcurrent && currentBatchIsConcurrent) {\n currentBatch.push(call);\n } else {\n if (currentBatch.length > 0) {\n batches.push(currentBatch);\n }\n currentBatch = [call];\n currentBatchIsConcurrent = isConcurrent;\n }\n }\n\n if (currentBatch.length > 0) {\n batches.push(currentBatch);\n }\n\n return batches;\n}\n\nasync function executeToolCall(\n call: ToolUseBlock,\n registry: ToolRegistry,\n context: ToolContext,\n permissionCheck?: (name: string, input: Record<string, unknown>) => Promise<boolean>,\n abortSignal?: AbortSignal,\n): Promise<ToolExecutionResult> {\n if (abortSignal?.aborted) {\n return {\n id: call.id,\n name: call.name,\n output: 'Execution aborted',\n isError: true,\n durationMs: 0,\n };\n }\n\n const tool = registry.get(call.name);\n if (!tool) {\n return {\n id: call.id,\n name: call.name,\n output: `Unknown tool: ${call.name}`,\n isError: true,\n durationMs: 0,\n };\n }\n\n const start = performance.now();\n\n try {\n const parseResult = tool.inputSchema.safeParse(call.input);\n if (!parseResult.success) {\n return {\n id: call.id,\n name: call.name,\n output: `Invalid input for ${call.name}: ${parseResult.error.issues.map((i) => i.message).join(', ')}`,\n isError: true,\n durationMs: Math.round(performance.now() - start),\n };\n }\n\n if (permissionCheck) {\n const allowed = await permissionCheck(call.name, call.input);\n if (!allowed) {\n return {\n id: call.id,\n name: call.name,\n output: `Permission denied for tool: ${call.name}`,\n isError: true,\n durationMs: Math.round(performance.now() - start),\n };\n }\n }\n\n const output = await tool.execute(parseResult.data, context);\n\n return {\n id: call.id,\n name: call.name,\n output,\n isError: false,\n durationMs: Math.round(performance.now() - start),\n };\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : String(err);\n return {\n id: call.id,\n name: call.name,\n output: `Error executing ${call.name}: ${message}`,\n isError: true,\n durationMs: Math.round(performance.now() - start),\n };\n }\n}\n\n/**\n * Orchestrate execution of multiple tool calls with partition-based concurrency.\n *\n * Read-only, concurrency-safe tools are grouped into concurrent batches (max 10 parallel).\n * Non-safe tools are executed serially in their own batches.\n * Results are returned in the original call order.\n */\nexport async function orchestrateTools(\n tools: ToolRegistry,\n toolCalls: ToolUseBlock[],\n context: ToolContext,\n permissionCheck?: (name: string, input: Record<string, unknown>) => Promise<boolean>,\n abortSignal?: AbortSignal,\n): Promise<ToolExecutionResult[]> {\n const batches = partitionToolCalls(toolCalls, tools);\n const results: ToolExecutionResult[] = [];\n\n for (const batch of batches) {\n if (abortSignal?.aborted) {\n for (const call of batch) {\n results.push({\n id: call.id,\n name: call.name,\n output: 'Execution aborted',\n isError: true,\n durationMs: 0,\n });\n }\n continue;\n }\n\n if (batch.length > 1) {\n const semaphore = new Semaphore(10);\n const promises = batch.map((call) =>\n semaphore.acquire().then(async () => {\n try {\n return await executeToolCall(call, tools, context, permissionCheck, abortSignal);\n } finally {\n semaphore.release();\n }\n }),\n );\n const settled = await Promise.allSettled(promises);\n for (let i = 0; i < settled.length; i++) {\n const s = settled[i];\n if (s.status === 'fulfilled') {\n results.push(s.value);\n } else {\n results.push({\n id: batch[i].id,\n name: batch[i].name,\n output: `Unexpected error: ${s.reason instanceof Error ? s.reason.message : String(s.reason)}`,\n isError: true,\n durationMs: 0,\n });\n }\n }\n } else {\n const result = await executeToolCall(batch[0], tools, context, permissionCheck, abortSignal);\n results.push(result);\n }\n }\n\n return results;\n}\n","import type { Tool, APIToolDefinition } from './tool.js';\n\n/** Registry for managing tool lookup and deduplication. */\nexport class ToolRegistry {\n private readonly tools = new Map<string, Tool>();\n\n constructor(tools?: Tool[]) {\n if (tools) {\n for (const tool of tools) {\n this.add(tool);\n }\n }\n }\n\n /** Add a tool to the registry. Duplicate names are ignored (first one wins). */\n add(tool: Tool): void {\n if (this.tools.has(tool.name)) {\n console.warn(`[ToolRegistry] Duplicate tool \"${tool.name}\" ignored (first one wins)`);\n return;\n }\n this.tools.set(tool.name, tool);\n }\n\n /** Get a tool by name. */\n get(name: string): Tool | undefined {\n return this.tools.get(name);\n }\n\n /** Check if a tool exists by name. */\n has(name: string): boolean {\n return this.tools.has(name);\n }\n\n /** Find tool by case-insensitive name. Returns undefined if not found. */\n findCaseInsensitive(name: string): string | undefined {\n const lower = name.toLowerCase();\n if (this.tools.has(name)) return name;\n for (const key of this.tools.keys()) {\n if (key.toLowerCase() === lower) return key;\n }\n return undefined;\n }\n\n /** List all registered tool names. */\n listNames(): string[] {\n return Array.from(this.tools.keys());\n }\n\n /** Get all registered tools. */\n getAll(): Tool[] {\n return Array.from(this.tools.values());\n }\n\n /** Get all tools in API format, sorted by name for cache stability. */\n getAPI(): APIToolDefinition[] {\n return this.getAll()\n .sort((a, b) => a.name.localeCompare(b.name))\n .map((t) => t.toAPI());\n }\n\n /** Number of registered tools. */\n get size(): number {\n return this.tools.size;\n }\n}\n","import { exec } from 'node:child_process';\nimport { z } from 'zod';\nimport { defineTool } from './tool.js';\n\nconst MAX_OUTPUT = 50 * 1024;\nconst TRUNCATE_HALF = 25 * 1024;\n\nfunction truncateOutput(output: string): string {\n if (output.length <= MAX_OUTPUT) return output;\n const notice = `\\n\\n... [output truncated: showing first ${TRUNCATE_HALF} and last ${TRUNCATE_HALF} of ${output.length} characters] ...\\n\\n`;\n return output.slice(0, TRUNCATE_HALF) + notice + output.slice(-TRUNCATE_HALF);\n}\n\nexport const BashTool = defineTool({\n name: 'bash',\n description:\n 'Execute a shell command. Returns stdout and stderr. Use for running build commands, git operations, package managers, and other CLI tools.',\n inputSchema: z.object({\n command: z.string().describe('The shell command to execute'),\n timeout: z.number().optional().describe('Timeout in milliseconds (default 120000)'),\n workdir: z.string().optional().describe('Working directory for the command'),\n }),\n isReadOnly: false,\n isConcurrencySafe: false,\n execute: async ({ command, timeout = 120000, workdir }, context) => {\n return new Promise<string>((resolve) => {\n let settled = false;\n const done = (result: string) => {\n if (settled) return;\n settled = true;\n resolve(result);\n };\n\n if (context.abortSignal?.aborted) {\n done('Command aborted before execution');\n return;\n }\n\n const child = exec(\n command,\n {\n cwd: workdir ?? context.cwd,\n timeout,\n maxBuffer: 10 * 1024 * 1024,\n killSignal: 'SIGKILL',\n },\n (error, stdout, stderr) => {\n let output = '';\n if (stdout) output += `STDOUT:\\n${stdout}\\n\\n`;\n if (stderr) output += `STDERR:\\n${stderr}\\n\\n`;\n output += `Exit code: ${error?.code ?? 0}`;\n if (error && error.killed) {\n output = `Command timed out after ${timeout}ms\\n\\n${output}`;\n }\n done(truncateOutput(output));\n },\n );\n\n child.on('error', (err) => {\n done(`Failed to execute command: ${err.message}`);\n });\n\n if (context.abortSignal) {\n context.abortSignal.addEventListener(\n 'abort',\n () => {\n child.kill('SIGKILL');\n done('Command aborted');\n },\n { once: true },\n );\n }\n });\n },\n});\n","import fs from 'node:fs/promises';\nimport path from 'node:path';\nimport { z } from 'zod';\nimport { defineTool } from './tool.js';\n\nconst MAX_LINE_LENGTH = 2000;\n\nexport const FileReadTool = defineTool({\n name: 'file_read',\n description:\n 'Read the contents of a file. Returns the file content with line numbers. Use GlobTool to find files first.',\n inputSchema: z.object({\n path: z.string().describe('Absolute or relative path to the file'),\n offset: z.number().optional().describe('Line number to start reading from (1-indexed)'),\n limit: z.number().optional().describe('Maximum number of lines to read'),\n }),\n isReadOnly: true,\n isConcurrencySafe: true,\n execute: async ({ path: filePath, offset, limit }, context) => {\n try {\n const resolved = path.isAbsolute(filePath) ? filePath : path.resolve(context.cwd, filePath);\n\n const content = await fs.readFile(resolved, 'utf-8');\n const lines = content.split('\\n');\n\n const startLine = offset ? Math.max(1, offset) : 1;\n const startIndex = startLine - 1;\n const endIndex = limit != null ? startIndex + limit : lines.length;\n const selected = lines.slice(startIndex, endIndex);\n\n const formatted = selected\n .map((line, i) => {\n const lineNum = startLine + i;\n const truncated = line.length > MAX_LINE_LENGTH ? line.slice(0, MAX_LINE_LENGTH) + '...' : line;\n return `${lineNum}: ${truncated}`;\n })\n .join('\\n');\n\n return formatted;\n } catch (err: unknown) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') {\n return `Error: File not found: ${filePath}`;\n }\n if ((err as NodeJS.ErrnoException).code === 'EISDIR') {\n return `Error: Path is a directory: ${filePath}`;\n }\n return `Error reading file: ${err instanceof Error ? err.message : String(err)}`;\n }\n },\n});\n","import fs from 'node:fs/promises';\nimport path from 'node:path';\nimport { z } from 'zod';\nimport { defineTool } from './tool.js';\n\nexport const FileWriteTool = defineTool({\n name: 'file_write',\n description:\n \"Write content to a file. Creates the file if it doesn't exist, overwrites if it does. Parent directories are created automatically.\",\n inputSchema: z.object({\n path: z.string().describe('Path to the file'),\n content: z.string().describe('Content to write'),\n }),\n isReadOnly: false,\n isConcurrencySafe: false,\n execute: async ({ path: filePath, content }, context) => {\n try {\n const resolved = path.isAbsolute(filePath) ? filePath : path.resolve(context.cwd, filePath);\n const dir = path.dirname(resolved);\n\n await fs.mkdir(dir, { recursive: true });\n await fs.writeFile(resolved, content, 'utf-8');\n\n return `Wrote ${content.length} characters to ${filePath}`;\n } catch (err: unknown) {\n return `Error writing file: ${err instanceof Error ? err.message : String(err)}`;\n }\n },\n});\n","import fs from 'node:fs/promises';\nimport path from 'node:path';\nimport { z } from 'zod';\nimport { defineTool } from './tool.js';\nimport { fuzzyReplace } from './fuzzy-edit.js';\n\nexport const FileEditTool = defineTool({\n name: 'file_edit',\n description:\n 'Edit an existing file by replacing a string match with new content. Uses 9-strategy fuzzy matching (exact, line-trimmed, block-anchor with Levenshtein, whitespace-normalized, indentation-flexible, escape-normalized, trimmed-boundary, context-aware, multi-occurrence) so the oldString does not need to be a perfect character-for-character match. For multi-line edits, include enough surrounding context to ensure uniqueness.',\n inputSchema: z.object({\n path: z.string().describe('Path to the file'),\n oldString: z.string().describe('The string to find and replace (fuzzy-matched)'),\n newString: z.string().describe('The replacement string'),\n replaceAll: z.boolean().optional().describe('Replace all occurrences instead of just the first'),\n }),\n isReadOnly: false,\n isConcurrencySafe: false,\n execute: async ({ path: filePath, oldString, newString, replaceAll = false }, context) => {\n try {\n const resolved = path.isAbsolute(filePath) ? filePath : path.resolve(context.cwd, filePath);\n\n const content = await fs.readFile(resolved, 'utf-8');\n\n let newContent: string;\n let count = 0;\n\n if (replaceAll) {\n const occurrences = content.split(oldString).length - 1;\n if (occurrences === 0) {\n try {\n newContent = fuzzyReplace(content, oldString, newString, true);\n count = 1;\n } catch {\n return `Error: oldString not found in ${filePath} (tried 9 fuzzy strategies)`;\n }\n } else {\n newContent = content.split(oldString).join(newString);\n count = occurrences;\n }\n } else {\n try {\n newContent = fuzzyReplace(content, oldString, newString, false);\n count = 1;\n } catch (err) {\n const kind = (err as { kind?: string }).kind;\n if (kind === \"ambiguous\") {\n return `Error: Multiple matches for oldString in ${filePath}. Provide more surrounding context or set replaceAll to true.`;\n }\n return `Error: oldString not found in ${filePath} (tried 9 fuzzy strategies)`;\n }\n }\n\n await fs.writeFile(resolved, newContent, 'utf-8');\n\n return `Replaced ${count} occurrence(s) in ${filePath}`;\n } catch (err: unknown) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') {\n return `Error: File not found: ${filePath}`;\n }\n return `Error editing file: ${err instanceof Error ? err.message : String(err)}`;\n }\n },\n});\n","import fs from 'node:fs/promises';\nimport path from 'node:path';\nimport { z } from 'zod';\nimport { defineTool } from './tool.js';\nimport { globToRegExp } from '../utils.js';\n\nconst MAX_RESULTS = 200;\n\nasync function walkDir(dir: string): Promise<string[]> {\n const { walkDir: walk } = await import('../utils.js');\n const entries = await walk(dir);\n return entries.map((e) => e.path);\n}\n\nfunction matchInclude(filePath: string, includePattern?: string): boolean {\n if (!includePattern) return true;\n const base = path.basename(filePath);\n const re = globToRegExp(includePattern);\n return re.test(base);\n}\n\nexport const GlobTool = defineTool({\n name: 'glob',\n description:\n 'Find files matching a glob pattern. Returns matching file paths sorted by modification time.',\n inputSchema: z.object({\n pattern: z.string().describe('Glob pattern (e.g., \"**/*.ts\", \"src/**/*.tsx\")'),\n path: z.string().optional().describe('Directory to search in (default: current directory)'),\n include: z.string().optional().describe('File extension or pattern to include (e.g., \"*.ts\")'),\n }),\n isReadOnly: true,\n isConcurrencySafe: true,\n execute: async ({ pattern, path: searchPath, include }, context) => {\n try {\n const searchDir = searchPath\n ? path.isAbsolute(searchPath)\n ? searchPath\n : path.resolve(context.cwd, searchPath)\n : context.cwd;\n\n const allFiles = await walkDir(searchDir);\n const re = globToRegExp(pattern);\n\n const matched: Array<{ filePath: string; mtimeMs: number }> = [];\n\n for (const filePath of allFiles) {\n const relative = path.relative(searchDir, filePath);\n if (re.test(relative) && matchInclude(relative, include)) {\n try {\n const stat = await fs.stat(filePath);\n matched.push({ filePath: relative, mtimeMs: stat.mtimeMs });\n } catch {\n matched.push({ filePath: relative, mtimeMs: 0 });\n }\n }\n }\n\n matched.sort((a, b) => b.mtimeMs - a.mtimeMs);\n const limited = matched.slice(0, MAX_RESULTS);\n return limited.map((m) => m.filePath).join('\\n');\n } catch (err: unknown) {\n return `Error searching files: ${err instanceof Error ? err.message : String(err)}`;\n }\n },\n});\n","import fs from 'node:fs/promises';\nimport path from 'node:path';\nimport { z } from 'zod';\nimport { defineTool } from './tool.js';\nimport { globToRegExp } from '../utils.js';\n\nconst MAX_MATCHES = 200;\n\nasync function walkDir(dir: string): Promise<string[]> {\n const { walkDir: walk } = await import('../utils.js');\n const entries = await walk(dir);\n return entries.map((e) => e.path);\n}\n\nexport const GrepTool = defineTool({\n name: 'grep',\n description:\n 'Search file contents using a regular expression. Returns matching file paths with line numbers.',\n inputSchema: z.object({\n pattern: z.string().describe('Regular expression to search for'),\n path: z.string().optional().describe('Directory to search in'),\n include: z.string().optional().describe('File pattern to include (e.g., \"*.ts\")'),\n }),\n isReadOnly: true,\n isConcurrencySafe: true,\n execute: async ({ pattern, path: searchPath, include }, context) => {\n try {\n let regex: RegExp;\n try {\n regex = new RegExp(pattern);\n } catch {\n return `Error: Invalid regular expression: ${pattern}`;\n }\n\n const searchDir = searchPath\n ? path.isAbsolute(searchPath)\n ? searchPath\n : path.resolve(context.cwd, searchPath)\n : context.cwd;\n\n const includeRe = include ? globToRegExp(include) : null;\n const allFiles = await walkDir(searchDir);\n const matches: string[] = [];\n\n for (const filePath of allFiles) {\n if (matches.length >= MAX_MATCHES) break;\n\n if (includeRe) {\n const base = path.basename(filePath);\n if (!includeRe.test(base)) continue;\n }\n\n let content: string;\n try {\n content = await fs.readFile(filePath, 'utf-8');\n } catch {\n continue;\n }\n\n const lines = content.split('\\n');\n const relative = path.relative(searchDir, filePath);\n\n for (let lineIdx = 0; lineIdx < lines.length; lineIdx++) {\n if (matches.length >= MAX_MATCHES) break;\n const line = lines[lineIdx];\n if (regex.test(line)) {\n matches.push(`${relative}:${lineIdx + 1}: ${line}`);\n regex.lastIndex = 0;\n } else {\n regex.lastIndex = 0;\n }\n }\n }\n\n if (matches.length === 0) {\n return 'No matches found.';\n }\n\n return matches.join('\\n');\n } catch (err: unknown) {\n return `Error searching files: ${err instanceof Error ? err.message : String(err)}`;\n }\n },\n});\n","import { z } from 'zod';\nimport { defineTool } from './tool.js';\n\nconst MAX_RESPONSE_SIZE = 100 * 1024;\n\nexport const WebFetchTool = defineTool({\n name: 'web_fetch',\n description:\n 'Fetch content from a URL. Returns the response body as text. Supports HTTP and HTTPS.',\n inputSchema: z.object({\n url: z.string().url().describe('The URL to fetch'),\n method: z.enum(['GET', 'POST', 'PUT', 'DELETE']).optional().describe('HTTP method (default: GET)'),\n headers: z.record(z.string()).optional().describe('Request headers'),\n body: z.string().optional().describe('Request body (for POST/PUT)'),\n }),\n isReadOnly: true,\n isConcurrencySafe: true,\n execute: async ({ url, method = 'GET', headers, body }, context) => {\n try {\n if (context.abortSignal?.aborted) {\n return 'Request aborted before execution';\n }\n\n const timeoutSignal = AbortSignal.timeout(30_000);\n let signal: AbortSignal;\n if (context.abortSignal) {\n signal = AbortSignal.any([context.abortSignal, timeoutSignal]);\n } else {\n signal = timeoutSignal;\n }\n\n const fetchOptions: RequestInit = {\n method,\n headers,\n signal,\n redirect: 'follow',\n };\n\n if (body && method !== 'GET') {\n fetchOptions.body = body;\n }\n\n const response = await fetch(url, fetchOptions);\n const contentType = response.headers.get('content-type') ?? 'unknown';\n const status = response.status;\n\n const text = await response.text();\n\n let result = `Status: ${status}\\nContent-Type: ${contentType}\\n\\n`;\n if (text.length > MAX_RESPONSE_SIZE) {\n const half = Math.floor(MAX_RESPONSE_SIZE / 2);\n const notice = `\\n\\n... [response truncated: showing first ${half} and last ${half} of ${text.length} characters] ...\\n\\n`;\n result += text.slice(0, half) + notice + text.slice(-half);\n } else {\n result += text;\n }\n\n return result;\n } catch (err: unknown) {\n if (err instanceof Error && err.name === 'AbortError') {\n return 'Request aborted';\n }\n return `Error fetching URL: ${err instanceof Error ? err.message : String(err)}`;\n }\n },\n});\n"],"mappings":"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","names":["z","z","fs","path","z","z","path","fs","fs","path","z","z","path","fs","fs","path","z","path","z","fs","fs","path","z","walkDir","z","path","fs","z","z"]}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
// src/cli/init.ts
|
|
2
|
+
import * as fs from "fs";
|
|
3
|
+
import * as path from "path";
|
|
4
|
+
import { execSync } from "child_process";
|
|
5
|
+
var PACKAGE_JSON = JSON.stringify(
|
|
6
|
+
{
|
|
7
|
+
name: "my-agent",
|
|
8
|
+
version: "1.0.0",
|
|
9
|
+
type: "module",
|
|
10
|
+
scripts: {
|
|
11
|
+
start: "npx tsx src/index.ts",
|
|
12
|
+
test: "npx vitest run",
|
|
13
|
+
typecheck: "tsc --noEmit"
|
|
14
|
+
},
|
|
15
|
+
dependencies: {
|
|
16
|
+
"@avasis-ai/synthcode": "^0.6.0",
|
|
17
|
+
zod: "^3.24.0"
|
|
18
|
+
},
|
|
19
|
+
devDependencies: {
|
|
20
|
+
typescript: "^5.7.0",
|
|
21
|
+
tsx: "^4.19.0",
|
|
22
|
+
vitest: "^2.1.0"
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
null,
|
|
26
|
+
2
|
|
27
|
+
);
|
|
28
|
+
var TSCONFIG_JSON = JSON.stringify(
|
|
29
|
+
{
|
|
30
|
+
compilerOptions: {
|
|
31
|
+
target: "ES2022",
|
|
32
|
+
module: "ESNext",
|
|
33
|
+
moduleResolution: "bundler",
|
|
34
|
+
strict: true,
|
|
35
|
+
esModuleInterop: true,
|
|
36
|
+
skipLibCheck: true,
|
|
37
|
+
outDir: "./dist",
|
|
38
|
+
rootDir: "./src",
|
|
39
|
+
declaration: true
|
|
40
|
+
},
|
|
41
|
+
include: ["src"]
|
|
42
|
+
},
|
|
43
|
+
null,
|
|
44
|
+
2
|
|
45
|
+
);
|
|
46
|
+
var ENV_EXAMPLE = `# Pick one provider and set its key:
|
|
47
|
+
# ANTHROPIC_API_KEY=your-key-here
|
|
48
|
+
# OPENAI_API_KEY=your-key-here
|
|
49
|
+
# For Ollama (local, zero API costs): no key needed
|
|
50
|
+
`;
|
|
51
|
+
var INDEX_TS = `import { Agent, BashTool, FileReadTool, FileWriteTool, FileEditTool, GlobTool, GrepTool, WebFetchTool } from "@avasis-ai/synthcode";
|
|
52
|
+
import { defineTool } from "@avasis-ai/synthcode/tools";
|
|
53
|
+
import { z } from "zod";
|
|
54
|
+
|
|
55
|
+
const agent = new Agent({
|
|
56
|
+
model: process.env.OLLAMA_MODEL
|
|
57
|
+
? await import("@avasis-ai/synthcode/llm").then(m => new m.OllamaProvider({ model: process.env.OLLAMA_MODEL }))
|
|
58
|
+
: process.env.OPENAI_API_KEY
|
|
59
|
+
? await import("@avasis-ai/synthcode/llm").then(m => new m.OpenAIProvider({ apiKey: process.env.OPENAI_API_KEY }))
|
|
60
|
+
: await import("@avasis-ai/synthcode/llm").then(m => new m.AnthropicProvider({ apiKey: process.env.ANTHROPIC_API_KEY! })),
|
|
61
|
+
tools: [
|
|
62
|
+
BashTool,
|
|
63
|
+
FileReadTool,
|
|
64
|
+
FileWriteTool,
|
|
65
|
+
FileEditTool,
|
|
66
|
+
GlobTool,
|
|
67
|
+
GrepTool,
|
|
68
|
+
WebFetchTool,
|
|
69
|
+
],
|
|
70
|
+
systemPrompt: "You are a helpful AI coding assistant with shell and file access.",
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
const prompt = process.argv[2] || "Hello! What can I help you with?";
|
|
74
|
+
|
|
75
|
+
for await (const event of agent.run(prompt)) {
|
|
76
|
+
if (event.type === "text") process.stdout.write(event.text);
|
|
77
|
+
if (event.type === "tool_use") console.log(\`\\n [\${event.name}]\`);
|
|
78
|
+
if (event.type === "tool_result") {
|
|
79
|
+
if (event.isError) console.log(\`\\n [\${event.name}] FAILED\`);
|
|
80
|
+
}
|
|
81
|
+
if (event.type === "thinking") process.stderr.write(\`\\x1b[90m\${event.thinking}\\x1b[0m\`);
|
|
82
|
+
if (event.type === "done") console.log(\`\\n\\nTokens: \${event.usage.inputTokens} in, \${event.usage.outputTokens} out\`);
|
|
83
|
+
if (event.type === "error") {
|
|
84
|
+
console.error(\`\\nError: \${event.error.message}\`);
|
|
85
|
+
process.exit(1);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
`;
|
|
89
|
+
async function init(opts) {
|
|
90
|
+
const name = opts?.projectName ?? "my-agent";
|
|
91
|
+
const cwd = opts?.cwd ?? process.cwd();
|
|
92
|
+
const dir = path.join(cwd, name);
|
|
93
|
+
fs.mkdirSync(path.join(dir, "src", "tools"), { recursive: true });
|
|
94
|
+
fs.mkdirSync(path.join(dir, "tests"), { recursive: true });
|
|
95
|
+
fs.writeFileSync(path.join(dir, "package.json"), PACKAGE_JSON, "utf-8");
|
|
96
|
+
fs.writeFileSync(path.join(dir, "tsconfig.json"), TSCONFIG_JSON, "utf-8");
|
|
97
|
+
fs.writeFileSync(path.join(dir, ".env.example"), ENV_EXAMPLE, "utf-8");
|
|
98
|
+
fs.writeFileSync(path.join(dir, "src", "index.ts"), INDEX_TS, "utf-8");
|
|
99
|
+
fs.writeFileSync(path.join(dir, "tests", "agent.test.ts"), `import { describe, it, expect } from "vitest";
|
|
100
|
+
describe("Agent", () => { it("should have tools registered", () => { expect(true).toBe(true); }); });
|
|
101
|
+
`, "utf-8");
|
|
102
|
+
if (!opts?.skipInstall) {
|
|
103
|
+
console.log("Installing dependencies...");
|
|
104
|
+
execSync("npm install", { cwd: dir, stdio: "inherit" });
|
|
105
|
+
}
|
|
106
|
+
console.log(`
|
|
107
|
+
Created ${name}/`);
|
|
108
|
+
console.log(` cd ${name} && npm start "your prompt here"
|
|
109
|
+
`);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export {
|
|
113
|
+
init
|
|
114
|
+
};
|
|
115
|
+
//# sourceMappingURL=chunk-BWXHO6UJ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cli/init.ts"],"sourcesContent":["import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport { execSync } from \"node:child_process\";\n\nexport interface InitOptions {\n projectName?: string;\n cwd?: string;\n skipInstall?: boolean;\n}\n\nconst PACKAGE_JSON = JSON.stringify(\n {\n name: \"my-agent\",\n version: \"1.0.0\",\n type: \"module\",\n scripts: {\n start: \"npx tsx src/index.ts\",\n test: \"npx vitest run\",\n typecheck: \"tsc --noEmit\",\n },\n dependencies: {\n \"@avasis-ai/synthcode\": \"^0.6.0\",\n zod: \"^3.24.0\",\n },\n devDependencies: {\n typescript: \"^5.7.0\",\n tsx: \"^4.19.0\",\n vitest: \"^2.1.0\",\n },\n },\n null,\n 2,\n);\n\nconst TSCONFIG_JSON = JSON.stringify(\n {\n compilerOptions: {\n target: \"ES2022\",\n module: \"ESNext\",\n moduleResolution: \"bundler\",\n strict: true,\n esModuleInterop: true,\n skipLibCheck: true,\n outDir: \"./dist\",\n rootDir: \"./src\",\n declaration: true,\n },\n include: [\"src\"],\n },\n null,\n 2,\n);\n\nconst ENV_EXAMPLE = `# Pick one provider and set its key:\n# ANTHROPIC_API_KEY=your-key-here\n# OPENAI_API_KEY=your-key-here\n# For Ollama (local, zero API costs): no key needed\n`;\n\nconst INDEX_TS = `import { Agent, BashTool, FileReadTool, FileWriteTool, FileEditTool, GlobTool, GrepTool, WebFetchTool } from \"@avasis-ai/synthcode\";\nimport { defineTool } from \"@avasis-ai/synthcode/tools\";\nimport { z } from \"zod\";\n\nconst agent = new Agent({\n model: process.env.OLLAMA_MODEL\n ? await import(\"@avasis-ai/synthcode/llm\").then(m => new m.OllamaProvider({ model: process.env.OLLAMA_MODEL }))\n : process.env.OPENAI_API_KEY\n ? await import(\"@avasis-ai/synthcode/llm\").then(m => new m.OpenAIProvider({ apiKey: process.env.OPENAI_API_KEY }))\n : await import(\"@avasis-ai/synthcode/llm\").then(m => new m.AnthropicProvider({ apiKey: process.env.ANTHROPIC_API_KEY! })),\n tools: [\n BashTool,\n FileReadTool,\n FileWriteTool,\n FileEditTool,\n GlobTool,\n GrepTool,\n WebFetchTool,\n ],\n systemPrompt: \"You are a helpful AI coding assistant with shell and file access.\",\n});\n\nconst prompt = process.argv[2] || \"Hello! What can I help you with?\";\n\nfor await (const event of agent.run(prompt)) {\n if (event.type === \"text\") process.stdout.write(event.text);\n if (event.type === \"tool_use\") console.log(\\`\\\\n [\\${event.name}]\\`);\n if (event.type === \"tool_result\") {\n if (event.isError) console.log(\\`\\\\n [\\${event.name}] FAILED\\`);\n }\n if (event.type === \"thinking\") process.stderr.write(\\`\\\\x1b[90m\\${event.thinking}\\\\x1b[0m\\`);\n if (event.type === \"done\") console.log(\\`\\\\n\\\\nTokens: \\${event.usage.inputTokens} in, \\${event.usage.outputTokens} out\\`);\n if (event.type === \"error\") {\n console.error(\\`\\\\nError: \\${event.error.message}\\`);\n process.exit(1);\n }\n}\n`;\n\nexport async function init(opts?: InitOptions): Promise<void> {\n const name = opts?.projectName ?? \"my-agent\";\n const cwd = opts?.cwd ?? process.cwd();\n const dir = path.join(cwd, name);\n\n fs.mkdirSync(path.join(dir, \"src\", \"tools\"), { recursive: true });\n fs.mkdirSync(path.join(dir, \"tests\"), { recursive: true });\n\n fs.writeFileSync(path.join(dir, \"package.json\"), PACKAGE_JSON, \"utf-8\");\n fs.writeFileSync(path.join(dir, \"tsconfig.json\"), TSCONFIG_JSON, \"utf-8\");\n fs.writeFileSync(path.join(dir, \".env.example\"), ENV_EXAMPLE, \"utf-8\");\n fs.writeFileSync(path.join(dir, \"src\", \"index.ts\"), INDEX_TS, \"utf-8\");\n fs.writeFileSync(path.join(dir, \"tests\", \"agent.test.ts\"), `import { describe, it, expect } from \"vitest\";\\ndescribe(\"Agent\", () => { it(\"should have tools registered\", () => { expect(true).toBe(true); }); });\\n`, \"utf-8\");\n\n if (!opts?.skipInstall) {\n console.log(\"Installing dependencies...\");\n execSync(\"npm install\", { cwd: dir, stdio: \"inherit\" });\n }\n\n console.log(`\\n Created ${name}/`);\n console.log(` cd ${name} && npm start \"your prompt here\"\\n`);\n}\n"],"mappings":";AAAA,YAAY,QAAQ;AACpB,YAAY,UAAU;AACtB,SAAS,gBAAgB;AAQzB,IAAM,eAAe,KAAK;AAAA,EACxB;AAAA,IACE,MAAM;AAAA,IACN,SAAS;AAAA,IACT,MAAM;AAAA,IACN,SAAS;AAAA,MACP,OAAO;AAAA,MACP,MAAM;AAAA,MACN,WAAW;AAAA,IACb;AAAA,IACA,cAAc;AAAA,MACZ,wBAAwB;AAAA,MACxB,KAAK;AAAA,IACP;AAAA,IACA,iBAAiB;AAAA,MACf,YAAY;AAAA,MACZ,KAAK;AAAA,MACL,QAAQ;AAAA,IACV;AAAA,EACF;AAAA,EACA;AAAA,EACA;AACF;AAEA,IAAM,gBAAgB,KAAK;AAAA,EACzB;AAAA,IACE,iBAAiB;AAAA,MACf,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,kBAAkB;AAAA,MAClB,QAAQ;AAAA,MACR,iBAAiB;AAAA,MACjB,cAAc;AAAA,MACd,QAAQ;AAAA,MACR,SAAS;AAAA,MACT,aAAa;AAAA,IACf;AAAA,IACA,SAAS,CAAC,KAAK;AAAA,EACjB;AAAA,EACA;AAAA,EACA;AACF;AAEA,IAAM,cAAc;AAAA;AAAA;AAAA;AAAA;AAMpB,IAAM,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAuCjB,eAAsB,KAAK,MAAmC;AAC5D,QAAM,OAAO,MAAM,eAAe;AAClC,QAAM,MAAM,MAAM,OAAO,QAAQ,IAAI;AACrC,QAAM,MAAW,UAAK,KAAK,IAAI;AAE/B,EAAG,aAAe,UAAK,KAAK,OAAO,OAAO,GAAG,EAAE,WAAW,KAAK,CAAC;AAChE,EAAG,aAAe,UAAK,KAAK,OAAO,GAAG,EAAE,WAAW,KAAK,CAAC;AAEzD,EAAG,iBAAmB,UAAK,KAAK,cAAc,GAAG,cAAc,OAAO;AACtE,EAAG,iBAAmB,UAAK,KAAK,eAAe,GAAG,eAAe,OAAO;AACxE,EAAG,iBAAmB,UAAK,KAAK,cAAc,GAAG,aAAa,OAAO;AACrE,EAAG,iBAAmB,UAAK,KAAK,OAAO,UAAU,GAAG,UAAU,OAAO;AACrE,EAAG,iBAAmB,UAAK,KAAK,SAAS,eAAe,GAAG;AAAA;AAAA,GAA2J,OAAO;AAE7N,MAAI,CAAC,MAAM,aAAa;AACtB,YAAQ,IAAI,4BAA4B;AACxC,aAAS,eAAe,EAAE,KAAK,KAAK,OAAO,UAAU,CAAC;AAAA,EACxD;AAEA,UAAQ,IAAI;AAAA,YAAe,IAAI,GAAG;AAClC,UAAQ,IAAI,QAAQ,IAAI;AAAA,CAAoC;AAC9D;","names":[]}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import {
|
|
2
|
+
__require
|
|
3
|
+
} from "./chunk-DGUM43GV.js";
|
|
4
|
+
|
|
5
|
+
// src/memory/store.ts
|
|
6
|
+
var InMemoryStore = class {
|
|
7
|
+
threads = /* @__PURE__ */ new Map();
|
|
8
|
+
async getThread(threadId) {
|
|
9
|
+
return this.threads.get(threadId)?.messages ?? [];
|
|
10
|
+
}
|
|
11
|
+
async saveThread(threadId, messages) {
|
|
12
|
+
this.threads.set(threadId, { messages, updatedAt: Date.now() });
|
|
13
|
+
}
|
|
14
|
+
async appendMessage(threadId, message) {
|
|
15
|
+
const thread = this.threads.get(threadId);
|
|
16
|
+
if (thread) {
|
|
17
|
+
thread.messages.push(message);
|
|
18
|
+
thread.updatedAt = Date.now();
|
|
19
|
+
} else {
|
|
20
|
+
this.threads.set(threadId, { messages: [message], updatedAt: Date.now() });
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
async listThreads(opts) {
|
|
24
|
+
let entries = Array.from(this.threads.entries()).map(([id, data]) => ({ id, updatedAt: data.updatedAt, messageCount: data.messages.length })).sort((a, b) => b.updatedAt - a.updatedAt);
|
|
25
|
+
if (opts?.before) entries = entries.filter((e) => e.updatedAt < parseInt(opts.before, 10));
|
|
26
|
+
return entries.slice(0, opts?.limit ?? 100);
|
|
27
|
+
}
|
|
28
|
+
async deleteThread(threadId) {
|
|
29
|
+
this.threads.delete(threadId);
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
// src/memory/sqlite.ts
|
|
34
|
+
function jsonSerialize(messages) {
|
|
35
|
+
return JSON.stringify(messages, (_, value) => {
|
|
36
|
+
if (value === void 0) return "__UNDEFINED__";
|
|
37
|
+
return value;
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
function jsonDeserialize(str) {
|
|
41
|
+
return JSON.parse(str, (_, value) => {
|
|
42
|
+
if (value === "__UNDEFINED__") return void 0;
|
|
43
|
+
return value;
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
var SQLiteStore = class {
|
|
47
|
+
store;
|
|
48
|
+
constructor(dbPath) {
|
|
49
|
+
try {
|
|
50
|
+
const Database = __require("better-sqlite3");
|
|
51
|
+
const db = new Database(dbPath ?? "./synth-memory.db");
|
|
52
|
+
db.pragma("journal_mode = WAL");
|
|
53
|
+
db.exec(`
|
|
54
|
+
CREATE TABLE IF NOT EXISTS threads (
|
|
55
|
+
id TEXT PRIMARY KEY,
|
|
56
|
+
messages TEXT NOT NULL,
|
|
57
|
+
updated_at INTEGER NOT NULL,
|
|
58
|
+
message_count INTEGER NOT NULL DEFAULT 0
|
|
59
|
+
)
|
|
60
|
+
`);
|
|
61
|
+
try {
|
|
62
|
+
db.exec("ALTER TABLE threads ADD COLUMN message_count INTEGER NOT NULL DEFAULT 0");
|
|
63
|
+
} catch {
|
|
64
|
+
}
|
|
65
|
+
this.store = {
|
|
66
|
+
async getThread(threadId) {
|
|
67
|
+
const row = db.prepare("SELECT messages FROM threads WHERE id = ?").get(threadId);
|
|
68
|
+
if (!row) return [];
|
|
69
|
+
return jsonDeserialize(row.messages);
|
|
70
|
+
},
|
|
71
|
+
async saveThread(threadId, messages) {
|
|
72
|
+
const now = Date.now();
|
|
73
|
+
const json = jsonSerialize(messages);
|
|
74
|
+
const msgCount = messages.length;
|
|
75
|
+
const exists = db.prepare("SELECT 1 FROM threads WHERE id = ?").get(threadId);
|
|
76
|
+
const stmt = exists ? db.prepare("UPDATE threads SET messages = ?, updated_at = ?, message_count = ? WHERE id = ?") : db.prepare("INSERT INTO threads (id, messages, updated_at, message_count) VALUES (?, ?, ?, ?)");
|
|
77
|
+
stmt.run(json, now, msgCount, threadId);
|
|
78
|
+
},
|
|
79
|
+
async appendMessage(threadId, message) {
|
|
80
|
+
const row = db.prepare("SELECT messages FROM threads WHERE id = ?").get(threadId);
|
|
81
|
+
const messages = row ? jsonDeserialize(row.messages) : [];
|
|
82
|
+
messages.push(message);
|
|
83
|
+
const json = jsonSerialize(messages);
|
|
84
|
+
const now = Date.now();
|
|
85
|
+
db.prepare("INSERT INTO threads (id, messages, updated_at, message_count) VALUES (?, ?, ?, ?) ON CONFLICT(id) DO UPDATE SET messages = excluded.messages, updated_at = excluded.updated_at, message_count = excluded.message_count").run(threadId, json, now, messages.length);
|
|
86
|
+
},
|
|
87
|
+
async listThreads(opts) {
|
|
88
|
+
const rows = db.prepare("SELECT id, updated_at, message_count FROM threads ORDER BY updated_at DESC").all();
|
|
89
|
+
let results = rows.map((r) => ({ id: r.id, updatedAt: r.updated_at, messageCount: r.message_count }));
|
|
90
|
+
if (opts?.before) results = results.filter((e) => e.updatedAt < parseInt(opts.before, 10));
|
|
91
|
+
return results.slice(0, opts?.limit ?? 100);
|
|
92
|
+
},
|
|
93
|
+
async deleteThread(threadId) {
|
|
94
|
+
db.prepare("DELETE FROM threads WHERE id = ?").run(threadId);
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
} catch {
|
|
98
|
+
console.warn("[synth] better-sqlite3 not available, falling back to in-memory store. Install it with: npm install better-sqlite3");
|
|
99
|
+
this.store = new InMemoryStore();
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
async getThread(threadId) {
|
|
103
|
+
return this.store.getThread(threadId);
|
|
104
|
+
}
|
|
105
|
+
async saveThread(threadId, messages) {
|
|
106
|
+
return this.store.saveThread(threadId, messages);
|
|
107
|
+
}
|
|
108
|
+
async appendMessage(threadId, message) {
|
|
109
|
+
return this.store.appendMessage(threadId, message);
|
|
110
|
+
}
|
|
111
|
+
async listThreads(opts) {
|
|
112
|
+
return this.store.listThreads(opts);
|
|
113
|
+
}
|
|
114
|
+
async deleteThread(threadId) {
|
|
115
|
+
return this.store.deleteThread(threadId);
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
export {
|
|
120
|
+
InMemoryStore,
|
|
121
|
+
SQLiteStore
|
|
122
|
+
};
|
|
123
|
+
//# sourceMappingURL=chunk-CARUMOML.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/memory/store.ts","../src/memory/sqlite.ts"],"sourcesContent":["import type { Message } from \"../types.js\";\n\nexport interface MemoryStore {\n getThread(threadId: string): Promise<Message[]>;\n saveThread(threadId: string, messages: Message[]): Promise<void>;\n appendMessage(threadId: string, message: Message): Promise<void>;\n listThreads(opts?: { limit?: number; before?: string }): Promise<Array<{ id: string; updatedAt: number; messageCount: number }>>;\n deleteThread(threadId: string): Promise<void>;\n}\n\nexport class InMemoryStore implements MemoryStore {\n private threads: Map<string, { messages: Message[]; updatedAt: number }> = new Map();\n\n async getThread(threadId: string): Promise<Message[]> {\n return this.threads.get(threadId)?.messages ?? [];\n }\n\n async saveThread(threadId: string, messages: Message[]): Promise<void> {\n this.threads.set(threadId, { messages, updatedAt: Date.now() });\n }\n\n async appendMessage(threadId: string, message: Message): Promise<void> {\n const thread = this.threads.get(threadId);\n if (thread) {\n thread.messages.push(message);\n thread.updatedAt = Date.now();\n } else {\n this.threads.set(threadId, { messages: [message], updatedAt: Date.now() });\n }\n }\n\n async listThreads(opts?: { limit?: number; before?: string }): Promise<Array<{ id: string; updatedAt: number; messageCount: number }>> {\n let entries = Array.from(this.threads.entries())\n .map(([id, data]) => ({ id, updatedAt: data.updatedAt, messageCount: data.messages.length }))\n .sort((a, b) => b.updatedAt - a.updatedAt);\n if (opts?.before) entries = entries.filter(e => e.updatedAt < parseInt(opts.before as string, 10));\n return entries.slice(0, opts?.limit ?? 100);\n }\n\n async deleteThread(threadId: string): Promise<void> {\n this.threads.delete(threadId);\n }\n}\n","import type { MemoryStore } from \"./store.js\";\nimport type { Message } from \"../types.js\";\nimport { InMemoryStore } from \"./store.js\";\n\nfunction jsonSerialize(messages: Message[]): string {\n return JSON.stringify(messages, (_, value) => {\n if (value === undefined) return \"__UNDEFINED__\";\n return value;\n });\n}\n\nfunction jsonDeserialize(str: string): Message[] {\n return JSON.parse(str, (_, value) => {\n if (value === \"__UNDEFINED__\") return undefined;\n return value;\n });\n}\n\nexport class SQLiteStore implements MemoryStore {\n private store: MemoryStore;\n\n constructor(dbPath?: string) {\n try {\n const Database = require(\"better-sqlite3\");\n const db = new Database(dbPath ?? \"./synth-memory.db\");\n db.pragma(\"journal_mode = WAL\");\n db.exec(`\n CREATE TABLE IF NOT EXISTS threads (\n id TEXT PRIMARY KEY,\n messages TEXT NOT NULL,\n updated_at INTEGER NOT NULL,\n message_count INTEGER NOT NULL DEFAULT 0\n )\n `);\n try {\n db.exec(\"ALTER TABLE threads ADD COLUMN message_count INTEGER NOT NULL DEFAULT 0\");\n } catch {\n // column already exists\n }\n this.store = {\n async getThread(threadId: string): Promise<Message[]> {\n const row = db.prepare(\"SELECT messages FROM threads WHERE id = ?\").get(threadId);\n if (!row) return [];\n return jsonDeserialize(row.messages);\n },\n async saveThread(threadId: string, messages: Message[]): Promise<void> {\n const now = Date.now();\n const json = jsonSerialize(messages);\n const msgCount = messages.length;\n const exists = db.prepare(\"SELECT 1 FROM threads WHERE id = ?\").get(threadId);\n const stmt = exists\n ? db.prepare(\"UPDATE threads SET messages = ?, updated_at = ?, message_count = ? WHERE id = ?\")\n : db.prepare(\"INSERT INTO threads (id, messages, updated_at, message_count) VALUES (?, ?, ?, ?)\");\n stmt.run(json, now, msgCount, threadId);\n },\n async appendMessage(threadId: string, message: Message): Promise<void> {\n const row = db.prepare(\"SELECT messages FROM threads WHERE id = ?\").get(threadId);\n const messages: Message[] = row ? jsonDeserialize(row.messages) : [];\n messages.push(message);\n const json = jsonSerialize(messages);\n const now = Date.now();\n db.prepare(\"INSERT INTO threads (id, messages, updated_at, message_count) VALUES (?, ?, ?, ?) ON CONFLICT(id) DO UPDATE SET messages = excluded.messages, updated_at = excluded.updated_at, message_count = excluded.message_count\")\n .run(threadId, json, now, messages.length);\n },\n async listThreads(opts?: { limit?: number; before?: string }): Promise<Array<{ id: string; updatedAt: number; messageCount: number }>> {\n const rows = db.prepare(\"SELECT id, updated_at, message_count FROM threads ORDER BY updated_at DESC\").all();\n let results = rows.map((r: any) => ({ id: r.id, updatedAt: r.updated_at, messageCount: r.message_count }));\n if (opts?.before) results = results.filter((e: { updatedAt: number }) => e.updatedAt < parseInt(opts.before!, 10));\n return results.slice(0, opts?.limit ?? 100);\n },\n async deleteThread(threadId: string): Promise<void> {\n db.prepare(\"DELETE FROM threads WHERE id = ?\").run(threadId);\n },\n };\n } catch {\n console.warn(\"[synth] better-sqlite3 not available, falling back to in-memory store. Install it with: npm install better-sqlite3\");\n this.store = new InMemoryStore();\n }\n }\n\n async getThread(threadId: string): Promise<Message[]> { return this.store.getThread(threadId); }\n async saveThread(threadId: string, messages: Message[]): Promise<void> { return this.store.saveThread(threadId, messages); }\n async appendMessage(threadId: string, message: Message): Promise<void> { return this.store.appendMessage(threadId, message); }\n async listThreads(opts?: { limit?: number; before?: string }): Promise<Array<{ id: string; updatedAt: number; messageCount: number }>> { return this.store.listThreads(opts); }\n async deleteThread(threadId: string): Promise<void> { return this.store.deleteThread(threadId); }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
2
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
3
|
+
}) : x)(function(x) {
|
|
4
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
5
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
export {
|
|
9
|
+
__require
|
|
10
|
+
};
|
|
11
|
+
//# sourceMappingURL=chunk-DGUM43GV.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|