@agentprojectcontext/apx 1.31.2 → 1.32.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +6 -1
- package/skills/apc-context/SKILL.md +5 -2
- package/skills/apx/SKILL.md +3 -3
- package/skills/apx-agency-agents/SKILL.md +5 -5
- package/skills/apx-agent/SKILL.md +7 -7
- package/skills/apx-mcp/SKILL.md +6 -4
- package/skills/apx-mcp-builder/SKILL.md +4 -7
- package/skills/apx-project/SKILL.md +4 -5
- package/skills/apx-routine/SKILL.md +14 -12
- package/skills/apx-runtime/SKILL.md +5 -3
- package/skills/apx-sessions/SKILL.md +5 -5
- package/skills/apx-skill-builder/SKILL.md +10 -6
- package/skills/apx-task/SKILL.md +8 -8
- package/skills/apx-telegram/SKILL.md +23 -7
- package/skills/apx-voice/SKILL.md +8 -6
- package/src/core/{agent-system.js → agent/build-agent-system.js} +10 -12
- package/src/core/agent/constants.js +5 -0
- package/src/core/agent/index.js +0 -2
- package/src/core/{agent-memory.js → agent/memory.js} +2 -2
- package/src/core/agent/model-router.js +21 -43
- package/src/core/agent/prompt-builder.js +17 -63
- package/src/core/agent/prompts/action-discipline.md +17 -0
- package/src/core/agent/prompts/channels/code.md +8 -12
- package/src/core/agent/prompts/channels/desktop.md +6 -4
- package/src/core/agent/prompts/channels/routine.md +10 -1
- package/src/core/agent/prompts/channels/telegram.md +5 -0
- package/src/core/agent/prompts/channels/web_code.md +20 -0
- package/src/core/agent/prompts/modes/voice.md +2 -2
- package/src/core/agent/prompts/super-agent-base.md +2 -2
- package/src/core/agent/run-agent.js +66 -36
- package/src/core/agent/runtime-bridge.js +42 -0
- package/src/core/agent/self-memory.js +19 -9
- package/src/core/agent/skills/catalog.js +65 -0
- package/src/core/agent/skills/index.js +6 -0
- package/src/{host/daemon/skills-loader.js → core/agent/skills/loader.js} +3 -3
- package/src/core/agent/skills/rag.js +91 -0
- package/src/core/agent/skills/trigger.js +71 -0
- package/src/{host/daemon → core/agent}/super-agent.js +5 -5
- package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/add-project.js +3 -4
- package/src/core/agent/tools/handlers/ask-questions.js +115 -0
- package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/call-agent.js +2 -2
- package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/call-mcp.js +1 -2
- package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/call-runtime.js +10 -11
- package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/create-task.js +1 -1
- package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/discover-tools.js +1 -1
- package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/edit-file.js +1 -2
- package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/import-agent.js +4 -5
- package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/list-agents.js +1 -1
- package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/list-skills.js +7 -2
- package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/list-tasks.js +1 -1
- package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/list-vault-agents.js +1 -1
- package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/load-skill.js +1 -1
- package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/read-agent-memory.js +1 -1
- package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/read-self-memory.js +1 -1
- package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/remember.js +1 -1
- package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/run-shell.js +1 -2
- package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/search-messages.js +1 -1
- package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/search-sessions.js +1 -1
- package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/send-telegram.js +0 -2
- package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/set-identity.js +1 -3
- package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/set-permission-mode.js +1 -3
- package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/tail-messages.js +1 -1
- package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/transcribe-audio.js +1 -1
- package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/write-file.js +1 -2
- package/src/core/agent/tools/helpers.js +74 -0
- package/src/{host/daemon/super-agent-tools → core/agent/tools}/registry-bridge.js +3 -3
- package/src/{host/daemon/super-agent-tools/index.js → core/agent/tools/registry.js} +31 -32
- package/src/core/apc/agents-vault.js +37 -0
- package/src/core/{scaffold.js → apc/scaffold.js} +4 -5
- package/src/core/{config.js → config/index.js} +21 -27
- package/src/core/config/paths.js +32 -0
- package/src/core/constants/actors.js +8 -0
- package/src/core/constants/channels.js +19 -0
- package/src/core/constants/index.js +5 -0
- package/src/core/constants/permissions.js +17 -0
- package/src/core/constants/roles.js +9 -0
- package/src/core/engines/_streaming.js +63 -0
- package/src/core/engines/anthropic.js +11 -22
- package/src/core/engines/ollama.js +7 -16
- package/src/core/identity/index.js +8 -0
- package/src/core/{identity.js → identity/self.js} +5 -5
- package/src/core/{telegram-identity.js → identity/telegram.js} +1 -1
- package/src/core/logging.js +1 -1
- package/src/core/mascot.js +1 -1
- package/src/core/memory/active-threads.js +10 -10
- package/src/core/memory/broker.js +9 -9
- package/src/core/memory/compactor.js +2 -2
- package/src/core/memory/index.js +2 -2
- package/src/core/memory/indexer.js +1 -1
- package/src/core/{code-sessions-store.js → stores/code-sessions.js} +3 -7
- package/src/core/{messages-store.js → stores/messages.js} +6 -4
- package/src/core/stores/routine-memory.js +71 -0
- package/src/core/{routines-store.js → stores/routines.js} +1 -3
- package/src/core/stores/runtime-sessions.js +99 -0
- package/src/core/{tasks-store.js → stores/tasks.js} +3 -8
- package/src/core/update-check.js +1 -1
- package/src/core/util/ids.js +14 -0
- package/src/core/util/index.js +2 -0
- package/src/core/util/text-similarity.js +52 -0
- package/src/core/util/time.js +9 -0
- package/src/core/voice/tts.js +1 -1
- package/src/host/daemon/api/admin-config.js +4 -3
- package/src/host/daemon/api/admin.js +1 -1
- package/src/host/daemon/api/agents.js +4 -25
- package/src/host/daemon/api/artifacts.js +118 -1
- package/src/host/daemon/api/code.js +60 -16
- package/src/host/daemon/api/confirm.js +1 -1
- package/src/host/daemon/api/connections.js +2 -2
- package/src/host/daemon/api/conversations.js +2 -2
- package/src/host/daemon/api/deck.js +1 -1
- package/src/host/daemon/api/desktop.js +1 -1
- package/src/host/daemon/api/embeddings.js +4 -4
- package/src/host/daemon/api/engines.js +2 -2
- package/src/host/daemon/api/exec.js +3 -3
- package/src/host/daemon/api/identity.js +1 -1
- package/src/host/daemon/api/mcps.js +1 -1
- package/src/host/daemon/api/messages.js +1 -1
- package/src/host/daemon/api/runtimes.js +9 -8
- package/src/host/daemon/api/sessions-search.js +1 -1
- package/src/host/daemon/api/sessions.js +2 -2
- package/src/host/daemon/api/shared.js +5 -4
- package/src/host/daemon/api/skills.js +30 -0
- package/src/host/daemon/api/super-agent.js +29 -9
- package/src/host/daemon/api/tasks.js +2 -2
- package/src/host/daemon/api/telegram.js +1 -1
- package/src/host/daemon/api/tools.js +6 -6
- package/src/host/daemon/api/tts.js +2 -2
- package/src/host/daemon/api/voice.js +14 -12
- package/src/host/daemon/api.js +2 -0
- package/src/host/daemon/compact.js +1 -1
- package/src/host/daemon/db.js +4 -4
- package/src/host/daemon/desktop-ws.js +1 -1
- package/src/host/daemon/index.js +4 -4
- package/src/host/daemon/plugins/{desktop.js → desktop/index.js} +45 -6
- package/src/host/daemon/plugins/index.js +2 -2
- package/src/host/daemon/plugins/telegram/ask.js +309 -0
- package/src/host/daemon/plugins/{telegram.js → telegram/index.js} +390 -191
- package/src/host/daemon/plugins/telegram/media.js +162 -0
- package/src/host/daemon/projects-helpers.js +54 -0
- package/src/host/daemon/routines.js +28 -12
- package/src/host/daemon/smoke.js +2 -2
- package/src/host/daemon/token-store.js +1 -1
- package/src/host/daemon/transcription.js +2 -2
- package/src/host/daemon/wakeup.js +2 -2
- package/src/interfaces/cli/commands/agent.js +3 -3
- package/src/interfaces/cli/commands/artifact.js +99 -0
- package/src/interfaces/cli/commands/command.js +1 -1
- package/src/interfaces/cli/commands/config.js +3 -2
- package/src/interfaces/cli/commands/desktop.js +1 -1
- package/src/interfaces/cli/commands/exec.js +2 -1
- package/src/interfaces/cli/commands/identity.js +2 -2
- package/src/interfaces/cli/commands/init.js +1 -1
- package/src/interfaces/cli/commands/mcp.js +1 -1
- package/src/interfaces/cli/commands/memory.js +2 -2
- package/src/interfaces/cli/commands/model.js +16 -6
- package/src/interfaces/cli/commands/project.js +1 -1
- package/src/interfaces/cli/commands/routine.js +58 -0
- package/src/interfaces/cli/commands/search.js +1 -1
- package/src/interfaces/cli/commands/session.js +4 -4
- package/src/interfaces/cli/commands/setup.js +4 -3
- package/src/interfaces/cli/commands/skills.js +25 -4
- package/src/interfaces/cli/commands/status.js +1 -1
- package/src/interfaces/cli/commands/sys.js +11 -4
- package/src/interfaces/cli/commands/update.js +1 -1
- package/src/interfaces/cli/index.js +8 -4
- package/src/interfaces/cli/postinstall.js +2 -2
- package/src/interfaces/cli/terminal-chat/renderer.js +22 -2
- package/src/interfaces/mcp-server/index.js +1 -1
- package/src/interfaces/tui/component/prompt/index.tsx +3 -1
- package/src/interfaces/tui/context/sdk-apx.tsx +47 -7
- package/src/interfaces/tui/context/sync-apx.tsx +20 -2
- package/src/interfaces/tui/context/sync.tsx +2 -1
- package/src/interfaces/tui/routes/session/index.tsx +151 -136
- package/src/interfaces/tui/routes/session/sidebar-apx.tsx +37 -15
- package/src/interfaces/tui/run.ts +2 -0
- package/src/interfaces/web/dist/assets/index-34U_Mp1M.css +1 -0
- package/src/interfaces/web/dist/assets/index-BkybwwRn.js +570 -0
- package/src/interfaces/web/dist/assets/index-BkybwwRn.js.map +1 -0
- package/src/interfaces/web/dist/index.html +2 -2
- package/src/interfaces/web/package-lock.json +9 -9
- package/src/interfaces/web/src/App.tsx +51 -32
- package/src/interfaces/web/src/components/RobyBubble.tsx +12 -6
- package/src/interfaces/web/src/components/UiSelect.tsx +1 -1
- package/src/interfaces/web/src/components/chat/AskQuestionsCard.tsx +72 -0
- package/src/interfaces/web/src/components/chat/InlineAskPanel.tsx +399 -0
- package/src/interfaces/web/src/components/chat/MessageBubble.tsx +16 -3
- package/src/interfaces/web/src/components/chat/MessageList.tsx +2 -1
- package/src/interfaces/web/src/components/chat/SkillPicker.tsx +77 -0
- package/src/interfaces/web/src/components/code/CodeArtifactsTab.tsx +230 -0
- package/src/interfaces/web/src/components/code/CodeProjectPicker.tsx +1 -1
- package/src/interfaces/web/src/components/code/CodeSidePanel.tsx +40 -17
- package/src/interfaces/web/src/components/common/TabLayout.tsx +9 -5
- package/src/interfaces/web/src/components/common/TabNav.tsx +3 -3
- package/src/interfaces/web/src/components/layout/ProjectSidebar.tsx +4 -2
- package/src/interfaces/web/src/hooks/useChat.ts +47 -2
- package/src/interfaces/web/src/hooks/useNavCollapseCtx.tsx +59 -0
- package/src/interfaces/web/src/hooks/usePersonaName.ts +11 -0
- package/src/interfaces/web/src/i18n/en.ts +27 -7
- package/src/interfaces/web/src/i18n/es.ts +27 -7
- package/src/interfaces/web/src/lib/api/artifacts.ts +47 -0
- package/src/interfaces/web/src/lib/api/skills.ts +25 -0
- package/src/interfaces/web/src/lib/api.ts +2 -0
- package/src/interfaces/web/src/screens/modules/CodeScreen.tsx +41 -20
- package/src/interfaces/web/src/screens/modules/DeckScreen.tsx +5 -18
- package/src/interfaces/web/src/screens/modules/DesktopScreen.tsx +1 -8
- package/src/interfaces/web/src/screens/modules/VoiceScreen.tsx +39 -40
- package/src/interfaces/web/src/screens/project/ChatTab.tsx +27 -9
- package/src/skills/apc-context/SKILL.md +159 -0
- package/src/core/agent/ghost-guard.js +0 -24
- package/src/core/agent/prompts/channels/terminal.md +0 -16
- package/src/host/daemon/apc-runtime-context.js +0 -124
- package/src/host/daemon/super-agent-tools/helpers.js +0 -124
- package/src/host/daemon/super-agent-tools/tools/ask-questions.js +0 -32
- package/src/host/daemon/tool-call-parser.js +0 -2
- package/src/interfaces/web/dist/assets/index-BDUsA6L6.css +0 -1
- package/src/interfaces/web/dist/assets/index-BV615I9p.js +0 -548
- package/src/interfaces/web/dist/assets/index-BV615I9p.js.map +0 -1
- /package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/list-files.js +0 -0
- /package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/list-mcps.js +0 -0
- /package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/list-projects.js +0 -0
- /package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/read-file.js +0 -0
- /package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/search-files.js +0 -0
- /package/src/core/agent/{pseudo-tools.js → tools/pseudo-tools.js} +0 -0
- /package/src/core/agent/{tool-call-parser.js → tools/tool-call-parser.js} +0 -0
- /package/src/core/{parser.js → apc/parser.js} +0 -0
- /package/src/core/{apc-skill-sync.js → apc/skill-sync.js} +0 -0
- /package/src/core/{artifacts-store.js → stores/artifacts.js} +0 -0
- /package/src/{host/daemon → core/stores}/engine-sessions.js +0 -0
- /package/src/core/{session-store.js → stores/sessions.js} +0 -0
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
// Telegram media helpers: send photo/voice/document/audio + download a remote
|
|
2
|
+
// file. Auto-extracted from plugins/telegram/index.js — these used to live
|
|
3
|
+
// inline next to the poll loop and the super-agent dispatch.
|
|
4
|
+
//
|
|
5
|
+
// Each helper takes the bot token and chat id explicitly so they can be used
|
|
6
|
+
// from any code path (tests, other plugins, future agents). Buffer or
|
|
7
|
+
// absolute path input is accepted for media; for URLs the helpers pass them
|
|
8
|
+
// through to Telegram and let the API fetch them.
|
|
9
|
+
import fs from "node:fs";
|
|
10
|
+
import path from "node:path";
|
|
11
|
+
|
|
12
|
+
export const API_BASE = "https://api.telegram.org";
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Send a photo to a Telegram chat.
|
|
16
|
+
* @param {string} token Bot token
|
|
17
|
+
* @param {string|number} chatId Telegram chat_id
|
|
18
|
+
* @param {string|Buffer} photo Absolute file path OR Buffer of image data
|
|
19
|
+
* @param {object} [opts]
|
|
20
|
+
* @param {string} [opts.caption]
|
|
21
|
+
* @param {string} [opts.parse_mode] "HTML" | "Markdown" | "MarkdownV2"
|
|
22
|
+
*/
|
|
23
|
+
export async function sendPhoto(token, chatId, photo, { caption, parse_mode } = {}) {
|
|
24
|
+
const url = `${API_BASE}/bot${token}/sendPhoto`;
|
|
25
|
+
const form = new FormData();
|
|
26
|
+
form.append("chat_id", String(chatId));
|
|
27
|
+
if (caption) form.append("caption", caption);
|
|
28
|
+
if (parse_mode) form.append("parse_mode", parse_mode);
|
|
29
|
+
|
|
30
|
+
if (typeof photo === "string" && photo.startsWith("http")) {
|
|
31
|
+
// Public URL — send as string
|
|
32
|
+
form.append("photo", photo);
|
|
33
|
+
} else {
|
|
34
|
+
// Local file path or Buffer
|
|
35
|
+
const buf = Buffer.isBuffer(photo) ? photo : fs.readFileSync(photo);
|
|
36
|
+
const name = typeof photo === "string" ? path.basename(photo) : "photo.jpg";
|
|
37
|
+
const blob = new Blob([buf], { type: name.endsWith(".png") ? "image/png" : "image/jpeg" });
|
|
38
|
+
form.append("photo", blob, name);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const res = await fetch(url, { method: "POST", body: form });
|
|
42
|
+
const json = await res.json();
|
|
43
|
+
if (!json.ok) throw new Error(`sendPhoto failed: ${json.description || res.status}`);
|
|
44
|
+
return json.result;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Send a voice message (OGG/Opus preferred by Telegram).
|
|
49
|
+
* @param {string} token
|
|
50
|
+
* @param {string|number} chatId
|
|
51
|
+
* @param {string|Buffer} audio Path or Buffer
|
|
52
|
+
* @param {object} [opts]
|
|
53
|
+
* @param {string} [opts.caption]
|
|
54
|
+
* @param {number} [opts.duration]
|
|
55
|
+
*/
|
|
56
|
+
export async function sendVoice(token, chatId, audio, { caption, duration } = {}) {
|
|
57
|
+
const url = `${API_BASE}/bot${token}/sendVoice`;
|
|
58
|
+
const form = new FormData();
|
|
59
|
+
form.append("chat_id", String(chatId));
|
|
60
|
+
if (caption) form.append("caption", caption);
|
|
61
|
+
if (duration) form.append("duration", String(duration));
|
|
62
|
+
|
|
63
|
+
const buf = Buffer.isBuffer(audio) ? audio : fs.readFileSync(audio);
|
|
64
|
+
const name = typeof audio === "string" ? path.basename(audio) : "voice.ogg";
|
|
65
|
+
const blob = new Blob([buf], { type: "audio/ogg" });
|
|
66
|
+
form.append("voice", blob, name);
|
|
67
|
+
|
|
68
|
+
const res = await fetch(url, { method: "POST", body: form });
|
|
69
|
+
const json = await res.json();
|
|
70
|
+
if (!json.ok) throw new Error(`sendVoice failed: ${json.description || res.status}`);
|
|
71
|
+
return json.result;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Send an audio file (MP3, M4A, etc — shown in Telegram music player).
|
|
76
|
+
* @param {string} token
|
|
77
|
+
* @param {string|number} chatId
|
|
78
|
+
* @param {string|Buffer} audio Path or Buffer
|
|
79
|
+
* @param {object} [opts]
|
|
80
|
+
* @param {string} [opts.caption]
|
|
81
|
+
* @param {string} [opts.title]
|
|
82
|
+
* @param {string} [opts.performer]
|
|
83
|
+
*/
|
|
84
|
+
/**
|
|
85
|
+
* Send any file as a Telegram document (PDF, zip, txt, etc).
|
|
86
|
+
* @param {string} token
|
|
87
|
+
* @param {string|number} chatId
|
|
88
|
+
* @param {string|Buffer} document Path or Buffer of document data
|
|
89
|
+
* @param {object} [opts]
|
|
90
|
+
* @param {string} [opts.caption]
|
|
91
|
+
* @param {string} [opts.filename] override filename for Buffer input
|
|
92
|
+
* @param {string} [opts.mime_type]
|
|
93
|
+
*/
|
|
94
|
+
export async function sendDocument(token, chatId, document, { caption, filename, mime_type } = {}) {
|
|
95
|
+
const url = `${API_BASE}/bot${token}/sendDocument`;
|
|
96
|
+
const form = new FormData();
|
|
97
|
+
form.append("chat_id", String(chatId));
|
|
98
|
+
if (caption) form.append("caption", caption);
|
|
99
|
+
|
|
100
|
+
// URL string → let Telegram fetch it
|
|
101
|
+
if (typeof document === "string" && /^https?:\/\//.test(document)) {
|
|
102
|
+
form.append("document", document);
|
|
103
|
+
} else {
|
|
104
|
+
const buf = Buffer.isBuffer(document) ? document : fs.readFileSync(document);
|
|
105
|
+
const name =
|
|
106
|
+
filename ||
|
|
107
|
+
(typeof document === "string" ? path.basename(document) : "document.bin");
|
|
108
|
+
const blob = new Blob([buf], { type: mime_type || "application/octet-stream" });
|
|
109
|
+
form.append("document", blob, name);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const res = await fetch(url, { method: "POST", body: form });
|
|
113
|
+
const json = await res.json();
|
|
114
|
+
if (!json.ok) throw new Error(`sendDocument failed: ${json.description || res.status}`);
|
|
115
|
+
return json.result;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export async function sendAudio(token, chatId, audio, { caption, title, performer } = {}) {
|
|
119
|
+
const url = `${API_BASE}/bot${token}/sendAudio`;
|
|
120
|
+
const form = new FormData();
|
|
121
|
+
form.append("chat_id", String(chatId));
|
|
122
|
+
if (caption) form.append("caption", caption);
|
|
123
|
+
if (title) form.append("title", title);
|
|
124
|
+
if (performer) form.append("performer", performer);
|
|
125
|
+
|
|
126
|
+
const buf = Buffer.isBuffer(audio) ? audio : fs.readFileSync(audio);
|
|
127
|
+
const name = typeof audio === "string" ? path.basename(audio) : "audio.mp3";
|
|
128
|
+
const blob = new Blob([buf], { type: "audio/mpeg" });
|
|
129
|
+
form.append("audio", blob, name);
|
|
130
|
+
|
|
131
|
+
const res = await fetch(url, { method: "POST", body: form });
|
|
132
|
+
const json = await res.json();
|
|
133
|
+
if (!json.ok) throw new Error(`sendAudio failed: ${json.description || res.status}`);
|
|
134
|
+
return json.result;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// Audio transcription is delegated to the central dispatcher
|
|
138
|
+
// (../transcription.js) which handles local (faster-whisper via Python) +
|
|
139
|
+
// OpenAI cloud fallback. See that module for config keys.
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Download a file from Telegram servers.
|
|
143
|
+
* Returns the local file path where it was saved.
|
|
144
|
+
*/
|
|
145
|
+
export async function downloadTelegramFile(token, fileId, destDir) {
|
|
146
|
+
// Step 1: get file path from Telegram
|
|
147
|
+
const infoRes = await fetch(`${API_BASE}/bot${token}/getFile?file_id=${fileId}`);
|
|
148
|
+
const infoJson = await infoRes.json();
|
|
149
|
+
if (!infoJson.ok) throw new Error(`getFile failed: ${infoJson.description}`);
|
|
150
|
+
const filePath = infoJson.result.file_path; // e.g. "photos/file_123.jpg"
|
|
151
|
+
const ext = path.extname(filePath) || ".jpg";
|
|
152
|
+
const fileName = `tg_${fileId.slice(-8)}_${Date.now()}${ext}`;
|
|
153
|
+
const localPath = path.join(destDir, fileName);
|
|
154
|
+
|
|
155
|
+
// Step 2: download
|
|
156
|
+
const dlRes = await fetch(`${API_BASE}/file/bot${token}/${filePath}`);
|
|
157
|
+
if (!dlRes.ok) throw new Error(`download failed: ${dlRes.status}`);
|
|
158
|
+
const buf = Buffer.from(await dlRes.arrayBuffer());
|
|
159
|
+
fs.writeFileSync(localPath, buf);
|
|
160
|
+
return localPath;
|
|
161
|
+
}
|
|
162
|
+
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
// Helpers that need the running daemon's projects registry to do their work
|
|
2
|
+
// (projectMeta + resolveProject). Pure / config-only helpers live in
|
|
3
|
+
// core/agent/tools/helpers.js.
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
|
|
6
|
+
export function projectMeta(projects, entry) {
|
|
7
|
+
const meta = projects.list().find((p) => p.id === entry.id);
|
|
8
|
+
return {
|
|
9
|
+
id: entry.id,
|
|
10
|
+
name: meta?.name || path.basename(entry.path),
|
|
11
|
+
path: entry.path,
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function resolveProject(projects, target, { allowMulti = false } = {}) {
|
|
16
|
+
if (target === undefined || target === null || target === "") {
|
|
17
|
+
if (allowMulti) return null;
|
|
18
|
+
const defaultProject = projects.get(0);
|
|
19
|
+
if (defaultProject) return defaultProject;
|
|
20
|
+
const all = projects.list();
|
|
21
|
+
if (all.length === 1) return projects.get(all[0].id);
|
|
22
|
+
throw new Error(`multiple projects registered (${all.length}); specify project=<id|name|path>`);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const tgt = String(target);
|
|
26
|
+
if (tgt.toLowerCase() === "default") {
|
|
27
|
+
const defaultProject = projects.get(0);
|
|
28
|
+
if (!defaultProject) throw new Error("default project not available");
|
|
29
|
+
return defaultProject;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (typeof target === "number" || /^\d+$/.test(tgt)) {
|
|
33
|
+
const entry = projects.get(parseInt(tgt, 10));
|
|
34
|
+
if (!entry) throw new Error(`project id ${target} not found`);
|
|
35
|
+
return entry;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const all = projects.list();
|
|
39
|
+
const byPath = all.find((p) => p.path === path.resolve(tgt));
|
|
40
|
+
if (byPath) return projects.get(byPath.id);
|
|
41
|
+
|
|
42
|
+
const byName = all.find((p) => p.name === tgt);
|
|
43
|
+
if (byName) return projects.get(byName.id);
|
|
44
|
+
|
|
45
|
+
const tgtLow = tgt.toLowerCase();
|
|
46
|
+
const fuzzy = all.filter(
|
|
47
|
+
(p) => p.name.toLowerCase().includes(tgtLow) || p.path.toLowerCase().includes(tgtLow)
|
|
48
|
+
);
|
|
49
|
+
if (fuzzy.length === 1) return projects.get(fuzzy[0].id);
|
|
50
|
+
if (fuzzy.length > 1) {
|
|
51
|
+
throw new Error(`project "${tgt}" is ambiguous; matches: ${fuzzy.map((p) => p.name).join(", ")}`);
|
|
52
|
+
}
|
|
53
|
+
throw new Error(`project "${tgt}" not found`);
|
|
54
|
+
}
|
|
@@ -15,13 +15,15 @@ import { execFile } from "node:child_process";
|
|
|
15
15
|
import os from "node:os";
|
|
16
16
|
import fs from "node:fs";
|
|
17
17
|
import path from "node:path";
|
|
18
|
-
import { callEngine } from "
|
|
19
|
-
import { runSuperAgent } from "
|
|
20
|
-
import { computeSuppressedTools } from "
|
|
21
|
-
import { readAgents } from "
|
|
22
|
-
import { buildAgentSystem } from "
|
|
23
|
-
import { resolveAgentName, SUPERAGENT_ACTOR_ID } from "
|
|
24
|
-
import { resolveArtifactRef, ARTIFACTS_SKIP_SIGNAL } from "
|
|
18
|
+
import { callEngine } from "#core/engines/index.js";
|
|
19
|
+
import { runSuperAgent } from "#core/agent/super-agent.js";
|
|
20
|
+
import { computeSuppressedTools } from "#core/agent/index.js";
|
|
21
|
+
import { readAgents } from "#core/apc/parser.js";
|
|
22
|
+
import { buildAgentSystem } from "#core/agent/build-agent-system.js";
|
|
23
|
+
import { resolveAgentName, SUPERAGENT_ACTOR_ID } from "#core/identity/index.js";
|
|
24
|
+
import { resolveArtifactRef, ARTIFACTS_SKIP_SIGNAL } from "#core/stores/artifacts.js";
|
|
25
|
+
import { ensureRoutineMemory, readRoutineMemoryForPrompt, routineMemoryPath } from "#core/stores/routine-memory.js";
|
|
26
|
+
import { CHANNELS } from "#core/constants/channels.js";
|
|
25
27
|
import {
|
|
26
28
|
listRoutines,
|
|
27
29
|
getRoutine,
|
|
@@ -32,7 +34,7 @@ import {
|
|
|
32
34
|
getDueRoutines,
|
|
33
35
|
parseSchedule,
|
|
34
36
|
computeNextRun,
|
|
35
|
-
} from "
|
|
37
|
+
} from "#core/stores/routines.js";
|
|
36
38
|
|
|
37
39
|
export {
|
|
38
40
|
listRoutines,
|
|
@@ -89,7 +91,7 @@ async function handleExecAgent(ctx, routine) {
|
|
|
89
91
|
|
|
90
92
|
project.logMessage({
|
|
91
93
|
agent_slug: slug,
|
|
92
|
-
channel:
|
|
94
|
+
channel: CHANNELS.ROUTINE,
|
|
93
95
|
direction: "out",
|
|
94
96
|
type: "agent",
|
|
95
97
|
actor_id: slug,
|
|
@@ -129,16 +131,30 @@ async function handleSuperAgent(ctx, routine) {
|
|
|
129
131
|
plugins,
|
|
130
132
|
registries,
|
|
131
133
|
prompt,
|
|
132
|
-
channel:
|
|
134
|
+
channel: CHANNELS.ROUTINE,
|
|
133
135
|
channelMeta: {
|
|
134
136
|
routineName: routine.name,
|
|
137
|
+
routineId: routine.id || "",
|
|
138
|
+
routineSchedule: routine.schedule || "",
|
|
139
|
+
routineLastRun: routine.last_run || "",
|
|
140
|
+
routineMemoryPath: (() => {
|
|
141
|
+
try {
|
|
142
|
+
ensureRoutineMemory(project.storagePath || project.path, routine.id, routine.name);
|
|
143
|
+
return routineMemoryPath(project.storagePath || project.path, routine.id);
|
|
144
|
+
} catch { return ""; }
|
|
145
|
+
})(),
|
|
146
|
+
routineMemory: (() => {
|
|
147
|
+
try {
|
|
148
|
+
return readRoutineMemoryForPrompt(project.storagePath || project.path, routine.id);
|
|
149
|
+
} catch { return ""; }
|
|
150
|
+
})(),
|
|
135
151
|
projectPath: project.path,
|
|
136
152
|
},
|
|
137
153
|
suppressTools: suppressTools.length > 0 ? suppressTools : null,
|
|
138
154
|
});
|
|
139
155
|
|
|
140
156
|
project.logMessage({
|
|
141
|
-
channel:
|
|
157
|
+
channel: CHANNELS.ROUTINE,
|
|
142
158
|
direction: "out",
|
|
143
159
|
type: "agent",
|
|
144
160
|
actor_id: SUPERAGENT_ACTOR_ID,
|
|
@@ -346,7 +362,7 @@ export async function runRoutineNow(ctx, routine) {
|
|
|
346
362
|
disable: isOnce,
|
|
347
363
|
});
|
|
348
364
|
ctx.project.logMessage?.({
|
|
349
|
-
channel:
|
|
365
|
+
channel: CHANNELS.ROUTINE,
|
|
350
366
|
direction: "out",
|
|
351
367
|
type: "system",
|
|
352
368
|
actor_id: "apx:routine",
|
package/src/host/daemon/smoke.js
CHANGED
|
@@ -8,8 +8,8 @@ import path from "node:path";
|
|
|
8
8
|
import fs from "node:fs";
|
|
9
9
|
import { fileURLToPath } from "node:url";
|
|
10
10
|
import { ProjectManager } from "./db.js";
|
|
11
|
-
import { McpRegistry } from "
|
|
12
|
-
import { readAgents } from "
|
|
11
|
+
import { McpRegistry } from "#core/mcp/runner.js";
|
|
12
|
+
import { readAgents } from "#core/apc/parser.js";
|
|
13
13
|
|
|
14
14
|
const __filename = fileURLToPath(import.meta.url);
|
|
15
15
|
const __dirname = path.dirname(__filename);
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
import fs from "node:fs";
|
|
24
24
|
import path from "node:path";
|
|
25
25
|
import { randomBytes, randomUUID, createHash } from "node:crypto";
|
|
26
|
-
import { APX_HOME } from "
|
|
26
|
+
import { APX_HOME } from "#core/config/index.js";
|
|
27
27
|
|
|
28
28
|
export const CLIENTS_PATH = path.join(APX_HOME, "clients.json");
|
|
29
29
|
|
|
@@ -30,7 +30,7 @@ import fs from "node:fs";
|
|
|
30
30
|
import path from "node:path";
|
|
31
31
|
import { spawn, exec } from "node:child_process";
|
|
32
32
|
import { fileURLToPath } from "node:url";
|
|
33
|
-
import { logInfo, logWarn, logError } from "
|
|
33
|
+
import { logInfo, logWarn, logError } from "#core/logging.js";
|
|
34
34
|
|
|
35
35
|
const __filename = fileURLToPath(import.meta.url);
|
|
36
36
|
const __dirname = path.dirname(__filename);
|
|
@@ -76,7 +76,7 @@ export function resolveTranscriptionLanguage(localCfg, userLang) {
|
|
|
76
76
|
|
|
77
77
|
async function getConfig() {
|
|
78
78
|
try {
|
|
79
|
-
const { readConfig } = await import("
|
|
79
|
+
const { readConfig } = await import("#core/config/index.js");
|
|
80
80
|
const cfg = readConfig() || {};
|
|
81
81
|
const t = cfg.transcription || {};
|
|
82
82
|
const openaiKey = cfg.engines?.openai?.api_key || process.env.OPENAI_API_KEY || "";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Wake-up message — sent via Telegram once per daemon restart (with cooldown).
|
|
2
2
|
import fetch from "node-fetch";
|
|
3
|
-
import { readIdentity, writeIdentity } from "
|
|
4
|
-
import { resolveProvider, getAdapter } from "
|
|
3
|
+
import { readIdentity, writeIdentity } from "#core/identity/index.js";
|
|
4
|
+
import { resolveProvider, getAdapter } from "#core/engines/index.js";
|
|
5
5
|
|
|
6
6
|
const WAKEUP_COOLDOWN_MS = 30 * 60 * 1000; // 30 min
|
|
7
7
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
|
-
import { findApfRoot, readAgents, readVaultAgents, readVaultAgent, VAULT_DIR, SLUG_RE } from "
|
|
4
|
-
import { writeAgentFile, writeVaultAgentFile, removeVaultAgent, restoreVaultAgent, addImportedAgent, ensureAgentDir } from "
|
|
5
|
-
import { ensureAgentRuntimeDir, agentMemoryPath } from "
|
|
3
|
+
import { findApfRoot, readAgents, readVaultAgents, readVaultAgent, VAULT_DIR, SLUG_RE } from "#core/apc/parser.js";
|
|
4
|
+
import { writeAgentFile, writeVaultAgentFile, removeVaultAgent, restoreVaultAgent, addImportedAgent, ensureAgentDir } from "#core/apc/scaffold.js";
|
|
5
|
+
import { ensureAgentRuntimeDir, agentMemoryPath } from "#core/agent/memory.js";
|
|
6
6
|
import { http } from "../http.js";
|
|
7
7
|
|
|
8
8
|
// ── ANSI ──────────────────────────────────────────────────────────────────────
|
|
@@ -1,6 +1,40 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import { spawn } from "node:child_process";
|
|
3
|
+
import path from "node:path";
|
|
1
4
|
import { http } from "../http.js";
|
|
2
5
|
import { resolveProjectId } from "./project.js";
|
|
3
6
|
|
|
7
|
+
// First two bytes of an executable script. Used as a hint when the file
|
|
8
|
+
// doesn't have the exec bit but clearly intends to run (shebang line).
|
|
9
|
+
const SHEBANG = "#!";
|
|
10
|
+
|
|
11
|
+
// Decide if an artifact is "runnable": exec bit on the file, OR the file
|
|
12
|
+
// starts with a shebang. If shebang-but-not-exec, we set the bit before
|
|
13
|
+
// spawning so `./script` works without the user having to chmod +x.
|
|
14
|
+
function detectRunnable(absPath) {
|
|
15
|
+
let stat;
|
|
16
|
+
try {
|
|
17
|
+
stat = fs.statSync(absPath);
|
|
18
|
+
} catch {
|
|
19
|
+
return { runnable: false, reason: "not_found" };
|
|
20
|
+
}
|
|
21
|
+
if (!stat.isFile()) return { runnable: false, reason: "not_a_file" };
|
|
22
|
+
const execBit = (stat.mode & 0o111) !== 0;
|
|
23
|
+
let hasShebang = false;
|
|
24
|
+
try {
|
|
25
|
+
const fd = fs.openSync(absPath, "r");
|
|
26
|
+
const buf = Buffer.alloc(2);
|
|
27
|
+
fs.readSync(fd, buf, 0, 2, 0);
|
|
28
|
+
fs.closeSync(fd);
|
|
29
|
+
hasShebang = buf.toString("utf8") === SHEBANG;
|
|
30
|
+
} catch {
|
|
31
|
+
// ignore: hasShebang stays false
|
|
32
|
+
}
|
|
33
|
+
if (execBit) return { runnable: true, reason: "exec_bit", autoChmod: false };
|
|
34
|
+
if (hasShebang) return { runnable: true, reason: "shebang", autoChmod: true };
|
|
35
|
+
return { runnable: false, reason: "no_exec_no_shebang" };
|
|
36
|
+
}
|
|
37
|
+
|
|
4
38
|
export async function cmdArtifactCreate(args) {
|
|
5
39
|
const name = args._[0];
|
|
6
40
|
if (!name) throw new Error("apx artifact create: missing <name>");
|
|
@@ -43,3 +77,68 @@ export async function cmdArtifactRemove(args) {
|
|
|
43
77
|
await http.delete(`/projects/${pid}/artifacts/${encodeURIComponent(name)}`);
|
|
44
78
|
console.log(`removed artifact "${name}"`);
|
|
45
79
|
}
|
|
80
|
+
|
|
81
|
+
// `apx artifact run <name> [-- args...]`
|
|
82
|
+
//
|
|
83
|
+
// Resolves the artifact's absolute path via the daemon (single source of
|
|
84
|
+
// truth for project storage), then spawns the file LOCALLY with stdio
|
|
85
|
+
// inherited so the caller sees output as if they typed `./artifact <args>`.
|
|
86
|
+
// Detection is lenient: exec bit OR shebang → runnable; shebang-only files
|
|
87
|
+
// get a one-shot chmod +x so the user doesn't have to do it themselves.
|
|
88
|
+
//
|
|
89
|
+
// The remaining argv after `run <name>` is passed straight to the script,
|
|
90
|
+
// so `apx artifact run hello.sh -- hola mundo` becomes `./hello.sh hola mundo`.
|
|
91
|
+
export async function cmdArtifactRun(args) {
|
|
92
|
+
const name = args._[0];
|
|
93
|
+
if (!name) throw new Error("apx artifact run: missing <name>");
|
|
94
|
+
const pid = await resolveProjectId(args?.flags?.project);
|
|
95
|
+
// Pull the artifact record from the daemon for the absolute path.
|
|
96
|
+
let entry;
|
|
97
|
+
try {
|
|
98
|
+
entry = await http.get(`/projects/${pid}/artifacts/${encodeURIComponent(name)}`);
|
|
99
|
+
} catch (e) {
|
|
100
|
+
throw new Error(`artifact "${name}" not found in project #${pid}: ${e.message}`);
|
|
101
|
+
}
|
|
102
|
+
const absPath = entry.path;
|
|
103
|
+
if (!absPath || !fs.existsSync(absPath)) {
|
|
104
|
+
throw new Error(`artifact "${name}" path missing on disk: ${absPath}`);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const detection = detectRunnable(absPath);
|
|
108
|
+
if (!detection.runnable) {
|
|
109
|
+
const hint = detection.reason === "no_exec_no_shebang"
|
|
110
|
+
? "no es ejecutable (sin shebang ni bit +x). Probá `apx artifact show` para ver el contenido."
|
|
111
|
+
: `no se puede ejecutar (${detection.reason}).`;
|
|
112
|
+
throw new Error(`artifact "${name}" ${hint}`);
|
|
113
|
+
}
|
|
114
|
+
if (detection.autoChmod) {
|
|
115
|
+
try {
|
|
116
|
+
const st = fs.statSync(absPath);
|
|
117
|
+
fs.chmodSync(absPath, st.mode | 0o111);
|
|
118
|
+
} catch (e) {
|
|
119
|
+
throw new Error(`could not chmod +x ${absPath}: ${e.message}`);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Everything after the artifact name is forwarded to the script. The CLI's
|
|
124
|
+
// argv parser already strips top-level flags; what's left in `_` is name
|
|
125
|
+
// + script args.
|
|
126
|
+
const scriptArgs = (args._ || []).slice(1);
|
|
127
|
+
const cwd = path.dirname(absPath);
|
|
128
|
+
const child = spawn(absPath, scriptArgs, { stdio: "inherit", cwd });
|
|
129
|
+
|
|
130
|
+
await new Promise((resolve) => {
|
|
131
|
+
child.on("exit", (code, signal) => {
|
|
132
|
+
if (signal) {
|
|
133
|
+
// Killed by signal — surface a non-zero exit for shell pipelines.
|
|
134
|
+
process.exit(128 + (signal === "SIGINT" ? 2 : 15));
|
|
135
|
+
}
|
|
136
|
+
process.exit(code ?? 0);
|
|
137
|
+
});
|
|
138
|
+
child.on("error", (err) => {
|
|
139
|
+
console.error(`apx artifact run: spawn failed — ${err.message}`);
|
|
140
|
+
resolve();
|
|
141
|
+
process.exit(1);
|
|
142
|
+
});
|
|
143
|
+
});
|
|
144
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// apx command — list and show workflow commands from .apc/commands/
|
|
2
2
|
import fs from "node:fs";
|
|
3
3
|
import path from "node:path";
|
|
4
|
-
import { findApfRoot } from "
|
|
4
|
+
import { findApfRoot } from "#core/apc/parser.js";
|
|
5
5
|
import { http } from "../http.js";
|
|
6
6
|
import { resolveProjectId } from "./project.js";
|
|
7
7
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { http } from "../http.js";
|
|
2
2
|
import { resolveProjectId } from "./project.js";
|
|
3
|
-
import { readConfig, writeConfig } from "
|
|
3
|
+
import { readConfig, writeConfig } from "#core/config/index.js";
|
|
4
|
+
import { PERMISSION_MODES, DEFAULT_PERMISSION_MODE } from "#core/constants/permissions.js";
|
|
4
5
|
|
|
5
6
|
function parseValue(raw) {
|
|
6
7
|
// best-effort: try JSON first (covers numbers, bools, objects, arrays, null,
|
|
@@ -61,7 +62,7 @@ export function cmdPermission(args = {}) {
|
|
|
61
62
|
const cfg = readConfig();
|
|
62
63
|
cfg.super_agent = cfg.super_agent || {};
|
|
63
64
|
if (sub === "show" || sub === "get" || sub === "ls") {
|
|
64
|
-
console.log(`permission_mode=${cfg.super_agent.permission_mode ||
|
|
65
|
+
console.log(`permission_mode=${cfg.super_agent.permission_mode || DEFAULT_PERMISSION_MODE}`);
|
|
65
66
|
console.log(`allowed_tools=${(cfg.super_agent.allowed_tools || []).join(",") || "(none)"}`);
|
|
66
67
|
return;
|
|
67
68
|
}
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
LINUX_DESKTOP_PATH,
|
|
16
16
|
WIN_RUN_KEY,
|
|
17
17
|
WIN_RUN_NAME,
|
|
18
|
-
} from "
|
|
18
|
+
} from "#core/desktop/autostart.js";
|
|
19
19
|
|
|
20
20
|
// Re-exports — kept so existing tests (tests/desktop-autostart.test.js)
|
|
21
21
|
// can still import these directly from the CLI module.
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { http } from "../http.js";
|
|
2
2
|
import { resolveProjectId } from "./project.js";
|
|
3
|
+
import { CHANNELS } from "#core/constants/channels.js";
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* Resolve exec target from CLI args.
|
|
@@ -63,7 +64,7 @@ export async function cmdExec(args) {
|
|
|
63
64
|
const pid = await resolveProjectId(args?.flags?.project);
|
|
64
65
|
const body = {
|
|
65
66
|
prompt,
|
|
66
|
-
channel:
|
|
67
|
+
channel: CHANNELS.CLI,
|
|
67
68
|
channelMeta: { cwd: process.cwd() },
|
|
68
69
|
};
|
|
69
70
|
if (args.flags.model && args.flags.model !== true) body.model = args.flags.model;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import readline from "node:readline";
|
|
2
|
-
import { readIdentity, writeIdentity } from "
|
|
2
|
+
import { readIdentity, writeIdentity } from "#core/identity/index.js";
|
|
3
3
|
|
|
4
4
|
function ask(rl, question, defaultVal) {
|
|
5
5
|
return new Promise((resolve) => {
|
|
@@ -22,7 +22,7 @@ export async function cmdIdentity(args) {
|
|
|
22
22
|
console.log("No identity configured. Run: apx identity wizard");
|
|
23
23
|
return;
|
|
24
24
|
}
|
|
25
|
-
const { readConfig } = await import("
|
|
25
|
+
const { readConfig } = await import("#core/config/index.js");
|
|
26
26
|
const cfg = readConfig();
|
|
27
27
|
console.log("");
|
|
28
28
|
console.log(` Agent name : ${id.agent_name}`);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { http } from "../http.js";
|
|
2
2
|
import { resolveProjectId } from "./project.js";
|
|
3
|
-
import { findApfRoot } from "
|
|
3
|
+
import { findApfRoot } from "#core/apc/parser.js";
|
|
4
4
|
|
|
5
5
|
const VALID_SCOPES = new Set(["shared", "runtime", "global", "all"]);
|
|
6
6
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
|
-
import { findApfRoot } from "
|
|
3
|
-
import { agentMemoryPath, readAgentMemory, writeAgentMemory, ensureAgentRuntimeDir } from "
|
|
2
|
+
import { findApfRoot } from "#core/apc/parser.js";
|
|
3
|
+
import { agentMemoryPath, readAgentMemory, writeAgentMemory, ensureAgentRuntimeDir } from "#core/agent/memory.js";
|
|
4
4
|
import { http } from "../http.js";
|
|
5
5
|
|
|
6
6
|
function requireRoot() {
|
|
@@ -1,11 +1,22 @@
|
|
|
1
|
-
import { readConfig, writeConfig } from "
|
|
1
|
+
import { readConfig, writeConfig } from "#core/config/index.js";
|
|
2
2
|
import {
|
|
3
3
|
probeAllProviders,
|
|
4
4
|
resolveActiveModel,
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
fallbackModels,
|
|
6
|
+
parseModelId,
|
|
7
7
|
DEFAULT_FALLBACK_ORDER,
|
|
8
|
-
} from "
|
|
8
|
+
} from "#core/agent/model-router.js";
|
|
9
|
+
|
|
10
|
+
function providersFromFallback(cfg) {
|
|
11
|
+
const seen = [];
|
|
12
|
+
for (const m of fallbackModels(cfg)) {
|
|
13
|
+
try {
|
|
14
|
+
const p = parseModelId(m).provider;
|
|
15
|
+
if (!seen.includes(p)) seen.push(p);
|
|
16
|
+
} catch { /* skip malformed */ }
|
|
17
|
+
}
|
|
18
|
+
return seen.length ? seen : [...DEFAULT_FALLBACK_ORDER];
|
|
19
|
+
}
|
|
9
20
|
|
|
10
21
|
function parseValue(raw) {
|
|
11
22
|
try {
|
|
@@ -56,7 +67,7 @@ export async function cmdModel(args = {}) {
|
|
|
56
67
|
console.log("Model router");
|
|
57
68
|
console.log(` primary: ${cfg.super_agent.model || "(not set)"}`);
|
|
58
69
|
console.log(` fallback: ${cfg.super_agent.model_fallback.enabled !== false ? "on" : "off"}`);
|
|
59
|
-
console.log(` order: ${
|
|
70
|
+
console.log(` order: ${providersFromFallback(cfg).join(" → ")}`);
|
|
60
71
|
if (active) {
|
|
61
72
|
console.log(` active: ${active.modelId}${active.fromFallback ? " (fallback)" : ""}`);
|
|
62
73
|
}
|
|
@@ -133,4 +144,3 @@ export async function cmdModel(args = {}) {
|
|
|
133
144
|
throw new Error(`unknown model subcommand: ${sub}. Try: status | order | key | set | test | enable | disable`);
|
|
134
145
|
}
|
|
135
146
|
|
|
136
|
-
export { modelForProvider, fallbackOrder };
|