@jussmor/sdk-ai 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/conversation-kIkMQdYK.d.cts +105 -0
- package/dist/conversation-kIkMQdYK.d.ts +105 -0
- package/dist/conversation-store-CAyPuBjk.d.ts +10 -0
- package/dist/conversation-store-Cl42jpsA.d.cts +10 -0
- package/dist/index.cjs +1630 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +251 -0
- package/dist/index.d.ts +251 -0
- package/dist/index.js +1536 -0
- package/dist/index.js.map +1 -0
- package/dist/memory-uBLqrQRY.d.cts +28 -0
- package/dist/memory-uBLqrQRY.d.ts +28 -0
- package/dist/providers/llm/anthropic.cjs +275 -0
- package/dist/providers/llm/anthropic.cjs.map +1 -0
- package/dist/providers/llm/anthropic.d.cts +22 -0
- package/dist/providers/llm/anthropic.d.ts +22 -0
- package/dist/providers/llm/anthropic.js +240 -0
- package/dist/providers/llm/anthropic.js.map +1 -0
- package/dist/providers/llm/ollama.cjs +195 -0
- package/dist/providers/llm/ollama.cjs.map +1 -0
- package/dist/providers/llm/ollama.d.cts +23 -0
- package/dist/providers/llm/ollama.d.ts +23 -0
- package/dist/providers/llm/ollama.js +170 -0
- package/dist/providers/llm/ollama.js.map +1 -0
- package/dist/providers/llm/openai.cjs +213 -0
- package/dist/providers/llm/openai.cjs.map +1 -0
- package/dist/providers/llm/openai.d.cts +22 -0
- package/dist/providers/llm/openai.d.ts +22 -0
- package/dist/providers/llm/openai.js +178 -0
- package/dist/providers/llm/openai.js.map +1 -0
- package/dist/providers/memory/filesystem.cjs +112 -0
- package/dist/providers/memory/filesystem.cjs.map +1 -0
- package/dist/providers/memory/filesystem.d.cts +17 -0
- package/dist/providers/memory/filesystem.d.ts +17 -0
- package/dist/providers/memory/filesystem.js +87 -0
- package/dist/providers/memory/filesystem.js.map +1 -0
- package/dist/providers/store/filesystem.cjs +87 -0
- package/dist/providers/store/filesystem.cjs.map +1 -0
- package/dist/providers/store/filesystem.d.cts +14 -0
- package/dist/providers/store/filesystem.d.ts +14 -0
- package/dist/providers/store/filesystem.js +62 -0
- package/dist/providers/store/filesystem.js.map +1 -0
- package/dist/providers/thread/memory.cjs +81 -0
- package/dist/providers/thread/memory.cjs.map +1 -0
- package/dist/providers/thread/memory.d.cts +14 -0
- package/dist/providers/thread/memory.d.ts +14 -0
- package/dist/providers/thread/memory.js +56 -0
- package/dist/providers/thread/memory.js.map +1 -0
- package/dist/providers/thread/sqlite.cjs +917 -0
- package/dist/providers/thread/sqlite.cjs.map +1 -0
- package/dist/providers/thread/sqlite.d.cts +17 -0
- package/dist/providers/thread/sqlite.d.ts +17 -0
- package/dist/providers/thread/sqlite.js +911 -0
- package/dist/providers/thread/sqlite.js.map +1 -0
- package/dist/providers/tokenizers/auto.cjs +136 -0
- package/dist/providers/tokenizers/auto.cjs.map +1 -0
- package/dist/providers/tokenizers/auto.d.cts +24 -0
- package/dist/providers/tokenizers/auto.d.ts +24 -0
- package/dist/providers/tokenizers/auto.js +107 -0
- package/dist/providers/tokenizers/auto.js.map +1 -0
- package/dist/streaming-B-P6Fw_k.d.cts +372 -0
- package/dist/streaming-BtD23BE0.d.ts +372 -0
- package/dist/thread-C2b9xRMJ.d.cts +30 -0
- package/dist/thread-C2b9xRMJ.d.ts +30 -0
- package/dist/tokenizer-BhG_RGUk.d.cts +13 -0
- package/dist/tokenizer-BhG_RGUk.d.ts +13 -0
- package/package.json +84 -0
- package/src/agent-loop.ts +311 -0
- package/src/agent-source.ts +12 -0
- package/src/artifact.ts +31 -0
- package/src/compaction.ts +75 -0
- package/src/context-budget.ts +65 -0
- package/src/conversation-store.ts +8 -0
- package/src/conversation.ts +42 -0
- package/src/dispatch.ts +207 -0
- package/src/engine.ts +53 -0
- package/src/execution-context.ts +31 -0
- package/src/index.ts +37 -0
- package/src/interrupt-store.ts +25 -0
- package/src/interrupt.ts +55 -0
- package/src/llm-router.ts +34 -0
- package/src/llm.ts +100 -0
- package/src/memory-selector.ts +38 -0
- package/src/memory.ts +34 -0
- package/src/mode.ts +81 -0
- package/src/permissions.ts +104 -0
- package/src/protocol.ts +1 -0
- package/src/providers/llm/anthropic.ts +298 -0
- package/src/providers/llm/ollama.ts +219 -0
- package/src/providers/llm/openai.ts +215 -0
- package/src/providers/memory/filesystem.ts +99 -0
- package/src/providers/store/filesystem.ts +64 -0
- package/src/providers/thread/memory.ts +67 -0
- package/src/providers/thread/sqlite.ts +147 -0
- package/src/providers/tokenizers/auto.ts +26 -0
- package/src/providers/tokenizers/byte.ts +27 -0
- package/src/providers/tokenizers/tiktoken.ts +91 -0
- package/src/reasoning.ts +7 -0
- package/src/rule-matcher.ts +32 -0
- package/src/runtime.ts +416 -0
- package/src/safety.ts +56 -0
- package/src/sandbox.ts +23 -0
- package/src/session-context.ts +33 -0
- package/src/skill-source.ts +21 -0
- package/src/streaming.ts +124 -0
- package/src/system-prompt.ts +71 -0
- package/src/system-reminder.ts +9 -0
- package/src/thread.ts +33 -0
- package/src/tokenizer.ts +31 -0
- package/src/tool.ts +175 -0
- package/src/tracing.ts +63 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/providers/llm/openai.ts"],"sourcesContent":["import OpenAI from \"openai\";\nimport type {\n LLMProvider,\n ChatRequest,\n ChatResponse,\n ChatMessage,\n} from \"../../llm.js\";\nimport type { StreamingLLMProvider, StreamEvent } from \"../../streaming.js\";\n\nfunction toOpenAIMessages(\n messages: ChatMessage[],\n): OpenAI.ChatCompletionMessageParam[] {\n return messages.map((msg): OpenAI.ChatCompletionMessageParam => {\n if (msg.role === \"system\") {\n return { role: \"system\", content: msg.content };\n }\n if (msg.role === \"tool\") {\n return {\n role: \"tool\",\n tool_call_id: msg.toolCallId ?? \"\",\n content: msg.content,\n };\n }\n if (msg.role === \"assistant\") {\n const out: OpenAI.ChatCompletionAssistantMessageParam = {\n role: \"assistant\",\n content: msg.content || null,\n };\n if (msg.toolCalls?.length) {\n out.tool_calls = msg.toolCalls.map((tc) => ({\n id: tc.id,\n type: \"function\" as const,\n function: { name: tc.name, arguments: tc.arguments },\n }));\n }\n return out;\n }\n if (msg.images?.length) {\n const content: OpenAI.ChatCompletionContentPart[] = msg.images.map(\n (img) =>\n img.url\n ? ({ type: \"image_url\", image_url: { url: img.url } } as const)\n : ({\n type: \"image_url\",\n image_url: {\n url: `data:${img.mediaType};base64,${img.source}`,\n },\n } as const),\n );\n if (msg.content) content.push({ type: \"text\", text: msg.content });\n return { role: \"user\", content };\n }\n return { role: \"user\", content: msg.content };\n });\n}\n\nexport interface OpenAIProviderOptions {\n apiKey?: string;\n baseURL?: string;\n defaultModel?: string;\n defaultMaxTokens?: number;\n}\n\nexport class OpenAIProvider implements StreamingLLMProvider {\n private client: OpenAI;\n private defaultModel: string;\n private defaultMaxTokens: number;\n\n constructor(opts: OpenAIProviderOptions = {}) {\n this.client = new OpenAI({\n apiKey: opts.apiKey ?? process.env[\"OPENAI_API_KEY\"],\n baseURL: opts.baseURL ?? process.env[\"OPENAI_BASE_URL\"],\n });\n this.defaultModel = opts.defaultModel ?? \"gpt-4o\";\n this.defaultMaxTokens = opts.defaultMaxTokens ?? 4096;\n }\n\n async chat(req: ChatRequest, signal?: AbortSignal): Promise<ChatResponse> {\n const messages = toOpenAIMessages(req.messages);\n const tools = req.tools?.map((t) => ({\n type: \"function\" as const,\n function: {\n name: t.function.name,\n description: t.function.description,\n parameters: t.function.parameters as unknown as Record<string, unknown>,\n },\n }));\n\n const resp = await this.client.chat.completions.create(\n {\n model: req.model ?? this.defaultModel,\n messages,\n max_tokens: req.maxTokens ?? this.defaultMaxTokens,\n ...(tools?.length ? { tools } : {}),\n ...(req.temperature != null ? { temperature: req.temperature } : {}),\n ...(req.topP != null ? { top_p: req.topP } : {}),\n ...(req.stop?.length ? { stop: req.stop } : {}),\n },\n { signal },\n );\n\n const choice = resp.choices[0];\n const msg = choice?.message;\n\n return {\n content: msg?.content ?? \"\",\n toolCalls: msg?.tool_calls?.map((tc) => ({\n id: tc.id,\n name: tc.function.name,\n arguments: tc.function.arguments,\n })),\n finishReason: choice?.finish_reason ?? \"stop\",\n usage: {\n promptTokens: resp.usage?.prompt_tokens ?? 0,\n completionTokens: resp.usage?.completion_tokens ?? 0,\n totalTokens: resp.usage?.total_tokens ?? 0,\n },\n model: resp.model,\n };\n }\n\n async *chatStream(\n req: ChatRequest,\n signal?: AbortSignal,\n ): AsyncGenerator<StreamEvent> {\n const messages = toOpenAIMessages(req.messages);\n const tools = req.tools?.map((t) => ({\n type: \"function\" as const,\n function: {\n name: t.function.name,\n description: t.function.description,\n parameters: t.function.parameters as unknown as Record<string, unknown>,\n },\n }));\n\n const stream = await this.client.chat.completions.create(\n {\n model: req.model ?? this.defaultModel,\n messages,\n max_tokens: req.maxTokens ?? this.defaultMaxTokens,\n stream: true,\n stream_options: { include_usage: true },\n ...(tools?.length ? { tools } : {}),\n ...(req.temperature != null ? { temperature: req.temperature } : {}),\n ...(req.topP != null ? { top_p: req.topP } : {}),\n ...(req.stop?.length ? { stop: req.stop } : {}),\n },\n { signal },\n );\n\n const toolCallBufs = new Map<\n number,\n { id: string; name: string; argsBuf: string }\n >();\n let promptTokens = 0;\n let completionTokens = 0;\n\n for await (const chunk of stream) {\n if (signal?.aborted) break;\n\n if (chunk.usage) {\n promptTokens = chunk.usage.prompt_tokens;\n completionTokens = chunk.usage.completion_tokens;\n }\n\n const delta = chunk.choices[0]?.delta;\n if (!delta) continue;\n\n if (delta.content) {\n yield { type: \"delta\", delta: delta.content };\n }\n\n if (delta.tool_calls) {\n for (const tc of delta.tool_calls) {\n const idx = tc.index;\n if (!toolCallBufs.has(idx)) {\n toolCallBufs.set(idx, { id: tc.id ?? \"\", name: tc.function?.name ?? \"\", argsBuf: \"\" });\n }\n const buf = toolCallBufs.get(idx)!;\n if (tc.id) buf.id = tc.id;\n if (tc.function?.name) buf.name = tc.function.name;\n if (tc.function?.arguments) buf.argsBuf += tc.function.arguments;\n }\n }\n\n const finishReason = chunk.choices[0]?.finish_reason;\n if (finishReason) {\n for (const [, tc] of toolCallBufs) {\n yield {\n type: \"tool_call\",\n toolCall: { id: tc.id, name: tc.name, arguments: tc.argsBuf },\n };\n }\n toolCallBufs.clear();\n\n yield {\n type: \"done\",\n final: {\n finalContent: \"\",\n providerReasoning: \"\",\n totalTurns: 1,\n totalUsage: {\n promptTokens,\n completionTokens,\n totalTokens: promptTokens + completionTokens,\n },\n messages: [],\n reasoningTrace: [],\n stopReason: \"complete\",\n },\n };\n }\n }\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/providers/memory/filesystem.ts
|
|
21
|
+
var filesystem_exports = {};
|
|
22
|
+
__export(filesystem_exports, {
|
|
23
|
+
FilesystemMemoryProvider: () => FilesystemMemoryProvider
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(filesystem_exports);
|
|
26
|
+
var import_promises = require("fs/promises");
|
|
27
|
+
var import_node_path = require("path");
|
|
28
|
+
var import_node_fs = require("fs");
|
|
29
|
+
var FilesystemMemoryProvider = class {
|
|
30
|
+
constructor(root) {
|
|
31
|
+
this.root = root;
|
|
32
|
+
}
|
|
33
|
+
root;
|
|
34
|
+
scopeDir(scope) {
|
|
35
|
+
return (0, import_node_path.join)(this.root, scope);
|
|
36
|
+
}
|
|
37
|
+
resolvePath(scope, path) {
|
|
38
|
+
const base = this.scopeDir(scope);
|
|
39
|
+
const resolved = (0, import_node_path.normalize)((0, import_node_path.join)(base, path));
|
|
40
|
+
if (!resolved.startsWith(base)) {
|
|
41
|
+
throw new Error(`path traversal attempt: ${path}`);
|
|
42
|
+
}
|
|
43
|
+
return resolved;
|
|
44
|
+
}
|
|
45
|
+
async view(scope, path) {
|
|
46
|
+
const full = this.resolvePath(scope, path);
|
|
47
|
+
try {
|
|
48
|
+
return await (0, import_promises.readFile)(full, "utf-8");
|
|
49
|
+
} catch (e) {
|
|
50
|
+
const err = e;
|
|
51
|
+
if (err.code === "ENOENT") throw new Error(`not found: ${path}`);
|
|
52
|
+
throw e;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
async create(scope, path, content) {
|
|
56
|
+
const full = this.resolvePath(scope, path);
|
|
57
|
+
if ((0, import_node_fs.existsSync)(full)) {
|
|
58
|
+
throw new Error(`file already exists: ${path}`);
|
|
59
|
+
}
|
|
60
|
+
await (0, import_promises.mkdir)((0, import_node_path.dirname)(full), { recursive: true });
|
|
61
|
+
await (0, import_promises.writeFile)(full, content, "utf-8");
|
|
62
|
+
}
|
|
63
|
+
async strReplace(scope, path, oldStr, newStr) {
|
|
64
|
+
const full = this.resolvePath(scope, path);
|
|
65
|
+
const content = await (0, import_promises.readFile)(full, "utf-8");
|
|
66
|
+
const count = content.split(oldStr).length - 1;
|
|
67
|
+
if (count === 0) throw new Error(`string not found in ${path}`);
|
|
68
|
+
if (count > 1) throw new Error(`string appears ${count} times in ${path}, must appear exactly once`);
|
|
69
|
+
await (0, import_promises.writeFile)(full, content.replace(oldStr, newStr), "utf-8");
|
|
70
|
+
}
|
|
71
|
+
async delete(scope, path) {
|
|
72
|
+
const full = this.resolvePath(scope, path);
|
|
73
|
+
await (0, import_promises.rm)(full, { recursive: true, force: true });
|
|
74
|
+
}
|
|
75
|
+
async rename(scope, oldPath, newPath) {
|
|
76
|
+
const oldFull = this.resolvePath(scope, oldPath);
|
|
77
|
+
const newFull = this.resolvePath(scope, newPath);
|
|
78
|
+
await (0, import_promises.mkdir)((0, import_node_path.dirname)(newFull), { recursive: true });
|
|
79
|
+
await (0, import_promises.rename)(oldFull, newFull);
|
|
80
|
+
}
|
|
81
|
+
async list(scope, path) {
|
|
82
|
+
const full = this.resolvePath(scope, path);
|
|
83
|
+
const base = this.scopeDir(scope);
|
|
84
|
+
try {
|
|
85
|
+
const entries = await (0, import_promises.readdir)(full, { recursive: true });
|
|
86
|
+
return entries.map((e) => (0, import_node_path.relative)(base, (0, import_node_path.join)(full, e))).sort();
|
|
87
|
+
} catch {
|
|
88
|
+
return [];
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
async search(scope, query) {
|
|
92
|
+
const files = await this.list(scope, "/");
|
|
93
|
+
const results = [];
|
|
94
|
+
const q = query.toLowerCase();
|
|
95
|
+
for (const file of files) {
|
|
96
|
+
if (!file.endsWith(".md")) continue;
|
|
97
|
+
try {
|
|
98
|
+
const content = await this.view(scope, file);
|
|
99
|
+
if (content.toLowerCase().includes(q)) {
|
|
100
|
+
results.push({ path: file, scope, content: content.slice(0, 500) });
|
|
101
|
+
}
|
|
102
|
+
} catch {
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return results;
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
109
|
+
0 && (module.exports = {
|
|
110
|
+
FilesystemMemoryProvider
|
|
111
|
+
});
|
|
112
|
+
//# sourceMappingURL=filesystem.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/providers/memory/filesystem.ts"],"sourcesContent":["import { readFile, writeFile, mkdir, rm, rename, readdir } from \"node:fs/promises\";\nimport { join, dirname, normalize, relative } from \"node:path\";\nimport { existsSync } from \"node:fs\";\nimport type { MemoryProvider, MemoryEntry, Scope } from \"../../memory.js\";\n\nexport class FilesystemMemoryProvider implements MemoryProvider {\n constructor(private root: string) {}\n\n private scopeDir(scope: Scope): string {\n return join(this.root, scope);\n }\n\n private resolvePath(scope: Scope, path: string): string {\n const base = this.scopeDir(scope);\n const resolved = normalize(join(base, path));\n if (!resolved.startsWith(base)) {\n throw new Error(`path traversal attempt: ${path}`);\n }\n return resolved;\n }\n\n async view(scope: Scope, path: string): Promise<string> {\n const full = this.resolvePath(scope, path);\n try {\n return await readFile(full, \"utf-8\");\n } catch (e) {\n const err = e as NodeJS.ErrnoException;\n if (err.code === \"ENOENT\") throw new Error(`not found: ${path}`);\n throw e;\n }\n }\n\n async create(scope: Scope, path: string, content: string): Promise<void> {\n const full = this.resolvePath(scope, path);\n if (existsSync(full)) {\n throw new Error(`file already exists: ${path}`);\n }\n await mkdir(dirname(full), { recursive: true });\n await writeFile(full, content, \"utf-8\");\n }\n\n async strReplace(\n scope: Scope,\n path: string,\n oldStr: string,\n newStr: string,\n ): Promise<void> {\n const full = this.resolvePath(scope, path);\n const content = await readFile(full, \"utf-8\");\n const count = (content.split(oldStr).length - 1);\n if (count === 0) throw new Error(`string not found in ${path}`);\n if (count > 1) throw new Error(`string appears ${count} times in ${path}, must appear exactly once`);\n await writeFile(full, content.replace(oldStr, newStr), \"utf-8\");\n }\n\n async delete(scope: Scope, path: string): Promise<void> {\n const full = this.resolvePath(scope, path);\n await rm(full, { recursive: true, force: true });\n }\n\n async rename(scope: Scope, oldPath: string, newPath: string): Promise<void> {\n const oldFull = this.resolvePath(scope, oldPath);\n const newFull = this.resolvePath(scope, newPath);\n await mkdir(dirname(newFull), { recursive: true });\n await rename(oldFull, newFull);\n }\n\n async list(scope: Scope, path: string): Promise<string[]> {\n const full = this.resolvePath(scope, path);\n const base = this.scopeDir(scope);\n try {\n const entries = await readdir(full, { recursive: true });\n return (entries as string[])\n .map((e) => relative(base, join(full, e)))\n .sort();\n } catch {\n return [];\n }\n }\n\n async search(scope: Scope, query: string): Promise<MemoryEntry[]> {\n const files = await this.list(scope, \"/\");\n const results: MemoryEntry[] = [];\n const q = query.toLowerCase();\n\n for (const file of files) {\n if (!file.endsWith(\".md\")) continue;\n try {\n const content = await this.view(scope, file);\n if (content.toLowerCase().includes(q)) {\n results.push({ path: file, scope, content: content.slice(0, 500) });\n }\n } catch {\n // skip unreadable files\n }\n }\n return results;\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { b as MemoryProvider, S as Scope, a as MemoryEntry } from '../../memory-uBLqrQRY.cjs';
|
|
2
|
+
|
|
3
|
+
declare class FilesystemMemoryProvider implements MemoryProvider {
|
|
4
|
+
private root;
|
|
5
|
+
constructor(root: string);
|
|
6
|
+
private scopeDir;
|
|
7
|
+
private resolvePath;
|
|
8
|
+
view(scope: Scope, path: string): Promise<string>;
|
|
9
|
+
create(scope: Scope, path: string, content: string): Promise<void>;
|
|
10
|
+
strReplace(scope: Scope, path: string, oldStr: string, newStr: string): Promise<void>;
|
|
11
|
+
delete(scope: Scope, path: string): Promise<void>;
|
|
12
|
+
rename(scope: Scope, oldPath: string, newPath: string): Promise<void>;
|
|
13
|
+
list(scope: Scope, path: string): Promise<string[]>;
|
|
14
|
+
search(scope: Scope, query: string): Promise<MemoryEntry[]>;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export { FilesystemMemoryProvider };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { b as MemoryProvider, S as Scope, a as MemoryEntry } from '../../memory-uBLqrQRY.js';
|
|
2
|
+
|
|
3
|
+
declare class FilesystemMemoryProvider implements MemoryProvider {
|
|
4
|
+
private root;
|
|
5
|
+
constructor(root: string);
|
|
6
|
+
private scopeDir;
|
|
7
|
+
private resolvePath;
|
|
8
|
+
view(scope: Scope, path: string): Promise<string>;
|
|
9
|
+
create(scope: Scope, path: string, content: string): Promise<void>;
|
|
10
|
+
strReplace(scope: Scope, path: string, oldStr: string, newStr: string): Promise<void>;
|
|
11
|
+
delete(scope: Scope, path: string): Promise<void>;
|
|
12
|
+
rename(scope: Scope, oldPath: string, newPath: string): Promise<void>;
|
|
13
|
+
list(scope: Scope, path: string): Promise<string[]>;
|
|
14
|
+
search(scope: Scope, query: string): Promise<MemoryEntry[]>;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export { FilesystemMemoryProvider };
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
// src/providers/memory/filesystem.ts
|
|
2
|
+
import { readFile, writeFile, mkdir, rm, rename, readdir } from "fs/promises";
|
|
3
|
+
import { join, dirname, normalize, relative } from "path";
|
|
4
|
+
import { existsSync } from "fs";
|
|
5
|
+
var FilesystemMemoryProvider = class {
|
|
6
|
+
constructor(root) {
|
|
7
|
+
this.root = root;
|
|
8
|
+
}
|
|
9
|
+
root;
|
|
10
|
+
scopeDir(scope) {
|
|
11
|
+
return join(this.root, scope);
|
|
12
|
+
}
|
|
13
|
+
resolvePath(scope, path) {
|
|
14
|
+
const base = this.scopeDir(scope);
|
|
15
|
+
const resolved = normalize(join(base, path));
|
|
16
|
+
if (!resolved.startsWith(base)) {
|
|
17
|
+
throw new Error(`path traversal attempt: ${path}`);
|
|
18
|
+
}
|
|
19
|
+
return resolved;
|
|
20
|
+
}
|
|
21
|
+
async view(scope, path) {
|
|
22
|
+
const full = this.resolvePath(scope, path);
|
|
23
|
+
try {
|
|
24
|
+
return await readFile(full, "utf-8");
|
|
25
|
+
} catch (e) {
|
|
26
|
+
const err = e;
|
|
27
|
+
if (err.code === "ENOENT") throw new Error(`not found: ${path}`);
|
|
28
|
+
throw e;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
async create(scope, path, content) {
|
|
32
|
+
const full = this.resolvePath(scope, path);
|
|
33
|
+
if (existsSync(full)) {
|
|
34
|
+
throw new Error(`file already exists: ${path}`);
|
|
35
|
+
}
|
|
36
|
+
await mkdir(dirname(full), { recursive: true });
|
|
37
|
+
await writeFile(full, content, "utf-8");
|
|
38
|
+
}
|
|
39
|
+
async strReplace(scope, path, oldStr, newStr) {
|
|
40
|
+
const full = this.resolvePath(scope, path);
|
|
41
|
+
const content = await readFile(full, "utf-8");
|
|
42
|
+
const count = content.split(oldStr).length - 1;
|
|
43
|
+
if (count === 0) throw new Error(`string not found in ${path}`);
|
|
44
|
+
if (count > 1) throw new Error(`string appears ${count} times in ${path}, must appear exactly once`);
|
|
45
|
+
await writeFile(full, content.replace(oldStr, newStr), "utf-8");
|
|
46
|
+
}
|
|
47
|
+
async delete(scope, path) {
|
|
48
|
+
const full = this.resolvePath(scope, path);
|
|
49
|
+
await rm(full, { recursive: true, force: true });
|
|
50
|
+
}
|
|
51
|
+
async rename(scope, oldPath, newPath) {
|
|
52
|
+
const oldFull = this.resolvePath(scope, oldPath);
|
|
53
|
+
const newFull = this.resolvePath(scope, newPath);
|
|
54
|
+
await mkdir(dirname(newFull), { recursive: true });
|
|
55
|
+
await rename(oldFull, newFull);
|
|
56
|
+
}
|
|
57
|
+
async list(scope, path) {
|
|
58
|
+
const full = this.resolvePath(scope, path);
|
|
59
|
+
const base = this.scopeDir(scope);
|
|
60
|
+
try {
|
|
61
|
+
const entries = await readdir(full, { recursive: true });
|
|
62
|
+
return entries.map((e) => relative(base, join(full, e))).sort();
|
|
63
|
+
} catch {
|
|
64
|
+
return [];
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
async search(scope, query) {
|
|
68
|
+
const files = await this.list(scope, "/");
|
|
69
|
+
const results = [];
|
|
70
|
+
const q = query.toLowerCase();
|
|
71
|
+
for (const file of files) {
|
|
72
|
+
if (!file.endsWith(".md")) continue;
|
|
73
|
+
try {
|
|
74
|
+
const content = await this.view(scope, file);
|
|
75
|
+
if (content.toLowerCase().includes(q)) {
|
|
76
|
+
results.push({ path: file, scope, content: content.slice(0, 500) });
|
|
77
|
+
}
|
|
78
|
+
} catch {
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return results;
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
export {
|
|
85
|
+
FilesystemMemoryProvider
|
|
86
|
+
};
|
|
87
|
+
//# sourceMappingURL=filesystem.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/providers/memory/filesystem.ts"],"sourcesContent":["import { readFile, writeFile, mkdir, rm, rename, readdir } from \"node:fs/promises\";\nimport { join, dirname, normalize, relative } from \"node:path\";\nimport { existsSync } from \"node:fs\";\nimport type { MemoryProvider, MemoryEntry, Scope } from \"../../memory.js\";\n\nexport class FilesystemMemoryProvider implements MemoryProvider {\n constructor(private root: string) {}\n\n private scopeDir(scope: Scope): string {\n return join(this.root, scope);\n }\n\n private resolvePath(scope: Scope, path: string): string {\n const base = this.scopeDir(scope);\n const resolved = normalize(join(base, path));\n if (!resolved.startsWith(base)) {\n throw new Error(`path traversal attempt: ${path}`);\n }\n return resolved;\n }\n\n async view(scope: Scope, path: string): Promise<string> {\n const full = this.resolvePath(scope, path);\n try {\n return await readFile(full, \"utf-8\");\n } catch (e) {\n const err = e as NodeJS.ErrnoException;\n if (err.code === \"ENOENT\") throw new Error(`not found: ${path}`);\n throw e;\n }\n }\n\n async create(scope: Scope, path: string, content: string): Promise<void> {\n const full = this.resolvePath(scope, path);\n if (existsSync(full)) {\n throw new Error(`file already exists: ${path}`);\n }\n await mkdir(dirname(full), { recursive: true });\n await writeFile(full, content, \"utf-8\");\n }\n\n async strReplace(\n scope: Scope,\n path: string,\n oldStr: string,\n newStr: string,\n ): Promise<void> {\n const full = this.resolvePath(scope, path);\n const content = await readFile(full, \"utf-8\");\n const count = (content.split(oldStr).length - 1);\n if (count === 0) throw new Error(`string not found in ${path}`);\n if (count > 1) throw new Error(`string appears ${count} times in ${path}, must appear exactly once`);\n await writeFile(full, content.replace(oldStr, newStr), \"utf-8\");\n }\n\n async delete(scope: Scope, path: string): Promise<void> {\n const full = this.resolvePath(scope, path);\n await rm(full, { recursive: true, force: true });\n }\n\n async rename(scope: Scope, oldPath: string, newPath: string): Promise<void> {\n const oldFull = this.resolvePath(scope, oldPath);\n const newFull = this.resolvePath(scope, newPath);\n await mkdir(dirname(newFull), { recursive: true });\n await rename(oldFull, newFull);\n }\n\n async list(scope: Scope, path: string): Promise<string[]> {\n const full = this.resolvePath(scope, path);\n const base = this.scopeDir(scope);\n try {\n const entries = await readdir(full, { recursive: true });\n return (entries as string[])\n .map((e) => relative(base, join(full, e)))\n .sort();\n } catch {\n return [];\n }\n }\n\n async search(scope: Scope, query: string): Promise<MemoryEntry[]> {\n const files = await this.list(scope, \"/\");\n const results: MemoryEntry[] = [];\n const q = query.toLowerCase();\n\n for (const file of files) {\n if (!file.endsWith(\".md\")) continue;\n try {\n const content = await this.view(scope, file);\n if (content.toLowerCase().includes(q)) {\n results.push({ path: file, scope, content: content.slice(0, 500) });\n }\n } catch {\n // skip unreadable files\n }\n }\n return results;\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/providers/store/filesystem.ts
|
|
21
|
+
var filesystem_exports = {};
|
|
22
|
+
__export(filesystem_exports, {
|
|
23
|
+
FilesystemConversationStore: () => FilesystemConversationStore
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(filesystem_exports);
|
|
26
|
+
var import_promises = require("fs/promises");
|
|
27
|
+
var import_node_path = require("path");
|
|
28
|
+
var FilesystemConversationStore = class {
|
|
29
|
+
constructor(root) {
|
|
30
|
+
this.root = root;
|
|
31
|
+
}
|
|
32
|
+
root;
|
|
33
|
+
filePath(id) {
|
|
34
|
+
const safe = id.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
35
|
+
const full = (0, import_node_path.normalize)((0, import_node_path.join)(this.root, `${safe}.json`));
|
|
36
|
+
if (!full.startsWith((0, import_node_path.normalize)(this.root))) {
|
|
37
|
+
throw new Error(`invalid conversation id: ${id}`);
|
|
38
|
+
}
|
|
39
|
+
return full;
|
|
40
|
+
}
|
|
41
|
+
async save(conv) {
|
|
42
|
+
await (0, import_promises.mkdir)(this.root, { recursive: true });
|
|
43
|
+
const path = this.filePath(conv.id);
|
|
44
|
+
await (0, import_promises.writeFile)(path, JSON.stringify(conv, null, 2), "utf-8");
|
|
45
|
+
}
|
|
46
|
+
async load(id) {
|
|
47
|
+
try {
|
|
48
|
+
const raw = await (0, import_promises.readFile)(this.filePath(id), "utf-8");
|
|
49
|
+
const parsed = JSON.parse(raw);
|
|
50
|
+
parsed.createdAt = new Date(parsed.createdAt);
|
|
51
|
+
if (parsed.lastTurnAt) parsed.lastTurnAt = new Date(parsed.lastTurnAt);
|
|
52
|
+
return parsed;
|
|
53
|
+
} catch {
|
|
54
|
+
return void 0;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
async list(threadId) {
|
|
58
|
+
try {
|
|
59
|
+
const files = await (0, import_promises.readdir)(this.root);
|
|
60
|
+
const convs = [];
|
|
61
|
+
for (const f of files) {
|
|
62
|
+
if (!f.endsWith(".json")) continue;
|
|
63
|
+
const id = f.slice(0, -5);
|
|
64
|
+
const conv = await this.load(id);
|
|
65
|
+
if (conv && (!threadId || conv.threadId === threadId)) {
|
|
66
|
+
convs.push(conv);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return convs.sort(
|
|
70
|
+
(a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime()
|
|
71
|
+
);
|
|
72
|
+
} catch {
|
|
73
|
+
return [];
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
async delete(id) {
|
|
77
|
+
try {
|
|
78
|
+
await (0, import_promises.rm)(this.filePath(id));
|
|
79
|
+
} catch {
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
84
|
+
0 && (module.exports = {
|
|
85
|
+
FilesystemConversationStore
|
|
86
|
+
});
|
|
87
|
+
//# sourceMappingURL=filesystem.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/providers/store/filesystem.ts"],"sourcesContent":["import { readFile, writeFile, mkdir, rm, readdir } from \"node:fs/promises\";\nimport { join, normalize } from \"node:path\";\nimport type { ConversationStore } from \"../../conversation-store.js\";\nimport type { Conversation } from \"../../conversation.js\";\n\nexport class FilesystemConversationStore implements ConversationStore {\n constructor(private root: string) {}\n\n private filePath(id: string): string {\n const safe = id.replace(/[^a-zA-Z0-9_-]/g, \"_\");\n const full = normalize(join(this.root, `${safe}.json`));\n if (!full.startsWith(normalize(this.root))) {\n throw new Error(`invalid conversation id: ${id}`);\n }\n return full;\n }\n\n async save(conv: Conversation): Promise<void> {\n await mkdir(this.root, { recursive: true });\n const path = this.filePath(conv.id);\n await writeFile(path, JSON.stringify(conv, null, 2), \"utf-8\");\n }\n\n async load(id: string): Promise<Conversation | undefined> {\n try {\n const raw = await readFile(this.filePath(id), \"utf-8\");\n const parsed = JSON.parse(raw) as Conversation;\n parsed.createdAt = new Date(parsed.createdAt);\n if (parsed.lastTurnAt) parsed.lastTurnAt = new Date(parsed.lastTurnAt);\n return parsed;\n } catch {\n return undefined;\n }\n }\n\n async list(threadId?: string): Promise<Conversation[]> {\n try {\n const files = await readdir(this.root);\n const convs: Conversation[] = [];\n for (const f of files) {\n if (!f.endsWith(\".json\")) continue;\n const id = f.slice(0, -5);\n const conv = await this.load(id);\n if (conv && (!threadId || conv.threadId === threadId)) {\n convs.push(conv);\n }\n }\n return convs.sort(\n (a, b) =>\n new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime(),\n );\n } catch {\n return [];\n }\n }\n\n async delete(id: string): Promise<void> {\n try {\n await rm(this.filePath(id));\n } catch {\n // already gone\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,sBAAwD;AACxD,uBAAgC;AAIzB,IAAM,8BAAN,MAA+D;AAAA,EACpE,YAAoB,MAAc;AAAd;AAAA,EAAe;AAAA,EAAf;AAAA,EAEZ,SAAS,IAAoB;AACnC,UAAM,OAAO,GAAG,QAAQ,mBAAmB,GAAG;AAC9C,UAAM,WAAO,gCAAU,uBAAK,KAAK,MAAM,GAAG,IAAI,OAAO,CAAC;AACtD,QAAI,CAAC,KAAK,eAAW,4BAAU,KAAK,IAAI,CAAC,GAAG;AAC1C,YAAM,IAAI,MAAM,4BAA4B,EAAE,EAAE;AAAA,IAClD;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,KAAK,MAAmC;AAC5C,cAAM,uBAAM,KAAK,MAAM,EAAE,WAAW,KAAK,CAAC;AAC1C,UAAM,OAAO,KAAK,SAAS,KAAK,EAAE;AAClC,cAAM,2BAAU,MAAM,KAAK,UAAU,MAAM,MAAM,CAAC,GAAG,OAAO;AAAA,EAC9D;AAAA,EAEA,MAAM,KAAK,IAA+C;AACxD,QAAI;AACF,YAAM,MAAM,UAAM,0BAAS,KAAK,SAAS,EAAE,GAAG,OAAO;AACrD,YAAM,SAAS,KAAK,MAAM,GAAG;AAC7B,aAAO,YAAY,IAAI,KAAK,OAAO,SAAS;AAC5C,UAAI,OAAO,WAAY,QAAO,aAAa,IAAI,KAAK,OAAO,UAAU;AACrE,aAAO;AAAA,IACT,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAM,KAAK,UAA4C;AACrD,QAAI;AACF,YAAM,QAAQ,UAAM,yBAAQ,KAAK,IAAI;AACrC,YAAM,QAAwB,CAAC;AAC/B,iBAAW,KAAK,OAAO;AACrB,YAAI,CAAC,EAAE,SAAS,OAAO,EAAG;AAC1B,cAAM,KAAK,EAAE,MAAM,GAAG,EAAE;AACxB,cAAM,OAAO,MAAM,KAAK,KAAK,EAAE;AAC/B,YAAI,SAAS,CAAC,YAAY,KAAK,aAAa,WAAW;AACrD,gBAAM,KAAK,IAAI;AAAA,QACjB;AAAA,MACF;AACA,aAAO,MAAM;AAAA,QACX,CAAC,GAAG,MACF,IAAI,KAAK,EAAE,SAAS,EAAE,QAAQ,IAAI,IAAI,KAAK,EAAE,SAAS,EAAE,QAAQ;AAAA,MACpE;AAAA,IACF,QAAQ;AACN,aAAO,CAAC;AAAA,IACV;AAAA,EACF;AAAA,EAEA,MAAM,OAAO,IAA2B;AACtC,QAAI;AACF,gBAAM,oBAAG,KAAK,SAAS,EAAE,CAAC;AAAA,IAC5B,QAAQ;AAAA,IAER;AAAA,EACF;AACF;","names":[]}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { C as ConversationStore } from '../../conversation-store-Cl42jpsA.cjs';
|
|
2
|
+
import { a as Conversation } from '../../conversation-kIkMQdYK.cjs';
|
|
3
|
+
|
|
4
|
+
declare class FilesystemConversationStore implements ConversationStore {
|
|
5
|
+
private root;
|
|
6
|
+
constructor(root: string);
|
|
7
|
+
private filePath;
|
|
8
|
+
save(conv: Conversation): Promise<void>;
|
|
9
|
+
load(id: string): Promise<Conversation | undefined>;
|
|
10
|
+
list(threadId?: string): Promise<Conversation[]>;
|
|
11
|
+
delete(id: string): Promise<void>;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export { FilesystemConversationStore };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { C as ConversationStore } from '../../conversation-store-CAyPuBjk.js';
|
|
2
|
+
import { a as Conversation } from '../../conversation-kIkMQdYK.js';
|
|
3
|
+
|
|
4
|
+
declare class FilesystemConversationStore implements ConversationStore {
|
|
5
|
+
private root;
|
|
6
|
+
constructor(root: string);
|
|
7
|
+
private filePath;
|
|
8
|
+
save(conv: Conversation): Promise<void>;
|
|
9
|
+
load(id: string): Promise<Conversation | undefined>;
|
|
10
|
+
list(threadId?: string): Promise<Conversation[]>;
|
|
11
|
+
delete(id: string): Promise<void>;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export { FilesystemConversationStore };
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
// src/providers/store/filesystem.ts
|
|
2
|
+
import { readFile, writeFile, mkdir, rm, readdir } from "fs/promises";
|
|
3
|
+
import { join, normalize } from "path";
|
|
4
|
+
var FilesystemConversationStore = class {
|
|
5
|
+
constructor(root) {
|
|
6
|
+
this.root = root;
|
|
7
|
+
}
|
|
8
|
+
root;
|
|
9
|
+
filePath(id) {
|
|
10
|
+
const safe = id.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
11
|
+
const full = normalize(join(this.root, `${safe}.json`));
|
|
12
|
+
if (!full.startsWith(normalize(this.root))) {
|
|
13
|
+
throw new Error(`invalid conversation id: ${id}`);
|
|
14
|
+
}
|
|
15
|
+
return full;
|
|
16
|
+
}
|
|
17
|
+
async save(conv) {
|
|
18
|
+
await mkdir(this.root, { recursive: true });
|
|
19
|
+
const path = this.filePath(conv.id);
|
|
20
|
+
await writeFile(path, JSON.stringify(conv, null, 2), "utf-8");
|
|
21
|
+
}
|
|
22
|
+
async load(id) {
|
|
23
|
+
try {
|
|
24
|
+
const raw = await readFile(this.filePath(id), "utf-8");
|
|
25
|
+
const parsed = JSON.parse(raw);
|
|
26
|
+
parsed.createdAt = new Date(parsed.createdAt);
|
|
27
|
+
if (parsed.lastTurnAt) parsed.lastTurnAt = new Date(parsed.lastTurnAt);
|
|
28
|
+
return parsed;
|
|
29
|
+
} catch {
|
|
30
|
+
return void 0;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
async list(threadId) {
|
|
34
|
+
try {
|
|
35
|
+
const files = await readdir(this.root);
|
|
36
|
+
const convs = [];
|
|
37
|
+
for (const f of files) {
|
|
38
|
+
if (!f.endsWith(".json")) continue;
|
|
39
|
+
const id = f.slice(0, -5);
|
|
40
|
+
const conv = await this.load(id);
|
|
41
|
+
if (conv && (!threadId || conv.threadId === threadId)) {
|
|
42
|
+
convs.push(conv);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return convs.sort(
|
|
46
|
+
(a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime()
|
|
47
|
+
);
|
|
48
|
+
} catch {
|
|
49
|
+
return [];
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
async delete(id) {
|
|
53
|
+
try {
|
|
54
|
+
await rm(this.filePath(id));
|
|
55
|
+
} catch {
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
export {
|
|
60
|
+
FilesystemConversationStore
|
|
61
|
+
};
|
|
62
|
+
//# sourceMappingURL=filesystem.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/providers/store/filesystem.ts"],"sourcesContent":["import { readFile, writeFile, mkdir, rm, readdir } from \"node:fs/promises\";\nimport { join, normalize } from \"node:path\";\nimport type { ConversationStore } from \"../../conversation-store.js\";\nimport type { Conversation } from \"../../conversation.js\";\n\nexport class FilesystemConversationStore implements ConversationStore {\n constructor(private root: string) {}\n\n private filePath(id: string): string {\n const safe = id.replace(/[^a-zA-Z0-9_-]/g, \"_\");\n const full = normalize(join(this.root, `${safe}.json`));\n if (!full.startsWith(normalize(this.root))) {\n throw new Error(`invalid conversation id: ${id}`);\n }\n return full;\n }\n\n async save(conv: Conversation): Promise<void> {\n await mkdir(this.root, { recursive: true });\n const path = this.filePath(conv.id);\n await writeFile(path, JSON.stringify(conv, null, 2), \"utf-8\");\n }\n\n async load(id: string): Promise<Conversation | undefined> {\n try {\n const raw = await readFile(this.filePath(id), \"utf-8\");\n const parsed = JSON.parse(raw) as Conversation;\n parsed.createdAt = new Date(parsed.createdAt);\n if (parsed.lastTurnAt) parsed.lastTurnAt = new Date(parsed.lastTurnAt);\n return parsed;\n } catch {\n return undefined;\n }\n }\n\n async list(threadId?: string): Promise<Conversation[]> {\n try {\n const files = await readdir(this.root);\n const convs: Conversation[] = [];\n for (const f of files) {\n if (!f.endsWith(\".json\")) continue;\n const id = f.slice(0, -5);\n const conv = await this.load(id);\n if (conv && (!threadId || conv.threadId === threadId)) {\n convs.push(conv);\n }\n }\n return convs.sort(\n (a, b) =>\n new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime(),\n );\n } catch {\n return [];\n }\n }\n\n async delete(id: string): Promise<void> {\n try {\n await rm(this.filePath(id));\n } catch {\n // already gone\n }\n }\n}\n"],"mappings":";AAAA,SAAS,UAAU,WAAW,OAAO,IAAI,eAAe;AACxD,SAAS,MAAM,iBAAiB;AAIzB,IAAM,8BAAN,MAA+D;AAAA,EACpE,YAAoB,MAAc;AAAd;AAAA,EAAe;AAAA,EAAf;AAAA,EAEZ,SAAS,IAAoB;AACnC,UAAM,OAAO,GAAG,QAAQ,mBAAmB,GAAG;AAC9C,UAAM,OAAO,UAAU,KAAK,KAAK,MAAM,GAAG,IAAI,OAAO,CAAC;AACtD,QAAI,CAAC,KAAK,WAAW,UAAU,KAAK,IAAI,CAAC,GAAG;AAC1C,YAAM,IAAI,MAAM,4BAA4B,EAAE,EAAE;AAAA,IAClD;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,KAAK,MAAmC;AAC5C,UAAM,MAAM,KAAK,MAAM,EAAE,WAAW,KAAK,CAAC;AAC1C,UAAM,OAAO,KAAK,SAAS,KAAK,EAAE;AAClC,UAAM,UAAU,MAAM,KAAK,UAAU,MAAM,MAAM,CAAC,GAAG,OAAO;AAAA,EAC9D;AAAA,EAEA,MAAM,KAAK,IAA+C;AACxD,QAAI;AACF,YAAM,MAAM,MAAM,SAAS,KAAK,SAAS,EAAE,GAAG,OAAO;AACrD,YAAM,SAAS,KAAK,MAAM,GAAG;AAC7B,aAAO,YAAY,IAAI,KAAK,OAAO,SAAS;AAC5C,UAAI,OAAO,WAAY,QAAO,aAAa,IAAI,KAAK,OAAO,UAAU;AACrE,aAAO;AAAA,IACT,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAM,KAAK,UAA4C;AACrD,QAAI;AACF,YAAM,QAAQ,MAAM,QAAQ,KAAK,IAAI;AACrC,YAAM,QAAwB,CAAC;AAC/B,iBAAW,KAAK,OAAO;AACrB,YAAI,CAAC,EAAE,SAAS,OAAO,EAAG;AAC1B,cAAM,KAAK,EAAE,MAAM,GAAG,EAAE;AACxB,cAAM,OAAO,MAAM,KAAK,KAAK,EAAE;AAC/B,YAAI,SAAS,CAAC,YAAY,KAAK,aAAa,WAAW;AACrD,gBAAM,KAAK,IAAI;AAAA,QACjB;AAAA,MACF;AACA,aAAO,MAAM;AAAA,QACX,CAAC,GAAG,MACF,IAAI,KAAK,EAAE,SAAS,EAAE,QAAQ,IAAI,IAAI,KAAK,EAAE,SAAS,EAAE,QAAQ;AAAA,MACpE;AAAA,IACF,QAAQ;AACN,aAAO,CAAC;AAAA,IACV;AAAA,EACF;AAAA,EAEA,MAAM,OAAO,IAA2B;AACtC,QAAI;AACF,YAAM,GAAG,KAAK,SAAS,EAAE,CAAC;AAAA,IAC5B,QAAQ;AAAA,IAER;AAAA,EACF;AACF;","names":[]}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/providers/thread/memory.ts
|
|
21
|
+
var memory_exports = {};
|
|
22
|
+
__export(memory_exports, {
|
|
23
|
+
InMemoryThreadProvider: () => InMemoryThreadProvider
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(memory_exports);
|
|
26
|
+
var import_node_crypto = require("crypto");
|
|
27
|
+
|
|
28
|
+
// src/thread.ts
|
|
29
|
+
var ErrThreadAccessDenied = new Error("thread: access denied");
|
|
30
|
+
|
|
31
|
+
// src/providers/thread/memory.ts
|
|
32
|
+
var InMemoryThreadProvider = class {
|
|
33
|
+
threads = /* @__PURE__ */ new Map();
|
|
34
|
+
async create(projectId, modeId) {
|
|
35
|
+
const t = {
|
|
36
|
+
id: (0, import_node_crypto.randomUUID)(),
|
|
37
|
+
projectId,
|
|
38
|
+
modeId,
|
|
39
|
+
status: "active"
|
|
40
|
+
};
|
|
41
|
+
this.threads.set(t.id, t);
|
|
42
|
+
return t;
|
|
43
|
+
}
|
|
44
|
+
async createForUser(userId, projectId, modeId) {
|
|
45
|
+
const t = {
|
|
46
|
+
id: (0, import_node_crypto.randomUUID)(),
|
|
47
|
+
userId,
|
|
48
|
+
projectId,
|
|
49
|
+
modeId,
|
|
50
|
+
status: "active"
|
|
51
|
+
};
|
|
52
|
+
this.threads.set(t.id, t);
|
|
53
|
+
return t;
|
|
54
|
+
}
|
|
55
|
+
async get(threadId) {
|
|
56
|
+
const t = this.threads.get(threadId);
|
|
57
|
+
if (!t) throw new Error(`thread not found: ${threadId}`);
|
|
58
|
+
return t;
|
|
59
|
+
}
|
|
60
|
+
async getForUser(userId, threadId) {
|
|
61
|
+
const t = await this.get(threadId);
|
|
62
|
+
if (t.userId && t.userId !== userId) throw ErrThreadAccessDenied;
|
|
63
|
+
return t;
|
|
64
|
+
}
|
|
65
|
+
async listByUser(userId, status) {
|
|
66
|
+
return Array.from(this.threads.values()).filter(
|
|
67
|
+
(t) => t.userId === userId && (!status || t.status === status)
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
async archive(threadId) {
|
|
71
|
+
const t = await this.get(threadId);
|
|
72
|
+
t.status = "archived";
|
|
73
|
+
}
|
|
74
|
+
async sendMessage(_msg) {
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
78
|
+
0 && (module.exports = {
|
|
79
|
+
InMemoryThreadProvider
|
|
80
|
+
});
|
|
81
|
+
//# sourceMappingURL=memory.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/providers/thread/memory.ts","../../../src/thread.ts"],"sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport type {\n ThreadProvider,\n MultiUserThreadProvider,\n Thread,\n ThreadStatus,\n Message,\n} from \"../../thread.js\";\nimport { ErrThreadAccessDenied } from \"../../thread.js\";\n\nexport class InMemoryThreadProvider implements MultiUserThreadProvider {\n private threads = new Map<string, Thread>();\n\n async create(projectId: string, modeId: string): Promise<Thread> {\n const t: Thread = {\n id: randomUUID(),\n projectId,\n modeId,\n status: \"active\",\n };\n this.threads.set(t.id, t);\n return t;\n }\n\n async createForUser(\n userId: string,\n projectId: string,\n modeId: string,\n ): Promise<Thread> {\n const t: Thread = {\n id: randomUUID(),\n userId,\n projectId,\n modeId,\n status: \"active\",\n };\n this.threads.set(t.id, t);\n return t;\n }\n\n async get(threadId: string): Promise<Thread> {\n const t = this.threads.get(threadId);\n if (!t) throw new Error(`thread not found: ${threadId}`);\n return t;\n }\n\n async getForUser(userId: string, threadId: string): Promise<Thread> {\n const t = await this.get(threadId);\n if (t.userId && t.userId !== userId) throw ErrThreadAccessDenied;\n return t;\n }\n\n async listByUser(userId: string, status: ThreadStatus): Promise<Thread[]> {\n return Array.from(this.threads.values()).filter(\n (t) => t.userId === userId && (!status || t.status === status),\n );\n }\n\n async archive(threadId: string): Promise<void> {\n const t = await this.get(threadId);\n t.status = \"archived\";\n }\n\n async sendMessage(_msg: Message): Promise<void> {\n // in-memory: drop messages\n }\n}\n","export type ThreadStatus = \"active\" | \"completed\" | \"failed\" | \"archived\";\n\nexport interface Thread {\n id: string;\n userId?: string;\n projectId?: string;\n modeId?: string;\n status: ThreadStatus;\n parentId?: string;\n}\n\nexport interface Message {\n id?: string;\n fromThreadId: string;\n toThreadId: string;\n content: string;\n sentAt?: Date;\n}\n\nexport interface ThreadProvider {\n create(projectId: string, modeId: string, signal?: AbortSignal): Promise<Thread>;\n get(threadId: string, signal?: AbortSignal): Promise<Thread>;\n archive(threadId: string, signal?: AbortSignal): Promise<void>;\n sendMessage(msg: Message, signal?: AbortSignal): Promise<void>;\n}\n\nexport interface MultiUserThreadProvider extends ThreadProvider {\n createForUser(userId: string, projectId: string, modeId: string, signal?: AbortSignal): Promise<Thread>;\n getForUser(userId: string, threadId: string, signal?: AbortSignal): Promise<Thread>;\n listByUser(userId: string, status: ThreadStatus, signal?: AbortSignal): Promise<Thread[]>;\n}\n\nexport const ErrThreadAccessDenied = new Error(\"thread: access denied\");\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,yBAA2B;;;ACgCpB,IAAM,wBAAwB,IAAI,MAAM,uBAAuB;;;ADtB/D,IAAM,yBAAN,MAAgE;AAAA,EAC7D,UAAU,oBAAI,IAAoB;AAAA,EAE1C,MAAM,OAAO,WAAmB,QAAiC;AAC/D,UAAM,IAAY;AAAA,MAChB,QAAI,+BAAW;AAAA,MACf;AAAA,MACA;AAAA,MACA,QAAQ;AAAA,IACV;AACA,SAAK,QAAQ,IAAI,EAAE,IAAI,CAAC;AACxB,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,cACJ,QACA,WACA,QACiB;AACjB,UAAM,IAAY;AAAA,MAChB,QAAI,+BAAW;AAAA,MACf;AAAA,MACA;AAAA,MACA;AAAA,MACA,QAAQ;AAAA,IACV;AACA,SAAK,QAAQ,IAAI,EAAE,IAAI,CAAC;AACxB,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,IAAI,UAAmC;AAC3C,UAAM,IAAI,KAAK,QAAQ,IAAI,QAAQ;AACnC,QAAI,CAAC,EAAG,OAAM,IAAI,MAAM,qBAAqB,QAAQ,EAAE;AACvD,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,WAAW,QAAgB,UAAmC;AAClE,UAAM,IAAI,MAAM,KAAK,IAAI,QAAQ;AACjC,QAAI,EAAE,UAAU,EAAE,WAAW,OAAQ,OAAM;AAC3C,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,WAAW,QAAgB,QAAyC;AACxE,WAAO,MAAM,KAAK,KAAK,QAAQ,OAAO,CAAC,EAAE;AAAA,MACvC,CAAC,MAAM,EAAE,WAAW,WAAW,CAAC,UAAU,EAAE,WAAW;AAAA,IACzD;AAAA,EACF;AAAA,EAEA,MAAM,QAAQ,UAAiC;AAC7C,UAAM,IAAI,MAAM,KAAK,IAAI,QAAQ;AACjC,MAAE,SAAS;AAAA,EACb;AAAA,EAEA,MAAM,YAAY,MAA8B;AAAA,EAEhD;AACF;","names":[]}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { a as MultiUserThreadProvider, T as Thread, c as ThreadStatus, M as Message } from '../../thread-C2b9xRMJ.cjs';
|
|
2
|
+
|
|
3
|
+
declare class InMemoryThreadProvider implements MultiUserThreadProvider {
|
|
4
|
+
private threads;
|
|
5
|
+
create(projectId: string, modeId: string): Promise<Thread>;
|
|
6
|
+
createForUser(userId: string, projectId: string, modeId: string): Promise<Thread>;
|
|
7
|
+
get(threadId: string): Promise<Thread>;
|
|
8
|
+
getForUser(userId: string, threadId: string): Promise<Thread>;
|
|
9
|
+
listByUser(userId: string, status: ThreadStatus): Promise<Thread[]>;
|
|
10
|
+
archive(threadId: string): Promise<void>;
|
|
11
|
+
sendMessage(_msg: Message): Promise<void>;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export { InMemoryThreadProvider };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { a as MultiUserThreadProvider, T as Thread, c as ThreadStatus, M as Message } from '../../thread-C2b9xRMJ.js';
|
|
2
|
+
|
|
3
|
+
declare class InMemoryThreadProvider implements MultiUserThreadProvider {
|
|
4
|
+
private threads;
|
|
5
|
+
create(projectId: string, modeId: string): Promise<Thread>;
|
|
6
|
+
createForUser(userId: string, projectId: string, modeId: string): Promise<Thread>;
|
|
7
|
+
get(threadId: string): Promise<Thread>;
|
|
8
|
+
getForUser(userId: string, threadId: string): Promise<Thread>;
|
|
9
|
+
listByUser(userId: string, status: ThreadStatus): Promise<Thread[]>;
|
|
10
|
+
archive(threadId: string): Promise<void>;
|
|
11
|
+
sendMessage(_msg: Message): Promise<void>;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export { InMemoryThreadProvider };
|