@jcheesepkg/nanobot 0.1.2 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent/skills.d.mts.map +1 -1
- package/dist/agent/skills.mjs +2 -0
- package/dist/agent/skills.mjs.map +1 -1
- package/dist/cli/index.mjs +2 -0
- package/dist/cli/index.mjs.map +1 -1
- package/dist/config/schema.d.mts +24 -24
- package/dist/config/schema.d.mts.map +1 -1
- package/dist/config/schema.mjs +2 -1
- package/dist/config/schema.mjs.map +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"skills.d.mts","names":[],"sources":["../../src/agent/skills.ts"],"mappings":";
|
|
1
|
+
{"version":3,"file":"skills.d.mts","names":[],"sources":["../../src/agent/skills.ts"],"mappings":";UAeU,SAAA;EACR,IAAA;EACA,IAAA;EACA,MAAA;AAAA;AAAA,UAGQ,SAAA;EACR,WAAA;EACA,MAAA;EACA,QAAA;EAAA,CACC,GAAA;AAAA;;;;;cAOU,YAAA;EAAA,QACH,SAAA;EAAA,QACA,eAAA;EAAA,QACA,aAAA;cAEI,SAAA,UAAmB,gBAAA;EALpB;EAYX,UAAA,CAAW,iBAAA,aAA2B,SAAA;;EAsCtC,SAAA,CAAU,IAAA;EAjDF;EAgER,oBAAA,CAAqB,UAAA;EA9Db;EA2ER,kBAAA,CAAA;EAzEY;EA0GZ,eAAA,CAAA;EAnGA;EAgHA,gBAAA,CAAiB,IAAA,WAAe,SAAA;EAAA,QAsBxB,gBAAA;EAAA,QAQA,oBAAA;EAAA,QAWA,iBAAA;EAAA,QAWA,YAAA;EAAA,QAKA,mBAAA;EAAA,QAKA,sBAAA;AAAA"}
|
package/dist/agent/skills.mjs
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { which } from "../utils/which.mjs";
|
|
2
2
|
import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
|
|
3
3
|
import { dirname, join } from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
4
5
|
|
|
5
6
|
//#region src/agent/skills.ts
|
|
7
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
6
8
|
/** Default builtin skills directory (relative to this file in dist). */
|
|
7
9
|
function getBuiltinSkillsDir() {
|
|
8
10
|
return join(dirname(dirname(__dirname)), "skills");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"skills.mjs","names":[],"sources":["../../src/agent/skills.ts"],"sourcesContent":["import { readFileSync, existsSync, readdirSync, statSync } from \"node:fs\";\nimport { join, dirname } from \"node:path\";\nimport { which } from \"../utils/which.js\";\n\n/** Default builtin skills directory (relative to this file in dist). */\nfunction getBuiltinSkillsDir(): string {\n // In dist: dist/agent/skills.js -> ../../skills\n // In src: src/agent/skills.ts -> ../../skills\n return join(dirname(dirname(__dirname)), \"skills\");\n}\n\ninterface SkillInfo {\n name: string;\n path: string;\n source: \"workspace\" | \"builtin\";\n}\n\ninterface SkillMeta {\n description?: string;\n always?: string;\n metadata?: string;\n [key: string]: string | undefined;\n}\n\n/**\n * Loader for agent skills.\n * Skills are markdown files (SKILL.md) that teach the agent specific capabilities.\n */\nexport class SkillsLoader {\n private workspace: string;\n private workspaceSkills: string;\n private builtinSkills: string;\n\n constructor(workspace: string, builtinSkillsDir?: string) {\n this.workspace = workspace;\n this.workspaceSkills = join(workspace, \"skills\");\n this.builtinSkills = builtinSkillsDir ?? getBuiltinSkillsDir();\n }\n\n /** List all available skills. */\n listSkills(filterUnavailable = true): SkillInfo[] {\n const skills: SkillInfo[] = [];\n\n // Workspace skills (highest priority)\n if (existsSync(this.workspaceSkills)) {\n for (const entry of readdirSync(this.workspaceSkills)) {\n const skillDir = join(this.workspaceSkills, entry);\n const skillFile = join(skillDir, \"SKILL.md\");\n if (statSync(skillDir).isDirectory() && existsSync(skillFile)) {\n skills.push({ name: entry, path: skillFile, source: \"workspace\" });\n }\n }\n }\n\n // Built-in skills\n if (existsSync(this.builtinSkills)) {\n for (const entry of readdirSync(this.builtinSkills)) {\n const skillDir = join(this.builtinSkills, entry);\n const skillFile = join(skillDir, \"SKILL.md\");\n if (\n statSync(skillDir).isDirectory() &&\n existsSync(skillFile) &&\n !skills.some((s) => s.name === entry)\n ) {\n skills.push({ name: entry, path: skillFile, source: \"builtin\" });\n }\n }\n }\n\n if (filterUnavailable) {\n return skills.filter((s) =>\n this.checkRequirements(this.getSkillMeta(s.name)),\n );\n }\n return skills;\n }\n\n /** Load a skill by name. */\n loadSkill(name: string): string | null {\n const wsSkill = join(this.workspaceSkills, name, \"SKILL.md\");\n if (existsSync(wsSkill)) {\n return readFileSync(wsSkill, \"utf-8\");\n }\n\n const builtinSkill = join(this.builtinSkills, name, \"SKILL.md\");\n if (existsSync(builtinSkill)) {\n return readFileSync(builtinSkill, \"utf-8\");\n }\n\n return null;\n }\n\n /** Load specific skills for inclusion in agent context. */\n loadSkillsForContext(skillNames: string[]): string {\n const parts: string[] = [];\n for (const name of skillNames) {\n const content = this.loadSkill(name);\n if (content) {\n const stripped = this.stripFrontmatter(content);\n parts.push(`### Skill: ${name}\\n\\n${stripped}`);\n }\n }\n return parts.join(\"\\n\\n---\\n\\n\");\n }\n\n /** Build a summary of all skills. */\n buildSkillsSummary(): string {\n const allSkills = this.listSkills(false);\n if (allSkills.length === 0) return \"\";\n\n const escapeXml = (s: string) =>\n s.replace(/&/g, \"&\").replace(/</g, \"<\").replace(/>/g, \">\");\n\n const lines = [\"<skills>\"];\n for (const s of allSkills) {\n const name = escapeXml(s.name);\n const desc = escapeXml(this.getSkillDescription(s.name));\n const meta = this.getSkillMeta(s.name);\n const available = this.checkRequirements(meta);\n\n lines.push(` <skill available=\"${available}\">`);\n lines.push(` <name>${name}</name>`);\n lines.push(` <description>${desc}</description>`);\n lines.push(` <location>${s.path}</location>`);\n\n if (!available) {\n const missing = this.getMissingRequirements(meta);\n if (missing) {\n lines.push(` <requires>${escapeXml(missing)}</requires>`);\n }\n }\n\n lines.push(\" </skill>\");\n }\n lines.push(\"</skills>\");\n return lines.join(\"\\n\");\n }\n\n /** Get skills marked as always=true. */\n getAlwaysSkills(): string[] {\n const result: string[] = [];\n for (const s of this.listSkills(true)) {\n const meta = this.getSkillMetadata(s.name);\n const skillMeta = this.parseNanobotMetadata(meta?.metadata ?? \"\");\n if (skillMeta.always || meta?.always) {\n result.push(s.name);\n }\n }\n return result;\n }\n\n /** Get metadata from a skill's frontmatter. */\n getSkillMetadata(name: string): SkillMeta | null {\n const content = this.loadSkill(name);\n if (!content) return null;\n\n if (content.startsWith(\"---\")) {\n const match = content.match(/^---\\n([\\s\\S]*?)\\n---/);\n if (match) {\n const metadata: SkillMeta = {};\n for (const line of match[1].split(\"\\n\")) {\n const colonIdx = line.indexOf(\":\");\n if (colonIdx !== -1) {\n const key = line.slice(0, colonIdx).trim();\n const value = line.slice(colonIdx + 1).trim().replace(/^[\"']|[\"']$/g, \"\");\n metadata[key] = value;\n }\n }\n return metadata;\n }\n }\n return null;\n }\n\n private stripFrontmatter(content: string): string {\n if (content.startsWith(\"---\")) {\n const match = content.match(/^---\\n[\\s\\S]*?\\n---\\n/);\n if (match) return content.slice(match[0].length).trim();\n }\n return content;\n }\n\n private parseNanobotMetadata(raw: string): Record<string, unknown> {\n try {\n const data = JSON.parse(raw);\n return typeof data === \"object\" && data !== null\n ? (data.nanobot ?? {})\n : {};\n } catch {\n return {};\n }\n }\n\n private checkRequirements(meta: Record<string, unknown>): boolean {\n const requires = (meta.requires ?? {}) as Record<string, string[]>;\n for (const bin of requires.bins ?? []) {\n if (!which(bin)) return false;\n }\n for (const env of requires.env ?? []) {\n if (!process.env[env]) return false;\n }\n return true;\n }\n\n private getSkillMeta(name: string): Record<string, unknown> {\n const meta = this.getSkillMetadata(name) ?? {};\n return this.parseNanobotMetadata(String(meta.metadata ?? \"\"));\n }\n\n private getSkillDescription(name: string): string {\n const meta = this.getSkillMetadata(name);\n return meta?.description ?? name;\n }\n\n private getMissingRequirements(meta: Record<string, unknown>): string {\n const missing: string[] = [];\n const requires = (meta.requires ?? {}) as Record<string, string[]>;\n for (const bin of requires.bins ?? []) {\n if (!which(bin)) missing.push(`CLI: ${bin}`);\n }\n for (const env of requires.env ?? []) {\n if (!process.env[env]) missing.push(`ENV: ${env}`);\n }\n return missing.join(\", \");\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"skills.mjs","names":[],"sources":["../../src/agent/skills.ts"],"sourcesContent":["import { readFileSync, existsSync, readdirSync, statSync } from \"node:fs\";\nimport { join, dirname } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { which } from \"../utils/which.js\";\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\n/** Default builtin skills directory (relative to this file in dist). */\nfunction getBuiltinSkillsDir(): string {\n // In dist: dist/agent/skills.js -> ../../skills\n // In src: src/agent/skills.ts -> ../../skills\n return join(dirname(dirname(__dirname)), \"skills\");\n}\n\ninterface SkillInfo {\n name: string;\n path: string;\n source: \"workspace\" | \"builtin\";\n}\n\ninterface SkillMeta {\n description?: string;\n always?: string;\n metadata?: string;\n [key: string]: string | undefined;\n}\n\n/**\n * Loader for agent skills.\n * Skills are markdown files (SKILL.md) that teach the agent specific capabilities.\n */\nexport class SkillsLoader {\n private workspace: string;\n private workspaceSkills: string;\n private builtinSkills: string;\n\n constructor(workspace: string, builtinSkillsDir?: string) {\n this.workspace = workspace;\n this.workspaceSkills = join(workspace, \"skills\");\n this.builtinSkills = builtinSkillsDir ?? getBuiltinSkillsDir();\n }\n\n /** List all available skills. */\n listSkills(filterUnavailable = true): SkillInfo[] {\n const skills: SkillInfo[] = [];\n\n // Workspace skills (highest priority)\n if (existsSync(this.workspaceSkills)) {\n for (const entry of readdirSync(this.workspaceSkills)) {\n const skillDir = join(this.workspaceSkills, entry);\n const skillFile = join(skillDir, \"SKILL.md\");\n if (statSync(skillDir).isDirectory() && existsSync(skillFile)) {\n skills.push({ name: entry, path: skillFile, source: \"workspace\" });\n }\n }\n }\n\n // Built-in skills\n if (existsSync(this.builtinSkills)) {\n for (const entry of readdirSync(this.builtinSkills)) {\n const skillDir = join(this.builtinSkills, entry);\n const skillFile = join(skillDir, \"SKILL.md\");\n if (\n statSync(skillDir).isDirectory() &&\n existsSync(skillFile) &&\n !skills.some((s) => s.name === entry)\n ) {\n skills.push({ name: entry, path: skillFile, source: \"builtin\" });\n }\n }\n }\n\n if (filterUnavailable) {\n return skills.filter((s) =>\n this.checkRequirements(this.getSkillMeta(s.name)),\n );\n }\n return skills;\n }\n\n /** Load a skill by name. */\n loadSkill(name: string): string | null {\n const wsSkill = join(this.workspaceSkills, name, \"SKILL.md\");\n if (existsSync(wsSkill)) {\n return readFileSync(wsSkill, \"utf-8\");\n }\n\n const builtinSkill = join(this.builtinSkills, name, \"SKILL.md\");\n if (existsSync(builtinSkill)) {\n return readFileSync(builtinSkill, \"utf-8\");\n }\n\n return null;\n }\n\n /** Load specific skills for inclusion in agent context. */\n loadSkillsForContext(skillNames: string[]): string {\n const parts: string[] = [];\n for (const name of skillNames) {\n const content = this.loadSkill(name);\n if (content) {\n const stripped = this.stripFrontmatter(content);\n parts.push(`### Skill: ${name}\\n\\n${stripped}`);\n }\n }\n return parts.join(\"\\n\\n---\\n\\n\");\n }\n\n /** Build a summary of all skills. */\n buildSkillsSummary(): string {\n const allSkills = this.listSkills(false);\n if (allSkills.length === 0) return \"\";\n\n const escapeXml = (s: string) =>\n s.replace(/&/g, \"&\").replace(/</g, \"<\").replace(/>/g, \">\");\n\n const lines = [\"<skills>\"];\n for (const s of allSkills) {\n const name = escapeXml(s.name);\n const desc = escapeXml(this.getSkillDescription(s.name));\n const meta = this.getSkillMeta(s.name);\n const available = this.checkRequirements(meta);\n\n lines.push(` <skill available=\"${available}\">`);\n lines.push(` <name>${name}</name>`);\n lines.push(` <description>${desc}</description>`);\n lines.push(` <location>${s.path}</location>`);\n\n if (!available) {\n const missing = this.getMissingRequirements(meta);\n if (missing) {\n lines.push(` <requires>${escapeXml(missing)}</requires>`);\n }\n }\n\n lines.push(\" </skill>\");\n }\n lines.push(\"</skills>\");\n return lines.join(\"\\n\");\n }\n\n /** Get skills marked as always=true. */\n getAlwaysSkills(): string[] {\n const result: string[] = [];\n for (const s of this.listSkills(true)) {\n const meta = this.getSkillMetadata(s.name);\n const skillMeta = this.parseNanobotMetadata(meta?.metadata ?? \"\");\n if (skillMeta.always || meta?.always) {\n result.push(s.name);\n }\n }\n return result;\n }\n\n /** Get metadata from a skill's frontmatter. */\n getSkillMetadata(name: string): SkillMeta | null {\n const content = this.loadSkill(name);\n if (!content) return null;\n\n if (content.startsWith(\"---\")) {\n const match = content.match(/^---\\n([\\s\\S]*?)\\n---/);\n if (match) {\n const metadata: SkillMeta = {};\n for (const line of match[1].split(\"\\n\")) {\n const colonIdx = line.indexOf(\":\");\n if (colonIdx !== -1) {\n const key = line.slice(0, colonIdx).trim();\n const value = line.slice(colonIdx + 1).trim().replace(/^[\"']|[\"']$/g, \"\");\n metadata[key] = value;\n }\n }\n return metadata;\n }\n }\n return null;\n }\n\n private stripFrontmatter(content: string): string {\n if (content.startsWith(\"---\")) {\n const match = content.match(/^---\\n[\\s\\S]*?\\n---\\n/);\n if (match) return content.slice(match[0].length).trim();\n }\n return content;\n }\n\n private parseNanobotMetadata(raw: string): Record<string, unknown> {\n try {\n const data = JSON.parse(raw);\n return typeof data === \"object\" && data !== null\n ? (data.nanobot ?? {})\n : {};\n } catch {\n return {};\n }\n }\n\n private checkRequirements(meta: Record<string, unknown>): boolean {\n const requires = (meta.requires ?? {}) as Record<string, string[]>;\n for (const bin of requires.bins ?? []) {\n if (!which(bin)) return false;\n }\n for (const env of requires.env ?? []) {\n if (!process.env[env]) return false;\n }\n return true;\n }\n\n private getSkillMeta(name: string): Record<string, unknown> {\n const meta = this.getSkillMetadata(name) ?? {};\n return this.parseNanobotMetadata(String(meta.metadata ?? \"\"));\n }\n\n private getSkillDescription(name: string): string {\n const meta = this.getSkillMetadata(name);\n return meta?.description ?? name;\n }\n\n private getMissingRequirements(meta: Record<string, unknown>): string {\n const missing: string[] = [];\n const requires = (meta.requires ?? {}) as Record<string, string[]>;\n for (const bin of requires.bins ?? []) {\n if (!which(bin)) missing.push(`CLI: ${bin}`);\n }\n for (const env of requires.env ?? []) {\n if (!process.env[env]) missing.push(`ENV: ${env}`);\n }\n return missing.join(\", \");\n }\n}\n"],"mappings":";;;;;;AAMA,MAAM,YAAY,QADC,cAAc,OAAO,KAAK,IAAI,CACZ;;AAGrC,SAAS,sBAA8B;AAGrC,QAAO,KAAK,QAAQ,QAAQ,UAAU,CAAC,EAAE,SAAS;;;;;;AAoBpD,IAAa,eAAb,MAA0B;CACxB,AAAQ;CACR,AAAQ;CACR,AAAQ;CAER,YAAY,WAAmB,kBAA2B;AACxD,OAAK,YAAY;AACjB,OAAK,kBAAkB,KAAK,WAAW,SAAS;AAChD,OAAK,gBAAgB,oBAAoB,qBAAqB;;;CAIhE,WAAW,oBAAoB,MAAmB;EAChD,MAAM,SAAsB,EAAE;AAG9B,MAAI,WAAW,KAAK,gBAAgB,CAClC,MAAK,MAAM,SAAS,YAAY,KAAK,gBAAgB,EAAE;GACrD,MAAM,WAAW,KAAK,KAAK,iBAAiB,MAAM;GAClD,MAAM,YAAY,KAAK,UAAU,WAAW;AAC5C,OAAI,SAAS,SAAS,CAAC,aAAa,IAAI,WAAW,UAAU,CAC3D,QAAO,KAAK;IAAE,MAAM;IAAO,MAAM;IAAW,QAAQ;IAAa,CAAC;;AAMxE,MAAI,WAAW,KAAK,cAAc,CAChC,MAAK,MAAM,SAAS,YAAY,KAAK,cAAc,EAAE;GACnD,MAAM,WAAW,KAAK,KAAK,eAAe,MAAM;GAChD,MAAM,YAAY,KAAK,UAAU,WAAW;AAC5C,OACE,SAAS,SAAS,CAAC,aAAa,IAChC,WAAW,UAAU,IACrB,CAAC,OAAO,MAAM,MAAM,EAAE,SAAS,MAAM,CAErC,QAAO,KAAK;IAAE,MAAM;IAAO,MAAM;IAAW,QAAQ;IAAW,CAAC;;AAKtE,MAAI,kBACF,QAAO,OAAO,QAAQ,MACpB,KAAK,kBAAkB,KAAK,aAAa,EAAE,KAAK,CAAC,CAClD;AAEH,SAAO;;;CAIT,UAAU,MAA6B;EACrC,MAAM,UAAU,KAAK,KAAK,iBAAiB,MAAM,WAAW;AAC5D,MAAI,WAAW,QAAQ,CACrB,QAAO,aAAa,SAAS,QAAQ;EAGvC,MAAM,eAAe,KAAK,KAAK,eAAe,MAAM,WAAW;AAC/D,MAAI,WAAW,aAAa,CAC1B,QAAO,aAAa,cAAc,QAAQ;AAG5C,SAAO;;;CAIT,qBAAqB,YAA8B;EACjD,MAAM,QAAkB,EAAE;AAC1B,OAAK,MAAM,QAAQ,YAAY;GAC7B,MAAM,UAAU,KAAK,UAAU,KAAK;AACpC,OAAI,SAAS;IACX,MAAM,WAAW,KAAK,iBAAiB,QAAQ;AAC/C,UAAM,KAAK,cAAc,KAAK,MAAM,WAAW;;;AAGnD,SAAO,MAAM,KAAK,cAAc;;;CAIlC,qBAA6B;EAC3B,MAAM,YAAY,KAAK,WAAW,MAAM;AACxC,MAAI,UAAU,WAAW,EAAG,QAAO;EAEnC,MAAM,aAAa,MACjB,EAAE,QAAQ,MAAM,QAAQ,CAAC,QAAQ,MAAM,OAAO,CAAC,QAAQ,MAAM,OAAO;EAEtE,MAAM,QAAQ,CAAC,WAAW;AAC1B,OAAK,MAAM,KAAK,WAAW;GACzB,MAAM,OAAO,UAAU,EAAE,KAAK;GAC9B,MAAM,OAAO,UAAU,KAAK,oBAAoB,EAAE,KAAK,CAAC;GACxD,MAAM,OAAO,KAAK,aAAa,EAAE,KAAK;GACtC,MAAM,YAAY,KAAK,kBAAkB,KAAK;AAE9C,SAAM,KAAK,uBAAuB,UAAU,IAAI;AAChD,SAAM,KAAK,aAAa,KAAK,SAAS;AACtC,SAAM,KAAK,oBAAoB,KAAK,gBAAgB;AACpD,SAAM,KAAK,iBAAiB,EAAE,KAAK,aAAa;AAEhD,OAAI,CAAC,WAAW;IACd,MAAM,UAAU,KAAK,uBAAuB,KAAK;AACjD,QAAI,QACF,OAAM,KAAK,iBAAiB,UAAU,QAAQ,CAAC,aAAa;;AAIhE,SAAM,KAAK,aAAa;;AAE1B,QAAM,KAAK,YAAY;AACvB,SAAO,MAAM,KAAK,KAAK;;;CAIzB,kBAA4B;EAC1B,MAAM,SAAmB,EAAE;AAC3B,OAAK,MAAM,KAAK,KAAK,WAAW,KAAK,EAAE;GACrC,MAAM,OAAO,KAAK,iBAAiB,EAAE,KAAK;AAE1C,OADkB,KAAK,qBAAqB,MAAM,YAAY,GAAG,CACnD,UAAU,MAAM,OAC5B,QAAO,KAAK,EAAE,KAAK;;AAGvB,SAAO;;;CAIT,iBAAiB,MAAgC;EAC/C,MAAM,UAAU,KAAK,UAAU,KAAK;AACpC,MAAI,CAAC,QAAS,QAAO;AAErB,MAAI,QAAQ,WAAW,MAAM,EAAE;GAC7B,MAAM,QAAQ,QAAQ,MAAM,wBAAwB;AACpD,OAAI,OAAO;IACT,MAAM,WAAsB,EAAE;AAC9B,SAAK,MAAM,QAAQ,MAAM,GAAG,MAAM,KAAK,EAAE;KACvC,MAAM,WAAW,KAAK,QAAQ,IAAI;AAClC,SAAI,aAAa,IAAI;MACnB,MAAM,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC,MAAM;AAE1C,eAAS,OADK,KAAK,MAAM,WAAW,EAAE,CAAC,MAAM,CAAC,QAAQ,gBAAgB,GAAG;;;AAI7E,WAAO;;;AAGX,SAAO;;CAGT,AAAQ,iBAAiB,SAAyB;AAChD,MAAI,QAAQ,WAAW,MAAM,EAAE;GAC7B,MAAM,QAAQ,QAAQ,MAAM,wBAAwB;AACpD,OAAI,MAAO,QAAO,QAAQ,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM;;AAEzD,SAAO;;CAGT,AAAQ,qBAAqB,KAAsC;AACjE,MAAI;GACF,MAAM,OAAO,KAAK,MAAM,IAAI;AAC5B,UAAO,OAAO,SAAS,YAAY,SAAS,OACvC,KAAK,WAAW,EAAE,GACnB,EAAE;UACA;AACN,UAAO,EAAE;;;CAIb,AAAQ,kBAAkB,MAAwC;EAChE,MAAM,WAAY,KAAK,YAAY,EAAE;AACrC,OAAK,MAAM,OAAO,SAAS,QAAQ,EAAE,CACnC,KAAI,CAAC,MAAM,IAAI,CAAE,QAAO;AAE1B,OAAK,MAAM,OAAO,SAAS,OAAO,EAAE,CAClC,KAAI,CAAC,QAAQ,IAAI,KAAM,QAAO;AAEhC,SAAO;;CAGT,AAAQ,aAAa,MAAuC;EAC1D,MAAM,OAAO,KAAK,iBAAiB,KAAK,IAAI,EAAE;AAC9C,SAAO,KAAK,qBAAqB,OAAO,KAAK,YAAY,GAAG,CAAC;;CAG/D,AAAQ,oBAAoB,MAAsB;AAEhD,SADa,KAAK,iBAAiB,KAAK,EAC3B,eAAe;;CAG9B,AAAQ,uBAAuB,MAAuC;EACpE,MAAM,UAAoB,EAAE;EAC5B,MAAM,WAAY,KAAK,YAAY,EAAE;AACrC,OAAK,MAAM,OAAO,SAAS,QAAQ,EAAE,CACnC,KAAI,CAAC,MAAM,IAAI,CAAE,SAAQ,KAAK,QAAQ,MAAM;AAE9C,OAAK,MAAM,OAAO,SAAS,OAAO,EAAE,CAClC,KAAI,CAAC,QAAQ,IAAI,KAAM,SAAQ,KAAK,QAAQ,MAAM;AAEpD,SAAO,QAAQ,KAAK,KAAK"}
|
package/dist/cli/index.mjs
CHANGED
|
@@ -323,11 +323,13 @@ program.command("status").description("Show nanobot status").action(() => {
|
|
|
323
323
|
const hasOpenai = Boolean(config.providers.openai.apiKey);
|
|
324
324
|
const hasGemini = Boolean(config.providers.gemini.apiKey);
|
|
325
325
|
const hasDeepseek = Boolean(config.providers.deepseek.apiKey);
|
|
326
|
+
const hasOpenaiCompatible = Boolean(config.providers.openaiCompatible.apiKey);
|
|
326
327
|
console.log(`OpenRouter API: ${hasOpenrouter ? "[set]" : "[not set]"}`);
|
|
327
328
|
console.log(`Anthropic API: ${hasAnthropic ? "[set]" : "[not set]"}`);
|
|
328
329
|
console.log(`OpenAI API: ${hasOpenai ? "[set]" : "[not set]"}`);
|
|
329
330
|
console.log(`Gemini API: ${hasGemini ? "[set]" : "[not set]"}`);
|
|
330
331
|
console.log(`DeepSeek API: ${hasDeepseek ? "[set]" : "[not set]"}`);
|
|
332
|
+
console.log(`OpenAI Compatible API: ${hasOpenaiCompatible ? "[set]" : "[not set]"}`);
|
|
331
333
|
}
|
|
332
334
|
});
|
|
333
335
|
program.parse();
|
package/dist/cli/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../../src/cli/index.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * nanobot CLI - Personal AI Assistant\n */\n\nimport { Command } from \"commander\";\nimport { existsSync, writeFileSync, mkdirSync } from \"node:fs\";\nimport { join, dirname } from \"node:path\";\nimport { VERSION, LOGO } from \"../index.js\";\nimport { loadConfig, saveConfig } from \"../config/loader.js\";\nimport { getConfigPath, getDataDir } from \"../config/loader.js\";\nimport {\n ConfigSchema,\n getConfigWorkspacePath,\n getApiKey,\n getApiBase,\n} from \"../config/schema.js\";\nimport type { Config } from \"../config/schema.js\";\n\nconst program = new Command();\n\nprogram\n .name(\"nanobot\")\n .description(`${LOGO} nanobot - Personal AI Assistant`)\n .version(`${LOGO} nanobot v${VERSION}`, \"-v, --version\");\n\n// ============================================================================\n// Onboard / Setup\n// ============================================================================\n\nprogram\n .command(\"onboard\")\n .description(\"Initialize nanobot configuration and workspace\")\n .action(() => {\n const configPath = getConfigPath();\n\n if (existsSync(configPath)) {\n console.log(`Config already exists at ${configPath}`);\n console.log(\"Delete it first if you want to start fresh.\");\n return;\n }\n\n // Create default config\n const config = ConfigSchema.parse({});\n saveConfig(config);\n console.log(`Created config at ${configPath}`);\n\n // Create workspace\n const workspace = getConfigWorkspacePath(config);\n createWorkspaceTemplates(workspace);\n\n console.log(`\\n${LOGO} nanobot is ready!`);\n console.log(\"\\nNext steps:\");\n console.log(\" 1. Add your API key to ~/.nanobot/config.json\");\n console.log(\" Get one at: https://openrouter.ai/keys\");\n console.log(' 2. Chat: nanobot agent -m \"Hello!\"');\n console.log(\n \"\\nWant Telegram? See: https://github.com/HKUDS/nanobot#-chat-apps\",\n );\n });\n\nfunction createWorkspaceTemplates(workspace: string): void {\n if (!existsSync(workspace)) {\n mkdirSync(workspace, { recursive: true });\n }\n\n const templates: Record<string, string> = {\n \"AGENTS.md\": `# Agent Instructions\n\nYou are a helpful AI assistant. Be concise, accurate, and friendly.\n\n## Guidelines\n\n- Always explain what you're doing before taking actions\n- Ask for clarification when the request is ambiguous\n- Use tools to help accomplish tasks\n- Remember important information in your memory files\n`,\n \"SOUL.md\": `# Soul\n\nI am nanobot, a lightweight AI assistant.\n\n## Personality\n\n- Helpful and friendly\n- Concise and to the point\n- Curious and eager to learn\n\n## Values\n\n- Accuracy over speed\n- User privacy and safety\n- Transparency in actions\n`,\n \"USER.md\": `# User\n\nInformation about the user goes here.\n\n## Preferences\n\n- Communication style: (casual/formal)\n- Timezone: (your timezone)\n- Language: (your preferred language)\n`,\n };\n\n for (const [filename, content] of Object.entries(templates)) {\n const filePath = join(workspace, filename);\n if (!existsSync(filePath)) {\n writeFileSync(filePath, content);\n console.log(` Created ${filename}`);\n }\n }\n\n // Create memory directory and MEMORY.md\n const memoryDir = join(workspace, \"memory\");\n if (!existsSync(memoryDir)) {\n mkdirSync(memoryDir, { recursive: true });\n }\n const memoryFile = join(memoryDir, \"MEMORY.md\");\n if (!existsSync(memoryFile)) {\n writeFileSync(\n memoryFile,\n `# Long-term Memory\n\nThis file stores important information that should persist across sessions.\n\n## User Information\n\n(Important facts about the user)\n\n## Preferences\n\n(User preferences learned over time)\n\n## Important Notes\n\n(Things to remember)\n`,\n );\n console.log(\" Created memory/MEMORY.md\");\n }\n}\n\n// ============================================================================\n// Gateway / Server\n// ============================================================================\n\nprogram\n .command(\"gateway\")\n .description(\"Start the nanobot gateway\")\n .option(\"-p, --port <number>\", \"Gateway port\", \"18790\")\n .option(\"--verbose\", \"Verbose output\", false)\n .action(async (opts) => {\n console.log(\n `${LOGO} Starting nanobot gateway on port ${opts.port}...`,\n );\n\n const config = loadConfig();\n const apiKey = getApiKey(config);\n const apiBase = getApiBase(config);\n const model = config.agents.defaults.model;\n\n if (!apiKey) {\n console.error(\"Error: No API key configured.\");\n console.error(\n \"Set one in ~/.nanobot/config.json under providers.openrouter.apiKey\",\n );\n process.exit(1);\n }\n\n // Dynamic imports to avoid loading heavy deps up front\n const { MessageBus } = await import(\"../bus/queue.js\");\n const { OpenAIProvider } = await import(\n \"../providers/openai-provider.js\"\n );\n const { AgentLoop } = await import(\"../agent/loop.js\");\n const { ChannelManager } = await import(\"../channels/manager.js\");\n const { CronService } = await import(\"../cron/service.js\");\n const { HeartbeatService } = await import(\n \"../heartbeat/service.js\"\n );\n\n const bus = new MessageBus();\n const workspace = getConfigWorkspacePath(config);\n\n const provider = new OpenAIProvider({\n apiKey,\n apiBase: apiBase ?? undefined,\n defaultModel: model,\n });\n\n // Create cron service\n const cronStorePath = join(getDataDir(), \"cron\", \"jobs.json\");\n const cron = new CronService(cronStorePath);\n\n // Create agent\n const agent = new AgentLoop({\n bus,\n provider,\n workspace,\n model,\n maxIterations: config.agents.defaults.maxToolIterations,\n braveApiKey: config.tools.web.search.apiKey || undefined,\n execConfig: config.tools.exec,\n cronService: cron,\n });\n\n // Wire cron callback\n cron.onJob = async (job) => {\n const response = await agent.processDirect(\n job.payload.message,\n `cron:${job.id}`,\n job.payload.channel ?? \"cli\",\n job.payload.to ?? \"direct\",\n );\n\n if (job.payload.deliver && job.payload.to) {\n const { createOutboundMessage } = await import(\n \"../bus/events.js\"\n );\n await bus.publishOutbound(\n createOutboundMessage({\n channel: job.payload.channel ?? \"cli\",\n chatId: job.payload.to,\n content: response ?? \"\",\n }),\n );\n }\n return response;\n };\n\n // Create heartbeat\n const heartbeat = new HeartbeatService({\n workspace,\n onHeartbeat: (prompt) =>\n agent.processDirect(prompt, \"heartbeat\"),\n intervalS: 30 * 60,\n enabled: true,\n });\n\n // Create channel manager\n const channels = new ChannelManager(config, bus);\n\n if (channels.enabledChannels.length > 0) {\n console.log(\n `Channels enabled: ${channels.enabledChannels.join(\", \")}`,\n );\n } else {\n console.log(\"Warning: No channels enabled\");\n }\n\n const cronStatus = cron.status();\n if (cronStatus.jobs > 0) {\n console.log(`Cron: ${cronStatus.jobs} scheduled jobs`);\n }\n console.log(\"Heartbeat: every 30m\");\n\n // Handle graceful shutdown\n const shutdown = async () => {\n console.log(\"\\nShutting down...\");\n heartbeat.stop();\n cron.stop();\n agent.stop();\n await channels.stopAll();\n process.exit(0);\n };\n process.on(\"SIGINT\", shutdown);\n process.on(\"SIGTERM\", shutdown);\n\n try {\n await cron.start();\n await heartbeat.start();\n await Promise.all([agent.run(), channels.startAll()]);\n } catch (err) {\n console.error(\"Gateway error:\", err);\n process.exit(1);\n }\n });\n\n// ============================================================================\n// Agent Commands\n// ============================================================================\n\nprogram\n .command(\"agent\")\n .description(\"Interact with the agent directly\")\n .option(\"-m, --message <text>\", \"Message to send to the agent\")\n .option(\n \"-s, --session <id>\",\n \"Session ID\",\n \"cli:default\",\n )\n .action(async (opts) => {\n const config = loadConfig();\n const apiKey = getApiKey(config);\n const apiBase = getApiBase(config);\n\n if (!apiKey) {\n console.error(\"Error: No API key configured.\");\n process.exit(1);\n }\n\n const { MessageBus } = await import(\"../bus/queue.js\");\n const { OpenAIProvider } = await import(\n \"../providers/openai-provider.js\"\n );\n const { AgentLoop } = await import(\"../agent/loop.js\");\n\n const bus = new MessageBus();\n const workspace = getConfigWorkspacePath(config);\n\n const provider = new OpenAIProvider({\n apiKey,\n apiBase: apiBase ?? undefined,\n defaultModel: config.agents.defaults.model,\n });\n\n const agentLoop = new AgentLoop({\n bus,\n provider,\n workspace,\n braveApiKey: config.tools.web.search.apiKey || undefined,\n execConfig: config.tools.exec,\n });\n\n if (opts.message) {\n // Single message mode\n const response = await agentLoop.processDirect(\n opts.message,\n opts.session,\n );\n console.log(`\\n${LOGO} ${response}`);\n } else {\n // Interactive mode\n console.log(`${LOGO} Interactive mode (Ctrl+C to exit)\\n`);\n\n const readline = await import(\"node:readline\");\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n\n const ask = (): void => {\n rl.question(\"You: \", async (input) => {\n const trimmed = input.trim();\n if (!trimmed) {\n ask();\n return;\n }\n\n try {\n const response = await agentLoop.processDirect(\n trimmed,\n opts.session,\n );\n console.log(`\\n${LOGO} ${response}\\n`);\n } catch (err) {\n console.error(\"Error:\", err);\n }\n ask();\n });\n };\n\n rl.on(\"close\", () => {\n console.log(\"\\nGoodbye!\");\n process.exit(0);\n });\n\n ask();\n }\n });\n\n// ============================================================================\n// Channel Commands\n// ============================================================================\n\nconst channelsCmd = program\n .command(\"channels\")\n .description(\"Manage channels\");\n\nchannelsCmd\n .command(\"status\")\n .description(\"Show channel status\")\n .action(() => {\n const config = loadConfig();\n\n console.log(\"Channel Status\");\n console.log(\"─\".repeat(50));\n\n const tg = config.channels.telegram;\n const tgToken = tg.token\n ? `token: ${tg.token.slice(0, 10)}...`\n : \"not configured\";\n console.log(\n ` Telegram ${tg.enabled ? \"[enabled]\" : \"[disabled]\"} ${tgToken}`,\n );\n });\n\n// ============================================================================\n// Cron Commands\n// ============================================================================\n\nconst cronCmd = program\n .command(\"cron\")\n .description(\"Manage scheduled tasks\");\n\ncronCmd\n .command(\"list\")\n .description(\"List scheduled jobs\")\n .option(\"-a, --all\", \"Include disabled jobs\", false)\n .action((opts) => {\n const { CronService } = require(\"../cron/service.js\") as typeof import(\"../cron/service.js\");\n\n const storePath = join(getDataDir(), \"cron\", \"jobs.json\");\n const service = new CronService(storePath);\n\n const jobs = service.listJobs(opts.all);\n\n if (jobs.length === 0) {\n console.log(\"No scheduled jobs.\");\n return;\n }\n\n console.log(\"Scheduled Jobs\");\n console.log(\"─\".repeat(70));\n console.log(\n `${\"ID\".padEnd(10)} ${\"Name\".padEnd(20)} ${\"Schedule\".padEnd(18)} ${\"Status\".padEnd(10)} Next Run`,\n );\n console.log(\"─\".repeat(70));\n\n for (const job of jobs) {\n let sched: string;\n if (job.schedule.kind === \"every\") {\n sched = `every ${(job.schedule.everyMs ?? 0) / 1000}s`;\n } else if (job.schedule.kind === \"cron\") {\n sched = job.schedule.expr ?? \"\";\n } else {\n sched = \"one-time\";\n }\n\n let nextRun = \"\";\n if (job.state.nextRunAtMs) {\n nextRun = new Date(job.state.nextRunAtMs).toLocaleString();\n }\n\n const status = job.enabled ? \"enabled\" : \"disabled\";\n\n console.log(\n `${job.id.padEnd(10)} ${job.name.padEnd(20)} ${sched.padEnd(18)} ${status.padEnd(10)} ${nextRun}`,\n );\n }\n });\n\ncronCmd\n .command(\"add\")\n .description(\"Add a scheduled job\")\n .requiredOption(\"-n, --name <name>\", \"Job name\")\n .requiredOption(\"-m, --message <text>\", \"Message for agent\")\n .option(\"-e, --every <seconds>\", \"Run every N seconds\")\n .option(\"-c, --cron <expr>\", \"Cron expression (e.g. '0 9 * * *')\")\n .option(\"--at <iso>\", \"Run once at time (ISO format)\")\n .option(\"-d, --deliver\", \"Deliver response to channel\", false)\n .option(\"--to <recipient>\", \"Recipient for delivery\")\n .option(\"--channel <name>\", \"Channel for delivery\")\n .action((opts) => {\n const { CronService } = require(\"../cron/service.js\") as typeof import(\"../cron/service.js\");\n\n let schedule: { kind: string; everyMs?: number; expr?: string; atMs?: number };\n if (opts.every) {\n schedule = { kind: \"every\", everyMs: Number(opts.every) * 1000 };\n } else if (opts.cron) {\n schedule = { kind: \"cron\", expr: opts.cron };\n } else if (opts.at) {\n const dt = new Date(opts.at);\n schedule = { kind: \"at\", atMs: dt.getTime() };\n } else {\n console.error(\"Error: Must specify --every, --cron, or --at\");\n process.exit(1);\n }\n\n const storePath = join(getDataDir(), \"cron\", \"jobs.json\");\n const service = new CronService(storePath);\n\n const job = service.addJob({\n name: opts.name,\n schedule: schedule as import(\"../cron/types.js\").CronSchedule,\n message: opts.message,\n deliver: opts.deliver,\n to: opts.to,\n channel: opts.channel,\n });\n\n console.log(`Added job '${job.name}' (${job.id})`);\n });\n\ncronCmd\n .command(\"remove\")\n .description(\"Remove a scheduled job\")\n .argument(\"<jobId>\", \"Job ID to remove\")\n .action((jobId: string) => {\n const { CronService } = require(\"../cron/service.js\") as typeof import(\"../cron/service.js\");\n\n const storePath = join(getDataDir(), \"cron\", \"jobs.json\");\n const service = new CronService(storePath);\n\n if (service.removeJob(jobId)) {\n console.log(`Removed job ${jobId}`);\n } else {\n console.error(`Job ${jobId} not found`);\n }\n });\n\ncronCmd\n .command(\"enable\")\n .description(\"Enable or disable a job\")\n .argument(\"<jobId>\", \"Job ID\")\n .option(\"--disable\", \"Disable instead of enable\", false)\n .action((jobId: string, opts: { disable: boolean }) => {\n const { CronService } = require(\"../cron/service.js\") as typeof import(\"../cron/service.js\");\n\n const storePath = join(getDataDir(), \"cron\", \"jobs.json\");\n const service = new CronService(storePath);\n\n const job = service.enableJob(jobId, !opts.disable);\n if (job) {\n const status = opts.disable ? \"disabled\" : \"enabled\";\n console.log(`Job '${job.name}' ${status}`);\n } else {\n console.error(`Job ${jobId} not found`);\n }\n });\n\n// ============================================================================\n// Status\n// ============================================================================\n\nprogram\n .command(\"status\")\n .description(\"Show nanobot status\")\n .action(() => {\n const configPath = getConfigPath();\n const config = loadConfig();\n const workspace = getConfigWorkspacePath(config);\n\n console.log(`${LOGO} nanobot Status\\n`);\n\n console.log(\n `Config: ${configPath} ${existsSync(configPath) ? \"[ok]\" : \"[missing]\"}`,\n );\n console.log(\n `Workspace: ${workspace} ${existsSync(workspace) ? \"[ok]\" : \"[missing]\"}`,\n );\n\n if (existsSync(configPath)) {\n console.log(`Model: ${config.agents.defaults.model}`);\n\n const hasOpenrouter = Boolean(config.providers.openrouter.apiKey);\n const hasAnthropic = Boolean(config.providers.anthropic.apiKey);\n const hasOpenai = Boolean(config.providers.openai.apiKey);\n const hasGemini = Boolean(config.providers.gemini.apiKey);\n const hasDeepseek = Boolean(config.providers.deepseek.apiKey);\n\n console.log(\n `OpenRouter API: ${hasOpenrouter ? \"[set]\" : \"[not set]\"}`,\n );\n console.log(\n `Anthropic API: ${hasAnthropic ? \"[set]\" : \"[not set]\"}`,\n );\n console.log(\n `OpenAI API: ${hasOpenai ? \"[set]\" : \"[not set]\"}`,\n );\n console.log(\n `Gemini API: ${hasGemini ? \"[set]\" : \"[not set]\"}`,\n );\n console.log(\n `DeepSeek API: ${hasDeepseek ? \"[set]\" : \"[not set]\"}`,\n );\n }\n });\n\nprogram.parse();\n"],"mappings":";;;;;;;;;;;;;;AAmBA,MAAM,UAAU,IAAI,SAAS;AAE7B,QACG,KAAK,UAAU,CACf,YAAY,GAAG,KAAK,kCAAkC,CACtD,QAAQ,GAAG,KAAK,YAAY,WAAW,gBAAgB;AAM1D,QACG,QAAQ,UAAU,CAClB,YAAY,iDAAiD,CAC7D,aAAa;CACZ,MAAM,aAAa,eAAe;AAElC,KAAI,WAAW,WAAW,EAAE;AAC1B,UAAQ,IAAI,4BAA4B,aAAa;AACrD,UAAQ,IAAI,8CAA8C;AAC1D;;CAIF,MAAM,SAAS,aAAa,MAAM,EAAE,CAAC;AACrC,YAAW,OAAO;AAClB,SAAQ,IAAI,qBAAqB,aAAa;AAI9C,0BADkB,uBAAuB,OAAO,CACb;AAEnC,SAAQ,IAAI,KAAK,KAAK,oBAAoB;AAC1C,SAAQ,IAAI,gBAAgB;AAC5B,SAAQ,IAAI,kDAAkD;AAC9D,SAAQ,IAAI,8CAA8C;AAC1D,SAAQ,IAAI,yCAAuC;AACnD,SAAQ,IACN,oEACD;EACD;AAEJ,SAAS,yBAAyB,WAAyB;AACzD,KAAI,CAAC,WAAW,UAAU,CACxB,WAAU,WAAW,EAAE,WAAW,MAAM,CAAC;AA2C3C,MAAK,MAAM,CAAC,UAAU,YAAY,OAAO,QAxCC;EACxC,aAAa;;;;;;;;;;;EAWb,WAAW;;;;;;;;;;;;;;;;EAgBX,WAAW;;;;;;;;;;EAUZ,CAE0D,EAAE;EAC3D,MAAM,WAAW,KAAK,WAAW,SAAS;AAC1C,MAAI,CAAC,WAAW,SAAS,EAAE;AACzB,iBAAc,UAAU,QAAQ;AAChC,WAAQ,IAAI,aAAa,WAAW;;;CAKxC,MAAM,YAAY,KAAK,WAAW,SAAS;AAC3C,KAAI,CAAC,WAAW,UAAU,CACxB,WAAU,WAAW,EAAE,WAAW,MAAM,CAAC;CAE3C,MAAM,aAAa,KAAK,WAAW,YAAY;AAC/C,KAAI,CAAC,WAAW,WAAW,EAAE;AAC3B,gBACE,YACA;;;;;;;;;;;;;;;EAgBD;AACD,UAAQ,IAAI,6BAA6B;;;AAQ7C,QACG,QAAQ,UAAU,CAClB,YAAY,4BAA4B,CACxC,OAAO,uBAAuB,gBAAgB,QAAQ,CACtD,OAAO,aAAa,kBAAkB,MAAM,CAC5C,OAAO,OAAO,SAAS;AACtB,SAAQ,IACN,GAAG,KAAK,oCAAoC,KAAK,KAAK,KACvD;CAED,MAAM,SAAS,YAAY;CAC3B,MAAM,SAAS,UAAU,OAAO;CAChC,MAAM,UAAU,WAAW,OAAO;CAClC,MAAM,QAAQ,OAAO,OAAO,SAAS;AAErC,KAAI,CAAC,QAAQ;AACX,UAAQ,MAAM,gCAAgC;AAC9C,UAAQ,MACN,sEACD;AACD,UAAQ,KAAK,EAAE;;CAIjB,MAAM,EAAE,eAAe,MAAM,OAAO;CACpC,MAAM,EAAE,mBAAmB,MAAM,OAC/B;CAEF,MAAM,EAAE,cAAc,MAAM,OAAO;CACnC,MAAM,EAAE,mBAAmB,MAAM,OAAO;CACxC,MAAM,EAAE,gBAAgB,MAAM,OAAO;CACrC,MAAM,EAAE,qBAAqB,MAAM,OACjC;CAGF,MAAM,MAAM,IAAI,YAAY;CAC5B,MAAM,YAAY,uBAAuB,OAAO;CAEhD,MAAM,WAAW,IAAI,eAAe;EAClC;EACA,SAAS,WAAW;EACpB,cAAc;EACf,CAAC;CAIF,MAAM,OAAO,IAAI,YADK,KAAK,YAAY,EAAE,QAAQ,YAAY,CAClB;CAG3C,MAAM,QAAQ,IAAI,UAAU;EAC1B;EACA;EACA;EACA;EACA,eAAe,OAAO,OAAO,SAAS;EACtC,aAAa,OAAO,MAAM,IAAI,OAAO,UAAU;EAC/C,YAAY,OAAO,MAAM;EACzB,aAAa;EACd,CAAC;AAGF,MAAK,QAAQ,OAAO,QAAQ;EAC1B,MAAM,WAAW,MAAM,MAAM,cAC3B,IAAI,QAAQ,SACZ,QAAQ,IAAI,MACZ,IAAI,QAAQ,WAAW,OACvB,IAAI,QAAQ,MAAM,SACnB;AAED,MAAI,IAAI,QAAQ,WAAW,IAAI,QAAQ,IAAI;GACzC,MAAM,EAAE,0BAA0B,MAAM,OACtC;AAEF,SAAM,IAAI,gBACR,sBAAsB;IACpB,SAAS,IAAI,QAAQ,WAAW;IAChC,QAAQ,IAAI,QAAQ;IACpB,SAAS,YAAY;IACtB,CAAC,CACH;;AAEH,SAAO;;CAIT,MAAM,YAAY,IAAI,iBAAiB;EACrC;EACA,cAAc,WACZ,MAAM,cAAc,QAAQ,YAAY;EAC1C,WAAW;EACX,SAAS;EACV,CAAC;CAGF,MAAM,WAAW,IAAI,eAAe,QAAQ,IAAI;AAEhD,KAAI,SAAS,gBAAgB,SAAS,EACpC,SAAQ,IACN,qBAAqB,SAAS,gBAAgB,KAAK,KAAK,GACzD;KAED,SAAQ,IAAI,+BAA+B;CAG7C,MAAM,aAAa,KAAK,QAAQ;AAChC,KAAI,WAAW,OAAO,EACpB,SAAQ,IAAI,SAAS,WAAW,KAAK,iBAAiB;AAExD,SAAQ,IAAI,uBAAuB;CAGnC,MAAM,WAAW,YAAY;AAC3B,UAAQ,IAAI,qBAAqB;AACjC,YAAU,MAAM;AAChB,OAAK,MAAM;AACX,QAAM,MAAM;AACZ,QAAM,SAAS,SAAS;AACxB,UAAQ,KAAK,EAAE;;AAEjB,SAAQ,GAAG,UAAU,SAAS;AAC9B,SAAQ,GAAG,WAAW,SAAS;AAE/B,KAAI;AACF,QAAM,KAAK,OAAO;AAClB,QAAM,UAAU,OAAO;AACvB,QAAM,QAAQ,IAAI,CAAC,MAAM,KAAK,EAAE,SAAS,UAAU,CAAC,CAAC;UAC9C,KAAK;AACZ,UAAQ,MAAM,kBAAkB,IAAI;AACpC,UAAQ,KAAK,EAAE;;EAEjB;AAMJ,QACG,QAAQ,QAAQ,CAChB,YAAY,mCAAmC,CAC/C,OAAO,wBAAwB,+BAA+B,CAC9D,OACC,sBACA,cACA,cACD,CACA,OAAO,OAAO,SAAS;CACtB,MAAM,SAAS,YAAY;CAC3B,MAAM,SAAS,UAAU,OAAO;CAChC,MAAM,UAAU,WAAW,OAAO;AAElC,KAAI,CAAC,QAAQ;AACX,UAAQ,MAAM,gCAAgC;AAC9C,UAAQ,KAAK,EAAE;;CAGjB,MAAM,EAAE,eAAe,MAAM,OAAO;CACpC,MAAM,EAAE,mBAAmB,MAAM,OAC/B;CAEF,MAAM,EAAE,cAAc,MAAM,OAAO;CAEnC,MAAM,MAAM,IAAI,YAAY;CAC5B,MAAM,YAAY,uBAAuB,OAAO;CAQhD,MAAM,YAAY,IAAI,UAAU;EAC9B;EACA,UARe,IAAI,eAAe;GAClC;GACA,SAAS,WAAW;GACpB,cAAc,OAAO,OAAO,SAAS;GACtC,CAAC;EAKA;EACA,aAAa,OAAO,MAAM,IAAI,OAAO,UAAU;EAC/C,YAAY,OAAO,MAAM;EAC1B,CAAC;AAEF,KAAI,KAAK,SAAS;EAEhB,MAAM,WAAW,MAAM,UAAU,cAC/B,KAAK,SACL,KAAK,QACN;AACD,UAAQ,IAAI,KAAK,KAAK,GAAG,WAAW;QAC/B;AAEL,UAAQ,IAAI,GAAG,KAAK,sCAAsC;EAG1D,MAAM,MADW,MAAM,OAAO,kBACV,gBAAgB;GAClC,OAAO,QAAQ;GACf,QAAQ,QAAQ;GACjB,CAAC;EAEF,MAAM,YAAkB;AACtB,MAAG,SAAS,SAAS,OAAO,UAAU;IACpC,MAAM,UAAU,MAAM,MAAM;AAC5B,QAAI,CAAC,SAAS;AACZ,UAAK;AACL;;AAGF,QAAI;KACF,MAAM,WAAW,MAAM,UAAU,cAC/B,SACA,KAAK,QACN;AACD,aAAQ,IAAI,KAAK,KAAK,GAAG,SAAS,IAAI;aAC/B,KAAK;AACZ,aAAQ,MAAM,UAAU,IAAI;;AAE9B,SAAK;KACL;;AAGJ,KAAG,GAAG,eAAe;AACnB,WAAQ,IAAI,aAAa;AACzB,WAAQ,KAAK,EAAE;IACf;AAEF,OAAK;;EAEP;AAMgB,QACjB,QAAQ,WAAW,CACnB,YAAY,kBAAkB,CAG9B,QAAQ,SAAS,CACjB,YAAY,sBAAsB,CAClC,aAAa;CACZ,MAAM,SAAS,YAAY;AAE3B,SAAQ,IAAI,iBAAiB;AAC7B,SAAQ,IAAI,IAAI,OAAO,GAAG,CAAC;CAE3B,MAAM,KAAK,OAAO,SAAS;CAC3B,MAAM,UAAU,GAAG,QACf,UAAU,GAAG,MAAM,MAAM,GAAG,GAAG,CAAC,OAChC;AACJ,SAAQ,IACN,eAAe,GAAG,UAAU,cAAc,aAAa,IAAI,UAC5D;EACD;AAMJ,MAAM,UAAU,QACb,QAAQ,OAAO,CACf,YAAY,yBAAyB;AAExC,QACG,QAAQ,OAAO,CACf,YAAY,sBAAsB,CAClC,OAAO,aAAa,yBAAyB,MAAM,CACnD,QAAQ,SAAS;CAChB,MAAM,EAAE;CAKR,MAAM,OAFU,IAAI,YADF,KAAK,YAAY,EAAE,QAAQ,YAAY,CACf,CAErB,SAAS,KAAK,IAAI;AAEvC,KAAI,KAAK,WAAW,GAAG;AACrB,UAAQ,IAAI,qBAAqB;AACjC;;AAGF,SAAQ,IAAI,iBAAiB;AAC7B,SAAQ,IAAI,IAAI,OAAO,GAAG,CAAC;AAC3B,SAAQ,IACN,GAAG,KAAK,OAAO,GAAG,CAAC,GAAG,OAAO,OAAO,GAAG,CAAC,GAAG,WAAW,OAAO,GAAG,CAAC,GAAG,SAAS,OAAO,GAAG,CAAC,WACzF;AACD,SAAQ,IAAI,IAAI,OAAO,GAAG,CAAC;AAE3B,MAAK,MAAM,OAAO,MAAM;EACtB,IAAI;AACJ,MAAI,IAAI,SAAS,SAAS,QACxB,SAAQ,UAAU,IAAI,SAAS,WAAW,KAAK,IAAK;WAC3C,IAAI,SAAS,SAAS,OAC/B,SAAQ,IAAI,SAAS,QAAQ;MAE7B,SAAQ;EAGV,IAAI,UAAU;AACd,MAAI,IAAI,MAAM,YACZ,WAAU,IAAI,KAAK,IAAI,MAAM,YAAY,CAAC,gBAAgB;EAG5D,MAAM,SAAS,IAAI,UAAU,YAAY;AAEzC,UAAQ,IACN,GAAG,IAAI,GAAG,OAAO,GAAG,CAAC,GAAG,IAAI,KAAK,OAAO,GAAG,CAAC,GAAG,MAAM,OAAO,GAAG,CAAC,GAAG,OAAO,OAAO,GAAG,CAAC,GAAG,UACzF;;EAEH;AAEJ,QACG,QAAQ,MAAM,CACd,YAAY,sBAAsB,CAClC,eAAe,qBAAqB,WAAW,CAC/C,eAAe,wBAAwB,oBAAoB,CAC3D,OAAO,yBAAyB,sBAAsB,CACtD,OAAO,qBAAqB,qCAAqC,CACjE,OAAO,cAAc,gCAAgC,CACrD,OAAO,iBAAiB,+BAA+B,MAAM,CAC7D,OAAO,oBAAoB,yBAAyB,CACpD,OAAO,oBAAoB,uBAAuB,CAClD,QAAQ,SAAS;CAChB,MAAM,EAAE;CAER,IAAI;AACJ,KAAI,KAAK,MACP,YAAW;EAAE,MAAM;EAAS,SAAS,OAAO,KAAK,MAAM,GAAG;EAAM;UACvD,KAAK,KACd,YAAW;EAAE,MAAM;EAAQ,MAAM,KAAK;EAAM;UACnC,KAAK,GAEd,YAAW;EAAE,MAAM;EAAM,MADd,IAAI,KAAK,KAAK,GAAG,CACM,SAAS;EAAE;MACxC;AACL,UAAQ,MAAM,+CAA+C;AAC7D,UAAQ,KAAK,EAAE;;CAMjB,MAAM,MAFU,IAAI,YADF,KAAK,YAAY,EAAE,QAAQ,YAAY,CACf,CAEtB,OAAO;EACzB,MAAM,KAAK;EACD;EACV,SAAS,KAAK;EACd,SAAS,KAAK;EACd,IAAI,KAAK;EACT,SAAS,KAAK;EACf,CAAC;AAEF,SAAQ,IAAI,cAAc,IAAI,KAAK,KAAK,IAAI,GAAG,GAAG;EAClD;AAEJ,QACG,QAAQ,SAAS,CACjB,YAAY,yBAAyB,CACrC,SAAS,WAAW,mBAAmB,CACvC,QAAQ,UAAkB;CACzB,MAAM,EAAE;AAKR,KAFgB,IAAI,YADF,KAAK,YAAY,EAAE,QAAQ,YAAY,CACf,CAE9B,UAAU,MAAM,CAC1B,SAAQ,IAAI,eAAe,QAAQ;KAEnC,SAAQ,MAAM,OAAO,MAAM,YAAY;EAEzC;AAEJ,QACG,QAAQ,SAAS,CACjB,YAAY,0BAA0B,CACtC,SAAS,WAAW,SAAS,CAC7B,OAAO,aAAa,6BAA6B,MAAM,CACvD,QAAQ,OAAe,SAA+B;CACrD,MAAM,EAAE;CAKR,MAAM,MAFU,IAAI,YADF,KAAK,YAAY,EAAE,QAAQ,YAAY,CACf,CAEtB,UAAU,OAAO,CAAC,KAAK,QAAQ;AACnD,KAAI,KAAK;EACP,MAAM,SAAS,KAAK,UAAU,aAAa;AAC3C,UAAQ,IAAI,QAAQ,IAAI,KAAK,IAAI,SAAS;OAE1C,SAAQ,MAAM,OAAO,MAAM,YAAY;EAEzC;AAMJ,QACG,QAAQ,SAAS,CACjB,YAAY,sBAAsB,CAClC,aAAa;CACZ,MAAM,aAAa,eAAe;CAClC,MAAM,SAAS,YAAY;CAC3B,MAAM,YAAY,uBAAuB,OAAO;AAEhD,SAAQ,IAAI,GAAG,KAAK,mBAAmB;AAEvC,SAAQ,IACN,WAAW,WAAW,GAAG,WAAW,WAAW,GAAG,SAAS,cAC5D;AACD,SAAQ,IACN,cAAc,UAAU,GAAG,WAAW,UAAU,GAAG,SAAS,cAC7D;AAED,KAAI,WAAW,WAAW,EAAE;AAC1B,UAAQ,IAAI,UAAU,OAAO,OAAO,SAAS,QAAQ;EAErD,MAAM,gBAAgB,QAAQ,OAAO,UAAU,WAAW,OAAO;EACjE,MAAM,eAAe,QAAQ,OAAO,UAAU,UAAU,OAAO;EAC/D,MAAM,YAAY,QAAQ,OAAO,UAAU,OAAO,OAAO;EACzD,MAAM,YAAY,QAAQ,OAAO,UAAU,OAAO,OAAO;EACzD,MAAM,cAAc,QAAQ,OAAO,UAAU,SAAS,OAAO;AAE7D,UAAQ,IACN,mBAAmB,gBAAgB,UAAU,cAC9C;AACD,UAAQ,IACN,kBAAkB,eAAe,UAAU,cAC5C;AACD,UAAQ,IACN,eAAe,YAAY,UAAU,cACtC;AACD,UAAQ,IACN,eAAe,YAAY,UAAU,cACtC;AACD,UAAQ,IACN,iBAAiB,cAAc,UAAU,cAC1C;;EAEH;AAEJ,QAAQ,OAAO"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../src/cli/index.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * nanobot CLI - Personal AI Assistant\n */\n\nimport { Command } from \"commander\";\nimport { existsSync, writeFileSync, mkdirSync } from \"node:fs\";\nimport { join, dirname } from \"node:path\";\nimport { VERSION, LOGO } from \"../index.js\";\nimport { loadConfig, saveConfig } from \"../config/loader.js\";\nimport { getConfigPath, getDataDir } from \"../config/loader.js\";\nimport {\n ConfigSchema,\n getConfigWorkspacePath,\n getApiKey,\n getApiBase,\n} from \"../config/schema.js\";\nimport type { Config } from \"../config/schema.js\";\n\nconst program = new Command();\n\nprogram\n .name(\"nanobot\")\n .description(`${LOGO} nanobot - Personal AI Assistant`)\n .version(`${LOGO} nanobot v${VERSION}`, \"-v, --version\");\n\n// ============================================================================\n// Onboard / Setup\n// ============================================================================\n\nprogram\n .command(\"onboard\")\n .description(\"Initialize nanobot configuration and workspace\")\n .action(() => {\n const configPath = getConfigPath();\n\n if (existsSync(configPath)) {\n console.log(`Config already exists at ${configPath}`);\n console.log(\"Delete it first if you want to start fresh.\");\n return;\n }\n\n // Create default config\n const config = ConfigSchema.parse({});\n saveConfig(config);\n console.log(`Created config at ${configPath}`);\n\n // Create workspace\n const workspace = getConfigWorkspacePath(config);\n createWorkspaceTemplates(workspace);\n\n console.log(`\\n${LOGO} nanobot is ready!`);\n console.log(\"\\nNext steps:\");\n console.log(\" 1. Add your API key to ~/.nanobot/config.json\");\n console.log(\" Get one at: https://openrouter.ai/keys\");\n console.log(' 2. Chat: nanobot agent -m \"Hello!\"');\n console.log(\n \"\\nWant Telegram? See: https://github.com/HKUDS/nanobot#-chat-apps\",\n );\n });\n\nfunction createWorkspaceTemplates(workspace: string): void {\n if (!existsSync(workspace)) {\n mkdirSync(workspace, { recursive: true });\n }\n\n const templates: Record<string, string> = {\n \"AGENTS.md\": `# Agent Instructions\n\nYou are a helpful AI assistant. Be concise, accurate, and friendly.\n\n## Guidelines\n\n- Always explain what you're doing before taking actions\n- Ask for clarification when the request is ambiguous\n- Use tools to help accomplish tasks\n- Remember important information in your memory files\n`,\n \"SOUL.md\": `# Soul\n\nI am nanobot, a lightweight AI assistant.\n\n## Personality\n\n- Helpful and friendly\n- Concise and to the point\n- Curious and eager to learn\n\n## Values\n\n- Accuracy over speed\n- User privacy and safety\n- Transparency in actions\n`,\n \"USER.md\": `# User\n\nInformation about the user goes here.\n\n## Preferences\n\n- Communication style: (casual/formal)\n- Timezone: (your timezone)\n- Language: (your preferred language)\n`,\n };\n\n for (const [filename, content] of Object.entries(templates)) {\n const filePath = join(workspace, filename);\n if (!existsSync(filePath)) {\n writeFileSync(filePath, content);\n console.log(` Created ${filename}`);\n }\n }\n\n // Create memory directory and MEMORY.md\n const memoryDir = join(workspace, \"memory\");\n if (!existsSync(memoryDir)) {\n mkdirSync(memoryDir, { recursive: true });\n }\n const memoryFile = join(memoryDir, \"MEMORY.md\");\n if (!existsSync(memoryFile)) {\n writeFileSync(\n memoryFile,\n `# Long-term Memory\n\nThis file stores important information that should persist across sessions.\n\n## User Information\n\n(Important facts about the user)\n\n## Preferences\n\n(User preferences learned over time)\n\n## Important Notes\n\n(Things to remember)\n`,\n );\n console.log(\" Created memory/MEMORY.md\");\n }\n}\n\n// ============================================================================\n// Gateway / Server\n// ============================================================================\n\nprogram\n .command(\"gateway\")\n .description(\"Start the nanobot gateway\")\n .option(\"-p, --port <number>\", \"Gateway port\", \"18790\")\n .option(\"--verbose\", \"Verbose output\", false)\n .action(async (opts) => {\n console.log(\n `${LOGO} Starting nanobot gateway on port ${opts.port}...`,\n );\n\n const config = loadConfig();\n const apiKey = getApiKey(config);\n const apiBase = getApiBase(config);\n const model = config.agents.defaults.model;\n\n if (!apiKey) {\n console.error(\"Error: No API key configured.\");\n console.error(\n \"Set one in ~/.nanobot/config.json under providers.openrouter.apiKey\",\n );\n process.exit(1);\n }\n\n // Dynamic imports to avoid loading heavy deps up front\n const { MessageBus } = await import(\"../bus/queue.js\");\n const { OpenAIProvider } = await import(\n \"../providers/openai-provider.js\"\n );\n const { AgentLoop } = await import(\"../agent/loop.js\");\n const { ChannelManager } = await import(\"../channels/manager.js\");\n const { CronService } = await import(\"../cron/service.js\");\n const { HeartbeatService } = await import(\n \"../heartbeat/service.js\"\n );\n\n const bus = new MessageBus();\n const workspace = getConfigWorkspacePath(config);\n\n const provider = new OpenAIProvider({\n apiKey,\n apiBase: apiBase ?? undefined,\n defaultModel: model,\n });\n\n // Create cron service\n const cronStorePath = join(getDataDir(), \"cron\", \"jobs.json\");\n const cron = new CronService(cronStorePath);\n\n // Create agent\n const agent = new AgentLoop({\n bus,\n provider,\n workspace,\n model,\n maxIterations: config.agents.defaults.maxToolIterations,\n braveApiKey: config.tools.web.search.apiKey || undefined,\n execConfig: config.tools.exec,\n cronService: cron,\n });\n\n // Wire cron callback\n cron.onJob = async (job) => {\n const response = await agent.processDirect(\n job.payload.message,\n `cron:${job.id}`,\n job.payload.channel ?? \"cli\",\n job.payload.to ?? \"direct\",\n );\n\n if (job.payload.deliver && job.payload.to) {\n const { createOutboundMessage } = await import(\n \"../bus/events.js\"\n );\n await bus.publishOutbound(\n createOutboundMessage({\n channel: job.payload.channel ?? \"cli\",\n chatId: job.payload.to,\n content: response ?? \"\",\n }),\n );\n }\n return response;\n };\n\n // Create heartbeat\n const heartbeat = new HeartbeatService({\n workspace,\n onHeartbeat: (prompt) =>\n agent.processDirect(prompt, \"heartbeat\"),\n intervalS: 30 * 60,\n enabled: true,\n });\n\n // Create channel manager\n const channels = new ChannelManager(config, bus);\n\n if (channels.enabledChannels.length > 0) {\n console.log(\n `Channels enabled: ${channels.enabledChannels.join(\", \")}`,\n );\n } else {\n console.log(\"Warning: No channels enabled\");\n }\n\n const cronStatus = cron.status();\n if (cronStatus.jobs > 0) {\n console.log(`Cron: ${cronStatus.jobs} scheduled jobs`);\n }\n console.log(\"Heartbeat: every 30m\");\n\n // Handle graceful shutdown\n const shutdown = async () => {\n console.log(\"\\nShutting down...\");\n heartbeat.stop();\n cron.stop();\n agent.stop();\n await channels.stopAll();\n process.exit(0);\n };\n process.on(\"SIGINT\", shutdown);\n process.on(\"SIGTERM\", shutdown);\n\n try {\n await cron.start();\n await heartbeat.start();\n await Promise.all([agent.run(), channels.startAll()]);\n } catch (err) {\n console.error(\"Gateway error:\", err);\n process.exit(1);\n }\n });\n\n// ============================================================================\n// Agent Commands\n// ============================================================================\n\nprogram\n .command(\"agent\")\n .description(\"Interact with the agent directly\")\n .option(\"-m, --message <text>\", \"Message to send to the agent\")\n .option(\n \"-s, --session <id>\",\n \"Session ID\",\n \"cli:default\",\n )\n .action(async (opts) => {\n const config = loadConfig();\n const apiKey = getApiKey(config);\n const apiBase = getApiBase(config);\n\n if (!apiKey) {\n console.error(\"Error: No API key configured.\");\n process.exit(1);\n }\n\n const { MessageBus } = await import(\"../bus/queue.js\");\n const { OpenAIProvider } = await import(\n \"../providers/openai-provider.js\"\n );\n const { AgentLoop } = await import(\"../agent/loop.js\");\n\n const bus = new MessageBus();\n const workspace = getConfigWorkspacePath(config);\n\n const provider = new OpenAIProvider({\n apiKey,\n apiBase: apiBase ?? undefined,\n defaultModel: config.agents.defaults.model,\n });\n\n const agentLoop = new AgentLoop({\n bus,\n provider,\n workspace,\n braveApiKey: config.tools.web.search.apiKey || undefined,\n execConfig: config.tools.exec,\n });\n\n if (opts.message) {\n // Single message mode\n const response = await agentLoop.processDirect(\n opts.message,\n opts.session,\n );\n console.log(`\\n${LOGO} ${response}`);\n } else {\n // Interactive mode\n console.log(`${LOGO} Interactive mode (Ctrl+C to exit)\\n`);\n\n const readline = await import(\"node:readline\");\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n\n const ask = (): void => {\n rl.question(\"You: \", async (input) => {\n const trimmed = input.trim();\n if (!trimmed) {\n ask();\n return;\n }\n\n try {\n const response = await agentLoop.processDirect(\n trimmed,\n opts.session,\n );\n console.log(`\\n${LOGO} ${response}\\n`);\n } catch (err) {\n console.error(\"Error:\", err);\n }\n ask();\n });\n };\n\n rl.on(\"close\", () => {\n console.log(\"\\nGoodbye!\");\n process.exit(0);\n });\n\n ask();\n }\n });\n\n// ============================================================================\n// Channel Commands\n// ============================================================================\n\nconst channelsCmd = program\n .command(\"channels\")\n .description(\"Manage channels\");\n\nchannelsCmd\n .command(\"status\")\n .description(\"Show channel status\")\n .action(() => {\n const config = loadConfig();\n\n console.log(\"Channel Status\");\n console.log(\"─\".repeat(50));\n\n const tg = config.channels.telegram;\n const tgToken = tg.token\n ? `token: ${tg.token.slice(0, 10)}...`\n : \"not configured\";\n console.log(\n ` Telegram ${tg.enabled ? \"[enabled]\" : \"[disabled]\"} ${tgToken}`,\n );\n });\n\n// ============================================================================\n// Cron Commands\n// ============================================================================\n\nconst cronCmd = program\n .command(\"cron\")\n .description(\"Manage scheduled tasks\");\n\ncronCmd\n .command(\"list\")\n .description(\"List scheduled jobs\")\n .option(\"-a, --all\", \"Include disabled jobs\", false)\n .action((opts) => {\n const { CronService } = require(\"../cron/service.js\") as typeof import(\"../cron/service.js\");\n\n const storePath = join(getDataDir(), \"cron\", \"jobs.json\");\n const service = new CronService(storePath);\n\n const jobs = service.listJobs(opts.all);\n\n if (jobs.length === 0) {\n console.log(\"No scheduled jobs.\");\n return;\n }\n\n console.log(\"Scheduled Jobs\");\n console.log(\"─\".repeat(70));\n console.log(\n `${\"ID\".padEnd(10)} ${\"Name\".padEnd(20)} ${\"Schedule\".padEnd(18)} ${\"Status\".padEnd(10)} Next Run`,\n );\n console.log(\"─\".repeat(70));\n\n for (const job of jobs) {\n let sched: string;\n if (job.schedule.kind === \"every\") {\n sched = `every ${(job.schedule.everyMs ?? 0) / 1000}s`;\n } else if (job.schedule.kind === \"cron\") {\n sched = job.schedule.expr ?? \"\";\n } else {\n sched = \"one-time\";\n }\n\n let nextRun = \"\";\n if (job.state.nextRunAtMs) {\n nextRun = new Date(job.state.nextRunAtMs).toLocaleString();\n }\n\n const status = job.enabled ? \"enabled\" : \"disabled\";\n\n console.log(\n `${job.id.padEnd(10)} ${job.name.padEnd(20)} ${sched.padEnd(18)} ${status.padEnd(10)} ${nextRun}`,\n );\n }\n });\n\ncronCmd\n .command(\"add\")\n .description(\"Add a scheduled job\")\n .requiredOption(\"-n, --name <name>\", \"Job name\")\n .requiredOption(\"-m, --message <text>\", \"Message for agent\")\n .option(\"-e, --every <seconds>\", \"Run every N seconds\")\n .option(\"-c, --cron <expr>\", \"Cron expression (e.g. '0 9 * * *')\")\n .option(\"--at <iso>\", \"Run once at time (ISO format)\")\n .option(\"-d, --deliver\", \"Deliver response to channel\", false)\n .option(\"--to <recipient>\", \"Recipient for delivery\")\n .option(\"--channel <name>\", \"Channel for delivery\")\n .action((opts) => {\n const { CronService } = require(\"../cron/service.js\") as typeof import(\"../cron/service.js\");\n\n let schedule: { kind: string; everyMs?: number; expr?: string; atMs?: number };\n if (opts.every) {\n schedule = { kind: \"every\", everyMs: Number(opts.every) * 1000 };\n } else if (opts.cron) {\n schedule = { kind: \"cron\", expr: opts.cron };\n } else if (opts.at) {\n const dt = new Date(opts.at);\n schedule = { kind: \"at\", atMs: dt.getTime() };\n } else {\n console.error(\"Error: Must specify --every, --cron, or --at\");\n process.exit(1);\n }\n\n const storePath = join(getDataDir(), \"cron\", \"jobs.json\");\n const service = new CronService(storePath);\n\n const job = service.addJob({\n name: opts.name,\n schedule: schedule as import(\"../cron/types.js\").CronSchedule,\n message: opts.message,\n deliver: opts.deliver,\n to: opts.to,\n channel: opts.channel,\n });\n\n console.log(`Added job '${job.name}' (${job.id})`);\n });\n\ncronCmd\n .command(\"remove\")\n .description(\"Remove a scheduled job\")\n .argument(\"<jobId>\", \"Job ID to remove\")\n .action((jobId: string) => {\n const { CronService } = require(\"../cron/service.js\") as typeof import(\"../cron/service.js\");\n\n const storePath = join(getDataDir(), \"cron\", \"jobs.json\");\n const service = new CronService(storePath);\n\n if (service.removeJob(jobId)) {\n console.log(`Removed job ${jobId}`);\n } else {\n console.error(`Job ${jobId} not found`);\n }\n });\n\ncronCmd\n .command(\"enable\")\n .description(\"Enable or disable a job\")\n .argument(\"<jobId>\", \"Job ID\")\n .option(\"--disable\", \"Disable instead of enable\", false)\n .action((jobId: string, opts: { disable: boolean }) => {\n const { CronService } = require(\"../cron/service.js\") as typeof import(\"../cron/service.js\");\n\n const storePath = join(getDataDir(), \"cron\", \"jobs.json\");\n const service = new CronService(storePath);\n\n const job = service.enableJob(jobId, !opts.disable);\n if (job) {\n const status = opts.disable ? \"disabled\" : \"enabled\";\n console.log(`Job '${job.name}' ${status}`);\n } else {\n console.error(`Job ${jobId} not found`);\n }\n });\n\n// ============================================================================\n// Status\n// ============================================================================\n\nprogram\n .command(\"status\")\n .description(\"Show nanobot status\")\n .action(() => {\n const configPath = getConfigPath();\n const config = loadConfig();\n const workspace = getConfigWorkspacePath(config);\n\n console.log(`${LOGO} nanobot Status\\n`);\n\n console.log(\n `Config: ${configPath} ${existsSync(configPath) ? \"[ok]\" : \"[missing]\"}`,\n );\n console.log(\n `Workspace: ${workspace} ${existsSync(workspace) ? \"[ok]\" : \"[missing]\"}`,\n );\n\n if (existsSync(configPath)) {\n console.log(`Model: ${config.agents.defaults.model}`);\n\n const hasOpenrouter = Boolean(config.providers.openrouter.apiKey);\n const hasAnthropic = Boolean(config.providers.anthropic.apiKey);\n const hasOpenai = Boolean(config.providers.openai.apiKey);\n const hasGemini = Boolean(config.providers.gemini.apiKey);\n const hasDeepseek = Boolean(config.providers.deepseek.apiKey);\n const hasOpenaiCompatible = Boolean(config.providers.openaiCompatible.apiKey);\n console.log(\n `OpenRouter API: ${hasOpenrouter ? \"[set]\" : \"[not set]\"}`,\n );\n console.log(\n `Anthropic API: ${hasAnthropic ? \"[set]\" : \"[not set]\"}`,\n );\n console.log(\n `OpenAI API: ${hasOpenai ? \"[set]\" : \"[not set]\"}`,\n );\n console.log(\n `Gemini API: ${hasGemini ? \"[set]\" : \"[not set]\"}`,\n );\n console.log(\n `DeepSeek API: ${hasDeepseek ? \"[set]\" : \"[not set]\"}`,\n );\n console.log(\n `OpenAI Compatible API: ${hasOpenaiCompatible ? \"[set]\" : \"[not set]\"}`,\n );\n }\n });\n\nprogram.parse();\n"],"mappings":"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"}
|
package/dist/config/schema.d.mts
CHANGED
|
@@ -339,27 +339,27 @@ declare const ToolsConfigSchema: z.ZodObject<{
|
|
|
339
339
|
restrictToWorkspace?: boolean | undefined;
|
|
340
340
|
}>>;
|
|
341
341
|
}, "strip", z.ZodTypeAny, {
|
|
342
|
-
exec: {
|
|
343
|
-
timeout: number;
|
|
344
|
-
restrictToWorkspace: boolean;
|
|
345
|
-
};
|
|
346
342
|
web: {
|
|
347
343
|
search: {
|
|
348
344
|
apiKey: string;
|
|
349
345
|
maxResults: number;
|
|
350
346
|
};
|
|
351
347
|
};
|
|
348
|
+
exec: {
|
|
349
|
+
timeout: number;
|
|
350
|
+
restrictToWorkspace: boolean;
|
|
351
|
+
};
|
|
352
352
|
}, {
|
|
353
|
-
exec?: {
|
|
354
|
-
timeout?: number | undefined;
|
|
355
|
-
restrictToWorkspace?: boolean | undefined;
|
|
356
|
-
} | undefined;
|
|
357
353
|
web?: {
|
|
358
354
|
search?: {
|
|
359
355
|
apiKey?: string | undefined;
|
|
360
356
|
maxResults?: number | undefined;
|
|
361
357
|
} | undefined;
|
|
362
358
|
} | undefined;
|
|
359
|
+
exec?: {
|
|
360
|
+
timeout?: number | undefined;
|
|
361
|
+
restrictToWorkspace?: boolean | undefined;
|
|
362
|
+
} | undefined;
|
|
363
363
|
}>;
|
|
364
364
|
declare const ConfigSchema: z.ZodObject<{
|
|
365
365
|
agents: z.ZodDefault<z.ZodObject<{
|
|
@@ -605,27 +605,27 @@ declare const ConfigSchema: z.ZodObject<{
|
|
|
605
605
|
restrictToWorkspace?: boolean | undefined;
|
|
606
606
|
}>>;
|
|
607
607
|
}, "strip", z.ZodTypeAny, {
|
|
608
|
-
exec: {
|
|
609
|
-
timeout: number;
|
|
610
|
-
restrictToWorkspace: boolean;
|
|
611
|
-
};
|
|
612
608
|
web: {
|
|
613
609
|
search: {
|
|
614
610
|
apiKey: string;
|
|
615
611
|
maxResults: number;
|
|
616
612
|
};
|
|
617
613
|
};
|
|
614
|
+
exec: {
|
|
615
|
+
timeout: number;
|
|
616
|
+
restrictToWorkspace: boolean;
|
|
617
|
+
};
|
|
618
618
|
}, {
|
|
619
|
-
exec?: {
|
|
620
|
-
timeout?: number | undefined;
|
|
621
|
-
restrictToWorkspace?: boolean | undefined;
|
|
622
|
-
} | undefined;
|
|
623
619
|
web?: {
|
|
624
620
|
search?: {
|
|
625
621
|
apiKey?: string | undefined;
|
|
626
622
|
maxResults?: number | undefined;
|
|
627
623
|
} | undefined;
|
|
628
624
|
} | undefined;
|
|
625
|
+
exec?: {
|
|
626
|
+
timeout?: number | undefined;
|
|
627
|
+
restrictToWorkspace?: boolean | undefined;
|
|
628
|
+
} | undefined;
|
|
629
629
|
}>>;
|
|
630
630
|
}, "strip", z.ZodTypeAny, {
|
|
631
631
|
agents: {
|
|
@@ -680,16 +680,16 @@ declare const ConfigSchema: z.ZodObject<{
|
|
|
680
680
|
port: number;
|
|
681
681
|
};
|
|
682
682
|
tools: {
|
|
683
|
-
exec: {
|
|
684
|
-
timeout: number;
|
|
685
|
-
restrictToWorkspace: boolean;
|
|
686
|
-
};
|
|
687
683
|
web: {
|
|
688
684
|
search: {
|
|
689
685
|
apiKey: string;
|
|
690
686
|
maxResults: number;
|
|
691
687
|
};
|
|
692
688
|
};
|
|
689
|
+
exec: {
|
|
690
|
+
timeout: number;
|
|
691
|
+
restrictToWorkspace: boolean;
|
|
692
|
+
};
|
|
693
693
|
};
|
|
694
694
|
}, {
|
|
695
695
|
agents?: {
|
|
@@ -744,16 +744,16 @@ declare const ConfigSchema: z.ZodObject<{
|
|
|
744
744
|
port?: number | undefined;
|
|
745
745
|
} | undefined;
|
|
746
746
|
tools?: {
|
|
747
|
-
exec?: {
|
|
748
|
-
timeout?: number | undefined;
|
|
749
|
-
restrictToWorkspace?: boolean | undefined;
|
|
750
|
-
} | undefined;
|
|
751
747
|
web?: {
|
|
752
748
|
search?: {
|
|
753
749
|
apiKey?: string | undefined;
|
|
754
750
|
maxResults?: number | undefined;
|
|
755
751
|
} | undefined;
|
|
756
752
|
} | undefined;
|
|
753
|
+
exec?: {
|
|
754
|
+
timeout?: number | undefined;
|
|
755
|
+
restrictToWorkspace?: boolean | undefined;
|
|
756
|
+
} | undefined;
|
|
757
757
|
} | undefined;
|
|
758
758
|
}>;
|
|
759
759
|
type Config = z.infer<typeof ConfigSchema>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.d.mts","names":[],"sources":["../../src/config/schema.ts"],"mappings":";;;cAGa,oBAAA,EAAoB,CAAA,CAAA,SAAA;;;;;;;;;;;;;;;;KAMrB,cAAA,GAAiB,CAAA,CAAE,KAAA,QAAa,oBAAA;AAAA,cAE/B,oBAAA,EAAoB,CAAA,CAAA,SAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAOrB,cAAA,GAAiB,CAAA,CAAE,KAAA,QAAa,oBAAA;AAAA,cAE/B,mBAAA,EAAmB,CAAA,CAAA,SAAA;;;;;;;;;;;;;;;;;;;KAOpB,aAAA,GAAgB,CAAA,CAAE,KAAA,QAAa,mBAAA;AAAA,cAE9B,kBAAA,EAAkB,CAAA,CAAA,SAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KASnB,YAAA,GAAe,CAAA,CAAE,KAAA,QAAa,kBAAA;AAAA,cAE7B,oBAAA,EAAoB,CAAA,CAAA,SAAA;;;;;;;;;;KAIrB,cAAA,GAAiB,CAAA,CAAE,KAAA,QAAa,oBAAA;AAAA,cAI/B,qBAAA,EAAqB,CAAA,CAAA,SAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAStB,eAAA,GAAkB,CAAA,CAAE,KAAA,QAAa,qBAAA;AAAA,cAEhC,mBAAA,EAAmB,CAAA,CAAA,SAAA;;;;;;;;;;KAIpB,aAAA,GAAgB,CAAA,CAAE,KAAA,QAAa,mBAAA;AAAA,cAE9B,qBAAA,EAAqB,CAAA,CAAA,SAAA;;;;;;;;;;cAKrB,oBAAA,EAAoB,CAAA,CAAA,SAAA;;;;;;;;;;;;;;;;;;;;;;cAIpB,oBAAA,EAAoB,CAAA,CAAA,SAAA;;;;;;;;;;KAIrB,cAAA,GAAiB,CAAA,CAAE,KAAA,QAAa,oBAAA;AAAA,cAE/B,iBAAA,EAAiB,CAAA,CAAA,SAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAUjB,YAAA,EAAY,CAAA,CAAA,SAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"schema.d.mts","names":[],"sources":["../../src/config/schema.ts"],"mappings":";;;cAGa,oBAAA,EAAoB,CAAA,CAAA,SAAA;;;;;;;;;;;;;;;;KAMrB,cAAA,GAAiB,CAAA,CAAE,KAAA,QAAa,oBAAA;AAAA,cAE/B,oBAAA,EAAoB,CAAA,CAAA,SAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAOrB,cAAA,GAAiB,CAAA,CAAE,KAAA,QAAa,oBAAA;AAAA,cAE/B,mBAAA,EAAmB,CAAA,CAAA,SAAA;;;;;;;;;;;;;;;;;;;KAOpB,aAAA,GAAgB,CAAA,CAAE,KAAA,QAAa,mBAAA;AAAA,cAE9B,kBAAA,EAAkB,CAAA,CAAA,SAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KASnB,YAAA,GAAe,CAAA,CAAE,KAAA,QAAa,kBAAA;AAAA,cAE7B,oBAAA,EAAoB,CAAA,CAAA,SAAA;;;;;;;;;;KAIrB,cAAA,GAAiB,CAAA,CAAE,KAAA,QAAa,oBAAA;AAAA,cAI/B,qBAAA,EAAqB,CAAA,CAAA,SAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAStB,eAAA,GAAkB,CAAA,CAAE,KAAA,QAAa,qBAAA;AAAA,cAEhC,mBAAA,EAAmB,CAAA,CAAA,SAAA;;;;;;;;;;KAIpB,aAAA,GAAgB,CAAA,CAAE,KAAA,QAAa,mBAAA;AAAA,cAE9B,qBAAA,EAAqB,CAAA,CAAA,SAAA;;;;;;;;;;cAKrB,oBAAA,EAAoB,CAAA,CAAA,SAAA;;;;;;;;;;;;;;;;;;;;;;cAIpB,oBAAA,EAAoB,CAAA,CAAA,SAAA;;;;;;;;;;KAIrB,cAAA,GAAiB,CAAA,CAAE,KAAA,QAAa,oBAAA;AAAA,cAE/B,iBAAA,EAAiB,CAAA,CAAA,SAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAUjB,YAAA,EAAY,CAAA,CAAA,SAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KA4Bb,MAAA,GAAS,CAAA,CAAE,KAAA,QAAa,YAAA;;iBAGpB,sBAAA,CAAuB,MAAA,EAAQ,MAAA;;iBAS/B,SAAA,CAAU,MAAA,EAAQ,MAAA;;iBAclB,UAAA,CAAW,MAAA,EAAQ,MAAA"}
|
package/dist/config/schema.mjs
CHANGED
|
@@ -86,7 +86,8 @@ const ConfigSchema = z.object({
|
|
|
86
86
|
openrouter: defaultProvider,
|
|
87
87
|
deepseek: defaultProvider,
|
|
88
88
|
groq: defaultProvider,
|
|
89
|
-
gemini: defaultProvider
|
|
89
|
+
gemini: defaultProvider,
|
|
90
|
+
openaiCompatible: defaultProvider
|
|
90
91
|
}),
|
|
91
92
|
gateway: GatewayConfigSchema.default({
|
|
92
93
|
host: "0.0.0.0",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.mjs","names":[],"sources":["../../src/config/schema.ts"],"sourcesContent":["import { z } from \"zod\";\nimport { homedir } from \"node:os\";\n\nexport const TelegramConfigSchema = z.object({\n enabled: z.boolean().default(false),\n token: z.string().default(\"\"),\n allowFrom: z.array(z.string()).default([]),\n proxy: z.string().nullish(),\n});\nexport type TelegramConfig = z.infer<typeof TelegramConfigSchema>;\n\nexport const ChannelsConfigSchema = z.object({\n telegram: TelegramConfigSchema.default({\n enabled: false,\n token: \"\",\n allowFrom: [],\n }),\n});\nexport type ChannelsConfig = z.infer<typeof ChannelsConfigSchema>;\n\nexport const AgentDefaultsSchema = z.object({\n workspace: z.string().default(\"~/.nanobot/workspace\"),\n model: z.string().default(\"anthropic/claude-sonnet-4-20250514\"),\n maxTokens: z.number().default(8192),\n temperature: z.number().default(0.7),\n maxToolIterations: z.number().default(20),\n});\nexport type AgentDefaults = z.infer<typeof AgentDefaultsSchema>;\n\nexport const AgentsConfigSchema = z.object({\n defaults: AgentDefaultsSchema.default({\n workspace: \"~/.nanobot/workspace\",\n model: \"anthropic/claude-sonnet-4-20250514\",\n maxTokens: 8192,\n temperature: 0.7,\n maxToolIterations: 20,\n }),\n});\nexport type AgentsConfig = z.infer<typeof AgentsConfigSchema>;\n\nexport const ProviderConfigSchema = z.object({\n apiKey: z.string().default(\"\"),\n apiBase: z.string().nullish(),\n});\nexport type ProviderConfig = z.infer<typeof ProviderConfigSchema>;\n\nconst defaultProvider = { apiKey: \"\" } as const;\n\nexport const ProvidersConfigSchema = z.object({\n anthropic: ProviderConfigSchema.default(defaultProvider),\n openai: ProviderConfigSchema.default(defaultProvider),\n openrouter: ProviderConfigSchema.default(defaultProvider),\n deepseek: ProviderConfigSchema.default(defaultProvider),\n groq: ProviderConfigSchema.default(defaultProvider),\n gemini: ProviderConfigSchema.default(defaultProvider),\n openaiCompatible: ProviderConfigSchema.default(defaultProvider),\n});\nexport type ProvidersConfig = z.infer<typeof ProvidersConfigSchema>;\n\nexport const GatewayConfigSchema = z.object({\n host: z.string().default(\"0.0.0.0\"),\n port: z.number().default(18790),\n});\nexport type GatewayConfig = z.infer<typeof GatewayConfigSchema>;\n\nexport const WebSearchConfigSchema = z.object({\n apiKey: z.string().default(\"\"),\n maxResults: z.number().default(5),\n});\n\nexport const WebToolsConfigSchema = z.object({\n search: WebSearchConfigSchema.default({ apiKey: \"\", maxResults: 5 }),\n});\n\nexport const ExecToolConfigSchema = z.object({\n timeout: z.number().default(60),\n restrictToWorkspace: z.boolean().default(false),\n});\nexport type ExecToolConfig = z.infer<typeof ExecToolConfigSchema>;\n\nexport const ToolsConfigSchema = z.object({\n web: WebToolsConfigSchema.default({\n search: { apiKey: \"\", maxResults: 5 },\n }),\n exec: ExecToolConfigSchema.default({\n timeout: 60,\n restrictToWorkspace: false,\n }),\n});\n\nexport const ConfigSchema = z.object({\n agents: AgentsConfigSchema.default({\n defaults: {\n workspace: \"~/.nanobot/workspace\",\n model: \"anthropic/claude-sonnet-4-20250514\",\n maxTokens: 8192,\n temperature: 0.7,\n maxToolIterations: 20,\n },\n }),\n channels: ChannelsConfigSchema.default({\n telegram: { enabled: false, token: \"\", allowFrom: [] },\n }),\n providers: ProvidersConfigSchema.default({\n anthropic: defaultProvider,\n openai: defaultProvider,\n openrouter: defaultProvider,\n deepseek: defaultProvider,\n groq: defaultProvider,\n gemini: defaultProvider,\n }),\n gateway: GatewayConfigSchema.default({ host: \"0.0.0.0\", port: 18790 }),\n tools: ToolsConfigSchema.default({\n web: { search: { apiKey: \"\", maxResults: 5 } },\n exec: { timeout: 60, restrictToWorkspace: false },\n }),\n});\nexport type Config = z.infer<typeof ConfigSchema>;\n\n/** Get expanded workspace path. */\nexport function getConfigWorkspacePath(config: Config): string {\n const ws = config.agents.defaults.workspace;\n if (ws.startsWith(\"~\")) {\n return ws.replace(/^~/, homedir());\n }\n return ws;\n}\n\n/** Get API key in priority order. */\nexport function getApiKey(config: Config): string | null {\n return (\n config.providers.openrouter.apiKey ||\n config.providers.deepseek.apiKey ||\n config.providers.anthropic.apiKey ||\n config.providers.openai.apiKey ||\n config.providers.gemini.apiKey ||\n config.providers.groq.apiKey ||\n config.providers.openaiCompatible.apiKey ||\n null\n );\n}\n\n/** Get API base URL if using OpenRouter. */\nexport function getApiBase(config: Config): string | null {\n if (config.providers.openrouter.apiKey) {\n return (\n config.providers.openrouter.apiBase ?? \"https://openrouter.ai/api/v1\"\n );\n }\n if (config.providers.openaiCompatible.apiKey) {\n return config.providers.openaiCompatible.apiBase ?? null;\n }\n return null;\n}\n"],"mappings":";;;;AAGA,MAAa,uBAAuB,EAAE,OAAO;CAC3C,SAAS,EAAE,SAAS,CAAC,QAAQ,MAAM;CACnC,OAAO,EAAE,QAAQ,CAAC,QAAQ,GAAG;CAC7B,WAAW,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,QAAQ,EAAE,CAAC;CAC1C,OAAO,EAAE,QAAQ,CAAC,SAAS;CAC5B,CAAC;AAGF,MAAa,uBAAuB,EAAE,OAAO,EAC3C,UAAU,qBAAqB,QAAQ;CACrC,SAAS;CACT,OAAO;CACP,WAAW,EAAE;CACd,CAAC,EACH,CAAC;AAGF,MAAa,sBAAsB,EAAE,OAAO;CAC1C,WAAW,EAAE,QAAQ,CAAC,QAAQ,uBAAuB;CACrD,OAAO,EAAE,QAAQ,CAAC,QAAQ,qCAAqC;CAC/D,WAAW,EAAE,QAAQ,CAAC,QAAQ,KAAK;CACnC,aAAa,EAAE,QAAQ,CAAC,QAAQ,GAAI;CACpC,mBAAmB,EAAE,QAAQ,CAAC,QAAQ,GAAG;CAC1C,CAAC;AAGF,MAAa,qBAAqB,EAAE,OAAO,EACzC,UAAU,oBAAoB,QAAQ;CACpC,WAAW;CACX,OAAO;CACP,WAAW;CACX,aAAa;CACb,mBAAmB;CACpB,CAAC,EACH,CAAC;AAGF,MAAa,uBAAuB,EAAE,OAAO;CAC3C,QAAQ,EAAE,QAAQ,CAAC,QAAQ,GAAG;CAC9B,SAAS,EAAE,QAAQ,CAAC,SAAS;CAC9B,CAAC;AAGF,MAAM,kBAAkB,EAAE,QAAQ,IAAI;AAEtC,MAAa,wBAAwB,EAAE,OAAO;CAC5C,WAAW,qBAAqB,QAAQ,gBAAgB;CACxD,QAAQ,qBAAqB,QAAQ,gBAAgB;CACrD,YAAY,qBAAqB,QAAQ,gBAAgB;CACzD,UAAU,qBAAqB,QAAQ,gBAAgB;CACvD,MAAM,qBAAqB,QAAQ,gBAAgB;CACnD,QAAQ,qBAAqB,QAAQ,gBAAgB;CACrD,kBAAkB,qBAAqB,QAAQ,gBAAgB;CAChE,CAAC;AAGF,MAAa,sBAAsB,EAAE,OAAO;CAC1C,MAAM,EAAE,QAAQ,CAAC,QAAQ,UAAU;CACnC,MAAM,EAAE,QAAQ,CAAC,QAAQ,MAAM;CAChC,CAAC;AAGF,MAAa,wBAAwB,EAAE,OAAO;CAC5C,QAAQ,EAAE,QAAQ,CAAC,QAAQ,GAAG;CAC9B,YAAY,EAAE,QAAQ,CAAC,QAAQ,EAAE;CAClC,CAAC;AAEF,MAAa,uBAAuB,EAAE,OAAO,EAC3C,QAAQ,sBAAsB,QAAQ;CAAE,QAAQ;CAAI,YAAY;CAAG,CAAC,EACrE,CAAC;AAEF,MAAa,uBAAuB,EAAE,OAAO;CAC3C,SAAS,EAAE,QAAQ,CAAC,QAAQ,GAAG;CAC/B,qBAAqB,EAAE,SAAS,CAAC,QAAQ,MAAM;CAChD,CAAC;AAGF,MAAa,oBAAoB,EAAE,OAAO;CACxC,KAAK,qBAAqB,QAAQ,EAChC,QAAQ;EAAE,QAAQ;EAAI,YAAY;EAAG,EACtC,CAAC;CACF,MAAM,qBAAqB,QAAQ;EACjC,SAAS;EACT,qBAAqB;EACtB,CAAC;CACH,CAAC;AAEF,MAAa,eAAe,EAAE,OAAO;CACnC,QAAQ,mBAAmB,QAAQ,EACjC,UAAU;EACR,WAAW;EACX,OAAO;EACP,WAAW;EACX,aAAa;EACb,mBAAmB;EACpB,EACF,CAAC;CACF,UAAU,qBAAqB,QAAQ,EACrC,UAAU;EAAE,SAAS;EAAO,OAAO;EAAI,WAAW,EAAE;EAAE,EACvD,CAAC;CACF,WAAW,sBAAsB,QAAQ;EACvC,WAAW;EACX,QAAQ;EACR,YAAY;EACZ,UAAU;EACV,MAAM;EACN,QAAQ;
|
|
1
|
+
{"version":3,"file":"schema.mjs","names":[],"sources":["../../src/config/schema.ts"],"sourcesContent":["import { z } from \"zod\";\nimport { homedir } from \"node:os\";\n\nexport const TelegramConfigSchema = z.object({\n enabled: z.boolean().default(false),\n token: z.string().default(\"\"),\n allowFrom: z.array(z.string()).default([]),\n proxy: z.string().nullish(),\n});\nexport type TelegramConfig = z.infer<typeof TelegramConfigSchema>;\n\nexport const ChannelsConfigSchema = z.object({\n telegram: TelegramConfigSchema.default({\n enabled: false,\n token: \"\",\n allowFrom: [],\n }),\n});\nexport type ChannelsConfig = z.infer<typeof ChannelsConfigSchema>;\n\nexport const AgentDefaultsSchema = z.object({\n workspace: z.string().default(\"~/.nanobot/workspace\"),\n model: z.string().default(\"anthropic/claude-sonnet-4-20250514\"),\n maxTokens: z.number().default(8192),\n temperature: z.number().default(0.7),\n maxToolIterations: z.number().default(20),\n});\nexport type AgentDefaults = z.infer<typeof AgentDefaultsSchema>;\n\nexport const AgentsConfigSchema = z.object({\n defaults: AgentDefaultsSchema.default({\n workspace: \"~/.nanobot/workspace\",\n model: \"anthropic/claude-sonnet-4-20250514\",\n maxTokens: 8192,\n temperature: 0.7,\n maxToolIterations: 20,\n }),\n});\nexport type AgentsConfig = z.infer<typeof AgentsConfigSchema>;\n\nexport const ProviderConfigSchema = z.object({\n apiKey: z.string().default(\"\"),\n apiBase: z.string().nullish(),\n});\nexport type ProviderConfig = z.infer<typeof ProviderConfigSchema>;\n\nconst defaultProvider = { apiKey: \"\" } as const;\n\nexport const ProvidersConfigSchema = z.object({\n anthropic: ProviderConfigSchema.default(defaultProvider),\n openai: ProviderConfigSchema.default(defaultProvider),\n openrouter: ProviderConfigSchema.default(defaultProvider),\n deepseek: ProviderConfigSchema.default(defaultProvider),\n groq: ProviderConfigSchema.default(defaultProvider),\n gemini: ProviderConfigSchema.default(defaultProvider),\n openaiCompatible: ProviderConfigSchema.default(defaultProvider),\n});\nexport type ProvidersConfig = z.infer<typeof ProvidersConfigSchema>;\n\nexport const GatewayConfigSchema = z.object({\n host: z.string().default(\"0.0.0.0\"),\n port: z.number().default(18790),\n});\nexport type GatewayConfig = z.infer<typeof GatewayConfigSchema>;\n\nexport const WebSearchConfigSchema = z.object({\n apiKey: z.string().default(\"\"),\n maxResults: z.number().default(5),\n});\n\nexport const WebToolsConfigSchema = z.object({\n search: WebSearchConfigSchema.default({ apiKey: \"\", maxResults: 5 }),\n});\n\nexport const ExecToolConfigSchema = z.object({\n timeout: z.number().default(60),\n restrictToWorkspace: z.boolean().default(false),\n});\nexport type ExecToolConfig = z.infer<typeof ExecToolConfigSchema>;\n\nexport const ToolsConfigSchema = z.object({\n web: WebToolsConfigSchema.default({\n search: { apiKey: \"\", maxResults: 5 },\n }),\n exec: ExecToolConfigSchema.default({\n timeout: 60,\n restrictToWorkspace: false,\n }),\n});\n\nexport const ConfigSchema = z.object({\n agents: AgentsConfigSchema.default({\n defaults: {\n workspace: \"~/.nanobot/workspace\",\n model: \"anthropic/claude-sonnet-4-20250514\",\n maxTokens: 8192,\n temperature: 0.7,\n maxToolIterations: 20,\n },\n }),\n channels: ChannelsConfigSchema.default({\n telegram: { enabled: false, token: \"\", allowFrom: [] },\n }),\n providers: ProvidersConfigSchema.default({\n anthropic: defaultProvider,\n openai: defaultProvider,\n openrouter: defaultProvider,\n deepseek: defaultProvider,\n groq: defaultProvider,\n gemini: defaultProvider,\n openaiCompatible: defaultProvider,\n }),\n gateway: GatewayConfigSchema.default({ host: \"0.0.0.0\", port: 18790 }),\n tools: ToolsConfigSchema.default({\n web: { search: { apiKey: \"\", maxResults: 5 } },\n exec: { timeout: 60, restrictToWorkspace: false },\n }),\n});\nexport type Config = z.infer<typeof ConfigSchema>;\n\n/** Get expanded workspace path. */\nexport function getConfigWorkspacePath(config: Config): string {\n const ws = config.agents.defaults.workspace;\n if (ws.startsWith(\"~\")) {\n return ws.replace(/^~/, homedir());\n }\n return ws;\n}\n\n/** Get API key in priority order. */\nexport function getApiKey(config: Config): string | null {\n return (\n config.providers.openrouter.apiKey ||\n config.providers.deepseek.apiKey ||\n config.providers.anthropic.apiKey ||\n config.providers.openai.apiKey ||\n config.providers.gemini.apiKey ||\n config.providers.groq.apiKey ||\n config.providers.openaiCompatible.apiKey ||\n null\n );\n}\n\n/** Get API base URL if using OpenRouter. */\nexport function getApiBase(config: Config): string | null {\n if (config.providers.openrouter.apiKey) {\n return (\n config.providers.openrouter.apiBase ?? \"https://openrouter.ai/api/v1\"\n );\n }\n if (config.providers.openaiCompatible.apiKey) {\n return config.providers.openaiCompatible.apiBase ?? null;\n }\n return null;\n}\n"],"mappings":"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"}
|
package/dist/index.d.mts
CHANGED
|
@@ -16,7 +16,7 @@ import { HeartbeatService } from "./heartbeat/service.mjs";
|
|
|
16
16
|
import { OpenAIProvider } from "./providers/openai-provider.mjs";
|
|
17
17
|
|
|
18
18
|
//#region src/index.d.ts
|
|
19
|
-
declare const VERSION = "0.1.
|
|
19
|
+
declare const VERSION = "0.1.4";
|
|
20
20
|
declare const LOGO = "\uD83D\uDC08";
|
|
21
21
|
//#endregion
|
|
22
22
|
export { AgentLoop, ChannelManager, type Config, ContextBuilder, CronService, HeartbeatService, type InboundMessage, type LLMProvider, type LLMResponse, LOGO, MemoryStore, MessageBus, OpenAIProvider, type OutboundMessage, SessionManager, SkillsLoader, SubagentManager, TelegramChannel, type ToolCallRequest, VERSION, loadConfig, saveConfig };
|
package/dist/index.mjs
CHANGED
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../src/index.ts"],"sourcesContent":["export const VERSION = \"0.1.
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../src/index.ts"],"sourcesContent":["export const VERSION = \"0.1.4\";\nexport const LOGO = \"\\u{1F408}\";\n\n// Core exports\nexport { AgentLoop } from \"./agent/loop.js\";\nexport { ContextBuilder } from \"./agent/context.js\";\nexport { MemoryStore } from \"./agent/memory.js\";\nexport { SkillsLoader } from \"./agent/skills.js\";\nexport { SubagentManager } from \"./agent/subagent.js\";\n\n// Bus\nexport { MessageBus } from \"./bus/queue.js\";\nexport type { InboundMessage, OutboundMessage } from \"./bus/events.js\";\n\n// Config\nexport { loadConfig, saveConfig } from \"./config/loader.js\";\nexport type { Config } from \"./config/schema.js\";\n\n// Providers\nexport { OpenAIProvider } from \"./providers/openai-provider.js\";\nexport type { LLMProvider, LLMResponse, ToolCallRequest } from \"./providers/base.js\";\n\n// Channels\nexport { TelegramChannel } from \"./channels/telegram.js\";\nexport { ChannelManager } from \"./channels/manager.js\";\n\n// Services\nexport { CronService } from \"./cron/service.js\";\nexport { HeartbeatService } from \"./heartbeat/service.js\";\nexport { SessionManager } from \"./session/manager.js\";\n"],"mappings":";;;;;;;;;;;;;;;eAuByD;cAIT;AA3BhD,MAAa,UAAU;AACvB,MAAa,OAAO"}
|