openclaw-cloudflare-vectorize-memory 0.1.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 +674 -0
- package/README.md +197 -0
- package/dist/index.js +1459 -0
- package/dist/index.js.map +1 -0
- package/dist/types/cli.d.ts +17 -0
- package/dist/types/cloudflare-api.d.ts +8 -0
- package/dist/types/companion-store.d.ts +10 -0
- package/dist/types/config.d.ts +172 -0
- package/dist/types/constants.d.ts +31 -0
- package/dist/types/doctor.d.ts +6 -0
- package/dist/types/embeddings-client.d.ts +8 -0
- package/dist/types/errors.d.ts +11 -0
- package/dist/types/index.d.ts +8 -0
- package/dist/types/migration.d.ts +35 -0
- package/dist/types/namespace.d.ts +7 -0
- package/dist/types/prompt.d.ts +2 -0
- package/dist/types/public-artifacts.d.ts +2 -0
- package/dist/types/record-mapper.d.ts +24 -0
- package/dist/types/runtime.d.ts +5 -0
- package/dist/types/search-manager.d.ts +24 -0
- package/dist/types/service-factory.d.ts +8 -0
- package/dist/types/service.d.ts +59 -0
- package/dist/types/tools.d.ts +5 -0
- package/dist/types/types.d.ts +169 -0
- package/dist/types/vectorize-client.d.ts +17 -0
- package/openclaw.plugin.json +169 -0
- package/package.json +63 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../src/namespace.ts","../src/migration.ts","../src/constants.ts","../src/errors.ts","../src/config.ts","../src/cloudflare-api.ts","../src/companion-store.ts","../src/doctor.ts","../src/embeddings-client.ts","../src/record-mapper.ts","../src/vectorize-client.ts","../src/service.ts","../src/service-factory.ts","../src/cli.ts","../src/prompt.ts","../src/public-artifacts.ts","../src/search-manager.ts","../src/runtime.ts","../src/tools.ts","../src/index.ts"],"sourcesContent":["import { basename } from \"node:path\";\nimport { resolveAgentIdFromSessionKey } from \"openclaw/plugin-sdk/routing\";\n\nfunction normalizeNamespacePart(value: string): string {\n\treturn value\n\t\t.trim()\n\t\t.toLowerCase()\n\t\t.replace(/[^a-z0-9-_]+/g, \"-\")\n\t\t.replace(/-{2,}/g, \"-\")\n\t\t.replace(/^-+|-+$/g, \"\")\n\t\t.slice(0, 64);\n}\n\nexport function sanitizeNamespace(value: string): string {\n\tconst normalized = normalizeNamespacePart(value);\n\treturn normalized || \"main\";\n}\n\nexport function resolveDefaultNamespace(params: { fixedNamespace?: string; sessionKey?: string; agentId?: string; workspaceDir?: string }): string {\n\tif (params.fixedNamespace) {\n\t\treturn sanitizeNamespace(params.fixedNamespace);\n\t}\n\tconst agentId = params.sessionKey ? resolveAgentIdFromSessionKey(params.sessionKey) : params.agentId;\n\tif (agentId) {\n\t\treturn sanitizeNamespace(`agent-${agentId}`);\n\t}\n\tif (params.workspaceDir) {\n\t\treturn sanitizeNamespace(`workspace-${basename(params.workspaceDir)}`);\n\t}\n\treturn \"main\";\n}\n","import { createHash } from \"node:crypto\";\r\nimport { glob, readFile, stat } from \"node:fs/promises\";\r\nimport { basename, extname, isAbsolute, relative, resolve } from \"node:path\";\r\nimport { listMemoryFiles } from \"openclaw/plugin-sdk/memory-core\";\r\nimport { sanitizeNamespace } from \"./namespace.js\";\r\nimport type { CloudflareMemoryService } from \"./service.js\";\r\nimport type {\r\n\tDoctorReport,\r\n\tMetadataValue,\r\n\tMigrationDuplicateStrategy,\r\n\tMigrationNamespaceStrategy,\r\n\tMigrationResult,\r\n\tMigrationRunOptions,\r\n\tMigrationSourceMode,\r\n\tMigrationSummary,\r\n} from \"./types.js\";\r\n\r\ntype DiscoveredMigrationFile = {\r\n\tabsolutePath: string;\r\n\trelativePath: string;\r\n};\r\n\r\ntype ParsedMigrationRecord = {\r\n\tinput: {\r\n\t\tid: string;\r\n\t\ttext: string;\r\n\t\ttitle?: string;\r\n\t\tmetadata: Record<string, MetadataValue>;\r\n\t\tnamespace?: string;\r\n\t\tsource?: string;\r\n\t};\r\n\tsourcePath: string;\r\n\trelativePath: string;\r\n};\r\n\r\nconst MARKDOWN_EXTENSIONS = new Set([\".md\", \".markdown\"]);\r\nconst RESERVED_FRONTMATTER_FIELDS = new Set([\"id\", \"namespace\", \"source\", \"title\"]);\r\n\r\nfunction normalizePathForMetadata(value: string): string {\r\n\treturn value.replace(/\\\\/g, \"/\").replace(/^\\.\\//, \"\");\r\n}\r\n\r\nfunction normalizeRelativePath(value: string): string {\r\n\tconst normalized = normalizePathForMetadata(value).replace(/^\\/+/, \"\");\r\n\treturn normalized || basename(value);\r\n}\r\n\r\nfunction isMarkdownFile(value: string): boolean {\r\n\treturn MARKDOWN_EXTENSIONS.has(extname(value).toLowerCase());\r\n}\r\n\r\nfunction hasGlobMagic(value: string): boolean {\r\n\treturn /[*?[\\]{}]/.test(value);\r\n}\r\n\r\nfunction shouldIgnoreDiscoveredFile(value: string): boolean {\r\n\tconst normalized = normalizePathForMetadata(value).toLowerCase();\r\n\treturn normalized.includes(\"/node_modules/\") || normalized.includes(\"/.git/\");\r\n}\r\n\r\nasync function statIfExists(path: string) {\r\n\ttry {\r\n\t\treturn await stat(path);\r\n\t} catch {\r\n\t\treturn null;\r\n\t}\r\n}\r\n\r\nasync function collectDirectoryMarkdownFiles(directory: string): Promise<string[]> {\r\n\tconst matches: string[] = [];\r\n\tfor await (const match of glob(\"**/*.{md,markdown}\", { cwd: directory })) {\r\n\t\tconst absolutePath = resolve(directory, match);\r\n\t\tif (!shouldIgnoreDiscoveredFile(absolutePath)) {\r\n\t\t\tmatches.push(absolutePath);\r\n\t\t}\r\n\t}\r\n\treturn matches;\r\n}\r\n\r\nasync function collectGlobMatches(pattern: string, workspaceDir: string): Promise<string[]> {\r\n\tconst matches: string[] = [];\r\n\tconst normalizedPattern = normalizePathForMetadata(pattern);\r\n\tconst iterator = isAbsolute(pattern) ? glob(normalizedPattern) : glob(normalizedPattern, { cwd: workspaceDir });\r\n\tfor await (const match of iterator) {\r\n\t\tconst absolutePath = isAbsolute(match) ? match : resolve(workspaceDir, match);\r\n\t\tif (shouldIgnoreDiscoveredFile(absolutePath) || !isMarkdownFile(absolutePath)) {\r\n\t\t\tcontinue;\r\n\t\t}\r\n\t\tconst fileStats = await statIfExists(absolutePath);\r\n\t\tif (fileStats?.isFile()) {\r\n\t\t\tmatches.push(absolutePath);\r\n\t\t}\r\n\t}\r\n\treturn matches;\r\n}\r\n\r\nexport async function discoverMigrationFiles(params: {\r\n\tworkspaceDir: string;\r\n\tsourceMode: MigrationSourceMode;\r\n\tsourcePaths?: string[];\r\n}): Promise<DiscoveredMigrationFile[]> {\r\n\tconst workspaceDir = resolve(params.workspaceDir);\r\n\tconst discovered = new Map<string, DiscoveredMigrationFile>();\r\n\r\n\tif (params.sourceMode === \"default-provider\") {\r\n\t\tfor (const relPath of await listMemoryFiles(workspaceDir)) {\r\n\t\t\tconst relativePath = normalizeRelativePath(relPath);\r\n\t\t\tconst absolutePath = resolve(workspaceDir, relativePath);\r\n\t\t\tif (shouldIgnoreDiscoveredFile(absolutePath) || !isMarkdownFile(relativePath)) {\r\n\t\t\t\tcontinue;\r\n\t\t\t}\r\n\t\t\tconst fileStats = await statIfExists(absolutePath);\r\n\t\t\tif (fileStats?.isFile()) {\r\n\t\t\t\tdiscovered.set(absolutePath.toLowerCase(), {\r\n\t\t\t\t\tabsolutePath,\r\n\t\t\t\t\trelativePath,\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tfor (const input of params.sourcePaths ?? []) {\r\n\t\tconst absoluteInput = resolve(workspaceDir, input);\r\n\t\tconst fileStats = await statIfExists(absoluteInput);\r\n\t\tlet matches: string[] = [];\r\n\t\tif (fileStats?.isDirectory()) {\r\n\t\t\tmatches = await collectDirectoryMarkdownFiles(absoluteInput);\r\n\t\t} else if (fileStats?.isFile()) {\r\n\t\t\tmatches = isMarkdownFile(absoluteInput) ? [absoluteInput] : [];\r\n\t\t} else if (hasGlobMagic(input)) {\r\n\t\t\tmatches = await collectGlobMatches(input, workspaceDir);\r\n\t\t}\r\n\r\n\t\tfor (const match of matches) {\r\n\t\t\tconst relativePath = normalizeRelativePath(relative(workspaceDir, match));\r\n\t\t\tdiscovered.set(match.toLowerCase(), {\r\n\t\t\t\tabsolutePath: match,\r\n\t\t\t\trelativePath,\r\n\t\t\t});\r\n\t\t}\r\n\t}\r\n\r\n\treturn [...discovered.values()].sort((left, right) => left.relativePath.localeCompare(right.relativePath));\r\n}\r\n\r\nfunction parseFrontmatterValue(value: string): MetadataValue | undefined {\r\n\tconst trimmed = value.trim();\r\n\tif (!trimmed) {\r\n\t\treturn \"\";\r\n\t}\r\n\tif (/^\"(.*)\"$/.test(trimmed) || /^'(.*)'$/.test(trimmed)) {\r\n\t\treturn trimmed.slice(1, -1);\r\n\t}\r\n\tif (trimmed === \"true\") {\r\n\t\treturn true;\r\n\t}\r\n\tif (trimmed === \"false\") {\r\n\t\treturn false;\r\n\t}\r\n\tconst numeric = Number(trimmed);\r\n\tif (!Number.isNaN(numeric) && trimmed !== \"\") {\r\n\t\treturn numeric;\r\n\t}\r\n\tif (trimmed.startsWith(\"[\") || trimmed.startsWith(\"{\")) {\r\n\t\treturn undefined;\r\n\t}\r\n\treturn trimmed;\r\n}\r\n\r\nfunction parseFrontmatter(content: string): { body: string; attributes: Record<string, MetadataValue> } {\r\n\tconst normalized = content.replace(/\\r\\n/g, \"\\n\");\r\n\tif (!normalized.startsWith(\"---\\n\")) {\r\n\t\treturn { body: normalized, attributes: {} };\r\n\t}\r\n\r\n\tconst lines = normalized.split(\"\\n\");\r\n\tconst closingIndex = lines.findIndex((line, index) => index > 0 && line.trim() === \"---\");\r\n\tif (closingIndex === -1) {\r\n\t\treturn { body: normalized, attributes: {} };\r\n\t}\r\n\r\n\tconst attributes: Record<string, MetadataValue> = {};\r\n\tfor (const line of lines.slice(1, closingIndex)) {\r\n\t\tconst separatorIndex = line.indexOf(\":\");\r\n\t\tif (separatorIndex === -1) {\r\n\t\t\tcontinue;\r\n\t\t}\r\n\t\tconst key = line.slice(0, separatorIndex).trim();\r\n\t\tif (!key) {\r\n\t\t\tcontinue;\r\n\t\t}\r\n\t\tconst parsedValue = parseFrontmatterValue(line.slice(separatorIndex + 1));\r\n\t\tif (parsedValue !== undefined) {\r\n\t\t\tattributes[key] = parsedValue;\r\n\t\t}\r\n\t}\r\n\r\n\treturn {\r\n\t\tbody: lines.slice(closingIndex + 1).join(\"\\n\"),\r\n\t\tattributes,\r\n\t};\r\n}\r\n\r\nfunction extractHeadingTitleAndBody(content: string): { title?: string; text: string } {\r\n\tconst lines = content.split(\"\\n\");\r\n\tconst firstContentLine = lines.findIndex((line) => line.trim().length > 0);\r\n\tif (firstContentLine === -1) {\r\n\t\treturn { text: \"\" };\r\n\t}\r\n\r\n\tconst headingMatch = /^#\\s+(.+?)\\s*$/.exec(lines[firstContentLine]?.trim() ?? \"\");\r\n\tif (!headingMatch) {\r\n\t\treturn { text: content.trim() };\r\n\t}\r\n\r\n\tconst remainingLines = [...lines];\r\n\tremainingLines.splice(firstContentLine, 1);\r\n\tif ((remainingLines[firstContentLine] ?? \"\").trim() === \"\") {\r\n\t\tremainingLines.splice(firstContentLine, 1);\r\n\t}\r\n\tconst body = remainingLines.join(\"\\n\").trim();\r\n\treturn {\r\n\t\ttitle: headingMatch[1].trim(),\r\n\t\ttext: body || content.trim(),\r\n\t};\r\n}\r\n\r\nfunction buildStableLogicalId(relativePath: string): string {\r\n\tconst withoutExtension = relativePath.replace(/\\.(md|markdown)$/i, \"\");\r\n\tconst slug = withoutExtension\r\n\t\t.toLowerCase()\r\n\t\t.replace(/[^a-z0-9]+/g, \"-\")\r\n\t\t.replace(/-{2,}/g, \"-\")\r\n\t\t.replace(/^-+|-+$/g, \"\")\r\n\t\t.slice(0, 80);\r\n\tconst hash = createHash(\"sha1\").update(relativePath).digest(\"hex\").slice(0, 10);\r\n\treturn `${slug || \"memory\"}-${hash}`;\r\n}\r\n\r\nfunction pickTitle(relativePath: string, frontmatterTitle: MetadataValue | undefined, headingTitle: string | undefined): string | undefined {\r\n\tif (typeof frontmatterTitle === \"string\" && frontmatterTitle.trim().length > 0) {\r\n\t\treturn frontmatterTitle.trim();\r\n\t}\r\n\tif (headingTitle) {\r\n\t\treturn headingTitle;\r\n\t}\r\n\tconst fileName = basename(relativePath, extname(relativePath)).trim();\r\n\treturn fileName || undefined;\r\n}\r\n\r\nfunction buildTargetNamespace(service: CloudflareMemoryService, options: MigrationRunOptions, workspaceDir: string): string {\r\n\treturn service.resolveNamespace({\r\n\t\tnamespace: options.namespace,\r\n\t\tworkspaceDir,\r\n\t});\r\n}\r\n\r\nfunction deriveRecordNamespace(params: {\r\n\trelativePath: string;\r\n\tfrontmatterNamespace: MetadataValue | undefined;\r\n\ttargetNamespace: string;\r\n\tnamespaceStrategy: MigrationNamespaceStrategy;\r\n}): string {\r\n\tif (params.namespaceStrategy === \"single-target\") {\r\n\t\treturn params.targetNamespace;\r\n\t}\r\n\r\n\tif (typeof params.frontmatterNamespace === \"string\" && params.frontmatterNamespace.trim().length > 0) {\r\n\t\treturn sanitizeNamespace(params.frontmatterNamespace);\r\n\t}\r\n\r\n\tconst firstSegment = normalizeRelativePath(params.relativePath).split(\"/\")[0];\r\n\tif (!firstSegment || firstSegment === \".\" || firstSegment === \"..\") {\r\n\t\treturn params.targetNamespace;\r\n\t}\r\n\treturn sanitizeNamespace(firstSegment);\r\n}\r\n\r\nexport async function parseMigrationFile(params: {\r\n\tfile: DiscoveredMigrationFile;\r\n\tsourceMode: MigrationSourceMode;\r\n\ttargetNamespace: string;\r\n\tnamespaceStrategy: MigrationNamespaceStrategy;\r\n}): Promise<ParsedMigrationRecord | null> {\r\n\tconst raw = await readFile(params.file.absolutePath, \"utf8\");\r\n\tconst { body, attributes } = parseFrontmatter(raw);\r\n\tconst { title: headingTitle, text: extractedText } = extractHeadingTitleAndBody(body);\r\n\tconst title = pickTitle(params.file.relativePath, attributes.title, headingTitle);\r\n\tconst text = extractedText.trim() || title || \"\";\r\n\tif (!text) {\r\n\t\treturn null;\r\n\t}\r\n\r\n\tconst metadata: Record<string, MetadataValue> = {\r\n\t\tlegacySourceMode: params.sourceMode,\r\n\t\tlegacySourcePath: params.file.relativePath.startsWith(\"..\") ? params.file.absolutePath : params.file.relativePath,\r\n\t};\r\n\tfor (const [key, value] of Object.entries(attributes)) {\r\n\t\tif (RESERVED_FRONTMATTER_FIELDS.has(key)) {\r\n\t\t\tcontinue;\r\n\t\t}\r\n\t\tmetadata[key] = value;\r\n\t}\r\n\r\n\tconst logicalId =\r\n\t\ttypeof attributes.id === \"string\" && attributes.id.trim().length > 0 ? attributes.id.trim() : buildStableLogicalId(params.file.relativePath);\r\n\tconst namespace = deriveRecordNamespace({\r\n\t\trelativePath: params.file.relativePath,\r\n\t\tfrontmatterNamespace: attributes.namespace,\r\n\t\ttargetNamespace: params.targetNamespace,\r\n\t\tnamespaceStrategy: params.namespaceStrategy,\r\n\t});\r\n\tconst source =\r\n\t\ttypeof attributes.source === \"string\" && attributes.source.trim().length > 0\r\n\t\t\t? attributes.source.trim()\r\n\t\t\t: params.sourceMode === \"default-provider\"\r\n\t\t\t\t? \"openclaw-default-memory\"\r\n\t\t\t\t: \"markdown-import\";\r\n\r\n\treturn {\r\n\t\tsourcePath: params.file.absolutePath,\r\n\t\trelativePath: params.file.relativePath,\r\n\t\tinput: {\r\n\t\t\tid: logicalId,\r\n\t\t\tnamespace,\r\n\t\t\ttitle,\r\n\t\t\ttext,\r\n\t\t\tsource,\r\n\t\t\tmetadata,\r\n\t\t},\r\n\t};\r\n}\r\n\r\nfunction formatDoctorFailure(report: DoctorReport): string {\r\n\tconst failedChecks = report.checks.filter((check) => check.status === \"fail\");\r\n\treturn failedChecks.map((check) => `${check.name}: ${check.message}`).join(\" | \");\r\n}\r\n\r\nexport async function runCloudflareMemoryMigration(params: {\r\n\tservice: CloudflareMemoryService;\r\n\toptions?: MigrationRunOptions;\r\n}): Promise<MigrationSummary> {\r\n\tconst options = params.options ?? {};\r\n\tconst workspaceDir = resolve(options.workspaceDir ?? process.cwd());\r\n\tconst sourceMode: MigrationSourceMode = (options.sourcePaths?.length ?? 0) > 0 ? \"paths\" : \"default-provider\";\r\n\tconst namespaceStrategy = options.namespaceStrategy ?? \"single-target\";\r\n\tconst duplicateStrategy: MigrationDuplicateStrategy = options.duplicateStrategy ?? \"overwrite\";\r\n\tconst dryRun = options.dryRun ?? false;\r\n\tconst targetNamespace = buildTargetNamespace(params.service, options, workspaceDir);\r\n\tconst doctor = await params.service.doctor({\r\n\t\tcreateIndexIfMissing: options.createIndexIfMissing ?? false,\r\n\t});\r\n\tif (!doctor.ok) {\r\n\t\tthrow new Error(`Migration validation failed. ${formatDoctorFailure(doctor)}`);\r\n\t}\r\n\r\n\tconst discoveredFiles = await discoverMigrationFiles({\r\n\t\tworkspaceDir,\r\n\t\tsourceMode,\r\n\t\tsourcePaths: options.sourcePaths,\r\n\t});\r\n\tif (discoveredFiles.length === 0) {\r\n\t\tthrow new Error(\r\n\t\t\tsourceMode === \"default-provider\"\r\n\t\t\t\t? `No default OpenClaw markdown memory files were found under ${workspaceDir}.`\r\n\t\t\t\t: \"No markdown files matched the provided migration sources.\",\r\n\t\t);\r\n\t}\r\n\r\n\tconst results: MigrationResult[] = [];\r\n\tlet preparedRecords = 0;\r\n\tlet imported = 0;\r\n\tlet skipped = 0;\r\n\tlet failed = 0;\r\n\r\n\tfor (const file of discoveredFiles) {\r\n\t\ttry {\r\n\t\t\tconst parsed = await parseMigrationFile({\r\n\t\t\t\tfile,\r\n\t\t\t\tsourceMode,\r\n\t\t\t\ttargetNamespace,\r\n\t\t\t\tnamespaceStrategy,\r\n\t\t\t});\r\n\t\t\tif (!parsed) {\r\n\t\t\t\tskipped += 1;\r\n\t\t\t\tresults.push({\r\n\t\t\t\t\taction: \"skipped\",\r\n\t\t\t\t\tsourcePath: file.absolutePath,\r\n\t\t\t\t\trelativePath: file.relativePath,\r\n\t\t\t\t\treason: \"File did not contain any importable markdown content.\",\r\n\t\t\t\t});\r\n\t\t\t\tcontinue;\r\n\t\t\t}\r\n\r\n\t\t\tpreparedRecords += 1;\r\n\t\t\tconst logicalId = parsed.input.id;\r\n\t\t\tconst namespace = parsed.input.namespace;\r\n\t\t\tif (!logicalId || !namespace) {\r\n\t\t\t\tthrow new Error(\"Parsed migration record is missing a logical id or namespace.\");\r\n\t\t\t}\r\n\r\n\t\t\tif (duplicateStrategy !== \"overwrite\") {\r\n\t\t\t\tconst existing = await params.service.get({\r\n\t\t\t\t\tid: logicalId,\r\n\t\t\t\t\tnamespace,\r\n\t\t\t\t});\r\n\t\t\t\tif (existing) {\r\n\t\t\t\t\tif (duplicateStrategy === \"skip\") {\r\n\t\t\t\t\t\tskipped += 1;\r\n\t\t\t\t\t\tresults.push({\r\n\t\t\t\t\t\t\taction: \"skipped\",\r\n\t\t\t\t\t\t\tsourcePath: parsed.sourcePath,\r\n\t\t\t\t\t\t\trelativePath: parsed.relativePath,\r\n\t\t\t\t\t\t\tlogicalId,\r\n\t\t\t\t\t\t\tnamespace,\r\n\t\t\t\t\t\t\ttitle: parsed.input.title,\r\n\t\t\t\t\t\t\treason: \"A record with the same logical id already exists.\",\r\n\t\t\t\t\t\t});\r\n\t\t\t\t\t\tcontinue;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tthrow new Error(`A record with logical id ${logicalId} already exists in namespace ${namespace}.`);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tif (dryRun) {\r\n\t\t\t\tresults.push({\r\n\t\t\t\t\taction: \"would-import\",\r\n\t\t\t\t\tsourcePath: parsed.sourcePath,\r\n\t\t\t\t\trelativePath: parsed.relativePath,\r\n\t\t\t\t\tlogicalId,\r\n\t\t\t\t\tnamespace,\r\n\t\t\t\t\ttitle: parsed.input.title,\r\n\t\t\t\t});\r\n\t\t\t\tcontinue;\r\n\t\t\t}\r\n\r\n\t\t\tawait params.service.upsert({\r\n\t\t\t\tinput: parsed.input,\r\n\t\t\t});\r\n\t\t\timported += 1;\r\n\t\t\tresults.push({\r\n\t\t\t\taction: \"imported\",\r\n\t\t\t\tsourcePath: parsed.sourcePath,\r\n\t\t\t\trelativePath: parsed.relativePath,\r\n\t\t\t\tlogicalId,\r\n\t\t\t\tnamespace,\r\n\t\t\t\ttitle: parsed.input.title,\r\n\t\t\t});\r\n\t\t} catch (error) {\r\n\t\t\tfailed += 1;\r\n\t\t\tresults.push({\r\n\t\t\t\taction: \"failed\",\r\n\t\t\t\tsourcePath: file.absolutePath,\r\n\t\t\t\trelativePath: file.relativePath,\r\n\t\t\t\terror: error instanceof Error ? error.message : \"Unknown migration failure.\",\r\n\t\t\t});\r\n\t\t}\r\n\t}\r\n\r\n\treturn {\r\n\t\tdryRun,\r\n\t\tsourceMode,\r\n\t\tworkspaceDir,\r\n\t\tnamespaceStrategy,\r\n\t\ttargetNamespace: namespaceStrategy === \"single-target\" ? targetNamespace : undefined,\r\n\t\tdiscoveredFiles: discoveredFiles.length,\r\n\t\tpreparedRecords,\r\n\t\timported,\r\n\t\tskipped,\r\n\t\tfailed,\r\n\t\tdoctor,\r\n\t\tresults,\r\n\t};\r\n}\r\n\r\nexport function formatMigrationSummary(summary: MigrationSummary): string {\r\n\tconst lines = [\r\n\t\t`${summary.dryRun ? \"Dry-run\" : \"Migration\"} ${summary.failed > 0 ? \"completed with failures\" : \"completed\"}.`,\r\n\t\t`Source mode: ${summary.sourceMode}`,\r\n\t\t`Workspace: ${summary.workspaceDir}`,\r\n\t\t`Files scanned: ${summary.discoveredFiles}`,\r\n\t\t`Records prepared: ${summary.preparedRecords}`,\r\n\t\t`Imported: ${summary.imported}`,\r\n\t\t`Skipped: ${summary.skipped}`,\r\n\t\t`Failed: ${summary.failed}`,\r\n\t];\r\n\r\n\tif (summary.targetNamespace) {\r\n\t\tlines.splice(3, 0, `Target namespace: ${summary.targetNamespace}`);\r\n\t}\r\n\r\n\tconst failedResults = summary.results.filter((result) => result.action === \"failed\").slice(0, 10);\r\n\tif (failedResults.length > 0) {\r\n\t\tlines.push(\"\", \"Failures:\");\r\n\t\tfor (const result of failedResults) {\r\n\t\t\tlines.push(`- ${result.relativePath}: ${result.error}`);\r\n\t\t}\r\n\t}\r\n\r\n\treturn lines.join(\"\\n\");\r\n}\r\n","import type { StorageMode, VectorizeMetric } from \"./types.js\";\n\nexport const PLUGIN_ID = \"memory-cloudflare-vectorize\";\nexport const PLUGIN_NAME = \"Cloudflare Vectorize Memory\";\nexport const PLUGIN_DESCRIPTION = \"OpenClaw memory plugin backed by Cloudflare Vectorize and Workers AI embeddings.\";\n\nexport const CLOUDFLARE_ACCOUNT_ID_ENV = \"CLOUDFLARE_ACCOUNT_ID\";\nexport const CLOUDFLARE_API_TOKEN_ENV = \"CLOUDFLARE_API_TOKEN\";\nexport const VECTORIZE_INDEX_ENV = \"CLOUDFLARE_VECTORIZE_INDEX_NAME\";\nexport const VECTORIZE_NAMESPACE_ENV = \"CLOUDFLARE_VECTORIZE_NAMESPACE\";\nexport const WORKERS_AI_MODEL_ENV = \"CLOUDFLARE_WORKERS_AI_EMBEDDING_MODEL\";\nexport const VECTORIZE_TOP_K_ENV = \"CLOUDFLARE_VECTORIZE_TOP_K\";\nexport const STORAGE_MODE_ENV = \"OPENCLAW_CF_MEMORY_STORAGE_MODE\";\nexport const COMPANION_PATH_ENV = \"OPENCLAW_CF_MEMORY_COMPANION_PATH\";\n\nexport const DEFAULT_EMBEDDING_MODEL = \"@cf/baai/bge-base-en-v1.5\";\nexport const DEFAULT_TOP_K = 5;\nexport const DEFAULT_MIN_SCORE = 0;\nexport const DEFAULT_INLINE_TEXT_MAX_BYTES = 6_000;\nexport const DEFAULT_VECTORIZE_METRIC: VectorizeMetric = \"cosine\";\nexport const DEFAULT_STORAGE_MODE: StorageMode = \"vectorize-inline\";\nexport const DEFAULT_CLOUDFLARE_API_BASE_URL = \"https://api.cloudflare.com/client/v4\";\nexport const DEFAULT_INDEX_DESCRIPTION = \"OpenClaw memory index backed by Cloudflare Vectorize.\";\n\nexport const RESERVED_METADATA_PREFIX = \"oc_\";\nexport const RESERVED_METADATA_KEYS = {\n\tlogicalId: \"oc_record_id\",\n\ttitle: \"oc_title\",\n\ttext: \"oc_text\",\n\tstorageMode: \"oc_storage_mode\",\n\tpointer: \"oc_pointer\",\n\tsource: \"oc_source\",\n\tcreatedAt: \"oc_created_at\",\n\tupdatedAt: \"oc_updated_at\",\n} as const;\n","export class ConfigurationError extends Error {\n\tconstructor(message: string) {\n\t\tsuper(message);\n\t\tthis.name = \"ConfigurationError\";\n\t}\n}\n\nexport class CloudflareApiError extends Error {\n\tconstructor(\n\t\tmessage: string,\n\t\treadonly status?: number,\n\t\treadonly details?: unknown,\n\t) {\n\t\tsuper(message);\n\t\tthis.name = \"CloudflareApiError\";\n\t}\n}\n\nexport class RecordSizeError extends Error {\n\tconstructor(message: string) {\n\t\tsuper(message);\n\t\tthis.name = \"RecordSizeError\";\n\t}\n}\n","import { join } from \"node:path\";\nimport type { OpenClawConfig } from \"openclaw/plugin-sdk/config-runtime\";\nimport { resolveConfiguredSecretInputWithFallback } from \"openclaw/plugin-sdk/config-runtime\";\nimport type { OpenClawPluginConfigSchema } from \"openclaw/plugin-sdk/plugin-entry\";\nimport type { SecretInput } from \"openclaw/plugin-sdk/secret-ref-runtime\";\nimport { z } from \"zod\";\nimport {\n\tCLOUDFLARE_ACCOUNT_ID_ENV,\n\tCLOUDFLARE_API_TOKEN_ENV,\n\tCOMPANION_PATH_ENV,\n\tDEFAULT_CLOUDFLARE_API_BASE_URL,\n\tDEFAULT_EMBEDDING_MODEL,\n\tDEFAULT_INDEX_DESCRIPTION,\n\tDEFAULT_INLINE_TEXT_MAX_BYTES,\n\tDEFAULT_MIN_SCORE,\n\tDEFAULT_STORAGE_MODE,\n\tDEFAULT_TOP_K,\n\tDEFAULT_VECTORIZE_METRIC,\n\tPLUGIN_ID,\n\tSTORAGE_MODE_ENV,\n\tVECTORIZE_INDEX_ENV,\n\tVECTORIZE_NAMESPACE_ENV,\n\tVECTORIZE_TOP_K_ENV,\n\tWORKERS_AI_MODEL_ENV,\n} from \"./constants.js\";\nimport { ConfigurationError } from \"./errors.js\";\nimport type { RawPluginConfig, ResolvedPluginConfig, StorageMode, VectorizeMetric } from \"./types.js\";\n\nconst secretRefSchema = z\n\t.object({\n\t\tsource: z.enum([\"env\", \"file\", \"exec\"]),\n\t\tprovider: z.string().min(1),\n\t\tid: z.string().min(1),\n\t})\n\t.strict();\n\nconst secretInputSchema: z.ZodType<SecretInput> = z.union([z.string().min(1), secretRefSchema]);\n\nconst createIndexSchema = z\n\t.object({\n\t\tdescription: z.string().min(1).optional(),\n\t\tdimensions: z.number().int().min(1).max(1536).optional(),\n\t\tmetric: z.enum([\"cosine\", \"euclidean\", \"dot-product\"]).optional(),\n\t})\n\t.strict();\n\nconst pluginConfigZod: z.ZodType<RawPluginConfig> = z\n\t.object({\n\t\tcloudflare: z\n\t\t\t.object({\n\t\t\t\taccountId: z.string().min(1).optional(),\n\t\t\t\tapiToken: secretInputSchema.optional(),\n\t\t\t\tapiBaseUrl: z.string().url().optional(),\n\t\t\t\tworkersAiBaseUrl: z.string().url().optional(),\n\t\t\t\tvectorizeBaseUrl: z.string().url().optional(),\n\t\t\t})\n\t\t\t.strict()\n\t\t\t.optional(),\n\t\tvectorize: z\n\t\t\t.object({\n\t\t\t\tindexName: z.string().min(1).optional(),\n\t\t\t\tnamespace: z.string().min(1).optional(),\n\t\t\t\ttopK: z.number().int().min(1).max(50).optional(),\n\t\t\t\tminScore: z.number().min(0).max(1).optional(),\n\t\t\t\tmetric: z.enum([\"cosine\", \"euclidean\", \"dot-product\"]).optional(),\n\t\t\t\tcreateIndex: createIndexSchema.optional(),\n\t\t\t\tmetadataIndexedFields: z.array(z.string().min(1)).default([]),\n\t\t\t})\n\t\t\t.strict()\n\t\t\t.optional(),\n\t\tembeddings: z\n\t\t\t.object({\n\t\t\t\tmodel: z.string().min(1).optional(),\n\t\t\t})\n\t\t\t.strict()\n\t\t\t.optional(),\n\t\tstorage: z\n\t\t\t.object({\n\t\t\t\tmode: z.enum([\"vectorize-inline\", \"companion-store\"]).optional(),\n\t\t\t\tcompanionStorePath: z.string().min(1).optional(),\n\t\t\t\tinlineTextMaxBytes: z.number().int().min(256).max(10_000).optional(),\n\t\t\t})\n\t\t\t.strict()\n\t\t\t.optional(),\n\t})\n\t.strict();\n\nexport const pluginConfigJsonSchema = {\n\ttype: \"object\",\n\tadditionalProperties: false,\n\tproperties: {\n\t\tcloudflare: {\n\t\t\ttype: \"object\",\n\t\t\tadditionalProperties: false,\n\t\t\tproperties: {\n\t\t\t\taccountId: { type: \"string\" },\n\t\t\t\tapiToken: {\n\t\t\t\t\tanyOf: [\n\t\t\t\t\t\t{ type: \"string\" },\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttype: \"object\",\n\t\t\t\t\t\t\tadditionalProperties: false,\n\t\t\t\t\t\t\tproperties: {\n\t\t\t\t\t\t\t\tsource: { type: \"string\", enum: [\"env\", \"file\", \"exec\"] },\n\t\t\t\t\t\t\t\tprovider: { type: \"string\" },\n\t\t\t\t\t\t\t\tid: { type: \"string\" },\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\trequired: [\"source\", \"provider\", \"id\"],\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t\tapiBaseUrl: { type: \"string\", format: \"uri\" },\n\t\t\t\tworkersAiBaseUrl: { type: \"string\", format: \"uri\" },\n\t\t\t\tvectorizeBaseUrl: { type: \"string\", format: \"uri\" },\n\t\t\t},\n\t\t},\n\t\tvectorize: {\n\t\t\ttype: \"object\",\n\t\t\tadditionalProperties: false,\n\t\t\tproperties: {\n\t\t\t\tindexName: { type: \"string\" },\n\t\t\t\tnamespace: { type: \"string\" },\n\t\t\t\ttopK: { type: \"integer\", minimum: 1, maximum: 50 },\n\t\t\t\tminScore: { type: \"number\", minimum: 0, maximum: 1 },\n\t\t\t\tmetric: {\n\t\t\t\t\ttype: \"string\",\n\t\t\t\t\tenum: [\"cosine\", \"euclidean\", \"dot-product\"],\n\t\t\t\t},\n\t\t\t\tcreateIndex: {\n\t\t\t\t\ttype: \"object\",\n\t\t\t\t\tadditionalProperties: false,\n\t\t\t\t\tproperties: {\n\t\t\t\t\t\tdescription: { type: \"string\" },\n\t\t\t\t\t\tdimensions: { type: \"integer\", minimum: 1, maximum: 1536 },\n\t\t\t\t\t\tmetric: {\n\t\t\t\t\t\t\ttype: \"string\",\n\t\t\t\t\t\t\tenum: [\"cosine\", \"euclidean\", \"dot-product\"],\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tmetadataIndexedFields: {\n\t\t\t\t\ttype: \"array\",\n\t\t\t\t\titems: { type: \"string\" },\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\tembeddings: {\n\t\t\ttype: \"object\",\n\t\t\tadditionalProperties: false,\n\t\t\tproperties: {\n\t\t\t\tmodel: { type: \"string\" },\n\t\t\t},\n\t\t},\n\t\tstorage: {\n\t\t\ttype: \"object\",\n\t\t\tadditionalProperties: false,\n\t\t\tproperties: {\n\t\t\t\tmode: { type: \"string\", enum: [\"vectorize-inline\", \"companion-store\"] },\n\t\t\t\tcompanionStorePath: { type: \"string\" },\n\t\t\t\tinlineTextMaxBytes: { type: \"integer\", minimum: 256, maximum: 10000 },\n\t\t\t},\n\t\t},\n\t},\n} as const;\n\nexport const pluginUiHints = {\n\t\"cloudflare.accountId\": {\n\t\tlabel: \"Cloudflare account ID\",\n\t\thelp: `Defaults to \\${${CLOUDFLARE_ACCOUNT_ID_ENV}}.`,\n\t},\n\t\"cloudflare.apiToken\": {\n\t\tlabel: \"Cloudflare API token\",\n\t\tsensitive: true,\n\t\thelp: `Defaults to \\${${CLOUDFLARE_API_TOKEN_ENV}}.`,\n\t},\n\t\"vectorize.indexName\": {\n\t\tlabel: \"Vectorize index name\",\n\t\thelp: `Defaults to \\${${VECTORIZE_INDEX_ENV}}.`,\n\t},\n\t\"vectorize.namespace\": {\n\t\tlabel: \"Fixed namespace override\",\n\t\thelp: `Defaults to \\${${VECTORIZE_NAMESPACE_ENV}} or derives from the agent/session context.`,\n\t},\n\t\"vectorize.topK\": {\n\t\tlabel: \"Top-K results\",\n\t\thelp: `Defaults to \\${${VECTORIZE_TOP_K_ENV}} or ${DEFAULT_TOP_K}.`,\n\t},\n\t\"embeddings.model\": {\n\t\tlabel: \"Workers AI embedding model\",\n\t\thelp: `Defaults to \\${${WORKERS_AI_MODEL_ENV}} or ${DEFAULT_EMBEDDING_MODEL}.`,\n\t},\n\t\"storage.mode\": {\n\t\tlabel: \"Storage mode\",\n\t\thelp: `Defaults to \\${${STORAGE_MODE_ENV}} or ${DEFAULT_STORAGE_MODE}.`,\n\t},\n\t\"storage.companionStorePath\": {\n\t\tlabel: \"Companion store path\",\n\t\thelp: `Defaults to \\${${COMPANION_PATH_ENV}} or the OpenClaw state directory.`,\n\t},\n} as const;\n\nexport const pluginConfigSchema: OpenClawPluginConfigSchema = {\n\tparse(value: unknown) {\n\t\treturn pluginConfigZod.parse(value ?? {});\n\t},\n\tsafeParse(value: unknown) {\n\t\tconst result = pluginConfigZod.safeParse(value ?? {});\n\t\tif (result.success) {\n\t\t\treturn { success: true, data: result.data };\n\t\t}\n\t\treturn {\n\t\t\tsuccess: false,\n\t\t\terror: {\n\t\t\t\tissues: result.error.issues.map((issue) => ({\n\t\t\t\t\tpath: issue.path.filter((segment): segment is string | number => typeof segment === \"string\" || typeof segment === \"number\"),\n\t\t\t\t\tmessage: issue.message,\n\t\t\t\t})),\n\t\t\t},\n\t\t};\n\t},\n\tjsonSchema: pluginConfigJsonSchema,\n\tuiHints: pluginUiHints,\n};\n\ntype PluginEntriesAwareConfig = OpenClawConfig & {\n\tplugins?: {\n\t\tentries?: Record<string, unknown>;\n\t};\n};\n\nfunction pickFirstDefined<T>(...values: Array<T | undefined>): T | undefined {\n\treturn values.find((value) => value !== undefined);\n}\n\nfunction pickTrimmed(...values: Array<string | undefined>): string | undefined {\n\tfor (const value of values) {\n\t\tif (value && value.trim().length > 0) {\n\t\t\treturn value.trim();\n\t\t}\n\t}\n\treturn undefined;\n}\n\nfunction pickNumber(...values: Array<number | undefined>): number | undefined {\n\treturn values.find((value) => typeof value === \"number\" && Number.isFinite(value));\n}\n\nfunction normalizeMetadataIndexedFields(fields: string[] | undefined): string[] {\n\treturn [...new Set((fields ?? []).map((field) => field.trim()).filter(Boolean))];\n}\n\nfunction ensureVectorizeMetric(metric: VectorizeMetric | undefined): VectorizeMetric {\n\treturn metric ?? DEFAULT_VECTORIZE_METRIC;\n}\n\nfunction ensureStorageMode(mode: StorageMode | undefined): StorageMode {\n\treturn mode ?? DEFAULT_STORAGE_MODE;\n}\n\nexport function parsePluginConfig(value: unknown): RawPluginConfig {\n\treturn pluginConfigZod.parse(value ?? {});\n}\n\nexport function getPluginConfigFromOpenClawConfig(config: OpenClawConfig): RawPluginConfig {\n\tconst candidate = (config as PluginEntriesAwareConfig).plugins?.entries?.[PLUGIN_ID];\n\treturn parsePluginConfig(candidate ?? {});\n}\n\nexport async function resolvePluginConfig(params: {\n\tpluginConfig: unknown;\n\topenClawConfig: OpenClawConfig;\n\tenv?: NodeJS.ProcessEnv;\n\tresolvePath?: (input: string) => string;\n}): Promise<ResolvedPluginConfig> {\n\tconst parsed = parsePluginConfig(params.pluginConfig);\n\tconst env = params.env ?? process.env;\n\tconst configPathBase = `plugins.entries.${PLUGIN_ID}`;\n\tconst accountId = pickTrimmed(parsed.cloudflare?.accountId, env[CLOUDFLARE_ACCOUNT_ID_ENV]);\n\tif (!accountId) {\n\t\tthrow new ConfigurationError(`Missing Cloudflare account id. Set ${CLOUDFLARE_ACCOUNT_ID_ENV} or ${configPathBase}.cloudflare.accountId.`);\n\t}\n\n\tconst tokenResult = await resolveConfiguredSecretInputWithFallback({\n\t\tconfig: params.openClawConfig,\n\t\tenv,\n\t\tvalue: parsed.cloudflare?.apiToken,\n\t\tpath: `${configPathBase}.cloudflare.apiToken`,\n\t\tunresolvedReasonStyle: \"detailed\",\n\t\treadFallback: () => env[CLOUDFLARE_API_TOKEN_ENV],\n\t});\n\tif (!tokenResult.value) {\n\t\tconst reason = tokenResult.unresolvedRefReason ? ` ${tokenResult.unresolvedRefReason}` : \"\";\n\t\tthrow new ConfigurationError(`Missing Cloudflare API token. Set ${CLOUDFLARE_API_TOKEN_ENV} or ${configPathBase}.cloudflare.apiToken.${reason}`.trim());\n\t}\n\n\tconst indexName = pickTrimmed(parsed.vectorize?.indexName, env[VECTORIZE_INDEX_ENV]);\n\tif (!indexName) {\n\t\tthrow new ConfigurationError(`Missing Vectorize index name. Set ${VECTORIZE_INDEX_ENV} or ${configPathBase}.vectorize.indexName.`);\n\t}\n\n\tconst apiBaseUrl = pickTrimmed(parsed.cloudflare?.apiBaseUrl, DEFAULT_CLOUDFLARE_API_BASE_URL);\n\tif (!apiBaseUrl) {\n\t\tthrow new ConfigurationError(\n\t\t\t`Invalid Cloudflare API base URL. Set ${configPathBase}.cloudflare.apiBaseUrl or ensure ${DEFAULT_CLOUDFLARE_API_BASE_URL} is a valid URL.`,\n\t\t);\n\t}\n\tconst fixedNamespace = pickTrimmed(parsed.vectorize?.namespace, env[VECTORIZE_NAMESPACE_ENV]);\n\tconst topK = pickNumber(parsed.vectorize?.topK, env[VECTORIZE_TOP_K_ENV] ? Number(env[VECTORIZE_TOP_K_ENV]) : undefined);\n\tconst storageMode = ensureStorageMode(pickFirstDefined(parsed.storage?.mode, env[STORAGE_MODE_ENV] as StorageMode | undefined));\n\tconst companionStorePath = pickTrimmed(parsed.storage?.companionStorePath, env[COMPANION_PATH_ENV]) ?? join(\".openclaw\", PLUGIN_ID, \"companion-store.json\");\n\n\tconst resolvePath = params.resolvePath ?? ((input: string) => input);\n\tconst model = pickTrimmed(parsed.embeddings?.model, env[WORKERS_AI_MODEL_ENV], DEFAULT_EMBEDDING_MODEL);\n\tif (!model) {\n\t\tthrow new ConfigurationError(`Missing Workers AI embedding model. Set ${WORKERS_AI_MODEL_ENV} or ${configPathBase}.embeddings.model.`);\n\t}\n\tconst inlineTextMaxBytes = pickNumber(parsed.storage?.inlineTextMaxBytes) ?? DEFAULT_INLINE_TEXT_MAX_BYTES;\n\tconst minScore = pickNumber(parsed.vectorize?.minScore) ?? DEFAULT_MIN_SCORE;\n\tconst metric = ensureVectorizeMetric(pickFirstDefined(parsed.vectorize?.metric, parsed.vectorize?.createIndex?.metric));\n\n\treturn {\n\t\taccountId,\n\t\tapiToken: tokenResult.value,\n\t\tapiBaseUrl,\n\t\tworkersAiBaseUrl: pickTrimmed(parsed.cloudflare?.workersAiBaseUrl) ?? `${apiBaseUrl}/accounts/${accountId}/ai/v1`,\n\t\tvectorizeBaseUrl: pickTrimmed(parsed.cloudflare?.vectorizeBaseUrl) ?? `${apiBaseUrl}/accounts/${accountId}/vectorize/v2/indexes/${indexName}`,\n\t\tindexName,\n\t\tfixedNamespace,\n\t\ttopK: topK ?? DEFAULT_TOP_K,\n\t\tminScore,\n\t\tmetric,\n\t\tmodel,\n\t\tstorageMode,\n\t\tcompanionStorePath: resolvePath(companionStorePath),\n\t\tinlineTextMaxBytes,\n\t\tmetadataIndexedFields: normalizeMetadataIndexedFields(parsed.vectorize?.metadataIndexedFields),\n\t\tcreateIndex: {\n\t\t\tdescription: parsed.vectorize?.createIndex?.description ?? DEFAULT_INDEX_DESCRIPTION,\n\t\t\tdimensions: parsed.vectorize?.createIndex?.dimensions,\n\t\t\tmetric,\n\t\t},\n\t};\n}\n","import { CloudflareApiError } from \"./errors.js\";\n\ntype CloudflareResponseEnvelope<T> = {\n\tsuccess: boolean;\n\tresult: T;\n\terrors?: Array<{ code?: number; message?: string }>;\n};\n\nfunction describeFailure(envelope: Partial<CloudflareResponseEnvelope<unknown>> | undefined, fallback: string): string {\n\tconst message = envelope?.errors\n\t\t?.map((entry) => entry.message)\n\t\t.filter(Boolean)\n\t\t.join(\"; \");\n\treturn message || fallback;\n}\n\nexport function isCloudflareNotFoundError(error: unknown): boolean {\n\treturn error instanceof CloudflareApiError && error.status === 404;\n}\n\nexport async function requestCloudflare<T>(params: {\n\turl: string;\n\tapiToken: string;\n\tmethod?: string;\n\theaders?: Record<string, string>;\n\tbody?: string;\n}): Promise<T> {\n\tconst headers = new Headers(params.headers);\n\theaders.set(\"Authorization\", `Bearer ${params.apiToken}`);\n\tif (!headers.has(\"Content-Type\") && params.body) {\n\t\theaders.set(\"Content-Type\", \"application/json\");\n\t}\n\n\tconst response = await fetch(params.url, {\n\t\tmethod: params.method ?? (params.body ? \"POST\" : \"GET\"),\n\t\theaders,\n\t\tbody: params.body,\n\t});\n\n\tconst rawText = await response.text();\n\tconst parsed = rawText ? (JSON.parse(rawText) as CloudflareResponseEnvelope<T>) : undefined;\n\tif (!response.ok) {\n\t\tthrow new CloudflareApiError(describeFailure(parsed, `Cloudflare request failed with ${response.status}.`), response.status, parsed);\n\t}\n\tif (!parsed?.success) {\n\t\tthrow new CloudflareApiError(describeFailure(parsed, \"Cloudflare request failed.\"), response.status, parsed);\n\t}\n\n\treturn parsed.result;\n}\n","import { mkdir, readFile, rm, writeFile } from \"node:fs/promises\";\nimport { dirname } from \"node:path\";\nimport type { CompanionRecord } from \"./types.js\";\n\ntype CompanionStoreFile = {\n\tversion: 1;\n\trecords: Record<string, CompanionRecord>;\n};\n\nfunction buildStoreKey(namespace: string, id: string): string {\n\treturn `${namespace}::${id}`;\n}\n\nasync function readStore(path: string): Promise<CompanionStoreFile> {\n\ttry {\n\t\tconst raw = await readFile(path, \"utf8\");\n\t\treturn JSON.parse(raw) as CompanionStoreFile;\n\t} catch {\n\t\treturn {\n\t\t\tversion: 1,\n\t\t\trecords: {},\n\t\t};\n\t}\n}\n\nexport class CompanionStore {\n\tconstructor(private readonly path: string) {}\n\n\tget filePath(): string {\n\t\treturn this.path;\n\t}\n\n\tasync upsert(record: CompanionRecord): Promise<void> {\n\t\tconst state = await readStore(this.path);\n\t\tstate.records[buildStoreKey(record.namespace, record.id)] = record;\n\t\tawait mkdir(dirname(this.path), { recursive: true });\n\t\tawait writeFile(this.path, JSON.stringify(state, null, 2), \"utf8\");\n\t}\n\n\tasync get(namespace: string, id: string): Promise<CompanionRecord | null> {\n\t\tconst state = await readStore(this.path);\n\t\treturn state.records[buildStoreKey(namespace, id)] ?? null;\n\t}\n\n\tasync delete(namespace: string, id: string): Promise<void> {\n\t\tconst state = await readStore(this.path);\n\t\tdelete state.records[buildStoreKey(namespace, id)];\n\t\tawait mkdir(dirname(this.path), { recursive: true });\n\t\tawait writeFile(this.path, JSON.stringify(state, null, 2), \"utf8\");\n\t}\n\n\tasync clear(): Promise<void> {\n\t\tawait rm(this.path, { force: true });\n\t}\n}\n","import type { CloudflareMemoryService } from \"./service.js\";\nimport type { DoctorCheck, DoctorReport } from \"./types.js\";\n\nexport async function runDoctor(params: { service: CloudflareMemoryService; createIndexIfMissing: boolean }): Promise<DoctorReport> {\n\tconst checks: DoctorCheck[] = [];\n\n\tchecks.push({\n\t\tname: \"credentials\",\n\t\tstatus: \"pass\",\n\t\tmessage: `Using Cloudflare account ${params.service.config.accountId} and Vectorize index ${params.service.config.indexName}.`,\n\t});\n\n\tconst indexResult = await params.service.ensureIndexExists(params.createIndexIfMissing);\n\tchecks.push({\n\t\tname: \"vectorize-index\",\n\t\tstatus: \"pass\",\n\t\tmessage: indexResult.created\n\t\t\t? `Created Vectorize index \"${params.service.config.indexName}\" with ${indexResult.dimensions} dimensions.`\n\t\t\t: `Vectorize index \"${params.service.config.indexName}\" is reachable.`,\n\t});\n\n\tconst embeddingDimensions = await params.service.embeddings.probeDimensions();\n\tchecks.push({\n\t\tname: \"workers-ai-embeddings\",\n\t\tstatus: \"pass\",\n\t\tmessage: `Workers AI model ${params.service.config.model} returned ${embeddingDimensions} dimensions.`,\n\t});\n\n\tif (embeddingDimensions !== indexResult.dimensions) {\n\t\tchecks.push({\n\t\t\tname: \"dimension-match\",\n\t\t\tstatus: \"fail\",\n\t\t\tmessage: `Embedding dimensions (${embeddingDimensions}) do not match the Vectorize index dimensions (${indexResult.dimensions}).`,\n\t\t});\n\t} else {\n\t\tchecks.push({\n\t\t\tname: \"dimension-match\",\n\t\t\tstatus: \"pass\",\n\t\t\tmessage: \"Embedding dimensions match the Vectorize index.\",\n\t\t});\n\t}\n\n\tchecks.push({\n\t\tname: \"metadata-filters\",\n\t\tstatus: params.service.config.metadataIndexedFields.length > 0 ? \"pass\" : \"warn\",\n\t\tmessage:\n\t\t\tparams.service.config.metadataIndexedFields.length > 0\n\t\t\t\t? `Configured metadata-index guidance for: ${params.service.config.metadataIndexedFields.join(\", \")}.`\n\t\t\t\t: \"No metadataIndexedFields configured. Add metadata indexes in Cloudflare before relying on filter-heavy queries.\",\n\t});\n\n\tconst ok = checks.every((check) => check.status !== \"fail\");\n\treturn { ok, checks };\n}\n","import { requestCloudflare } from \"./cloudflare-api.js\";\nimport type { ResolvedPluginConfig } from \"./types.js\";\n\ntype OpenAiEmbeddingResponse = {\n\tdata: Array<{\n\t\tembedding: number[];\n\t\tindex: number;\n\t}>;\n};\n\nexport class WorkersAiEmbeddingsClient {\n\tconstructor(private readonly config: ResolvedPluginConfig) {}\n\n\tasync embedQuery(text: string): Promise<number[]> {\n\t\tconst [embedding] = await this.embedBatch([text]);\n\t\treturn embedding;\n\t}\n\n\tasync embedBatch(texts: string[]): Promise<number[][]> {\n\t\tif (texts.length === 0) {\n\t\t\treturn [];\n\t\t}\n\t\tconst response = await requestCloudflare<OpenAiEmbeddingResponse>({\n\t\t\turl: `${this.config.workersAiBaseUrl}/embeddings`,\n\t\t\tapiToken: this.config.apiToken,\n\t\t\tbody: JSON.stringify({\n\t\t\t\tmodel: this.config.model,\n\t\t\t\tinput: texts,\n\t\t\t}),\n\t\t});\n\n\t\treturn [...response.data].sort((left, right) => left.index - right.index).map((entry) => entry.embedding);\n\t}\n\n\tasync probeDimensions(): Promise<number> {\n\t\tconst embedding = await this.embedQuery(\"openclaw-memory-dimension-probe\");\n\t\treturn embedding.length;\n\t}\n}\n","import { Buffer } from \"node:buffer\";\nimport { randomUUID } from \"node:crypto\";\nimport { RESERVED_METADATA_KEYS, RESERVED_METADATA_PREFIX } from \"./constants.js\";\nimport { RecordSizeError } from \"./errors.js\";\nimport type {\n\tCompanionRecord,\n\tHydratedMemoryRecord,\n\tMemoryRecordInput,\n\tMetadataValue,\n\tResolvedPluginConfig,\n\tVectorizeQueryMatch,\n\tVectorizeVector,\n} from \"./types.js\";\n\nfunction sanitizeMetadataKey(key: string): string {\n\tconst sanitized = key.trim().replace(/[.$\"]/g, \"_\").replace(/\\s+/g, \"_\");\n\tif (!sanitized) {\n\t\treturn \"metadata\";\n\t}\n\tif (sanitized.startsWith(RESERVED_METADATA_PREFIX)) {\n\t\treturn `user_${sanitized}`;\n\t}\n\treturn sanitized;\n}\n\nfunction sanitizeMetadata(metadata: Record<string, MetadataValue> | undefined): Record<string, MetadataValue> {\n\tif (!metadata) {\n\t\treturn {};\n\t}\n\tconst entries = Object.entries(metadata).filter(([, value]) => [\"string\", \"number\", \"boolean\"].includes(typeof value));\n\treturn Object.fromEntries(entries.map(([key, value]) => [sanitizeMetadataKey(key), value]));\n}\n\nexport function buildVectorId(namespace: string, logicalId: string): string {\n\treturn `${namespace}::${logicalId}`;\n}\n\nexport function buildVirtualPath(namespace: string, logicalId: string): string {\n\treturn `${namespace}/${logicalId}.md`;\n}\n\nexport function parseVirtualPath(path: string): { namespace: string; logicalId: string } | null {\n\tconst normalized = path.replace(/\\\\/g, \"/\").replace(/^\\//, \"\");\n\tconst segments = normalized.split(\"/\");\n\tif (segments.length !== 2 || !segments[1].endsWith(\".md\")) {\n\t\treturn null;\n\t}\n\treturn {\n\t\tnamespace: segments[0],\n\t\tlogicalId: segments[1].slice(0, -3),\n\t};\n}\n\nexport function buildSnippet(text: string, query: string): string {\n\tconst normalized = text.trim().replace(/\\s+/g, \" \");\n\tif (!normalized) {\n\t\treturn \"\";\n\t}\n\tconst lower = normalized.toLowerCase();\n\tconst index = lower.indexOf(query.trim().toLowerCase());\n\tif (index === -1) {\n\t\treturn normalized.slice(0, 220);\n\t}\n\tconst start = Math.max(0, index - 80);\n\tconst end = Math.min(normalized.length, index + Math.max(query.length, 40) + 80);\n\treturn normalized.slice(start, end);\n}\n\nexport function mapRecordForUpsert(params: { input: MemoryRecordInput; namespace: string; embedding: number[]; config: ResolvedPluginConfig }): {\n\tlogicalId: string;\n\tvectorId: string;\n\tpath: string;\n\tvector: VectorizeVector;\n\tcompanionRecord?: CompanionRecord;\n} {\n\tconst logicalId = params.input.id?.trim() || randomUUID();\n\tconst vectorId = buildVectorId(params.namespace, logicalId);\n\tconst now = new Date().toISOString();\n\tconst userMetadata = sanitizeMetadata(params.input.metadata);\n\tconst metadataBase: Record<string, MetadataValue> = {\n\t\t...userMetadata,\n\t\t[RESERVED_METADATA_KEYS.logicalId]: logicalId,\n\t\t[RESERVED_METADATA_KEYS.storageMode]: params.config.storageMode,\n\t\t[RESERVED_METADATA_KEYS.createdAt]: now,\n\t\t[RESERVED_METADATA_KEYS.updatedAt]: now,\n\t};\n\n\tif (params.input.title) {\n\t\tmetadataBase[RESERVED_METADATA_KEYS.title] = params.input.title;\n\t}\n\tif (params.input.source) {\n\t\tmetadataBase[RESERVED_METADATA_KEYS.source] = params.input.source;\n\t}\n\n\tlet companionRecord: CompanionRecord | undefined;\n\tif (params.config.storageMode === \"vectorize-inline\") {\n\t\tconst byteLength = Buffer.byteLength(params.input.text, \"utf8\");\n\t\tif (byteLength > params.config.inlineTextMaxBytes) {\n\t\t\tthrow new RecordSizeError(\n\t\t\t\t`Memory text is ${byteLength} bytes, which exceeds the inline metadata limit of ${params.config.inlineTextMaxBytes}. Switch storage.mode to \"companion-store\" or reduce the payload size.`,\n\t\t\t);\n\t\t}\n\t\tmetadataBase[RESERVED_METADATA_KEYS.text] = params.input.text;\n\t} else {\n\t\tconst pointer = buildVirtualPath(params.namespace, logicalId);\n\t\tmetadataBase[RESERVED_METADATA_KEYS.pointer] = pointer;\n\t\tcompanionRecord = {\n\t\t\tid: logicalId,\n\t\t\tnamespace: params.namespace,\n\t\t\ttitle: params.input.title,\n\t\t\ttext: params.input.text,\n\t\t\tmetadata: userMetadata,\n\t\t\tsource: params.input.source,\n\t\t\tcreatedAt: now,\n\t\t\tupdatedAt: now,\n\t\t};\n\t}\n\n\treturn {\n\t\tlogicalId,\n\t\tvectorId,\n\t\tpath: buildVirtualPath(params.namespace, logicalId),\n\t\tvector: {\n\t\t\tid: vectorId,\n\t\t\tnamespace: params.namespace,\n\t\t\tvalues: params.embedding,\n\t\t\tmetadata: metadataBase,\n\t\t},\n\t\tcompanionRecord,\n\t};\n}\n\nexport function hydrateInlineRecord(match: VectorizeQueryMatch): Omit<HydratedMemoryRecord, \"text\" | \"path\"> & {\n\ttext?: string;\n\tpath: string;\n} {\n\tconst metadata = match.metadata ?? {};\n\tconst namespace =\n\t\tmatch.namespace ?? (typeof metadata[RESERVED_METADATA_KEYS.pointer] === \"string\" ? String(metadata[RESERVED_METADATA_KEYS.pointer]).split(\"/\")[0] : \"main\");\n\tconst logicalId =\n\t\ttypeof metadata[RESERVED_METADATA_KEYS.logicalId] === \"string\" ? String(metadata[RESERVED_METADATA_KEYS.logicalId]) : String(match.id ?? \"\");\n\tconst userMetadata = Object.fromEntries(Object.entries(metadata).filter(([key]) => !key.startsWith(RESERVED_METADATA_PREFIX)));\n\treturn {\n\t\tlogicalId,\n\t\tvectorId: String(match.id ?? logicalId),\n\t\tnamespace,\n\t\ttitle: typeof metadata[RESERVED_METADATA_KEYS.title] === \"string\" ? String(metadata[RESERVED_METADATA_KEYS.title]) : undefined,\n\t\ttext: typeof metadata[RESERVED_METADATA_KEYS.text] === \"string\" ? String(metadata[RESERVED_METADATA_KEYS.text]) : undefined,\n\t\tmetadata: userMetadata,\n\t\tsource: typeof metadata[RESERVED_METADATA_KEYS.source] === \"string\" ? String(metadata[RESERVED_METADATA_KEYS.source]) : undefined,\n\t\tcreatedAt: typeof metadata[RESERVED_METADATA_KEYS.createdAt] === \"string\" ? String(metadata[RESERVED_METADATA_KEYS.createdAt]) : undefined,\n\t\tupdatedAt: typeof metadata[RESERVED_METADATA_KEYS.updatedAt] === \"string\" ? String(metadata[RESERVED_METADATA_KEYS.updatedAt]) : undefined,\n\t\tpath: buildVirtualPath(namespace, logicalId),\n\t};\n}\n","import { requestCloudflare } from \"./cloudflare-api.js\";\nimport type { MetadataFilter, ResolvedPluginConfig, VectorizeIndexDescription, VectorizeQueryMatch, VectorizeVector } from \"./types.js\";\n\ntype MutationResponse = {\n\tmutationId?: string;\n};\n\ntype QueryResponse = {\n\tcount?: number;\n\tmatches?: VectorizeQueryMatch[];\n};\n\nexport class VectorizeClient {\n\tconstructor(private readonly config: ResolvedPluginConfig) {}\n\n\tasync describeIndex(): Promise<VectorizeIndexDescription> {\n\t\treturn requestCloudflare<VectorizeIndexDescription>({\n\t\t\turl: this.config.vectorizeBaseUrl,\n\t\t\tapiToken: this.config.apiToken,\n\t\t\tmethod: \"GET\",\n\t\t});\n\t}\n\n\tasync createIndex(dimensions: number, metric = this.config.createIndex.metric): Promise<VectorizeIndexDescription> {\n\t\treturn requestCloudflare<VectorizeIndexDescription>({\n\t\t\turl: `${this.config.apiBaseUrl}/accounts/${this.config.accountId}/vectorize/v2/indexes`,\n\t\t\tapiToken: this.config.apiToken,\n\t\t\tbody: JSON.stringify({\n\t\t\t\tname: this.config.indexName,\n\t\t\t\tdescription: this.config.createIndex.description,\n\t\t\t\tconfig: {\n\t\t\t\t\tdimensions,\n\t\t\t\t\tmetric,\n\t\t\t\t},\n\t\t\t}),\n\t\t});\n\t}\n\n\tasync upsert(vectors: VectorizeVector[]): Promise<string | undefined> {\n\t\tconst body = vectors.map((vector) => JSON.stringify(vector)).join(\"\\n\");\n\t\tconst result = await requestCloudflare<MutationResponse>({\n\t\t\turl: `${this.config.vectorizeBaseUrl}/upsert`,\n\t\t\tapiToken: this.config.apiToken,\n\t\t\theaders: {\n\t\t\t\t\"Content-Type\": \"application/x-ndjson\",\n\t\t\t},\n\t\t\tbody,\n\t\t});\n\t\treturn result.mutationId;\n\t}\n\n\tasync query(params: {\n\t\tvector: number[];\n\t\tnamespace?: string;\n\t\ttopK?: number;\n\t\tfilter?: MetadataFilter;\n\t\treturnValues?: boolean;\n\t}): Promise<VectorizeQueryMatch[]> {\n\t\tconst result = await requestCloudflare<QueryResponse>({\n\t\t\turl: `${this.config.vectorizeBaseUrl}/query`,\n\t\t\tapiToken: this.config.apiToken,\n\t\t\tbody: JSON.stringify({\n\t\t\t\tvector: params.vector,\n\t\t\t\ttopK: params.topK ?? this.config.topK,\n\t\t\t\tfilter: params.filter,\n\t\t\t\tnamespace: params.namespace,\n\t\t\t\treturnValues: params.returnValues ?? false,\n\t\t\t}),\n\t\t});\n\t\treturn result.matches ?? [];\n\t}\n\n\tasync getByIds(ids: string[]): Promise<VectorizeQueryMatch[]> {\n\t\tif (ids.length === 0) {\n\t\t\treturn [];\n\t\t}\n\t\treturn requestCloudflare<VectorizeQueryMatch[]>({\n\t\t\turl: `${this.config.vectorizeBaseUrl}/get_by_ids`,\n\t\t\tapiToken: this.config.apiToken,\n\t\t\tbody: JSON.stringify({ ids }),\n\t\t});\n\t}\n\n\tasync deleteByIds(ids: string[]): Promise<string | undefined> {\n\t\tif (ids.length === 0) {\n\t\t\treturn undefined;\n\t\t}\n\t\tconst result = await requestCloudflare<MutationResponse>({\n\t\t\turl: `${this.config.vectorizeBaseUrl}/delete_by_ids`,\n\t\t\tapiToken: this.config.apiToken,\n\t\t\tbody: JSON.stringify({ ids }),\n\t\t});\n\t\treturn result.mutationId;\n\t}\n}\n","import type { OpenClawConfig } from \"openclaw/plugin-sdk/config-runtime\";\nimport { isCloudflareNotFoundError } from \"./cloudflare-api.js\";\nimport { CompanionStore } from \"./companion-store.js\";\nimport { runDoctor } from \"./doctor.js\";\nimport { WorkersAiEmbeddingsClient } from \"./embeddings-client.js\";\nimport { resolveDefaultNamespace } from \"./namespace.js\";\nimport { hydrateInlineRecord, mapRecordForUpsert } from \"./record-mapper.js\";\nimport type {\n\tCompanionRecord,\n\tDoctorReport,\n\tHydratedMemoryRecord,\n\tMemoryRecordInput,\n\tMetadataFilter,\n\tResolvedPluginConfig,\n\tUpsertedMemoryRecord,\n} from \"./types.js\";\nimport { VectorizeClient } from \"./vectorize-client.js\";\n\nexport class CloudflareMemoryService {\n\treadonly embeddings: WorkersAiEmbeddingsClient;\n\treadonly vectorize: VectorizeClient;\n\treadonly companionStore: CompanionStore;\n\n\tconstructor(\n\t\treadonly config: ResolvedPluginConfig,\n\t\treadonly openClawConfig: OpenClawConfig,\n\t) {\n\t\tthis.embeddings = new WorkersAiEmbeddingsClient(config);\n\t\tthis.vectorize = new VectorizeClient(config);\n\t\tthis.companionStore = new CompanionStore(config.companionStorePath);\n\t}\n\n\tresolveNamespace(params: { namespace?: string; sessionKey?: string; agentId?: string; workspaceDir?: string }): string {\n\t\treturn resolveDefaultNamespace({\n\t\t\tfixedNamespace: params.namespace ?? this.config.fixedNamespace,\n\t\t\tsessionKey: params.sessionKey,\n\t\t\tagentId: params.agentId,\n\t\t\tworkspaceDir: params.workspaceDir,\n\t\t});\n\t}\n\n\tasync search(params: {\n\t\tquery: string;\n\t\tnamespace?: string;\n\t\tmaxResults?: number;\n\t\tminScore?: number;\n\t\tfilter?: MetadataFilter;\n\t\tsessionKey?: string;\n\t\tagentId?: string;\n\t\tworkspaceDir?: string;\n\t}): Promise<Array<HydratedMemoryRecord & { score: number }>> {\n\t\tconst namespace = this.resolveNamespace(params);\n\t\tconst vector = await this.embeddings.embedQuery(params.query);\n\t\tconst matches = await this.vectorize.query({\n\t\t\tvector,\n\t\t\tnamespace,\n\t\t\ttopK: params.maxResults ?? this.config.topK,\n\t\t\tfilter: params.filter,\n\t\t});\n\n\t\tconst hydrated = await Promise.all(\n\t\t\tmatches.map(async (match) => {\n\t\t\t\tconst base = hydrateInlineRecord(match);\n\t\t\t\tconst text = base.text ?? (await this.companionStore.get(base.namespace, base.logicalId))?.text ?? \"\";\n\t\t\t\treturn {\n\t\t\t\t\t...base,\n\t\t\t\t\ttext,\n\t\t\t\t\tscore: match.score ?? 0,\n\t\t\t\t};\n\t\t\t}),\n\t\t);\n\n\t\treturn hydrated.filter((record) => record.score >= (params.minScore ?? this.config.minScore));\n\t}\n\n\tasync get(params: { id: string; namespace?: string; sessionKey?: string; agentId?: string; workspaceDir?: string }): Promise<HydratedMemoryRecord | null> {\n\t\tconst namespace = this.resolveNamespace(params);\n\t\tconst vectorId = `${namespace}::${params.id}`;\n\t\tconst [match] = await this.vectorize.getByIds([vectorId]);\n\t\tif (!match) {\n\t\t\treturn null;\n\t\t}\n\t\tconst base = hydrateInlineRecord(match);\n\t\tconst companion = await this.companionStore.get(base.namespace, base.logicalId);\n\t\treturn {\n\t\t\t...base,\n\t\t\ttext: base.text ?? companion?.text ?? \"\",\n\t\t};\n\t}\n\n\tasync upsert(params: { input: MemoryRecordInput; sessionKey?: string; agentId?: string; workspaceDir?: string }): Promise<UpsertedMemoryRecord> {\n\t\tconst namespace = this.resolveNamespace({\n\t\t\tnamespace: params.input.namespace,\n\t\t\tsessionKey: params.sessionKey,\n\t\t\tagentId: params.agentId,\n\t\t\tworkspaceDir: params.workspaceDir,\n\t\t});\n\t\tconst embedding = await this.embeddings.embedQuery(params.input.text);\n\t\tconst mapped = mapRecordForUpsert({\n\t\t\tinput: params.input,\n\t\t\tnamespace,\n\t\t\tembedding,\n\t\t\tconfig: this.config,\n\t\t});\n\n\t\tif (mapped.companionRecord) {\n\t\t\tawait this.companionStore.upsert(mapped.companionRecord);\n\t\t}\n\n\t\tconst mutationId = await this.vectorize.upsert([mapped.vector]);\n\t\tconst hydrated = await this.get({\n\t\t\tid: mapped.logicalId,\n\t\t\tnamespace,\n\t\t});\n\n\t\treturn {\n\t\t\t...(hydrated ?? this.fromCompanionFallback(mapped.companionRecord, mapped.logicalId, namespace, mapped.path)),\n\t\t\tmutationId,\n\t\t};\n\t}\n\n\tasync delete(params: { id: string; namespace?: string; sessionKey?: string; agentId?: string; workspaceDir?: string }): Promise<string | undefined> {\n\t\tconst namespace = this.resolveNamespace(params);\n\t\tawait this.companionStore.delete(namespace, params.id);\n\t\treturn this.vectorize.deleteByIds([`${namespace}::${params.id}`]);\n\t}\n\n\tasync doctor(options: { createIndexIfMissing?: boolean }): Promise<DoctorReport> {\n\t\treturn runDoctor({\n\t\t\tservice: this,\n\t\t\tcreateIndexIfMissing: options.createIndexIfMissing ?? false,\n\t\t});\n\t}\n\n\tasync ensureIndexExists(createIfMissing: boolean): Promise<{ created: boolean; dimensions: number }> {\n\t\ttry {\n\t\t\tconst description = await this.vectorize.describeIndex();\n\t\t\treturn {\n\t\t\t\tcreated: false,\n\t\t\t\tdimensions: description.config.dimensions,\n\t\t\t};\n\t\t} catch (error) {\n\t\t\tif (!createIfMissing || !isCloudflareNotFoundError(error)) {\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\tconst dimensions = this.config.createIndex.dimensions ?? (await this.embeddings.probeDimensions());\n\t\t\tawait this.vectorize.createIndex(dimensions);\n\t\t\treturn {\n\t\t\t\tcreated: true,\n\t\t\t\tdimensions,\n\t\t\t};\n\t\t}\n\t}\n\n\tprivate fromCompanionFallback(companionRecord: CompanionRecord | undefined, logicalId: string, namespace: string, path: string): UpsertedMemoryRecord {\n\t\treturn {\n\t\t\tlogicalId,\n\t\t\tvectorId: `${namespace}::${logicalId}`,\n\t\t\tnamespace,\n\t\t\ttitle: companionRecord?.title,\n\t\t\ttext: companionRecord?.text ?? \"\",\n\t\t\tmetadata: companionRecord?.metadata ?? {},\n\t\t\tsource: companionRecord?.source,\n\t\t\tcreatedAt: companionRecord?.createdAt,\n\t\t\tupdatedAt: companionRecord?.updatedAt,\n\t\t\tpath,\n\t\t};\n\t}\n}\n","import type { OpenClawConfig } from \"openclaw/plugin-sdk/config-runtime\";\nimport { resolvePluginConfig } from \"./config.js\";\nimport { CloudflareMemoryService } from \"./service.js\";\n\nexport async function createCloudflareMemoryService(params: {\n\tpluginConfig: unknown;\n\topenClawConfig: OpenClawConfig;\n\tenv?: NodeJS.ProcessEnv;\n\tresolvePath?: (input: string) => string;\n}): Promise<CloudflareMemoryService> {\n\tconst resolved = await resolvePluginConfig(params);\n\treturn new CloudflareMemoryService(resolved, params.openClawConfig);\n}\n","import type { OpenClawConfig } from \"openclaw/plugin-sdk/config-runtime\";\r\nimport type { MigrationDuplicateStrategy } from \"./types.js\";\r\nimport { formatMigrationSummary, runCloudflareMemoryMigration } from \"./migration.js\";\r\nimport { createCloudflareMemoryService } from \"./service-factory.js\";\r\nimport type { MetadataFilter } from \"./types.js\";\r\n\r\ntype CliCommand = {\r\n\tcommand: (name: string) => CliCommand;\r\n\tdescription: (description: string) => CliCommand;\r\n\targument: (name: string, description: string) => CliCommand;\r\n\toption: (flags: string, description: string) => CliCommand;\r\n\taction: (handler: (...args: unknown[]) => Promise<void> | void) => CliCommand;\r\n\topts?: () => Record<string, unknown>;\r\n};\r\n\r\nfunction printJson(value: unknown): void {\r\n\tconsole.log(JSON.stringify(value, null, 2));\r\n}\r\n\r\nfunction parseMetadataFlag(value: string | undefined): Record<string, string | number | boolean> | undefined {\r\n\tif (!value) {\r\n\t\treturn undefined;\r\n\t}\r\n\tconst parsed = JSON.parse(value) as unknown;\r\n\tif (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) {\r\n\t\tthrow new Error(\"--metadata must be a JSON object.\");\r\n\t}\r\n\treturn parsed as Record<string, string | number | boolean>;\r\n}\r\n\r\nfunction parseFilterFlag(value: string | undefined): MetadataFilter | undefined {\r\n\tif (!value) {\r\n\t\treturn undefined;\r\n\t}\r\n\tconst parsed = JSON.parse(value) as unknown;\r\n\tif (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) {\r\n\t\tthrow new Error(\"--filter must be a JSON object.\");\r\n\t}\r\n\treturn parsed as MetadataFilter;\r\n}\r\n\r\nfunction isCliCommand(value: unknown): value is CliCommand {\r\n\treturn Boolean(value) && typeof value === \"object\" && typeof (value as CliCommand).opts === \"function\";\r\n}\r\n\r\nfunction resolveInvocation(args: unknown[]): { positionals: unknown[]; options: Record<string, unknown> } {\r\n\tconst maybeCommand = args.at(-1);\r\n\tif (!isCliCommand(maybeCommand)) {\r\n\t\treturn {\r\n\t\t\tpositionals: args,\r\n\t\t\toptions: {},\r\n\t\t};\r\n\t}\r\n\treturn {\r\n\t\tpositionals: args.slice(0, -1),\r\n\t\toptions: maybeCommand.opts?.() ?? {},\r\n\t};\r\n}\r\n\r\nfunction parseDuplicateStrategy(value: unknown): MigrationDuplicateStrategy | undefined {\r\n\tif (value === undefined) {\r\n\t\treturn undefined;\r\n\t}\r\n\tif (value === \"overwrite\" || value === \"skip\" || value === \"fail\") {\r\n\t\treturn value;\r\n\t}\r\n\tthrow new Error(\"--if-exists must be overwrite, skip, or fail.\");\r\n}\r\n\r\nexport function registerCloudflareMemoryCli(\r\n\tprogram: {\r\n\t\tcommand: (name: string) => CliCommand;\r\n\t},\r\n\tparams: {\r\n\t\tpluginConfig: unknown;\r\n\t\topenClawConfig: OpenClawConfig;\r\n\t\tresolvePath?: (input: string) => string;\r\n\t},\r\n): void {\r\n\tconst root = program.command(\"cf-memory\").description(\"Manage Cloudflare memory records.\");\r\n\r\n\tfunction resolveOptions(args: unknown[]): Record<string, unknown> {\r\n\t\treturn resolveInvocation(args).options;\r\n\t}\r\n\r\n\troot\r\n\t\t.command(\"doctor\")\r\n\t\t.description(\"Validate Workers AI and Vectorize configuration.\")\r\n\t\t.option(\"--create-index\", \"Create the Vectorize index if missing.\")\r\n\t\t.option(\"--json\", \"Print structured JSON output.\")\r\n\t\t.action(async (...args) => {\r\n\t\t\tconst options = resolveOptions(args);\r\n\t\t\tconst service = await createCloudflareMemoryService({\r\n\t\t\t\tpluginConfig: params.pluginConfig,\r\n\t\t\t\topenClawConfig: params.openClawConfig,\r\n\t\t\t\tenv: process.env,\r\n\t\t\t\tresolvePath: params.resolvePath,\r\n\t\t\t});\r\n\t\t\tconst report = await service.doctor({\r\n\t\t\t\tcreateIndexIfMissing: Boolean(options.createIndex),\r\n\t\t\t});\r\n\t\t\tif (options.json) {\r\n\t\t\t\tprintJson(report);\r\n\t\t\t} else {\r\n\t\t\t\tfor (const check of report.checks) {\r\n\t\t\t\t\tconsole.log(`[${check.status}] ${check.name}: ${check.message}`);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tif (!report.ok) {\r\n\t\t\t\tprocess.exitCode = 1;\r\n\t\t\t}\r\n\t\t});\r\n\r\n\troot\r\n\t\t.command(\"search\")\r\n\t\t.description(\"Search stored Cloudflare memory.\")\r\n\t\t.argument(\"<query>\", \"Semantic search query.\")\r\n\t\t.option(\"--namespace <namespace>\", \"Optional namespace override.\")\r\n\t\t.option(\"--limit <count>\", \"Maximum number of results.\")\r\n\t\t.option(\"--filter <json>\", \"Optional metadata filter JSON.\")\r\n\t\t.action(async (query, opts) => {\r\n\t\t\tconst options = opts as Record<string, unknown>;\r\n\t\t\tconst service = await createCloudflareMemoryService({\r\n\t\t\t\tpluginConfig: params.pluginConfig,\r\n\t\t\t\topenClawConfig: params.openClawConfig,\r\n\t\t\t\tenv: process.env,\r\n\t\t\t\tresolvePath: params.resolvePath,\r\n\t\t\t});\r\n\t\t\tconst results = await service.search({\r\n\t\t\t\tquery: String(query),\r\n\t\t\t\tnamespace: options.namespace as string | undefined,\r\n\t\t\t\tmaxResults: options.limit ? Number(options.limit) : undefined,\r\n\t\t\t\tfilter: parseFilterFlag(options.filter as string | undefined),\r\n\t\t\t});\r\n\t\t\tprintJson(results);\r\n\t\t});\r\n\r\n\troot\r\n\t\t.command(\"upsert\")\r\n\t\t.description(\"Insert or update a memory record.\")\r\n\t\t.argument(\"<text>\", \"Memory text.\")\r\n\t\t.option(\"--id <id>\", \"Stable logical id.\")\r\n\t\t.option(\"--title <title>\", \"Optional title.\")\r\n\t\t.option(\"--namespace <namespace>\", \"Optional namespace override.\")\r\n\t\t.option(\"--source <source>\", \"Optional source label.\")\r\n\t\t.option(\"--metadata <json>\", \"Optional metadata JSON object.\")\r\n\t\t.action(async (text, opts) => {\r\n\t\t\tconst options = opts as Record<string, unknown>;\r\n\t\t\tconst service = await createCloudflareMemoryService({\r\n\t\t\t\tpluginConfig: params.pluginConfig,\r\n\t\t\t\topenClawConfig: params.openClawConfig,\r\n\t\t\t\tenv: process.env,\r\n\t\t\t\tresolvePath: params.resolvePath,\r\n\t\t\t});\r\n\t\t\tconst result = await service.upsert({\r\n\t\t\t\tinput: {\r\n\t\t\t\t\tid: options.id as string | undefined,\r\n\t\t\t\t\ttitle: options.title as string | undefined,\r\n\t\t\t\t\ttext: String(text),\r\n\t\t\t\t\tnamespace: options.namespace as string | undefined,\r\n\t\t\t\t\tsource: options.source as string | undefined,\r\n\t\t\t\t\tmetadata: parseMetadataFlag(options.metadata as string | undefined),\r\n\t\t\t\t},\r\n\t\t\t});\r\n\t\t\tprintJson(result);\r\n\t\t});\r\n\r\n\troot\r\n\t\t.command(\"delete\")\r\n\t\t.description(\"Delete a memory record.\")\r\n\t\t.argument(\"<id>\", \"Logical memory record id.\")\r\n\t\t.option(\"--namespace <namespace>\", \"Optional namespace override.\")\r\n\t\t.action(async (id, opts) => {\r\n\t\t\tconst options = opts as Record<string, unknown>;\r\n\t\t\tconst service = await createCloudflareMemoryService({\r\n\t\t\t\tpluginConfig: params.pluginConfig,\r\n\t\t\t\topenClawConfig: params.openClawConfig,\r\n\t\t\t\tenv: process.env,\r\n\t\t\t\tresolvePath: params.resolvePath,\r\n\t\t\t});\r\n\t\t\tconst mutationId = await service.delete({\r\n\t\t\t\tid: String(id),\r\n\t\t\t\tnamespace: options.namespace as string | undefined,\r\n\t\t\t});\r\n\t\t\tprintJson({ id, mutationId });\r\n\t\t});\r\n\r\n\troot\r\n\t\t.command(\"migrate\")\r\n\t\t.description(\"Migrate legacy markdown memory into Cloudflare Vectorize.\")\r\n\t\t.argument(\"[sources...]\", \"Markdown files, directories, or glob patterns. Defaults to the current OpenClaw memory corpus when omitted.\")\r\n\t\t.option(\"--workspace <path>\", \"Workspace root used for default-provider discovery and relative path normalization.\")\r\n\t\t.option(\"--namespace <namespace>\", \"Target namespace override.\")\r\n\t\t.option(\"--derive-namespace-from-path\", \"Derive namespaces from the first relative path segment instead of using a single target namespace.\")\r\n\t\t.option(\"--if-exists <strategy>\", \"Duplicate handling: overwrite, skip, or fail.\")\r\n\t\t.option(\"--create-index\", \"Create the Vectorize index if missing.\")\r\n\t\t.option(\"--dry-run\", \"Plan the migration without writing records.\")\r\n\t\t.option(\"--json\", \"Print structured JSON output.\")\r\n\t\t.action(async (...args) => {\r\n\t\t\tconst { positionals, options } = resolveInvocation(args);\r\n\t\t\tconst rawSources = positionals[0];\r\n\t\t\tconst sourcePaths =\r\n\t\t\t\tpositionals.length === 0\r\n\t\t\t\t\t? []\r\n\t\t\t\t\t: Array.isArray(rawSources)\r\n\t\t\t\t\t\t? rawSources.map((value) => String(value))\r\n\t\t\t\t\t\t: positionals.map((value) => String(value));\r\n\t\t\tconst service = await createCloudflareMemoryService({\r\n\t\t\t\tpluginConfig: params.pluginConfig,\r\n\t\t\t\topenClawConfig: params.openClawConfig,\r\n\t\t\t\tenv: process.env,\r\n\t\t\t\tresolvePath: params.resolvePath,\r\n\t\t\t});\r\n\t\t\tconst summary = await runCloudflareMemoryMigration({\r\n\t\t\t\tservice,\r\n\t\t\t\toptions: {\r\n\t\t\t\t\tsourcePaths,\r\n\t\t\t\t\tworkspaceDir: options.workspace as string | undefined,\r\n\t\t\t\t\tnamespace: options.namespace as string | undefined,\r\n\t\t\t\t\tnamespaceStrategy: options.deriveNamespaceFromPath ? \"path\" : \"single-target\",\r\n\t\t\t\t\tduplicateStrategy: parseDuplicateStrategy(options.ifExists),\r\n\t\t\t\t\tdryRun: Boolean(options.dryRun),\r\n\t\t\t\t\tcreateIndexIfMissing: Boolean(options.createIndex),\r\n\t\t\t\t},\r\n\t\t\t});\r\n\t\t\tif (options.json) {\r\n\t\t\t\tprintJson(summary);\r\n\t\t\t} else {\r\n\t\t\t\tconsole.log(formatMigrationSummary(summary));\r\n\t\t\t}\r\n\t\t\tif (summary.failed > 0) {\r\n\t\t\t\tprocess.exitCode = 1;\r\n\t\t\t}\r\n\t\t});\r\n}\r\n","import type { MemoryPromptSectionBuilder } from \"openclaw/plugin-sdk/memory-core\";\n\nexport const buildPromptSection: MemoryPromptSectionBuilder = ({ availableTools }) => {\n\tconst lines = [\n\t\t\"Cloudflare memory is available through Vectorize semantic search and Workers AI embeddings.\",\n\t\t\"Use the memory tools for recalling past facts, preferences, and durable notes before asking repetitive follow-up questions.\",\n\t];\n\n\tif (availableTools.has(\"cloudflare_memory_upsert\")) {\n\t\tlines.push(\"When the user wants something remembered long-term, store it with cloudflare_memory_upsert.\");\n\t}\n\tif (availableTools.has(\"cloudflare_memory_search\")) {\n\t\tlines.push(\"Use cloudflare_memory_search to retrieve prior memories by semantic similarity or metadata filters.\");\n\t}\n\n\treturn lines;\n};\n","import { access } from \"node:fs/promises\";\nimport { dirname } from \"node:path\";\nimport type { MemoryPluginPublicArtifact, MemoryPluginPublicArtifactsProvider } from \"openclaw/plugin-sdk/memory-core\";\nimport { createCloudflareMemoryService } from \"./service-factory.js\";\n\nexport function createPublicArtifactsProvider(pluginConfig: unknown, resolvePath?: (input: string) => string): MemoryPluginPublicArtifactsProvider {\n\treturn {\n\t\tasync listArtifacts({ cfg }): Promise<MemoryPluginPublicArtifact[]> {\n\t\t\tconst service = await createCloudflareMemoryService({\n\t\t\t\tpluginConfig,\n\t\t\t\topenClawConfig: cfg,\n\t\t\t\tenv: process.env,\n\t\t\t\tresolvePath,\n\t\t\t});\n\t\t\tconst config = service.config;\n\t\t\ttry {\n\t\t\t\tawait access(config.companionStorePath);\n\t\t\t} catch {\n\t\t\t\treturn [];\n\t\t\t}\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\tkind: \"cloudflare-companion-store\",\n\t\t\t\t\tworkspaceDir: dirname(config.companionStorePath),\n\t\t\t\t\trelativePath: config.companionStorePath.split(/[/\\\\]/).at(-1) ?? \"companion-store.json\",\n\t\t\t\t\tabsolutePath: config.companionStorePath,\n\t\t\t\t\tagentIds: [],\n\t\t\t\t\tcontentType: \"json\",\n\t\t\t\t},\n\t\t\t];\n\t\t},\n\t};\n}\n","import type {\n\tMemoryEmbeddingProbeResult,\n\tMemoryProviderStatus,\n\tMemorySearchManager,\n\tMemorySearchResult,\n} from \"openclaw/plugin-sdk/memory-core-host-engine-storage\";\nimport { buildSnippet, parseVirtualPath } from \"./record-mapper.js\";\nimport type { CloudflareMemoryService } from \"./service.js\";\n\nexport class CloudflareMemorySearchManager implements MemorySearchManager {\n\tconstructor(\n\t\tprivate readonly service: CloudflareMemoryService,\n\t\tprivate readonly agentId: string,\n\t) {}\n\n\tasync search(query: string, opts?: { maxResults?: number; minScore?: number; sessionKey?: string }): Promise<MemorySearchResult[]> {\n\t\tconst records = await this.service.search({\n\t\t\tquery,\n\t\t\tmaxResults: opts?.maxResults,\n\t\t\tminScore: opts?.minScore,\n\t\t\tsessionKey: opts?.sessionKey,\n\t\t\tagentId: this.agentId,\n\t\t});\n\n\t\treturn records.map((record) => ({\n\t\t\tpath: record.path,\n\t\t\tstartLine: 1,\n\t\t\tendLine: Math.max(1, record.text.split(/\\r?\\n/).length),\n\t\t\tscore: record.score,\n\t\t\tsnippet: buildSnippet(record.text, query),\n\t\t\tsource: \"memory\",\n\t\t\tcitation: record.path,\n\t\t}));\n\t}\n\n\tasync readFile(params: { relPath: string; from?: number; lines?: number }): Promise<{ text: string; path: string }> {\n\t\tconst parsed = parseVirtualPath(params.relPath);\n\t\tif (!parsed) {\n\t\t\tthrow new Error(`Unsupported memory lookup path: ${params.relPath}`);\n\t\t}\n\t\tconst record = await this.service.get({\n\t\t\tid: parsed.logicalId,\n\t\t\tnamespace: parsed.namespace,\n\t\t\tagentId: this.agentId,\n\t\t});\n\t\tif (!record) {\n\t\t\tthrow new Error(`Memory record not found for ${params.relPath}`);\n\t\t}\n\n\t\tconst from = Math.max(1, params.from ?? 1);\n\t\tconst lines = Math.max(1, params.lines ?? record.text.split(/\\r?\\n/).length);\n\t\tconst selected = record.text\n\t\t\t.split(/\\r?\\n/)\n\t\t\t.slice(from - 1, from - 1 + lines)\n\t\t\t.join(\"\\n\");\n\t\treturn {\n\t\t\ttext: selected,\n\t\t\tpath: record.path,\n\t\t};\n\t}\n\n\tstatus(): MemoryProviderStatus {\n\t\treturn {\n\t\t\tbackend: \"builtin\",\n\t\t\tprovider: \"cloudflare-vectorize\",\n\t\t\tmodel: this.service.config.model,\n\t\t\tworkspaceDir: this.service.config.companionStorePath,\n\t\t\tcustom: {\n\t\t\t\tindexName: this.service.config.indexName,\n\t\t\t\tstorageMode: this.service.config.storageMode,\n\t\t\t\tfixedNamespace: this.service.config.fixedNamespace,\n\t\t\t},\n\t\t};\n\t}\n\n\tasync probeEmbeddingAvailability(): Promise<MemoryEmbeddingProbeResult> {\n\t\ttry {\n\t\t\tawait this.service.embeddings.probeDimensions();\n\t\t\treturn { ok: true };\n\t\t} catch (error) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\terror: error instanceof Error ? error.message : \"Embedding probe failed.\",\n\t\t\t};\n\t\t}\n\t}\n\n\tasync probeVectorAvailability(): Promise<boolean> {\n\t\ttry {\n\t\t\tawait this.service.vectorize.describeIndex();\n\t\t\treturn true;\n\t\t} catch {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tasync close(): Promise<void> {}\n}\n","import type { OpenClawConfig } from \"openclaw/plugin-sdk/config-runtime\";\nimport type { MemoryPluginRuntime } from \"openclaw/plugin-sdk/memory-core\";\nimport { CloudflareMemorySearchManager } from \"./search-manager.js\";\nimport { createCloudflareMemoryService } from \"./service-factory.js\";\n\nexport function createMemoryRuntime(params: { pluginConfig: unknown; resolvePath?: (input: string) => string }): MemoryPluginRuntime {\n\tconst managers = new Map<string, CloudflareMemorySearchManager>();\n\n\tasync function getOrCreateManager(openClawConfig: OpenClawConfig, agentId: string): Promise<CloudflareMemorySearchManager> {\n\t\tconst service = await createCloudflareMemoryService({\n\t\t\tpluginConfig: params.pluginConfig,\n\t\t\topenClawConfig,\n\t\t\tenv: process.env,\n\t\t\tresolvePath: params.resolvePath,\n\t\t});\n\t\tconst key = `${agentId}::${service.config.indexName}::${service.config.storageMode}`;\n\t\tconst existing = managers.get(key);\n\t\tif (existing) {\n\t\t\treturn existing;\n\t\t}\n\t\tconst manager = new CloudflareMemorySearchManager(service, agentId);\n\t\tmanagers.set(key, manager);\n\t\treturn manager;\n\t}\n\n\treturn {\n\t\tasync getMemorySearchManager(params) {\n\t\t\ttry {\n\t\t\t\tconst manager = await getOrCreateManager(params.cfg, params.agentId);\n\t\t\t\treturn { manager };\n\t\t\t} catch (error) {\n\t\t\t\treturn {\n\t\t\t\t\tmanager: null,\n\t\t\t\t\terror: error instanceof Error ? error.message : \"Unable to create Cloudflare memory manager.\",\n\t\t\t\t};\n\t\t\t}\n\t\t},\n\t\tresolveMemoryBackendConfig() {\n\t\t\treturn { backend: \"builtin\" };\n\t\t},\n\t\tasync closeAllMemorySearchManagers() {\n\t\t\tawait Promise.all([...managers.values()].map((manager) => manager.close?.()));\n\t\t\tmanagers.clear();\n\t\t},\n\t};\n}\n","import { Type } from \"@sinclair/typebox\";\nimport type { AnyAgentTool, OpenClawPluginToolContext } from \"openclaw/plugin-sdk/plugin-entry\";\nimport type { CloudflareMemoryService } from \"./service.js\";\nimport { createCloudflareMemoryService } from \"./service-factory.js\";\nimport type { MetadataFilter, MetadataValue } from \"./types.js\";\n\nasync function buildService(pluginConfig: unknown, ctx: OpenClawPluginToolContext): Promise<CloudflareMemoryService> {\n\tconst runtimeConfig = ctx.runtimeConfig ?? ctx.config;\n\tif (!runtimeConfig) {\n\t\tthrow new Error(\"Cloudflare memory tools require an OpenClaw runtime config.\");\n\t}\n\treturn createCloudflareMemoryService({\n\t\tpluginConfig,\n\t\topenClawConfig: runtimeConfig,\n\t\tenv: process.env,\n\t});\n}\n\nfunction parseJsonObject<T>(value: string | undefined, label: string): T | undefined {\n\tif (!value) {\n\t\treturn undefined;\n\t}\n\tconst parsed = JSON.parse(value) as unknown;\n\tif (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n\t\tthrow new Error(`${label} must be a JSON object.`);\n\t}\n\treturn parsed as T;\n}\n\nconst metadataValueSchema = Type.Union([Type.String(), Type.Number(), Type.Boolean()]);\n\nfunction textResult<TDetails>(text: string, details: TDetails) {\n\treturn {\n\t\tcontent: [{ type: \"text\" as const, text }],\n\t\tdetails,\n\t};\n}\n\nexport function createSearchTool(pluginConfig: unknown, ctx: OpenClawPluginToolContext): AnyAgentTool {\n\treturn {\n\t\tname: \"cloudflare_memory_search\",\n\t\tlabel: \"Cloudflare Memory Search\",\n\t\tdescription: \"Search Cloudflare-backed memory records using semantic retrieval.\",\n\t\tparameters: Type.Object({\n\t\t\tquery: Type.String({ description: \"Semantic search query.\" }),\n\t\t\tnamespace: Type.Optional(Type.String({ description: \"Optional namespace override.\" })),\n\t\t\tmaxResults: Type.Optional(Type.Number({ description: \"Maximum results to return.\" })),\n\t\t\tminScore: Type.Optional(Type.Number({ description: \"Minimum similarity score from 0 to 1.\" })),\n\t\t\tfilterJson: Type.Optional(Type.String({ description: \"Optional JSON object for Vectorize metadata filtering.\" })),\n\t\t}),\n\t\tasync execute(_toolCallId, params, _signal, _onUpdate) {\n\t\t\tconst service = await buildService(pluginConfig, ctx);\n\t\t\tconst filter = parseJsonObject<MetadataFilter>(params.filterJson as string | undefined, \"filterJson\");\n\t\t\tconst records = await service.search({\n\t\t\t\tquery: params.query as string,\n\t\t\t\tnamespace: params.namespace as string | undefined,\n\t\t\t\tmaxResults: params.maxResults as number | undefined,\n\t\t\t\tminScore: params.minScore as number | undefined,\n\t\t\t\tfilter,\n\t\t\t\tsessionKey: ctx.sessionKey,\n\t\t\t\tagentId: ctx.agentId,\n\t\t\t\tworkspaceDir: ctx.workspaceDir,\n\t\t\t});\n\t\t\tif (records.length === 0) {\n\t\t\t\treturn textResult(\"No matching memories found.\", { count: 0, records: [] });\n\t\t\t}\n\t\t\tconst text = records\n\t\t\t\t.map((record, index) => `${index + 1}. [${record.namespace}] ${record.title ?? record.logicalId} (${record.score.toFixed(3)})\\n${record.text}`)\n\t\t\t\t.join(\"\\n\\n\");\n\t\t\treturn textResult(text, {\n\t\t\t\tcount: records.length,\n\t\t\t\trecords: records.map((record) => ({\n\t\t\t\t\tid: record.logicalId,\n\t\t\t\t\tnamespace: record.namespace,\n\t\t\t\t\ttitle: record.title,\n\t\t\t\t\tscore: record.score,\n\t\t\t\t\tpath: record.path,\n\t\t\t\t})),\n\t\t\t});\n\t\t},\n\t};\n}\n\nexport function createGetTool(pluginConfig: unknown, ctx: OpenClawPluginToolContext): AnyAgentTool {\n\treturn {\n\t\tname: \"cloudflare_memory_get\",\n\t\tlabel: \"Cloudflare Memory Get\",\n\t\tdescription: \"Get a Cloudflare-backed memory record by id.\",\n\t\tparameters: Type.Object({\n\t\t\tid: Type.String({ description: \"Logical memory record id.\" }),\n\t\t\tnamespace: Type.Optional(Type.String({ description: \"Optional namespace override.\" })),\n\t\t}),\n\t\tasync execute(_toolCallId, params, _signal, _onUpdate) {\n\t\t\tconst service = await buildService(pluginConfig, ctx);\n\t\t\tconst record = await service.get({\n\t\t\t\tid: params.id as string,\n\t\t\t\tnamespace: params.namespace as string | undefined,\n\t\t\t\tsessionKey: ctx.sessionKey,\n\t\t\t\tagentId: ctx.agentId,\n\t\t\t\tworkspaceDir: ctx.workspaceDir,\n\t\t\t});\n\t\t\tif (!record) {\n\t\t\t\treturn textResult(\"Memory record not found.\", { found: false });\n\t\t\t}\n\t\t\treturn textResult(`${record.title ?? record.logicalId}\\nNamespace: ${record.namespace}\\nPath: ${record.path}\\n\\n${record.text}`, {\n\t\t\t\tfound: true,\n\t\t\t\tid: record.logicalId,\n\t\t\t\tnamespace: record.namespace,\n\t\t\t\tmetadata: record.metadata,\n\t\t\t});\n\t\t},\n\t};\n}\n\nexport function createUpsertTool(pluginConfig: unknown, ctx: OpenClawPluginToolContext): AnyAgentTool {\n\treturn {\n\t\tname: \"cloudflare_memory_upsert\",\n\t\tlabel: \"Cloudflare Memory Upsert\",\n\t\tdescription: \"Insert or update a Cloudflare-backed memory record.\",\n\t\tparameters: Type.Object({\n\t\t\tid: Type.Optional(Type.String({ description: \"Optional stable logical id.\" })),\n\t\t\ttitle: Type.Optional(Type.String({ description: \"Optional title.\" })),\n\t\t\ttext: Type.String({ description: \"Memory text to store.\" }),\n\t\t\tnamespace: Type.Optional(Type.String({ description: \"Optional namespace override.\" })),\n\t\t\tsource: Type.Optional(Type.String({ description: \"Optional source label.\" })),\n\t\t\tmetadata: Type.Optional(\n\t\t\t\tType.Record(Type.String(), metadataValueSchema, {\n\t\t\t\t\tdescription: \"Flat metadata object with string, number, or boolean values.\",\n\t\t\t\t}),\n\t\t\t),\n\t\t}),\n\t\tasync execute(_toolCallId, params, _signal, _onUpdate) {\n\t\t\tconst service = await buildService(pluginConfig, ctx);\n\t\t\tconst record = await service.upsert({\n\t\t\t\tinput: {\n\t\t\t\t\tid: params.id as string | undefined,\n\t\t\t\t\ttitle: params.title as string | undefined,\n\t\t\t\t\ttext: params.text as string,\n\t\t\t\t\tnamespace: params.namespace as string | undefined,\n\t\t\t\t\tsource: params.source as string | undefined,\n\t\t\t\t\tmetadata: params.metadata as Record<string, MetadataValue> | undefined,\n\t\t\t\t},\n\t\t\t\tsessionKey: ctx.sessionKey,\n\t\t\t\tagentId: ctx.agentId,\n\t\t\t\tworkspaceDir: ctx.workspaceDir,\n\t\t\t});\n\t\t\treturn textResult(`Stored memory ${record.logicalId} in namespace ${record.namespace}.`, {\n\t\t\t\tid: record.logicalId,\n\t\t\t\tnamespace: record.namespace,\n\t\t\t\tpath: record.path,\n\t\t\t\tmutationId: record.mutationId,\n\t\t\t});\n\t\t},\n\t};\n}\n\nexport function createDeleteTool(pluginConfig: unknown, ctx: OpenClawPluginToolContext): AnyAgentTool {\n\treturn {\n\t\tname: \"cloudflare_memory_delete\",\n\t\tlabel: \"Cloudflare Memory Delete\",\n\t\tdescription: \"Delete a Cloudflare-backed memory record by id.\",\n\t\tparameters: Type.Object({\n\t\t\tid: Type.String({ description: \"Logical memory record id.\" }),\n\t\t\tnamespace: Type.Optional(Type.String({ description: \"Optional namespace override.\" })),\n\t\t}),\n\t\tasync execute(_toolCallId, params, _signal, _onUpdate) {\n\t\t\tconst service = await buildService(pluginConfig, ctx);\n\t\t\tconst mutationId = await service.delete({\n\t\t\t\tid: params.id as string,\n\t\t\t\tnamespace: params.namespace as string | undefined,\n\t\t\t\tsessionKey: ctx.sessionKey,\n\t\t\t\tagentId: ctx.agentId,\n\t\t\t\tworkspaceDir: ctx.workspaceDir,\n\t\t\t});\n\t\t\treturn textResult(`Deleted memory ${params.id as string}.`, { mutationId });\n\t\t},\n\t};\n}\n","import type { MemoryEmbeddingProviderAdapter } from \"openclaw/plugin-sdk/memory-core-host-engine-embeddings\";\nimport { definePluginEntry, type OpenClawPluginApi } from \"openclaw/plugin-sdk/plugin-entry\";\nimport { registerCloudflareMemoryCli } from \"./cli.js\";\nimport { getPluginConfigFromOpenClawConfig, pluginConfigSchema, resolvePluginConfig } from \"./config.js\";\nimport { DEFAULT_EMBEDDING_MODEL, PLUGIN_DESCRIPTION, PLUGIN_ID, PLUGIN_NAME } from \"./constants.js\";\nimport { buildPromptSection } from \"./prompt.js\";\nimport { createPublicArtifactsProvider } from \"./public-artifacts.js\";\nimport { createMemoryRuntime } from \"./runtime.js\";\nimport { CloudflareMemoryService } from \"./service.js\";\nimport { createDeleteTool, createGetTool, createSearchTool, createUpsertTool } from \"./tools.js\";\n\nfunction createMemoryEmbeddingProviderAdapter(): MemoryEmbeddingProviderAdapter {\n\treturn {\n\t\tid: \"cloudflare-workers-ai\",\n\t\tdefaultModel: DEFAULT_EMBEDDING_MODEL,\n\t\ttransport: \"remote\",\n\t\tallowExplicitWhenConfiguredAuto: true,\n\t\tasync create(options) {\n\t\t\tconst pluginConfig = getPluginConfigFromOpenClawConfig(options.config);\n\t\t\tconst resolved = await resolvePluginConfig({\n\t\t\t\tpluginConfig,\n\t\t\t\topenClawConfig: options.config,\n\t\t\t\tenv: process.env,\n\t\t\t});\n\t\t\tconst service = new CloudflareMemoryService(\n\t\t\t\t{\n\t\t\t\t\t...resolved,\n\t\t\t\t\tmodel: options.model || resolved.model,\n\t\t\t\t\tworkersAiBaseUrl: options.remote?.baseUrl && options.remote.baseUrl.trim().length > 0 ? options.remote.baseUrl : resolved.workersAiBaseUrl,\n\t\t\t\t\tapiToken: typeof options.remote?.apiKey === \"string\" && options.remote.apiKey.trim().length > 0 ? options.remote.apiKey : resolved.apiToken,\n\t\t\t\t},\n\t\t\t\toptions.config,\n\t\t\t);\n\t\t\treturn {\n\t\t\t\tprovider: {\n\t\t\t\t\tid: \"cloudflare-workers-ai\",\n\t\t\t\t\tmodel: options.model || resolved.model,\n\t\t\t\t\tembedQuery: (text) => service.embeddings.embedQuery(text),\n\t\t\t\t\tembedBatch: (texts) => service.embeddings.embedBatch(texts),\n\t\t\t\t},\n\t\t\t\truntime: {\n\t\t\t\t\tid: \"cloudflare-workers-ai\",\n\t\t\t\t\tcacheKeyData: {\n\t\t\t\t\t\taccountId: resolved.accountId,\n\t\t\t\t\t\tmodel: options.model || resolved.model,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t};\n\t\t},\n\t};\n}\n\nexport default definePluginEntry({\n\tid: PLUGIN_ID,\n\tname: PLUGIN_NAME,\n\tdescription: PLUGIN_DESCRIPTION,\n\tkind: \"memory\",\n\tconfigSchema: pluginConfigSchema,\n\tregister(api: OpenClawPluginApi) {\n\t\tpluginConfigSchema.parse?.(api.pluginConfig ?? {});\n\n\t\tapi.registerMemoryEmbeddingProvider(createMemoryEmbeddingProviderAdapter());\n\t\tapi.registerMemoryCapability({\n\t\t\tpromptBuilder: buildPromptSection,\n\t\t\truntime: createMemoryRuntime({\n\t\t\t\tpluginConfig: api.pluginConfig,\n\t\t\t\tresolvePath: api.resolvePath,\n\t\t\t}),\n\t\t\tpublicArtifacts: createPublicArtifactsProvider(api.pluginConfig, api.resolvePath),\n\t\t});\n\n\t\tapi.registerTool((ctx) => createSearchTool(api.pluginConfig, ctx), {\n\t\t\tnames: [\"cloudflare_memory_search\"],\n\t\t});\n\t\tapi.registerTool((ctx) => createGetTool(api.pluginConfig, ctx), {\n\t\t\tnames: [\"cloudflare_memory_get\"],\n\t\t});\n\t\tapi.registerTool((ctx) => createUpsertTool(api.pluginConfig, ctx), {\n\t\t\tnames: [\"cloudflare_memory_upsert\"],\n\t\t});\n\t\tapi.registerTool((ctx) => createDeleteTool(api.pluginConfig, ctx), {\n\t\t\tnames: [\"cloudflare_memory_delete\"],\n\t\t});\n\n\t\tapi.registerCli(\n\t\t\t({ program }) => {\n\t\t\t\tregisterCloudflareMemoryCli(program, {\n\t\t\t\t\tpluginConfig: api.pluginConfig,\n\t\t\t\t\topenClawConfig: api.config,\n\t\t\t\t\tresolvePath: api.resolvePath,\n\t\t\t\t});\n\t\t\t},\n\t\t\t{\n\t\t\t\tdescriptors: [\n\t\t\t\t\t{\n\t\t\t\t\t\tname: \"cf-memory\",\n\t\t\t\t\t\tdescription: \"Manage Cloudflare Vectorize memory\",\n\t\t\t\t\t\thasSubcommands: true,\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t);\n\n\t\tvoid resolvePluginConfig({\n\t\t\tpluginConfig: api.pluginConfig,\n\t\t\topenClawConfig: api.config,\n\t\t\tenv: process.env,\n\t\t\tresolvePath: api.resolvePath,\n\t\t})\n\t\t\t.then((resolved) => {\n\t\t\t\tapi.logger.info(`${PLUGIN_ID}: registered for index ${resolved.indexName} using model ${resolved.model}.`);\n\t\t\t})\n\t\t\t.catch((error: unknown) => {\n\t\t\t\tconst message = error instanceof Error ? error.message : \"Unknown configuration error.\";\n\t\t\t\tapi.logger.warn(`${PLUGIN_ID}: deferred config validation reported: ${message}`);\n\t\t\t});\n\t},\n});\n"],"mappings":";;;;;;;;;;;AAGA,SAAS,GAAuB,GAAuB;AACtD,QAAO,EACL,MAAM,CACN,aAAa,CACb,QAAQ,iBAAiB,IAAI,CAC7B,QAAQ,UAAU,IAAI,CACtB,QAAQ,YAAY,GAAG,CACvB,MAAM,GAAG,GAAG;;AAGf,SAAgB,EAAkB,GAAuB;AAExD,QADmB,GAAuB,EAAM,IAC3B;;AAGtB,SAAgB,GAAwB,GAA2G;AAClJ,KAAI,EAAO,eACV,QAAO,EAAkB,EAAO,eAAe;CAEhD,IAAM,IAAU,EAAO,aAAa,GAA6B,EAAO,WAAW,GAAG,EAAO;AAO7F,QANI,IACI,EAAkB,SAAS,IAAU,GAEzC,EAAO,eACH,EAAkB,aAAa,EAAS,EAAO,aAAa,GAAG,GAEhE;;;;ACMR,IAAM,KAAsB,IAAI,IAAI,CAAC,OAAO,YAAY,CAAC,EACnD,KAA8B,IAAI,IAAI;CAAC;CAAM;CAAa;CAAU;CAAQ,CAAC;AAEnF,SAAS,EAAyB,GAAuB;AACxD,QAAO,EAAM,QAAQ,OAAO,IAAI,CAAC,QAAQ,SAAS,GAAG;;AAGtD,SAAS,EAAsB,GAAuB;AAErD,QADmB,EAAyB,EAAM,CAAC,QAAQ,QAAQ,GAAG,IACjD,EAAS,EAAM;;AAGrC,SAAS,EAAe,GAAwB;AAC/C,QAAO,GAAoB,IAAI,EAAQ,EAAM,CAAC,aAAa,CAAC;;AAG7D,SAAS,GAAa,GAAwB;AAC7C,QAAO,YAAY,KAAK,EAAM;;AAG/B,SAAS,EAA2B,GAAwB;CAC3D,IAAM,IAAa,EAAyB,EAAM,CAAC,aAAa;AAChE,QAAO,EAAW,SAAS,iBAAiB,IAAI,EAAW,SAAS,SAAS;;AAG9E,eAAe,EAAa,GAAc;AACzC,KAAI;AACH,SAAO,MAAM,EAAK,EAAK;SAChB;AACP,SAAO;;;AAIT,eAAe,GAA8B,GAAsC;CAClF,IAAM,IAAoB,EAAE;AAC5B,YAAW,IAAM,KAAS,EAAK,sBAAsB,EAAE,KAAK,GAAW,CAAC,EAAE;EACzE,IAAM,IAAe,EAAQ,GAAW,EAAM;AAC9C,EAAK,EAA2B,EAAa,IAC5C,EAAQ,KAAK,EAAa;;AAG5B,QAAO;;AAGR,eAAe,GAAmB,GAAiB,GAAyC;CAC3F,IAAM,IAAoB,EAAE,EACtB,IAAoB,EAAyB,EAAQ,EACrD,IAAW,EAAW,EAAQ,GAAG,EAAK,EAAkB,GAAG,EAAK,GAAmB,EAAE,KAAK,GAAc,CAAC;AAC/G,YAAW,IAAM,KAAS,GAAU;EACnC,IAAM,IAAe,EAAW,EAAM,GAAG,IAAQ,EAAQ,GAAc,EAAM;AACzE,IAA2B,EAAa,IAAI,CAAC,EAAe,EAAa,KAG3D,MAAM,EAAa,EAAa,GACnC,QAAQ,IACtB,EAAQ,KAAK,EAAa;;AAG5B,QAAO;;AAGR,eAAsB,GAAuB,GAIN;CACtC,IAAM,IAAe,EAAQ,EAAO,aAAa,EAC3C,oBAAa,IAAI,KAAsC;AAE7D,KAAI,EAAO,eAAe,mBACzB,MAAK,IAAM,KAAW,MAAM,EAAgB,EAAa,EAAE;EAC1D,IAAM,IAAe,EAAsB,EAAQ,EAC7C,IAAe,EAAQ,GAAc,EAAa;AACpD,IAA2B,EAAa,IAAI,CAAC,EAAe,EAAa,KAG3D,MAAM,EAAa,EAAa,GACnC,QAAQ,IACtB,EAAW,IAAI,EAAa,aAAa,EAAE;GAC1C;GACA;GACA,CAAC;;AAKL,MAAK,IAAM,KAAS,EAAO,eAAe,EAAE,EAAE;EAC7C,IAAM,IAAgB,EAAQ,GAAc,EAAM,EAC5C,IAAY,MAAM,EAAa,EAAc,EAC/C,IAAoB,EAAE;AAC1B,EAAI,GAAW,aAAa,GAC3B,IAAU,MAAM,GAA8B,EAAc,GAClD,GAAW,QAAQ,GAC7B,IAAU,EAAe,EAAc,GAAG,CAAC,EAAc,GAAG,EAAE,GACpD,GAAa,EAAM,KAC7B,IAAU,MAAM,GAAmB,GAAO,EAAa;AAGxD,OAAK,IAAM,KAAS,GAAS;GAC5B,IAAM,IAAe,EAAsB,GAAS,GAAc,EAAM,CAAC;AACzE,KAAW,IAAI,EAAM,aAAa,EAAE;IACnC,cAAc;IACd;IACA,CAAC;;;AAIJ,QAAO,CAAC,GAAG,EAAW,QAAQ,CAAC,CAAC,MAAM,GAAM,MAAU,EAAK,aAAa,cAAc,EAAM,aAAa,CAAC;;AAG3G,SAAS,GAAsB,GAA0C;CACxE,IAAM,IAAU,EAAM,MAAM;AAC5B,KAAI,CAAC,EACJ,QAAO;AAER,KAAI,WAAW,KAAK,EAAQ,IAAI,WAAW,KAAK,EAAQ,CACvD,QAAO,EAAQ,MAAM,GAAG,GAAG;AAE5B,KAAI,MAAY,OACf,QAAO;AAER,KAAI,MAAY,QACf,QAAO;CAER,IAAM,IAAU,OAAO,EAAQ;AAC/B,KAAI,CAAC,OAAO,MAAM,EAAQ,IAAI,MAAY,GACzC,QAAO;AAEJ,SAAQ,WAAW,IAAI,IAAI,EAAQ,WAAW,IAAI,EAGtD,QAAO;;AAGR,SAAS,GAAiB,GAA8E;CACvG,IAAM,IAAa,EAAQ,QAAQ,SAAS,KAAK;AACjD,KAAI,CAAC,EAAW,WAAW,QAAQ,CAClC,QAAO;EAAE,MAAM;EAAY,YAAY,EAAE;EAAE;CAG5C,IAAM,IAAQ,EAAW,MAAM,KAAK,EAC9B,IAAe,EAAM,WAAW,GAAM,MAAU,IAAQ,KAAK,EAAK,MAAM,KAAK,MAAM;AACzF,KAAI,MAAiB,GACpB,QAAO;EAAE,MAAM;EAAY,YAAY,EAAE;EAAE;CAG5C,IAAM,IAA4C,EAAE;AACpD,MAAK,IAAM,KAAQ,EAAM,MAAM,GAAG,EAAa,EAAE;EAChD,IAAM,IAAiB,EAAK,QAAQ,IAAI;AACxC,MAAI,MAAmB,GACtB;EAED,IAAM,IAAM,EAAK,MAAM,GAAG,EAAe,CAAC,MAAM;AAChD,MAAI,CAAC,EACJ;EAED,IAAM,IAAc,GAAsB,EAAK,MAAM,IAAiB,EAAE,CAAC;AACzE,EAAI,MAAgB,KAAA,MACnB,EAAW,KAAO;;AAIpB,QAAO;EACN,MAAM,EAAM,MAAM,IAAe,EAAE,CAAC,KAAK,KAAK;EAC9C;EACA;;AAGF,SAAS,GAA2B,GAAmD;CACtF,IAAM,IAAQ,EAAQ,MAAM,KAAK,EAC3B,IAAmB,EAAM,WAAW,MAAS,EAAK,MAAM,CAAC,SAAS,EAAE;AAC1E,KAAI,MAAqB,GACxB,QAAO,EAAE,MAAM,IAAI;CAGpB,IAAM,IAAe,iBAAiB,KAAK,EAAM,IAAmB,MAAM,IAAI,GAAG;AACjF,KAAI,CAAC,EACJ,QAAO,EAAE,MAAM,EAAQ,MAAM,EAAE;CAGhC,IAAM,IAAiB,CAAC,GAAG,EAAM;AAEjC,CADA,EAAe,OAAO,GAAkB,EAAE,GACrC,EAAe,MAAqB,IAAI,MAAM,KAAK,MACvD,EAAe,OAAO,GAAkB,EAAE;CAE3C,IAAM,IAAO,EAAe,KAAK,KAAK,CAAC,MAAM;AAC7C,QAAO;EACN,OAAO,EAAa,GAAG,MAAM;EAC7B,MAAM,KAAQ,EAAQ,MAAM;EAC5B;;AAGF,SAAS,GAAqB,GAA8B;CAE3D,IAAM,IADmB,EAAa,QAAQ,qBAAqB,GAAG,CAEpE,aAAa,CACb,QAAQ,eAAe,IAAI,CAC3B,QAAQ,UAAU,IAAI,CACtB,QAAQ,YAAY,GAAG,CACvB,MAAM,GAAG,GAAG,EACR,IAAO,EAAW,OAAO,CAAC,OAAO,EAAa,CAAC,OAAO,MAAM,CAAC,MAAM,GAAG,GAAG;AAC/E,QAAO,GAAG,KAAQ,SAAS,GAAG;;AAG/B,SAAS,GAAU,GAAsB,GAA6C,GAAsD;AAQ3I,QAPI,OAAO,KAAqB,YAAY,EAAiB,MAAM,CAAC,SAAS,IACrE,EAAiB,MAAM,GAE3B,KAGa,EAAS,GAAc,EAAQ,EAAa,CAAC,CAAC,MAAM,IAClD,KAAA;;AAGpB,SAAS,GAAqB,GAAkC,GAA8B,GAA8B;AAC3H,QAAO,EAAQ,iBAAiB;EAC/B,WAAW,EAAQ;EACnB;EACA,CAAC;;AAGH,SAAS,GAAsB,GAKpB;AACV,KAAI,EAAO,sBAAsB,gBAChC,QAAO,EAAO;AAGf,KAAI,OAAO,EAAO,wBAAyB,YAAY,EAAO,qBAAqB,MAAM,CAAC,SAAS,EAClG,QAAO,EAAkB,EAAO,qBAAqB;CAGtD,IAAM,IAAe,EAAsB,EAAO,aAAa,CAAC,MAAM,IAAI,CAAC;AAI3E,QAHI,CAAC,KAAgB,MAAiB,OAAO,MAAiB,OACtD,EAAO,kBAER,EAAkB,EAAa;;AAGvC,eAAsB,GAAmB,GAKC;CAEzC,IAAM,EAAE,SAAM,kBAAe,GADjB,MAAM,EAAS,EAAO,KAAK,cAAc,OAAO,CACV,EAC5C,EAAE,OAAO,GAAc,MAAM,MAAkB,GAA2B,EAAK,EAC/E,IAAQ,GAAU,EAAO,KAAK,cAAc,EAAW,OAAO,EAAa,EAC3E,IAAO,EAAc,MAAM,IAAI,KAAS;AAC9C,KAAI,CAAC,EACJ,QAAO;CAGR,IAAM,IAA0C;EAC/C,kBAAkB,EAAO;EACzB,kBAAkB,EAAO,KAAK,aAAa,WAAW,KAAK,GAAG,EAAO,KAAK,eAAe,EAAO,KAAK;EACrG;AACD,MAAK,IAAM,CAAC,GAAK,MAAU,OAAO,QAAQ,EAAW,CAChD,IAA4B,IAAI,EAAI,KAGxC,EAAS,KAAO;CAGjB,IAAM,IACL,OAAO,EAAW,MAAO,YAAY,EAAW,GAAG,MAAM,CAAC,SAAS,IAAI,EAAW,GAAG,MAAM,GAAG,GAAqB,EAAO,KAAK,aAAa,EACvI,IAAY,GAAsB;EACvC,cAAc,EAAO,KAAK;EAC1B,sBAAsB,EAAW;EACjC,iBAAiB,EAAO;EACxB,mBAAmB,EAAO;EAC1B,CAAC,EACI,IACL,OAAO,EAAW,UAAW,YAAY,EAAW,OAAO,MAAM,CAAC,SAAS,IACxE,EAAW,OAAO,MAAM,GACxB,EAAO,eAAe,qBACrB,4BACA;AAEL,QAAO;EACN,YAAY,EAAO,KAAK;EACxB,cAAc,EAAO,KAAK;EAC1B,OAAO;GACN,IAAI;GACJ;GACA;GACA;GACA;GACA;GACA;EACD;;AAGF,SAAS,GAAoB,GAA8B;AAE1D,QADqB,EAAO,OAAO,QAAQ,MAAU,EAAM,WAAW,OAAO,CACzD,KAAK,MAAU,GAAG,EAAM,KAAK,IAAI,EAAM,UAAU,CAAC,KAAK,MAAM;;AAGlF,eAAsB,GAA6B,GAGrB;CAC7B,IAAM,IAAU,EAAO,WAAW,EAAE,EAC9B,IAAe,EAAQ,EAAQ,gBAAgB,QAAQ,KAAK,CAAC,EAC7D,KAAmC,EAAQ,aAAa,UAAU,KAAK,IAAI,UAAU,oBACrF,IAAoB,EAAQ,qBAAqB,iBACjD,IAAgD,EAAQ,qBAAqB,aAC7E,IAAS,EAAQ,UAAU,IAC3B,IAAkB,GAAqB,EAAO,SAAS,GAAS,EAAa,EAC7E,IAAS,MAAM,EAAO,QAAQ,OAAO,EAC1C,sBAAsB,EAAQ,wBAAwB,IACtD,CAAC;AACF,KAAI,CAAC,EAAO,GACX,OAAU,MAAM,gCAAgC,GAAoB,EAAO,GAAG;CAG/E,IAAM,IAAkB,MAAM,GAAuB;EACpD;EACA;EACA,aAAa,EAAQ;EACrB,CAAC;AACF,KAAI,EAAgB,WAAW,EAC9B,OAAU,MACT,MAAe,qBACZ,8DAA8D,EAAa,KAC3E,4DACH;CAGF,IAAM,IAA6B,EAAE,EACjC,IAAkB,GAClB,IAAW,GACX,IAAU,GACV,IAAS;AAEb,MAAK,IAAM,KAAQ,EAClB,KAAI;EACH,IAAM,IAAS,MAAM,GAAmB;GACvC;GACA;GACA;GACA;GACA,CAAC;AACF,MAAI,CAAC,GAAQ;AAEZ,GADA,KAAW,GACX,EAAQ,KAAK;IACZ,QAAQ;IACR,YAAY,EAAK;IACjB,cAAc,EAAK;IACnB,QAAQ;IACR,CAAC;AACF;;AAGD,OAAmB;EACnB,IAAM,IAAY,EAAO,MAAM,IACzB,IAAY,EAAO,MAAM;AAC/B,MAAI,CAAC,KAAa,CAAC,EAClB,OAAU,MAAM,gEAAgE;AAGjF,MAAI,MAAsB,eACR,MAAM,EAAO,QAAQ,IAAI;GACzC,IAAI;GACJ;GACA,CAAC,EACY;AACb,OAAI,MAAsB,QAAQ;AAEjC,IADA,KAAW,GACX,EAAQ,KAAK;KACZ,QAAQ;KACR,YAAY,EAAO;KACnB,cAAc,EAAO;KACrB;KACA;KACA,OAAO,EAAO,MAAM;KACpB,QAAQ;KACR,CAAC;AACF;;AAED,SAAU,MAAM,4BAA4B,EAAU,+BAA+B,EAAU,GAAG;;AAIpG,MAAI,GAAQ;AACX,KAAQ,KAAK;IACZ,QAAQ;IACR,YAAY,EAAO;IACnB,cAAc,EAAO;IACrB;IACA;IACA,OAAO,EAAO,MAAM;IACpB,CAAC;AACF;;AAOD,EAJA,MAAM,EAAO,QAAQ,OAAO,EAC3B,OAAO,EAAO,OACd,CAAC,EACF,KAAY,GACZ,EAAQ,KAAK;GACZ,QAAQ;GACR,YAAY,EAAO;GACnB,cAAc,EAAO;GACrB;GACA;GACA,OAAO,EAAO,MAAM;GACpB,CAAC;UACM,GAAO;AAEf,EADA,KAAU,GACV,EAAQ,KAAK;GACZ,QAAQ;GACR,YAAY,EAAK;GACjB,cAAc,EAAK;GACnB,OAAO,aAAiB,QAAQ,EAAM,UAAU;GAChD,CAAC;;AAIJ,QAAO;EACN;EACA;EACA;EACA;EACA,iBAAiB,MAAsB,kBAAkB,IAAkB,KAAA;EAC3E,iBAAiB,EAAgB;EACjC;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF,SAAgB,GAAuB,GAAmC;CACzE,IAAM,IAAQ;EACb,GAAG,EAAQ,SAAS,YAAY,YAAY,GAAG,EAAQ,SAAS,IAAI,4BAA4B,YAAY;EAC5G,gBAAgB,EAAQ;EACxB,cAAc,EAAQ;EACtB,kBAAkB,EAAQ;EAC1B,qBAAqB,EAAQ;EAC7B,aAAa,EAAQ;EACrB,YAAY,EAAQ;EACpB,WAAW,EAAQ;EACnB;AAED,CAAI,EAAQ,mBACX,EAAM,OAAO,GAAG,GAAG,qBAAqB,EAAQ,kBAAkB;CAGnE,IAAM,IAAgB,EAAQ,QAAQ,QAAQ,MAAW,EAAO,WAAW,SAAS,CAAC,MAAM,GAAG,GAAG;AACjG,KAAI,EAAc,SAAS,GAAG;AAC7B,IAAM,KAAK,IAAI,YAAY;AAC3B,OAAK,IAAM,KAAU,EACpB,GAAM,KAAK,KAAK,EAAO,aAAa,IAAI,EAAO,QAAQ;;AAIzD,QAAO,EAAM,KAAK,KAAK;;;;ACjfxB,IAAa,IAAY,+BACZ,KAAc,+BACd,KAAqB,oFAErB,IAA4B,yBAC5B,IAA2B,wBAC3B,IAAsB,mCACtB,IAA0B,kCAC1B,IAAuB,yCACvB,IAAsB,8BACtB,IAAmB,mCACnB,KAAqB,qCAErB,IAA0B,6BAK1B,KAAoC,oBACpC,IAAkC,wCAIlC,IAAyB;CACrC,WAAW;CACX,OAAO;CACP,MAAM;CACN,aAAa;CACb,SAAS;CACT,QAAQ;CACR,WAAW;CACX,WAAW;CACX,EClCY,IAAb,cAAwC,MAAM;CAC7C,YAAY,GAAiB;AAE5B,EADA,MAAM,EAAQ,EACd,KAAK,OAAO;;GAID,IAAb,cAAwC,MAAM;CAC7C,YACC,GACA,GACA,GACC;AAED,EADA,MAAM,EAAQ,EAHL,KAAA,SAAA,GACA,KAAA,UAAA,GAGT,KAAK,OAAO;;GAID,KAAb,cAAqC,MAAM;CAC1C,YAAY,GAAiB;AAE5B,EADA,MAAM,EAAQ,EACd,KAAK,OAAO;;GCOR,KAAkB,EACtB,OAAO;CACP,QAAQ,EAAE,KAAK;EAAC;EAAO;EAAQ;EAAO,CAAC;CACvC,UAAU,EAAE,QAAQ,CAAC,IAAI,EAAE;CAC3B,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE;CACrB,CAAC,CACD,QAAQ,EAEJ,KAA4C,EAAE,MAAM,CAAC,EAAE,QAAQ,CAAC,IAAI,EAAE,EAAE,GAAgB,CAAC,EAEzF,KAAoB,EACxB,OAAO;CACP,aAAa,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,UAAU;CACzC,YAAY,EAAE,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,IAAI,KAAK,CAAC,UAAU;CACxD,QAAQ,EAAE,KAAK;EAAC;EAAU;EAAa;EAAc,CAAC,CAAC,UAAU;CACjE,CAAC,CACD,QAAQ,EAEJ,IAA8C,EAClD,OAAO;CACP,YAAY,EACV,OAAO;EACP,WAAW,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,UAAU;EACvC,UAAU,GAAkB,UAAU;EACtC,YAAY,EAAE,QAAQ,CAAC,KAAK,CAAC,UAAU;EACvC,kBAAkB,EAAE,QAAQ,CAAC,KAAK,CAAC,UAAU;EAC7C,kBAAkB,EAAE,QAAQ,CAAC,KAAK,CAAC,UAAU;EAC7C,CAAC,CACD,QAAQ,CACR,UAAU;CACZ,WAAW,EACT,OAAO;EACP,WAAW,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,UAAU;EACvC,WAAW,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,UAAU;EACvC,MAAM,EAAE,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,IAAI,GAAG,CAAC,UAAU;EAChD,UAAU,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,UAAU;EAC7C,QAAQ,EAAE,KAAK;GAAC;GAAU;GAAa;GAAc,CAAC,CAAC,UAAU;EACjE,aAAa,GAAkB,UAAU;EACzC,uBAAuB,EAAE,MAAM,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC;EAC7D,CAAC,CACD,QAAQ,CACR,UAAU;CACZ,YAAY,EACV,OAAO,EACP,OAAO,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,UAAU,EACnC,CAAC,CACD,QAAQ,CACR,UAAU;CACZ,SAAS,EACP,OAAO;EACP,MAAM,EAAE,KAAK,CAAC,oBAAoB,kBAAkB,CAAC,CAAC,UAAU;EAChE,oBAAoB,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,UAAU;EAChD,oBAAoB,EAAE,QAAQ,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,IAAI,IAAO,CAAC,UAAU;EACpE,CAAC,CACD,QAAQ,CACR,UAAU;CACZ,CAAC,CACD,QAAQ,EAoHG,IAAiD;CAC7D,MAAM,GAAgB;AACrB,SAAO,EAAgB,MAAM,KAAS,EAAE,CAAC;;CAE1C,UAAU,GAAgB;EACzB,IAAM,IAAS,EAAgB,UAAU,KAAS,EAAE,CAAC;AAIrD,SAHI,EAAO,UACH;GAAE,SAAS;GAAM,MAAM,EAAO;GAAM,GAErC;GACN,SAAS;GACT,OAAO,EACN,QAAQ,EAAO,MAAM,OAAO,KAAK,OAAW;IAC3C,MAAM,EAAM,KAAK,QAAQ,MAAwC,OAAO,KAAY,YAAY,OAAO,KAAY,SAAS;IAC5H,SAAS,EAAM;IACf,EAAE,EACH;GACD;;CAEF,YArIqC;EACrC,MAAM;EACN,sBAAsB;EACtB,YAAY;GACX,YAAY;IACX,MAAM;IACN,sBAAsB;IACtB,YAAY;KACX,WAAW,EAAE,MAAM,UAAU;KAC7B,UAAU,EACT,OAAO,CACN,EAAE,MAAM,UAAU,EAClB;MACC,MAAM;MACN,sBAAsB;MACtB,YAAY;OACX,QAAQ;QAAE,MAAM;QAAU,MAAM;SAAC;SAAO;SAAQ;SAAO;QAAE;OACzD,UAAU,EAAE,MAAM,UAAU;OAC5B,IAAI,EAAE,MAAM,UAAU;OACtB;MACD,UAAU;OAAC;OAAU;OAAY;OAAK;MACtC,CACD,EACD;KACD,YAAY;MAAE,MAAM;MAAU,QAAQ;MAAO;KAC7C,kBAAkB;MAAE,MAAM;MAAU,QAAQ;MAAO;KACnD,kBAAkB;MAAE,MAAM;MAAU,QAAQ;MAAO;KACnD;IACD;GACD,WAAW;IACV,MAAM;IACN,sBAAsB;IACtB,YAAY;KACX,WAAW,EAAE,MAAM,UAAU;KAC7B,WAAW,EAAE,MAAM,UAAU;KAC7B,MAAM;MAAE,MAAM;MAAW,SAAS;MAAG,SAAS;MAAI;KAClD,UAAU;MAAE,MAAM;MAAU,SAAS;MAAG,SAAS;MAAG;KACpD,QAAQ;MACP,MAAM;MACN,MAAM;OAAC;OAAU;OAAa;OAAc;MAC5C;KACD,aAAa;MACZ,MAAM;MACN,sBAAsB;MACtB,YAAY;OACX,aAAa,EAAE,MAAM,UAAU;OAC/B,YAAY;QAAE,MAAM;QAAW,SAAS;QAAG,SAAS;QAAM;OAC1D,QAAQ;QACP,MAAM;QACN,MAAM;SAAC;SAAU;SAAa;SAAc;QAC5C;OACD;MACD;KACD,uBAAuB;MACtB,MAAM;MACN,OAAO,EAAE,MAAM,UAAU;MACzB;KACD;IACD;GACD,YAAY;IACX,MAAM;IACN,sBAAsB;IACtB,YAAY,EACX,OAAO,EAAE,MAAM,UAAU,EACzB;IACD;GACD,SAAS;IACR,MAAM;IACN,sBAAsB;IACtB,YAAY;KACX,MAAM;MAAE,MAAM;MAAU,MAAM,CAAC,oBAAoB,kBAAkB;MAAE;KACvE,oBAAoB,EAAE,MAAM,UAAU;KACtC,oBAAoB;MAAE,MAAM;MAAW,SAAS;MAAK,SAAS;MAAO;KACrE;IACD;GACD;EACD;CA0DA,SAxD4B;EAC5B,wBAAwB;GACvB,OAAO;GACP,MAAM,kBAAkB,EAA0B;GAClD;EACD,uBAAuB;GACtB,OAAO;GACP,WAAW;GACX,MAAM,kBAAkB,EAAyB;GACjD;EACD,uBAAuB;GACtB,OAAO;GACP,MAAM,kBAAkB,EAAoB;GAC5C;EACD,uBAAuB;GACtB,OAAO;GACP,MAAM,kBAAkB,EAAwB;GAChD;EACD,kBAAkB;GACjB,OAAO;GACP,MAAM,kBAAkB,EAAoB;GAC5C;EACD,oBAAoB;GACnB,OAAO;GACP,MAAM,kBAAkB,EAAqB,OAAO,EAAwB;GAC5E;EACD,gBAAgB;GACf,OAAO;GACP,MAAM,kBAAkB,EAAiB,OAAO,GAAqB;GACrE;EACD,8BAA8B;GAC7B,OAAO;GACP,MAAM,kBAAkB,GAAmB;GAC3C;EACD;CAuBA;AAQD,SAAS,EAAoB,GAAG,GAA6C;AAC5E,QAAO,EAAO,MAAM,MAAU,MAAU,KAAA,EAAU;;AAGnD,SAAS,EAAY,GAAG,GAAuD;AAC9E,MAAK,IAAM,KAAS,EACnB,KAAI,KAAS,EAAM,MAAM,CAAC,SAAS,EAClC,QAAO,EAAM,MAAM;;AAMtB,SAAS,EAAW,GAAG,GAAuD;AAC7E,QAAO,EAAO,MAAM,MAAU,OAAO,KAAU,YAAY,OAAO,SAAS,EAAM,CAAC;;AAGnF,SAAS,GAA+B,GAAwC;AAC/E,QAAO,CAAC,GAAG,IAAI,KAAK,KAAU,EAAE,EAAE,KAAK,MAAU,EAAM,MAAM,CAAC,CAAC,OAAO,QAAQ,CAAC,CAAC;;AAGjF,SAAS,GAAsB,GAAsD;AACpF,QAAO,KAAA;;AAGR,SAAS,GAAkB,GAA4C;AACtE,QAAO,KAAA;;AAGR,SAAgB,EAAkB,GAAiC;AAClE,QAAO,EAAgB,MAAM,KAAS,EAAE,CAAC;;AAG1C,SAAgB,GAAkC,GAAyC;CAC1F,IAAM,IAAa,EAAoC,SAAS,UAAU;AAC1E,QAAO,EAAkB,KAAa,EAAE,CAAC;;AAG1C,eAAsB,EAAoB,GAKR;CACjC,IAAM,IAAS,EAAkB,EAAO,aAAa,EAC/C,IAAM,EAAO,OAAO,QAAQ,KAC5B,IAAiB,mBAAmB,KACpC,IAAY,EAAY,EAAO,YAAY,WAAW,EAAI,GAA2B;AAC3F,KAAI,CAAC,EACJ,OAAM,IAAI,EAAmB,sCAAsC,EAA0B,MAAM,EAAe,wBAAwB;CAG3I,IAAM,IAAc,MAAM,GAAyC;EAClE,QAAQ,EAAO;EACf;EACA,OAAO,EAAO,YAAY;EAC1B,MAAM,GAAG,EAAe;EACxB,uBAAuB;EACvB,oBAAoB,EAAI;EACxB,CAAC;AACF,KAAI,CAAC,EAAY,MAEhB,OAAM,IAAI,EAAmB,qCAAqC,EAAyB,MAAM,EAAe,uBADjG,EAAY,sBAAsB,IAAI,EAAY,wBAAwB,KACuD,MAAM,CAAC;CAGxJ,IAAM,IAAY,EAAY,EAAO,WAAW,WAAW,EAAI,GAAqB;AACpF,KAAI,CAAC,EACJ,OAAM,IAAI,EAAmB,qCAAqC,EAAoB,MAAM,EAAe,uBAAuB;CAGnI,IAAM,IAAa,EAAY,EAAO,YAAY,YAAY,EAAgC;AAC9F,KAAI,CAAC,EACJ,OAAM,IAAI,EACT,wCAAwC,EAAe,mCAAmC,EAAgC,kBAC1H;CAEF,IAAM,IAAiB,EAAY,EAAO,WAAW,WAAW,EAAI,GAAyB,EACvF,IAAO,EAAW,EAAO,WAAW,MAAM,EAAA,6BAA2B,OAAO,EAAI,GAAqB,GAAG,KAAA,EAAU,EAClH,IAAc,GAAkB,EAAiB,EAAO,SAAS,MAAM,EAAI,GAA6C,CAAC,EACzH,IAAqB,EAAY,EAAO,SAAS,oBAAoB,EAAA,kCAAwB,IAAI,EAAK,aAAA,+BAAwB,uBAAuB,EAErJ,IAAc,EAAO,iBAAiB,MAAkB,IACxD,IAAQ,EAAY,EAAO,YAAY,OAAO,EAAI,IAAuB,EAAwB;AACvG,KAAI,CAAC,EACJ,OAAM,IAAI,EAAmB,2CAA2C,EAAqB,MAAM,EAAe,oBAAoB;CAEvI,IAAM,KAAqB,EAAW,EAAO,SAAS,mBAAmB,IAAA,KACnE,IAAW,EAAW,EAAO,WAAW,SAAS,IAAA,GACjD,IAAS,GAAsB,EAAiB,EAAO,WAAW,QAAQ,EAAO,WAAW,aAAa,OAAO,CAAC;AAEvH,QAAO;EACN;EACA,UAAU,EAAY;EACtB;EACA,kBAAkB,EAAY,EAAO,YAAY,iBAAiB,IAAI,GAAG,EAAW,YAAY,EAAU;EAC1G,kBAAkB,EAAY,EAAO,YAAY,iBAAiB,IAAI,GAAG,EAAW,YAAY,EAAU,wBAAwB;EAClI;EACA;EACA,MAAM,KAAA;EACN;EACA;EACA;EACA;EACA,oBAAoB,EAAY,EAAmB;EACnD;EACA,uBAAuB,GAA+B,EAAO,WAAW,sBAAsB;EAC9F,aAAa;GACZ,aAAa,EAAO,WAAW,aAAa,eAAA;GAC5C,YAAY,EAAO,WAAW,aAAa;GAC3C;GACA;EACD;;;;AC7UF,SAAS,EAAgB,GAAoE,GAA0B;AAKtH,QAJgB,GAAU,QACvB,KAAK,MAAU,EAAM,QAAQ,CAC9B,OAAO,QAAQ,CACf,KAAK,KAAK,IACM;;AAGnB,SAAgB,GAA0B,GAAyB;AAClE,QAAO,aAAiB,KAAsB,EAAM,WAAW;;AAGhE,eAAsB,EAAqB,GAM5B;CACd,IAAM,IAAU,IAAI,QAAQ,EAAO,QAAQ;AAE3C,CADA,EAAQ,IAAI,iBAAiB,UAAU,EAAO,WAAW,EACrD,CAAC,EAAQ,IAAI,eAAe,IAAI,EAAO,QAC1C,EAAQ,IAAI,gBAAgB,mBAAmB;CAGhD,IAAM,IAAW,MAAM,MAAM,EAAO,KAAK;EACxC,QAAQ,EAAO,WAAW,EAAO,OAAO,SAAS;EACjD;EACA,MAAM,EAAO;EACb,CAAC,EAEI,IAAU,MAAM,EAAS,MAAM,EAC/B,IAAS,IAAW,KAAK,MAAM,EAAQ,GAAqC,KAAA;AAClF,KAAI,CAAC,EAAS,GACb,OAAM,IAAI,EAAmB,EAAgB,GAAQ,kCAAkC,EAAS,OAAO,GAAG,EAAE,EAAS,QAAQ,EAAO;AAErI,KAAI,CAAC,GAAQ,QACZ,OAAM,IAAI,EAAmB,EAAgB,GAAQ,6BAA6B,EAAE,EAAS,QAAQ,EAAO;AAG7G,QAAO,EAAO;;;;ACvCf,SAAS,EAAc,GAAmB,GAAoB;AAC7D,QAAO,GAAG,EAAU,IAAI;;AAGzB,eAAe,EAAU,GAA2C;AACnE,KAAI;EACH,IAAM,IAAM,MAAM,EAAS,GAAM,OAAO;AACxC,SAAO,KAAK,MAAM,EAAI;SACf;AACP,SAAO;GACN,SAAS;GACT,SAAS,EAAE;GACX;;;AAIH,IAAa,KAAb,MAA4B;CAC3B,YAAY,GAA+B;AAAd,OAAA,OAAA;;CAE7B,IAAI,WAAmB;AACtB,SAAO,KAAK;;CAGb,MAAM,OAAO,GAAwC;EACpD,IAAM,IAAQ,MAAM,EAAU,KAAK,KAAK;AAGxC,EAFA,EAAM,QAAQ,EAAc,EAAO,WAAW,EAAO,GAAG,IAAI,GAC5D,MAAM,EAAM,EAAQ,KAAK,KAAK,EAAE,EAAE,WAAW,IAAM,CAAC,EACpD,MAAM,EAAU,KAAK,MAAM,KAAK,UAAU,GAAO,MAAM,EAAE,EAAE,OAAO;;CAGnE,MAAM,IAAI,GAAmB,GAA6C;AAEzE,UADc,MAAM,EAAU,KAAK,KAAK,EAC3B,QAAQ,EAAc,GAAW,EAAG,KAAK;;CAGvD,MAAM,OAAO,GAAmB,GAA2B;EAC1D,IAAM,IAAQ,MAAM,EAAU,KAAK,KAAK;AAGxC,EAFA,OAAO,EAAM,QAAQ,EAAc,GAAW,EAAG,GACjD,MAAM,EAAM,EAAQ,KAAK,KAAK,EAAE,EAAE,WAAW,IAAM,CAAC,EACpD,MAAM,EAAU,KAAK,MAAM,KAAK,UAAU,GAAO,MAAM,EAAE,EAAE,OAAO;;CAGnE,MAAM,QAAuB;AAC5B,QAAM,EAAG,KAAK,MAAM,EAAE,OAAO,IAAM,CAAC;;;;;ACjDtC,eAAsB,GAAU,GAAoG;CACnI,IAAM,IAAwB,EAAE;AAEhC,GAAO,KAAK;EACX,MAAM;EACN,QAAQ;EACR,SAAS,4BAA4B,EAAO,QAAQ,OAAO,UAAU,uBAAuB,EAAO,QAAQ,OAAO,UAAU;EAC5H,CAAC;CAEF,IAAM,IAAc,MAAM,EAAO,QAAQ,kBAAkB,EAAO,qBAAqB;AACvF,GAAO,KAAK;EACX,MAAM;EACN,QAAQ;EACR,SAAS,EAAY,UAClB,4BAA4B,EAAO,QAAQ,OAAO,UAAU,SAAS,EAAY,WAAW,gBAC5F,oBAAoB,EAAO,QAAQ,OAAO,UAAU;EACvD,CAAC;CAEF,IAAM,IAAsB,MAAM,EAAO,QAAQ,WAAW,iBAAiB;AA+B7E,QA9BA,EAAO,KAAK;EACX,MAAM;EACN,QAAQ;EACR,SAAS,oBAAoB,EAAO,QAAQ,OAAO,MAAM,YAAY,EAAoB;EACzF,CAAC,EAEE,MAAwB,EAAY,aAOvC,EAAO,KAAK;EACX,MAAM;EACN,QAAQ;EACR,SAAS;EACT,CAAC,GAVF,EAAO,KAAK;EACX,MAAM;EACN,QAAQ;EACR,SAAS,yBAAyB,EAAoB,iDAAiD,EAAY,WAAW;EAC9H,CAAC,EASH,EAAO,KAAK;EACX,MAAM;EACN,QAAQ,EAAO,QAAQ,OAAO,sBAAsB,SAAS,IAAI,SAAS;EAC1E,SACC,EAAO,QAAQ,OAAO,sBAAsB,SAAS,IAClD,2CAA2C,EAAO,QAAQ,OAAO,sBAAsB,KAAK,KAAK,CAAC,KAClG;EACJ,CAAC,EAGK;EAAE,IADE,EAAO,OAAO,MAAU,EAAM,WAAW,OAAO;EAC9C;EAAQ;;;;AC1CtB,IAAa,KAAb,MAAuC;CACtC,YAAY,GAA+C;AAA9B,OAAA,SAAA;;CAE7B,MAAM,WAAW,GAAiC;EACjD,IAAM,CAAC,KAAa,MAAM,KAAK,WAAW,CAAC,EAAK,CAAC;AACjD,SAAO;;CAGR,MAAM,WAAW,GAAsC;AAatD,SAZI,EAAM,WAAW,IACb,EAAE,GAWH,CAAC,IATS,MAAM,EAA2C;GACjE,KAAK,GAAG,KAAK,OAAO,iBAAiB;GACrC,UAAU,KAAK,OAAO;GACtB,MAAM,KAAK,UAAU;IACpB,OAAO,KAAK,OAAO;IACnB,OAAO;IACP,CAAC;GACF,CAAC,EAEkB,KAAK,CAAC,MAAM,GAAM,MAAU,EAAK,QAAQ,EAAM,MAAM,CAAC,KAAK,MAAU,EAAM,UAAU;;CAG1G,MAAM,kBAAmC;AAExC,UADkB,MAAM,KAAK,WAAW,kCAAkC,EACzD;;;;;ACtBnB,SAAS,GAAoB,GAAqB;CACjD,IAAM,IAAY,EAAI,MAAM,CAAC,QAAQ,UAAU,IAAI,CAAC,QAAQ,QAAQ,IAAI;AAOxE,QANK,IAGD,EAAU,WAAA,MAAoC,GAC1C,QAAQ,MAET,IALC;;AAQT,SAAS,GAAiB,GAAoF;AAC7G,KAAI,CAAC,EACJ,QAAO,EAAE;CAEV,IAAM,IAAU,OAAO,QAAQ,EAAS,CAAC,QAAQ,GAAG,OAAW;EAAC;EAAU;EAAU;EAAU,CAAC,SAAS,OAAO,EAAM,CAAC;AACtH,QAAO,OAAO,YAAY,EAAQ,KAAK,CAAC,GAAK,OAAW,CAAC,GAAoB,EAAI,EAAE,EAAM,CAAC,CAAC;;AAG5F,SAAgB,GAAc,GAAmB,GAA2B;AAC3E,QAAO,GAAG,EAAU,IAAI;;AAGzB,SAAgB,EAAiB,GAAmB,GAA2B;AAC9E,QAAO,GAAG,EAAU,GAAG,EAAU;;AAGlC,SAAgB,GAAiB,GAA+D;CAE/F,IAAM,IADa,EAAK,QAAQ,OAAO,IAAI,CAAC,QAAQ,OAAO,GAAG,CAClC,MAAM,IAAI;AAItC,QAHI,EAAS,WAAW,KAAK,CAAC,EAAS,GAAG,SAAS,MAAM,GACjD,OAED;EACN,WAAW,EAAS;EACpB,WAAW,EAAS,GAAG,MAAM,GAAG,GAAG;EACnC;;AAGF,SAAgB,GAAa,GAAc,GAAuB;CACjE,IAAM,IAAa,EAAK,MAAM,CAAC,QAAQ,QAAQ,IAAI;AACnD,KAAI,CAAC,EACJ,QAAO;CAGR,IAAM,IADQ,EAAW,aAAa,CAClB,QAAQ,EAAM,MAAM,CAAC,aAAa,CAAC;AACvD,KAAI,MAAU,GACb,QAAO,EAAW,MAAM,GAAG,IAAI;CAEhC,IAAM,IAAQ,KAAK,IAAI,GAAG,IAAQ,GAAG,EAC/B,IAAM,KAAK,IAAI,EAAW,QAAQ,IAAQ,KAAK,IAAI,EAAM,QAAQ,GAAG,GAAG,GAAG;AAChF,QAAO,EAAW,MAAM,GAAO,EAAI;;AAGpC,SAAgB,GAAmB,GAMjC;CACD,IAAM,IAAY,EAAO,MAAM,IAAI,MAAM,IAAI,GAAY,EACnD,IAAW,GAAc,EAAO,WAAW,EAAU,EACrD,qBAAM,IAAI,MAAM,EAAC,aAAa,EAC9B,IAAe,GAAiB,EAAO,MAAM,SAAS,EACtD,IAA8C;EACnD,GAAG;GACF,EAAuB,YAAY;GACnC,EAAuB,cAAc,EAAO,OAAO;GACnD,EAAuB,YAAY;GACnC,EAAuB,YAAY;EACpC;AAKD,CAHI,EAAO,MAAM,UAChB,EAAa,EAAuB,SAAS,EAAO,MAAM,QAEvD,EAAO,MAAM,WAChB,EAAa,EAAuB,UAAU,EAAO,MAAM;CAG5D,IAAI;AACJ,KAAI,EAAO,OAAO,gBAAgB,oBAAoB;EACrD,IAAM,IAAa,GAAO,WAAW,EAAO,MAAM,MAAM,OAAO;AAC/D,MAAI,IAAa,EAAO,OAAO,mBAC9B,OAAM,IAAI,GACT,kBAAkB,EAAW,qDAAqD,EAAO,OAAO,mBAAmB,wEACnH;AAEF,IAAa,EAAuB,QAAQ,EAAO,MAAM;QACnD;EACN,IAAM,IAAU,EAAiB,EAAO,WAAW,EAAU;AAE7D,EADA,EAAa,EAAuB,WAAW,GAC/C,IAAkB;GACjB,IAAI;GACJ,WAAW,EAAO;GAClB,OAAO,EAAO,MAAM;GACpB,MAAM,EAAO,MAAM;GACnB,UAAU;GACV,QAAQ,EAAO,MAAM;GACrB,WAAW;GACX,WAAW;GACX;;AAGF,QAAO;EACN;EACA;EACA,MAAM,EAAiB,EAAO,WAAW,EAAU;EACnD,QAAQ;GACP,IAAI;GACJ,WAAW,EAAO;GAClB,QAAQ,EAAO;GACf,UAAU;GACV;EACD;EACA;;AAGF,SAAgB,GAAoB,GAGlC;CACD,IAAM,IAAW,EAAM,YAAY,EAAE,EAC/B,IACL,EAAM,cAAc,OAAO,EAAS,EAAuB,YAAa,WAAW,OAAO,EAAS,EAAuB,SAAS,CAAC,MAAM,IAAI,CAAC,KAAK,SAC/I,IACL,OAAO,EAAS,EAAuB,cAAe,WAAW,OAAO,EAAS,EAAuB,WAAW,GAAG,OAAO,EAAM,MAAM,GAAG,EACvI,IAAe,OAAO,YAAY,OAAO,QAAQ,EAAS,CAAC,QAAQ,CAAC,OAAS,CAAC,EAAI,WAAA,MAAoC,CAAC,CAAC;AAC9H,QAAO;EACN;EACA,UAAU,OAAO,EAAM,MAAM,EAAU;EACvC;EACA,OAAO,OAAO,EAAS,EAAuB,UAAW,WAAW,OAAO,EAAS,EAAuB,OAAO,GAAG,KAAA;EACrH,MAAM,OAAO,EAAS,EAAuB,SAAU,WAAW,OAAO,EAAS,EAAuB,MAAM,GAAG,KAAA;EAClH,UAAU;EACV,QAAQ,OAAO,EAAS,EAAuB,WAAY,WAAW,OAAO,EAAS,EAAuB,QAAQ,GAAG,KAAA;EACxH,WAAW,OAAO,EAAS,EAAuB,cAAe,WAAW,OAAO,EAAS,EAAuB,WAAW,GAAG,KAAA;EACjI,WAAW,OAAO,EAAS,EAAuB,cAAe,WAAW,OAAO,EAAS,EAAuB,WAAW,GAAG,KAAA;EACjI,MAAM,EAAiB,GAAW,EAAU;EAC5C;;;;AC7IF,IAAa,KAAb,MAA6B;CAC5B,YAAY,GAA+C;AAA9B,OAAA,SAAA;;CAE7B,MAAM,gBAAoD;AACzD,SAAO,EAA6C;GACnD,KAAK,KAAK,OAAO;GACjB,UAAU,KAAK,OAAO;GACtB,QAAQ;GACR,CAAC;;CAGH,MAAM,YAAY,GAAoB,IAAS,KAAK,OAAO,YAAY,QAA4C;AAClH,SAAO,EAA6C;GACnD,KAAK,GAAG,KAAK,OAAO,WAAW,YAAY,KAAK,OAAO,UAAU;GACjE,UAAU,KAAK,OAAO;GACtB,MAAM,KAAK,UAAU;IACpB,MAAM,KAAK,OAAO;IAClB,aAAa,KAAK,OAAO,YAAY;IACrC,QAAQ;KACP;KACA;KACA;IACD,CAAC;GACF,CAAC;;CAGH,MAAM,OAAO,GAAyD;EACrE,IAAM,IAAO,EAAQ,KAAK,MAAW,KAAK,UAAU,EAAO,CAAC,CAAC,KAAK,KAAK;AASvE,UARe,MAAM,EAAoC;GACxD,KAAK,GAAG,KAAK,OAAO,iBAAiB;GACrC,UAAU,KAAK,OAAO;GACtB,SAAS,EACR,gBAAgB,wBAChB;GACD;GACA,CAAC,EACY;;CAGf,MAAM,MAAM,GAMuB;AAYlC,UAXe,MAAM,EAAiC;GACrD,KAAK,GAAG,KAAK,OAAO,iBAAiB;GACrC,UAAU,KAAK,OAAO;GACtB,MAAM,KAAK,UAAU;IACpB,QAAQ,EAAO;IACf,MAAM,EAAO,QAAQ,KAAK,OAAO;IACjC,QAAQ,EAAO;IACf,WAAW,EAAO;IAClB,cAAc,EAAO,gBAAgB;IACrC,CAAC;GACF,CAAC,EACY,WAAW,EAAE;;CAG5B,MAAM,SAAS,GAA+C;AAI7D,SAHI,EAAI,WAAW,IACX,EAAE,GAEH,EAAyC;GAC/C,KAAK,GAAG,KAAK,OAAO,iBAAiB;GACrC,UAAU,KAAK,OAAO;GACtB,MAAM,KAAK,UAAU,EAAE,QAAK,CAAC;GAC7B,CAAC;;CAGH,MAAM,YAAY,GAA4C;AACzD,QAAI,WAAW,EAQnB,SALe,MAAM,EAAoC;GACxD,KAAK,GAAG,KAAK,OAAO,iBAAiB;GACrC,UAAU,KAAK,OAAO;GACtB,MAAM,KAAK,UAAU,EAAE,QAAK,CAAC;GAC7B,CAAC,EACY;;GC1EH,KAAb,MAAqC;CACpC;CACA;CACA;CAEA,YACC,GACA,GACC;AAGD,EALS,KAAA,SAAA,GACA,KAAA,iBAAA,GAET,KAAK,aAAa,IAAI,GAA0B,EAAO,EACvD,KAAK,YAAY,IAAI,GAAgB,EAAO,EAC5C,KAAK,iBAAiB,IAAI,GAAe,EAAO,mBAAmB;;CAGpE,iBAAiB,GAAsG;AACtH,SAAO,GAAwB;GAC9B,gBAAgB,EAAO,aAAa,KAAK,OAAO;GAChD,YAAY,EAAO;GACnB,SAAS,EAAO;GAChB,cAAc,EAAO;GACrB,CAAC;;CAGH,MAAM,OAAO,GASgD;EAC5D,IAAM,IAAY,KAAK,iBAAiB,EAAO,EACzC,IAAS,MAAM,KAAK,WAAW,WAAW,EAAO,MAAM,EACvD,IAAU,MAAM,KAAK,UAAU,MAAM;GAC1C;GACA;GACA,MAAM,EAAO,cAAc,KAAK,OAAO;GACvC,QAAQ,EAAO;GACf,CAAC;AAcF,UAZiB,MAAM,QAAQ,IAC9B,EAAQ,IAAI,OAAO,MAAU;GAC5B,IAAM,IAAO,GAAoB,EAAM,EACjC,IAAO,EAAK,SAAS,MAAM,KAAK,eAAe,IAAI,EAAK,WAAW,EAAK,UAAU,GAAG,QAAQ;AACnG,UAAO;IACN,GAAG;IACH;IACA,OAAO,EAAM,SAAS;IACtB;IACA,CACF,EAEe,QAAQ,MAAW,EAAO,UAAU,EAAO,YAAY,KAAK,OAAO,UAAU;;CAG9F,MAAM,IAAI,GAAgJ;EAEzJ,IAAM,IAAW,GADC,KAAK,iBAAiB,EAAO,CACjB,IAAI,EAAO,MACnC,CAAC,KAAS,MAAM,KAAK,UAAU,SAAS,CAAC,EAAS,CAAC;AACzD,MAAI,CAAC,EACJ,QAAO;EAER,IAAM,IAAO,GAAoB,EAAM,EACjC,IAAY,MAAM,KAAK,eAAe,IAAI,EAAK,WAAW,EAAK,UAAU;AAC/E,SAAO;GACN,GAAG;GACH,MAAM,EAAK,QAAQ,GAAW,QAAQ;GACtC;;CAGF,MAAM,OAAO,GAAmI;EAC/I,IAAM,IAAY,KAAK,iBAAiB;GACvC,WAAW,EAAO,MAAM;GACxB,YAAY,EAAO;GACnB,SAAS,EAAO;GAChB,cAAc,EAAO;GACrB,CAAC,EACI,IAAY,MAAM,KAAK,WAAW,WAAW,EAAO,MAAM,KAAK,EAC/D,IAAS,GAAmB;GACjC,OAAO,EAAO;GACd;GACA;GACA,QAAQ,KAAK;GACb,CAAC;AAEF,EAAI,EAAO,mBACV,MAAM,KAAK,eAAe,OAAO,EAAO,gBAAgB;EAGzD,IAAM,IAAa,MAAM,KAAK,UAAU,OAAO,CAAC,EAAO,OAAO,CAAC;AAM/D,SAAO;GACN,GANgB,MAAM,KAAK,IAAI;IAC/B,IAAI,EAAO;IACX;IACA,CAAC,IAGe,KAAK,sBAAsB,EAAO,iBAAiB,EAAO,WAAW,GAAW,EAAO,KAAK;GAC5G;GACA;;CAGF,MAAM,OAAO,GAAuI;EACnJ,IAAM,IAAY,KAAK,iBAAiB,EAAO;AAE/C,SADA,MAAM,KAAK,eAAe,OAAO,GAAW,EAAO,GAAG,EAC/C,KAAK,UAAU,YAAY,CAAC,GAAG,EAAU,IAAI,EAAO,KAAK,CAAC;;CAGlE,MAAM,OAAO,GAAoE;AAChF,SAAO,GAAU;GAChB,SAAS;GACT,sBAAsB,EAAQ,wBAAwB;GACtD,CAAC;;CAGH,MAAM,kBAAkB,GAA6E;AACpG,MAAI;AAEH,UAAO;IACN,SAAS;IACT,aAHmB,MAAM,KAAK,UAAU,eAAe,EAG/B,OAAO;IAC/B;WACO,GAAO;AACf,OAAI,CAAC,KAAmB,CAAC,GAA0B,EAAM,CACxD,OAAM;GAEP,IAAM,IAAa,KAAK,OAAO,YAAY,cAAe,MAAM,KAAK,WAAW,iBAAiB;AAEjG,UADA,MAAM,KAAK,UAAU,YAAY,EAAW,EACrC;IACN,SAAS;IACT;IACA;;;CAIH,sBAA8B,GAA8C,GAAmB,GAAmB,GAAoC;AACrJ,SAAO;GACN;GACA,UAAU,GAAG,EAAU,IAAI;GAC3B;GACA,OAAO,GAAiB;GACxB,MAAM,GAAiB,QAAQ;GAC/B,UAAU,GAAiB,YAAY,EAAE;GACzC,QAAQ,GAAiB;GACzB,WAAW,GAAiB;GAC5B,WAAW,GAAiB;GAC5B;GACA;;;;;AClKH,eAAsB,EAA8B,GAKf;AAEpC,QAAO,IAAI,GADM,MAAM,EAAoB,EAAO,EACL,EAAO,eAAe;;;;ACIpE,SAAS,EAAU,GAAsB;AACxC,SAAQ,IAAI,KAAK,UAAU,GAAO,MAAM,EAAE,CAAC;;AAG5C,SAAS,GAAkB,GAAkF;AAC5G,KAAI,CAAC,EACJ;CAED,IAAM,IAAS,KAAK,MAAM,EAAM;AAChC,KAAI,CAAC,KAAU,OAAO,KAAW,YAAY,MAAM,QAAQ,EAAO,CACjE,OAAU,MAAM,oCAAoC;AAErD,QAAO;;AAGR,SAAS,GAAgB,GAAuD;AAC/E,KAAI,CAAC,EACJ;CAED,IAAM,IAAS,KAAK,MAAM,EAAM;AAChC,KAAI,CAAC,KAAU,OAAO,KAAW,YAAY,MAAM,QAAQ,EAAO,CACjE,OAAU,MAAM,kCAAkC;AAEnD,QAAO;;AAGR,SAAS,GAAa,GAAqC;AAC1D,QAAO,EAAQ,KAAU,OAAO,KAAU,YAAY,OAAQ,EAAqB,QAAS;;AAG7F,SAAS,GAAkB,GAA+E;CACzG,IAAM,IAAe,EAAK,GAAG,GAAG;AAOhC,QANK,GAAa,EAAa,GAMxB;EACN,aAAa,EAAK,MAAM,GAAG,GAAG;EAC9B,SAAS,EAAa,QAAQ,IAAI,EAAE;EACpC,GARO;EACN,aAAa;EACb,SAAS,EAAE;EACX;;AAQH,SAAS,GAAuB,GAAwD;AACnF,WAAU,KAAA,GAGd;MAAI,MAAU,eAAe,MAAU,UAAU,MAAU,OAC1D,QAAO;AAER,QAAU,MAAM,gDAAgD;;;AAGjE,SAAgB,GACf,GAGA,GAKO;CACP,IAAM,IAAO,EAAQ,QAAQ,YAAY,CAAC,YAAY,oCAAoC;CAE1F,SAAS,EAAe,GAA0C;AACjE,SAAO,GAAkB,EAAK,CAAC;;AAyGhC,CAtGA,EACE,QAAQ,SAAS,CACjB,YAAY,mDAAmD,CAC/D,OAAO,kBAAkB,yCAAyC,CAClE,OAAO,UAAU,gCAAgC,CACjD,OAAO,OAAO,GAAG,MAAS;EAC1B,IAAM,IAAU,EAAe,EAAK,EAO9B,IAAS,OANC,MAAM,EAA8B;GACnD,cAAc,EAAO;GACrB,gBAAgB,EAAO;GACvB,KAAK,QAAQ;GACb,aAAa,EAAO;GACpB,CAAC,EAC2B,OAAO,EACnC,sBAAsB,EAAQ,EAAQ,aACtC,CAAC;AACF,MAAI,EAAQ,KACX,GAAU,EAAO;MAEjB,MAAK,IAAM,KAAS,EAAO,OAC1B,SAAQ,IAAI,IAAI,EAAM,OAAO,IAAI,EAAM,KAAK,IAAI,EAAM,UAAU;AAGlE,EAAK,EAAO,OACX,QAAQ,WAAW;GAEnB,EAEH,EACE,QAAQ,SAAS,CACjB,YAAY,mCAAmC,CAC/C,SAAS,WAAW,yBAAyB,CAC7C,OAAO,2BAA2B,+BAA+B,CACjE,OAAO,mBAAmB,6BAA6B,CACvD,OAAO,mBAAmB,iCAAiC,CAC3D,OAAO,OAAO,GAAO,MAAS;EAC9B,IAAM,IAAU;AAahB,IANgB,OANA,MAAM,EAA8B;GACnD,cAAc,EAAO;GACrB,gBAAgB,EAAO;GACvB,KAAK,QAAQ;GACb,aAAa,EAAO;GACpB,CAAC,EAC4B,OAAO;GACpC,OAAO,OAAO,EAAM;GACpB,WAAW,EAAQ;GACnB,YAAY,EAAQ,QAAQ,OAAO,EAAQ,MAAM,GAAG,KAAA;GACpD,QAAQ,GAAgB,EAAQ,OAA6B;GAC7D,CAAC,CACgB;GACjB,EAEH,EACE,QAAQ,SAAS,CACjB,YAAY,oCAAoC,CAChD,SAAS,UAAU,eAAe,CAClC,OAAO,aAAa,qBAAqB,CACzC,OAAO,mBAAmB,kBAAkB,CAC5C,OAAO,2BAA2B,+BAA+B,CACjE,OAAO,qBAAqB,yBAAyB,CACrD,OAAO,qBAAqB,iCAAiC,CAC7D,OAAO,OAAO,GAAM,MAAS;EAC7B,IAAM,IAAU;AAiBhB,IAVe,OANC,MAAM,EAA8B;GACnD,cAAc,EAAO;GACrB,gBAAgB,EAAO;GACvB,KAAK,QAAQ;GACb,aAAa,EAAO;GACpB,CAAC,EAC2B,OAAO,EACnC,OAAO;GACN,IAAI,EAAQ;GACZ,OAAO,EAAQ;GACf,MAAM,OAAO,EAAK;GAClB,WAAW,EAAQ;GACnB,QAAQ,EAAQ;GAChB,UAAU,GAAkB,EAAQ,SAA+B;GACnE,EACD,CAAC,CACe;GAChB,EAEH,EACE,QAAQ,SAAS,CACjB,YAAY,0BAA0B,CACtC,SAAS,QAAQ,4BAA4B,CAC7C,OAAO,2BAA2B,+BAA+B,CACjE,OAAO,OAAO,GAAI,MAAS;EAC3B,IAAM,IAAU;AAWhB,IAAU;GAAE;GAAI,YAJG,OANH,MAAM,EAA8B;IACnD,cAAc,EAAO;IACrB,gBAAgB,EAAO;IACvB,KAAK,QAAQ;IACb,aAAa,EAAO;IACpB,CAAC,EAC+B,OAAO;IACvC,IAAI,OAAO,EAAG;IACd,WAAW,EAAQ;IACnB,CAAC;GAC0B,CAAC;GAC5B,EAEH,EACE,QAAQ,UAAU,CAClB,YAAY,4DAA4D,CACxE,SAAS,gBAAgB,8GAA8G,CACvI,OAAO,sBAAsB,sFAAsF,CACnH,OAAO,2BAA2B,6BAA6B,CAC/D,OAAO,gCAAgC,qGAAqG,CAC5I,OAAO,0BAA0B,gDAAgD,CACjF,OAAO,kBAAkB,yCAAyC,CAClE,OAAO,aAAa,8CAA8C,CAClE,OAAO,UAAU,gCAAgC,CACjD,OAAO,OAAO,GAAG,MAAS;EAC1B,IAAM,EAAE,gBAAa,eAAY,GAAkB,EAAK,EAClD,IAAa,EAAY,IACzB,IACL,EAAY,WAAW,IACpB,EAAE,GACF,MAAM,QAAQ,EAAW,GACxB,EAAW,KAAK,MAAU,OAAO,EAAM,CAAC,GACxC,EAAY,KAAK,MAAU,OAAO,EAAM,CAAC,EAOxC,IAAU,MAAM,GAA6B;GAClD,SAPe,MAAM,EAA8B;IACnD,cAAc,EAAO;IACrB,gBAAgB,EAAO;IACvB,KAAK,QAAQ;IACb,aAAa,EAAO;IACpB,CAAC;GAGD,SAAS;IACR;IACA,cAAc,EAAQ;IACtB,WAAW,EAAQ;IACnB,mBAAmB,EAAQ,0BAA0B,SAAS;IAC9D,mBAAmB,GAAuB,EAAQ,SAAS;IAC3D,QAAQ,EAAQ,EAAQ;IACxB,sBAAsB,EAAQ,EAAQ;IACtC;GACD,CAAC;AAMF,EALI,EAAQ,OACX,EAAU,EAAQ,GAElB,QAAQ,IAAI,GAAuB,EAAQ,CAAC,EAEzC,EAAQ,SAAS,MACpB,QAAQ,WAAW;GAEnB;;;;ACvOJ,IAAa,MAAkD,EAAE,wBAAqB;CACrF,IAAM,IAAQ,CACb,+FACA,8HACA;AASD,QAPI,EAAe,IAAI,2BAA2B,IACjD,EAAM,KAAK,8FAA8F,EAEtG,EAAe,IAAI,2BAA2B,IACjD,EAAM,KAAK,sGAAsG,EAG3G;;;;ACVR,SAAgB,GAA8B,GAAuB,GAA8E;AAClJ,QAAO,EACN,MAAM,cAAc,EAAE,UAA8C;EAOnE,IAAM,KANU,MAAM,EAA8B;GACnD;GACA,gBAAgB;GAChB,KAAK,QAAQ;GACb;GACA,CAAC,EACqB;AACvB,MAAI;AACH,SAAM,EAAO,EAAO,mBAAmB;UAChC;AACP,UAAO,EAAE;;AAEV,SAAO,CACN;GACC,MAAM;GACN,cAAc,EAAQ,EAAO,mBAAmB;GAChD,cAAc,EAAO,mBAAmB,MAAM,QAAQ,CAAC,GAAG,GAAG,IAAI;GACjE,cAAc,EAAO;GACrB,UAAU,EAAE;GACZ,aAAa;GACb,CACD;IAEF;;;;ACtBF,IAAa,KAAb,MAA0E;CACzE,YACC,GACA,GACC;AADgB,EADA,KAAA,UAAA,GACA,KAAA,UAAA;;CAGlB,MAAM,OAAO,GAAe,GAAuG;AASlI,UARgB,MAAM,KAAK,QAAQ,OAAO;GACzC;GACA,YAAY,GAAM;GAClB,UAAU,GAAM;GAChB,YAAY,GAAM;GAClB,SAAS,KAAK;GACd,CAAC,EAEa,KAAK,OAAY;GAC/B,MAAM,EAAO;GACb,WAAW;GACX,SAAS,KAAK,IAAI,GAAG,EAAO,KAAK,MAAM,QAAQ,CAAC,OAAO;GACvD,OAAO,EAAO;GACd,SAAS,GAAa,EAAO,MAAM,EAAM;GACzC,QAAQ;GACR,UAAU,EAAO;GACjB,EAAE;;CAGJ,MAAM,SAAS,GAAqG;EACnH,IAAM,IAAS,GAAiB,EAAO,QAAQ;AAC/C,MAAI,CAAC,EACJ,OAAU,MAAM,mCAAmC,EAAO,UAAU;EAErE,IAAM,IAAS,MAAM,KAAK,QAAQ,IAAI;GACrC,IAAI,EAAO;GACX,WAAW,EAAO;GAClB,SAAS,KAAK;GACd,CAAC;AACF,MAAI,CAAC,EACJ,OAAU,MAAM,+BAA+B,EAAO,UAAU;EAGjE,IAAM,IAAO,KAAK,IAAI,GAAG,EAAO,QAAQ,EAAE,EACpC,IAAQ,KAAK,IAAI,GAAG,EAAO,SAAS,EAAO,KAAK,MAAM,QAAQ,CAAC,OAAO;AAK5E,SAAO;GACN,MALgB,EAAO,KACtB,MAAM,QAAQ,CACd,MAAM,IAAO,GAAG,IAAO,IAAI,EAAM,CACjC,KAAK,KAAK;GAGX,MAAM,EAAO;GACb;;CAGF,SAA+B;AAC9B,SAAO;GACN,SAAS;GACT,UAAU;GACV,OAAO,KAAK,QAAQ,OAAO;GAC3B,cAAc,KAAK,QAAQ,OAAO;GAClC,QAAQ;IACP,WAAW,KAAK,QAAQ,OAAO;IAC/B,aAAa,KAAK,QAAQ,OAAO;IACjC,gBAAgB,KAAK,QAAQ,OAAO;IACpC;GACD;;CAGF,MAAM,6BAAkE;AACvE,MAAI;AAEH,UADA,MAAM,KAAK,QAAQ,WAAW,iBAAiB,EACxC,EAAE,IAAI,IAAM;WACX,GAAO;AACf,UAAO;IACN,IAAI;IACJ,OAAO,aAAiB,QAAQ,EAAM,UAAU;IAChD;;;CAIH,MAAM,0BAA4C;AACjD,MAAI;AAEH,UADA,MAAM,KAAK,QAAQ,UAAU,eAAe,EACrC;UACA;AACP,UAAO;;;CAIT,MAAM,QAAuB;;;;AC3F9B,SAAgB,GAAoB,GAAiG;CACpI,IAAM,oBAAW,IAAI,KAA4C;CAEjE,eAAe,EAAmB,GAAgC,GAAyD;EAC1H,IAAM,IAAU,MAAM,EAA8B;GACnD,cAAc,EAAO;GACrB;GACA,KAAK,QAAQ;GACb,aAAa,EAAO;GACpB,CAAC,EACI,IAAM,GAAG,EAAQ,IAAI,EAAQ,OAAO,UAAU,IAAI,EAAQ,OAAO,eACjE,IAAW,EAAS,IAAI,EAAI;AAClC,MAAI,EACH,QAAO;EAER,IAAM,IAAU,IAAI,GAA8B,GAAS,EAAQ;AAEnE,SADA,EAAS,IAAI,GAAK,EAAQ,EACnB;;AAGR,QAAO;EACN,MAAM,uBAAuB,GAAQ;AACpC,OAAI;AAEH,WAAO,EAAE,SADO,MAAM,EAAmB,EAAO,KAAK,EAAO,QAAQ,EAClD;YACV,GAAO;AACf,WAAO;KACN,SAAS;KACT,OAAO,aAAiB,QAAQ,EAAM,UAAU;KAChD;;;EAGH,6BAA6B;AAC5B,UAAO,EAAE,SAAS,WAAW;;EAE9B,MAAM,+BAA+B;AAEpC,GADA,MAAM,QAAQ,IAAI,CAAC,GAAG,EAAS,QAAQ,CAAC,CAAC,KAAK,MAAY,EAAQ,SAAS,CAAC,CAAC,EAC7E,EAAS,OAAO;;EAEjB;;;;ACtCF,eAAe,EAAa,GAAuB,GAAkE;CACpH,IAAM,IAAgB,EAAI,iBAAiB,EAAI;AAC/C,KAAI,CAAC,EACJ,OAAU,MAAM,8DAA8D;AAE/E,QAAO,EAA8B;EACpC;EACA,gBAAgB;EAChB,KAAK,QAAQ;EACb,CAAC;;AAGH,SAAS,GAAmB,GAA2B,GAA8B;AACpF,KAAI,CAAC,EACJ;CAED,IAAM,IAAS,KAAK,MAAM,EAAM;AAChC,KAAI,CAAC,KAAU,OAAO,KAAW,YAAY,MAAM,QAAQ,EAAO,CACjE,OAAU,MAAM,GAAG,EAAM,yBAAyB;AAEnD,QAAO;;AAGR,IAAM,KAAsB,EAAK,MAAM;CAAC,EAAK,QAAQ;CAAE,EAAK,QAAQ;CAAE,EAAK,SAAS;CAAC,CAAC;AAEtF,SAAS,EAAqB,GAAc,GAAmB;AAC9D,QAAO;EACN,SAAS,CAAC;GAAE,MAAM;GAAiB;GAAM,CAAC;EAC1C;EACA;;AAGF,SAAgB,GAAiB,GAAuB,GAA8C;AACrG,QAAO;EACN,MAAM;EACN,OAAO;EACP,aAAa;EACb,YAAY,EAAK,OAAO;GACvB,OAAO,EAAK,OAAO,EAAE,aAAa,0BAA0B,CAAC;GAC7D,WAAW,EAAK,SAAS,EAAK,OAAO,EAAE,aAAa,gCAAgC,CAAC,CAAC;GACtF,YAAY,EAAK,SAAS,EAAK,OAAO,EAAE,aAAa,8BAA8B,CAAC,CAAC;GACrF,UAAU,EAAK,SAAS,EAAK,OAAO,EAAE,aAAa,yCAAyC,CAAC,CAAC;GAC9F,YAAY,EAAK,SAAS,EAAK,OAAO,EAAE,aAAa,0DAA0D,CAAC,CAAC;GACjH,CAAC;EACF,MAAM,QAAQ,GAAa,GAAQ,GAAS,GAAW;GACtD,IAAM,IAAU,MAAM,EAAa,GAAc,EAAI,EAC/C,IAAS,GAAgC,EAAO,YAAkC,aAAa,EAC/F,IAAU,MAAM,EAAQ,OAAO;IACpC,OAAO,EAAO;IACd,WAAW,EAAO;IAClB,YAAY,EAAO;IACnB,UAAU,EAAO;IACjB;IACA,YAAY,EAAI;IAChB,SAAS,EAAI;IACb,cAAc,EAAI;IAClB,CAAC;AAOF,UANI,EAAQ,WAAW,IACf,EAAW,+BAA+B;IAAE,OAAO;IAAG,SAAS,EAAE;IAAE,CAAC,GAKrE,EAHM,EACX,KAAK,GAAQ,MAAU,GAAG,IAAQ,EAAE,KAAK,EAAO,UAAU,IAAI,EAAO,SAAS,EAAO,UAAU,IAAI,EAAO,MAAM,QAAQ,EAAE,CAAC,KAAK,EAAO,OAAO,CAC9I,KAAK,OAAO,EACU;IACvB,OAAO,EAAQ;IACf,SAAS,EAAQ,KAAK,OAAY;KACjC,IAAI,EAAO;KACX,WAAW,EAAO;KAClB,OAAO,EAAO;KACd,OAAO,EAAO;KACd,MAAM,EAAO;KACb,EAAE;IACH,CAAC;;EAEH;;AAGF,SAAgB,GAAc,GAAuB,GAA8C;AAClG,QAAO;EACN,MAAM;EACN,OAAO;EACP,aAAa;EACb,YAAY,EAAK,OAAO;GACvB,IAAI,EAAK,OAAO,EAAE,aAAa,6BAA6B,CAAC;GAC7D,WAAW,EAAK,SAAS,EAAK,OAAO,EAAE,aAAa,gCAAgC,CAAC,CAAC;GACtF,CAAC;EACF,MAAM,QAAQ,GAAa,GAAQ,GAAS,GAAW;GAEtD,IAAM,IAAS,OADC,MAAM,EAAa,GAAc,EAAI,EACxB,IAAI;IAChC,IAAI,EAAO;IACX,WAAW,EAAO;IAClB,YAAY,EAAI;IAChB,SAAS,EAAI;IACb,cAAc,EAAI;IAClB,CAAC;AAIF,UAHK,IAGE,EAAW,GAAG,EAAO,SAAS,EAAO,UAAU,eAAe,EAAO,UAAU,UAAU,EAAO,KAAK,MAAM,EAAO,QAAQ;IAChI,OAAO;IACP,IAAI,EAAO;IACX,WAAW,EAAO;IAClB,UAAU,EAAO;IACjB,CAAC,GAPM,EAAW,4BAA4B,EAAE,OAAO,IAAO,CAAC;;EASjE;;AAGF,SAAgB,GAAiB,GAAuB,GAA8C;AACrG,QAAO;EACN,MAAM;EACN,OAAO;EACP,aAAa;EACb,YAAY,EAAK,OAAO;GACvB,IAAI,EAAK,SAAS,EAAK,OAAO,EAAE,aAAa,+BAA+B,CAAC,CAAC;GAC9E,OAAO,EAAK,SAAS,EAAK,OAAO,EAAE,aAAa,mBAAmB,CAAC,CAAC;GACrE,MAAM,EAAK,OAAO,EAAE,aAAa,yBAAyB,CAAC;GAC3D,WAAW,EAAK,SAAS,EAAK,OAAO,EAAE,aAAa,gCAAgC,CAAC,CAAC;GACtF,QAAQ,EAAK,SAAS,EAAK,OAAO,EAAE,aAAa,0BAA0B,CAAC,CAAC;GAC7E,UAAU,EAAK,SACd,EAAK,OAAO,EAAK,QAAQ,EAAE,IAAqB,EAC/C,aAAa,gEACb,CAAC,CACF;GACD,CAAC;EACF,MAAM,QAAQ,GAAa,GAAQ,GAAS,GAAW;GAEtD,IAAM,IAAS,OADC,MAAM,EAAa,GAAc,EAAI,EACxB,OAAO;IACnC,OAAO;KACN,IAAI,EAAO;KACX,OAAO,EAAO;KACd,MAAM,EAAO;KACb,WAAW,EAAO;KAClB,QAAQ,EAAO;KACf,UAAU,EAAO;KACjB;IACD,YAAY,EAAI;IAChB,SAAS,EAAI;IACb,cAAc,EAAI;IAClB,CAAC;AACF,UAAO,EAAW,iBAAiB,EAAO,UAAU,gBAAgB,EAAO,UAAU,IAAI;IACxF,IAAI,EAAO;IACX,WAAW,EAAO;IAClB,MAAM,EAAO;IACb,YAAY,EAAO;IACnB,CAAC;;EAEH;;AAGF,SAAgB,GAAiB,GAAuB,GAA8C;AACrG,QAAO;EACN,MAAM;EACN,OAAO;EACP,aAAa;EACb,YAAY,EAAK,OAAO;GACvB,IAAI,EAAK,OAAO,EAAE,aAAa,6BAA6B,CAAC;GAC7D,WAAW,EAAK,SAAS,EAAK,OAAO,EAAE,aAAa,gCAAgC,CAAC,CAAC;GACtF,CAAC;EACF,MAAM,QAAQ,GAAa,GAAQ,GAAS,GAAW;GAEtD,IAAM,IAAa,OADH,MAAM,EAAa,GAAc,EAAI,EACpB,OAAO;IACvC,IAAI,EAAO;IACX,WAAW,EAAO;IAClB,YAAY,EAAI;IAChB,SAAS,EAAI;IACb,cAAc,EAAI;IAClB,CAAC;AACF,UAAO,EAAW,kBAAkB,EAAO,GAAa,IAAI,EAAE,eAAY,CAAC;;EAE5E;;;;ACrKF,SAAS,KAAuE;AAC/E,QAAO;EACN,IAAI;EACJ,cAAc;EACd,WAAW;EACX,iCAAiC;EACjC,MAAM,OAAO,GAAS;GAErB,IAAM,IAAW,MAAM,EAAoB;IAC1C,cAFoB,GAAkC,EAAQ,OAAO;IAGrE,gBAAgB,EAAQ;IACxB,KAAK,QAAQ;IACb,CAAC,EACI,IAAU,IAAI,GACnB;IACC,GAAG;IACH,OAAO,EAAQ,SAAS,EAAS;IACjC,kBAAkB,EAAQ,QAAQ,WAAW,EAAQ,OAAO,QAAQ,MAAM,CAAC,SAAS,IAAI,EAAQ,OAAO,UAAU,EAAS;IAC1H,UAAU,OAAO,EAAQ,QAAQ,UAAW,YAAY,EAAQ,OAAO,OAAO,MAAM,CAAC,SAAS,IAAI,EAAQ,OAAO,SAAS,EAAS;IACnI,EACD,EAAQ,OACR;AACD,UAAO;IACN,UAAU;KACT,IAAI;KACJ,OAAO,EAAQ,SAAS,EAAS;KACjC,aAAa,MAAS,EAAQ,WAAW,WAAW,EAAK;KACzD,aAAa,MAAU,EAAQ,WAAW,WAAW,EAAM;KAC3D;IACD,SAAS;KACR,IAAI;KACJ,cAAc;MACb,WAAW,EAAS;MACpB,OAAO,EAAQ,SAAS,EAAS;MACjC;KACD;IACD;;EAEF;;AAGF,IAAA,KAAe,EAAkB;CAChC,IAAI;CACJ,MAAM;CACN,aAAa;CACb,MAAM;CACN,cAAc;CACd,SAAS,GAAwB;AA6C3B,EA5CL,EAAmB,QAAQ,EAAI,gBAAgB,EAAE,CAAC,EAElD,EAAI,gCAAgC,IAAsC,CAAC,EAC3E,EAAI,yBAAyB;GAC5B,eAAe;GACf,SAAS,GAAoB;IAC5B,cAAc,EAAI;IAClB,aAAa,EAAI;IACjB,CAAC;GACF,iBAAiB,GAA8B,EAAI,cAAc,EAAI,YAAY;GACjF,CAAC,EAEF,EAAI,cAAc,MAAQ,GAAiB,EAAI,cAAc,EAAI,EAAE,EAClE,OAAO,CAAC,2BAA2B,EACnC,CAAC,EACF,EAAI,cAAc,MAAQ,GAAc,EAAI,cAAc,EAAI,EAAE,EAC/D,OAAO,CAAC,wBAAwB,EAChC,CAAC,EACF,EAAI,cAAc,MAAQ,GAAiB,EAAI,cAAc,EAAI,EAAE,EAClE,OAAO,CAAC,2BAA2B,EACnC,CAAC,EACF,EAAI,cAAc,MAAQ,GAAiB,EAAI,cAAc,EAAI,EAAE,EAClE,OAAO,CAAC,2BAA2B,EACnC,CAAC,EAEF,EAAI,aACF,EAAE,iBAAc;AAChB,MAA4B,GAAS;IACpC,cAAc,EAAI;IAClB,gBAAgB,EAAI;IACpB,aAAa,EAAI;IACjB,CAAC;KAEH,EACC,aAAa,CACZ;GACC,MAAM;GACN,aAAa;GACb,gBAAgB;GAChB,CACD,EACD,CACD,EAEI,EAAoB;GACxB,cAAc,EAAI;GAClB,gBAAgB,EAAI;GACpB,KAAK,QAAQ;GACb,aAAa,EAAI;GACjB,CAAC,CACA,MAAM,MAAa;AACnB,KAAI,OAAO,KAAK,GAAG,EAAU,yBAAyB,EAAS,UAAU,eAAe,EAAS,MAAM,GAAG;IACzG,CACD,OAAO,MAAmB;GAC1B,IAAM,IAAU,aAAiB,QAAQ,EAAM,UAAU;AACzD,KAAI,OAAO,KAAK,GAAG,EAAU,yCAAyC,IAAU;IAC/E;;CAEJ,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-runtime";
|
|
2
|
+
type CliCommand = {
|
|
3
|
+
command: (name: string) => CliCommand;
|
|
4
|
+
description: (description: string) => CliCommand;
|
|
5
|
+
argument: (name: string, description: string) => CliCommand;
|
|
6
|
+
option: (flags: string, description: string) => CliCommand;
|
|
7
|
+
action: (handler: (...args: unknown[]) => Promise<void> | void) => CliCommand;
|
|
8
|
+
opts?: () => Record<string, unknown>;
|
|
9
|
+
};
|
|
10
|
+
export declare function registerCloudflareMemoryCli(program: {
|
|
11
|
+
command: (name: string) => CliCommand;
|
|
12
|
+
}, params: {
|
|
13
|
+
pluginConfig: unknown;
|
|
14
|
+
openClawConfig: OpenClawConfig;
|
|
15
|
+
resolvePath?: (input: string) => string;
|
|
16
|
+
}): void;
|
|
17
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { CompanionRecord } from "./types.js";
|
|
2
|
+
export declare class CompanionStore {
|
|
3
|
+
private readonly path;
|
|
4
|
+
constructor(path: string);
|
|
5
|
+
get filePath(): string;
|
|
6
|
+
upsert(record: CompanionRecord): Promise<void>;
|
|
7
|
+
get(namespace: string, id: string): Promise<CompanionRecord | null>;
|
|
8
|
+
delete(namespace: string, id: string): Promise<void>;
|
|
9
|
+
clear(): Promise<void>;
|
|
10
|
+
}
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import type { OpenClawConfig } from "openclaw/plugin-sdk/config-runtime";
|
|
2
|
+
import type { OpenClawPluginConfigSchema } from "openclaw/plugin-sdk/plugin-entry";
|
|
3
|
+
import type { RawPluginConfig, ResolvedPluginConfig } from "./types.js";
|
|
4
|
+
export declare const pluginConfigJsonSchema: {
|
|
5
|
+
readonly type: "object";
|
|
6
|
+
readonly additionalProperties: false;
|
|
7
|
+
readonly properties: {
|
|
8
|
+
readonly cloudflare: {
|
|
9
|
+
readonly type: "object";
|
|
10
|
+
readonly additionalProperties: false;
|
|
11
|
+
readonly properties: {
|
|
12
|
+
readonly accountId: {
|
|
13
|
+
readonly type: "string";
|
|
14
|
+
};
|
|
15
|
+
readonly apiToken: {
|
|
16
|
+
readonly anyOf: readonly [{
|
|
17
|
+
readonly type: "string";
|
|
18
|
+
}, {
|
|
19
|
+
readonly type: "object";
|
|
20
|
+
readonly additionalProperties: false;
|
|
21
|
+
readonly properties: {
|
|
22
|
+
readonly source: {
|
|
23
|
+
readonly type: "string";
|
|
24
|
+
readonly enum: readonly ["env", "file", "exec"];
|
|
25
|
+
};
|
|
26
|
+
readonly provider: {
|
|
27
|
+
readonly type: "string";
|
|
28
|
+
};
|
|
29
|
+
readonly id: {
|
|
30
|
+
readonly type: "string";
|
|
31
|
+
};
|
|
32
|
+
};
|
|
33
|
+
readonly required: readonly ["source", "provider", "id"];
|
|
34
|
+
}];
|
|
35
|
+
};
|
|
36
|
+
readonly apiBaseUrl: {
|
|
37
|
+
readonly type: "string";
|
|
38
|
+
readonly format: "uri";
|
|
39
|
+
};
|
|
40
|
+
readonly workersAiBaseUrl: {
|
|
41
|
+
readonly type: "string";
|
|
42
|
+
readonly format: "uri";
|
|
43
|
+
};
|
|
44
|
+
readonly vectorizeBaseUrl: {
|
|
45
|
+
readonly type: "string";
|
|
46
|
+
readonly format: "uri";
|
|
47
|
+
};
|
|
48
|
+
};
|
|
49
|
+
};
|
|
50
|
+
readonly vectorize: {
|
|
51
|
+
readonly type: "object";
|
|
52
|
+
readonly additionalProperties: false;
|
|
53
|
+
readonly properties: {
|
|
54
|
+
readonly indexName: {
|
|
55
|
+
readonly type: "string";
|
|
56
|
+
};
|
|
57
|
+
readonly namespace: {
|
|
58
|
+
readonly type: "string";
|
|
59
|
+
};
|
|
60
|
+
readonly topK: {
|
|
61
|
+
readonly type: "integer";
|
|
62
|
+
readonly minimum: 1;
|
|
63
|
+
readonly maximum: 50;
|
|
64
|
+
};
|
|
65
|
+
readonly minScore: {
|
|
66
|
+
readonly type: "number";
|
|
67
|
+
readonly minimum: 0;
|
|
68
|
+
readonly maximum: 1;
|
|
69
|
+
};
|
|
70
|
+
readonly metric: {
|
|
71
|
+
readonly type: "string";
|
|
72
|
+
readonly enum: readonly ["cosine", "euclidean", "dot-product"];
|
|
73
|
+
};
|
|
74
|
+
readonly createIndex: {
|
|
75
|
+
readonly type: "object";
|
|
76
|
+
readonly additionalProperties: false;
|
|
77
|
+
readonly properties: {
|
|
78
|
+
readonly description: {
|
|
79
|
+
readonly type: "string";
|
|
80
|
+
};
|
|
81
|
+
readonly dimensions: {
|
|
82
|
+
readonly type: "integer";
|
|
83
|
+
readonly minimum: 1;
|
|
84
|
+
readonly maximum: 1536;
|
|
85
|
+
};
|
|
86
|
+
readonly metric: {
|
|
87
|
+
readonly type: "string";
|
|
88
|
+
readonly enum: readonly ["cosine", "euclidean", "dot-product"];
|
|
89
|
+
};
|
|
90
|
+
};
|
|
91
|
+
};
|
|
92
|
+
readonly metadataIndexedFields: {
|
|
93
|
+
readonly type: "array";
|
|
94
|
+
readonly items: {
|
|
95
|
+
readonly type: "string";
|
|
96
|
+
};
|
|
97
|
+
};
|
|
98
|
+
};
|
|
99
|
+
};
|
|
100
|
+
readonly embeddings: {
|
|
101
|
+
readonly type: "object";
|
|
102
|
+
readonly additionalProperties: false;
|
|
103
|
+
readonly properties: {
|
|
104
|
+
readonly model: {
|
|
105
|
+
readonly type: "string";
|
|
106
|
+
};
|
|
107
|
+
};
|
|
108
|
+
};
|
|
109
|
+
readonly storage: {
|
|
110
|
+
readonly type: "object";
|
|
111
|
+
readonly additionalProperties: false;
|
|
112
|
+
readonly properties: {
|
|
113
|
+
readonly mode: {
|
|
114
|
+
readonly type: "string";
|
|
115
|
+
readonly enum: readonly ["vectorize-inline", "companion-store"];
|
|
116
|
+
};
|
|
117
|
+
readonly companionStorePath: {
|
|
118
|
+
readonly type: "string";
|
|
119
|
+
};
|
|
120
|
+
readonly inlineTextMaxBytes: {
|
|
121
|
+
readonly type: "integer";
|
|
122
|
+
readonly minimum: 256;
|
|
123
|
+
readonly maximum: 10000;
|
|
124
|
+
};
|
|
125
|
+
};
|
|
126
|
+
};
|
|
127
|
+
};
|
|
128
|
+
};
|
|
129
|
+
export declare const pluginUiHints: {
|
|
130
|
+
readonly "cloudflare.accountId": {
|
|
131
|
+
readonly label: "Cloudflare account ID";
|
|
132
|
+
readonly help: "Defaults to ${CLOUDFLARE_ACCOUNT_ID}.";
|
|
133
|
+
};
|
|
134
|
+
readonly "cloudflare.apiToken": {
|
|
135
|
+
readonly label: "Cloudflare API token";
|
|
136
|
+
readonly sensitive: true;
|
|
137
|
+
readonly help: "Defaults to ${CLOUDFLARE_API_TOKEN}.";
|
|
138
|
+
};
|
|
139
|
+
readonly "vectorize.indexName": {
|
|
140
|
+
readonly label: "Vectorize index name";
|
|
141
|
+
readonly help: "Defaults to ${CLOUDFLARE_VECTORIZE_INDEX_NAME}.";
|
|
142
|
+
};
|
|
143
|
+
readonly "vectorize.namespace": {
|
|
144
|
+
readonly label: "Fixed namespace override";
|
|
145
|
+
readonly help: "Defaults to ${CLOUDFLARE_VECTORIZE_NAMESPACE} or derives from the agent/session context.";
|
|
146
|
+
};
|
|
147
|
+
readonly "vectorize.topK": {
|
|
148
|
+
readonly label: "Top-K results";
|
|
149
|
+
readonly help: "Defaults to ${CLOUDFLARE_VECTORIZE_TOP_K} or 5.";
|
|
150
|
+
};
|
|
151
|
+
readonly "embeddings.model": {
|
|
152
|
+
readonly label: "Workers AI embedding model";
|
|
153
|
+
readonly help: "Defaults to ${CLOUDFLARE_WORKERS_AI_EMBEDDING_MODEL} or @cf/baai/bge-base-en-v1.5.";
|
|
154
|
+
};
|
|
155
|
+
readonly "storage.mode": {
|
|
156
|
+
readonly label: "Storage mode";
|
|
157
|
+
readonly help: "Defaults to ${OPENCLAW_CF_MEMORY_STORAGE_MODE} or vectorize-inline." | "Defaults to ${OPENCLAW_CF_MEMORY_STORAGE_MODE} or companion-store.";
|
|
158
|
+
};
|
|
159
|
+
readonly "storage.companionStorePath": {
|
|
160
|
+
readonly label: "Companion store path";
|
|
161
|
+
readonly help: "Defaults to ${OPENCLAW_CF_MEMORY_COMPANION_PATH} or the OpenClaw state directory.";
|
|
162
|
+
};
|
|
163
|
+
};
|
|
164
|
+
export declare const pluginConfigSchema: OpenClawPluginConfigSchema;
|
|
165
|
+
export declare function parsePluginConfig(value: unknown): RawPluginConfig;
|
|
166
|
+
export declare function getPluginConfigFromOpenClawConfig(config: OpenClawConfig): RawPluginConfig;
|
|
167
|
+
export declare function resolvePluginConfig(params: {
|
|
168
|
+
pluginConfig: unknown;
|
|
169
|
+
openClawConfig: OpenClawConfig;
|
|
170
|
+
env?: NodeJS.ProcessEnv;
|
|
171
|
+
resolvePath?: (input: string) => string;
|
|
172
|
+
}): Promise<ResolvedPluginConfig>;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { StorageMode, VectorizeMetric } from "./types.js";
|
|
2
|
+
export declare const PLUGIN_ID = "memory-cloudflare-vectorize";
|
|
3
|
+
export declare const PLUGIN_NAME = "Cloudflare Vectorize Memory";
|
|
4
|
+
export declare const PLUGIN_DESCRIPTION = "OpenClaw memory plugin backed by Cloudflare Vectorize and Workers AI embeddings.";
|
|
5
|
+
export declare const CLOUDFLARE_ACCOUNT_ID_ENV = "CLOUDFLARE_ACCOUNT_ID";
|
|
6
|
+
export declare const CLOUDFLARE_API_TOKEN_ENV = "CLOUDFLARE_API_TOKEN";
|
|
7
|
+
export declare const VECTORIZE_INDEX_ENV = "CLOUDFLARE_VECTORIZE_INDEX_NAME";
|
|
8
|
+
export declare const VECTORIZE_NAMESPACE_ENV = "CLOUDFLARE_VECTORIZE_NAMESPACE";
|
|
9
|
+
export declare const WORKERS_AI_MODEL_ENV = "CLOUDFLARE_WORKERS_AI_EMBEDDING_MODEL";
|
|
10
|
+
export declare const VECTORIZE_TOP_K_ENV = "CLOUDFLARE_VECTORIZE_TOP_K";
|
|
11
|
+
export declare const STORAGE_MODE_ENV = "OPENCLAW_CF_MEMORY_STORAGE_MODE";
|
|
12
|
+
export declare const COMPANION_PATH_ENV = "OPENCLAW_CF_MEMORY_COMPANION_PATH";
|
|
13
|
+
export declare const DEFAULT_EMBEDDING_MODEL = "@cf/baai/bge-base-en-v1.5";
|
|
14
|
+
export declare const DEFAULT_TOP_K = 5;
|
|
15
|
+
export declare const DEFAULT_MIN_SCORE = 0;
|
|
16
|
+
export declare const DEFAULT_INLINE_TEXT_MAX_BYTES = 6000;
|
|
17
|
+
export declare const DEFAULT_VECTORIZE_METRIC: VectorizeMetric;
|
|
18
|
+
export declare const DEFAULT_STORAGE_MODE: StorageMode;
|
|
19
|
+
export declare const DEFAULT_CLOUDFLARE_API_BASE_URL = "https://api.cloudflare.com/client/v4";
|
|
20
|
+
export declare const DEFAULT_INDEX_DESCRIPTION = "OpenClaw memory index backed by Cloudflare Vectorize.";
|
|
21
|
+
export declare const RESERVED_METADATA_PREFIX = "oc_";
|
|
22
|
+
export declare const RESERVED_METADATA_KEYS: {
|
|
23
|
+
readonly logicalId: "oc_record_id";
|
|
24
|
+
readonly title: "oc_title";
|
|
25
|
+
readonly text: "oc_text";
|
|
26
|
+
readonly storageMode: "oc_storage_mode";
|
|
27
|
+
readonly pointer: "oc_pointer";
|
|
28
|
+
readonly source: "oc_source";
|
|
29
|
+
readonly createdAt: "oc_created_at";
|
|
30
|
+
readonly updatedAt: "oc_updated_at";
|
|
31
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ResolvedPluginConfig } from "./types.js";
|
|
2
|
+
export declare class WorkersAiEmbeddingsClient {
|
|
3
|
+
private readonly config;
|
|
4
|
+
constructor(config: ResolvedPluginConfig);
|
|
5
|
+
embedQuery(text: string): Promise<number[]>;
|
|
6
|
+
embedBatch(texts: string[]): Promise<number[][]>;
|
|
7
|
+
probeDimensions(): Promise<number>;
|
|
8
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare class ConfigurationError extends Error {
|
|
2
|
+
constructor(message: string);
|
|
3
|
+
}
|
|
4
|
+
export declare class CloudflareApiError extends Error {
|
|
5
|
+
readonly status?: number | undefined;
|
|
6
|
+
readonly details?: unknown | undefined;
|
|
7
|
+
constructor(message: string, status?: number | undefined, details?: unknown | undefined);
|
|
8
|
+
}
|
|
9
|
+
export declare class RecordSizeError extends Error {
|
|
10
|
+
constructor(message: string);
|
|
11
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
declare const _default: {
|
|
2
|
+
id: string;
|
|
3
|
+
name: string;
|
|
4
|
+
description: string;
|
|
5
|
+
configSchema: import("openclaw/plugin-sdk/plugin-entry").OpenClawPluginConfigSchema;
|
|
6
|
+
register: NonNullable<import("openclaw/plugin-sdk/plugin-entry").OpenClawPluginDefinition["register"]>;
|
|
7
|
+
} & Pick<import("openclaw/plugin-sdk/plugin-entry").OpenClawPluginDefinition, "kind" | "reload" | "nodeHostCommands" | "securityAuditCollectors">;
|
|
8
|
+
export default _default;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { CloudflareMemoryService } from "./service.js";
|
|
2
|
+
import type { MetadataValue, MigrationNamespaceStrategy, MigrationRunOptions, MigrationSourceMode, MigrationSummary } from "./types.js";
|
|
3
|
+
type DiscoveredMigrationFile = {
|
|
4
|
+
absolutePath: string;
|
|
5
|
+
relativePath: string;
|
|
6
|
+
};
|
|
7
|
+
type ParsedMigrationRecord = {
|
|
8
|
+
input: {
|
|
9
|
+
id: string;
|
|
10
|
+
text: string;
|
|
11
|
+
title?: string;
|
|
12
|
+
metadata: Record<string, MetadataValue>;
|
|
13
|
+
namespace?: string;
|
|
14
|
+
source?: string;
|
|
15
|
+
};
|
|
16
|
+
sourcePath: string;
|
|
17
|
+
relativePath: string;
|
|
18
|
+
};
|
|
19
|
+
export declare function discoverMigrationFiles(params: {
|
|
20
|
+
workspaceDir: string;
|
|
21
|
+
sourceMode: MigrationSourceMode;
|
|
22
|
+
sourcePaths?: string[];
|
|
23
|
+
}): Promise<DiscoveredMigrationFile[]>;
|
|
24
|
+
export declare function parseMigrationFile(params: {
|
|
25
|
+
file: DiscoveredMigrationFile;
|
|
26
|
+
sourceMode: MigrationSourceMode;
|
|
27
|
+
targetNamespace: string;
|
|
28
|
+
namespaceStrategy: MigrationNamespaceStrategy;
|
|
29
|
+
}): Promise<ParsedMigrationRecord | null>;
|
|
30
|
+
export declare function runCloudflareMemoryMigration(params: {
|
|
31
|
+
service: CloudflareMemoryService;
|
|
32
|
+
options?: MigrationRunOptions;
|
|
33
|
+
}): Promise<MigrationSummary>;
|
|
34
|
+
export declare function formatMigrationSummary(summary: MigrationSummary): string;
|
|
35
|
+
export {};
|