@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
|
@@ -1,21 +1,31 @@
|
|
|
1
|
-
//
|
|
1
|
+
// The super-agent's personal, persistent notebook.
|
|
2
2
|
//
|
|
3
|
-
//
|
|
4
|
-
// - identity.json → who
|
|
3
|
+
// Distinct from:
|
|
4
|
+
// - identity.json → who the super-agent is (name, personality, owner)
|
|
5
5
|
// - project agents' ~/.apx/projects/<apx_id>/agents/<slug>/memory.md → per-agent, per-project
|
|
6
6
|
// - sessions → raw transcripts of past work (search_sessions)
|
|
7
7
|
//
|
|
8
|
-
//
|
|
8
|
+
// A single free-form markdown file at ~/.apx/memory.md kept by the super-agent
|
|
9
9
|
// itself: durable facts about the owner, ongoing threads, decisions, and the
|
|
10
|
-
// gist of what it has been working on (
|
|
11
|
-
//
|
|
12
|
-
//
|
|
10
|
+
// gist of what it has been working on (refreshed by skimming its own recent
|
|
11
|
+
// sessions). A bounded slice is injected into every super-agent prompt; the
|
|
12
|
+
// `remember` / `read_self_memory` tools write and read it.
|
|
13
|
+
//
|
|
14
|
+
// The header inside the file picks up the current persona name from identity
|
|
15
|
+
// (resolveAgentName) — never hardcode the agent name here.
|
|
13
16
|
import fs from "node:fs";
|
|
14
17
|
import os from "node:os";
|
|
15
18
|
import path from "node:path";
|
|
19
|
+
import { resolveAgentName } from "../identity/index.js";
|
|
16
20
|
|
|
17
21
|
export const SELF_MEMORY_PATH = path.join(os.homedir(), ".apx", "memory.md");
|
|
18
22
|
|
|
23
|
+
function notebookHeader() {
|
|
24
|
+
let name = "";
|
|
25
|
+
try { name = resolveAgentName(); } catch { /* identity missing */ }
|
|
26
|
+
return name ? `# ${name}'s notebook` : "# Self-memory";
|
|
27
|
+
}
|
|
28
|
+
|
|
19
29
|
// How much of the notebook to inline into the system prompt. The full file is
|
|
20
30
|
// always readable via read_self_memory; this only bounds the always-on slice
|
|
21
31
|
// so a long notebook can't blow the token budget on cheap channels.
|
|
@@ -67,7 +77,7 @@ export function appendSelfMemory(note, opts = {}) {
|
|
|
67
77
|
|
|
68
78
|
let next;
|
|
69
79
|
if (!existing.trim()) {
|
|
70
|
-
next =
|
|
80
|
+
next = `${notebookHeader()}\n\n${heading}\n${bullet}\n`;
|
|
71
81
|
} else if (existing.includes(heading)) {
|
|
72
82
|
// Append the bullet under today's existing heading.
|
|
73
83
|
const lines = existing.split("\n");
|
|
@@ -100,7 +110,7 @@ export function ensureSelfMemoryFile() {
|
|
|
100
110
|
try {
|
|
101
111
|
if (fs.existsSync(SELF_MEMORY_PATH)) return false;
|
|
102
112
|
fs.mkdirSync(path.dirname(SELF_MEMORY_PATH), { recursive: true });
|
|
103
|
-
fs.writeFileSync(SELF_MEMORY_PATH,
|
|
113
|
+
fs.writeFileSync(SELF_MEMORY_PATH, `${notebookHeader()}\n`);
|
|
104
114
|
return true;
|
|
105
115
|
} catch {
|
|
106
116
|
return false;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
// Helpers for working with the skills catalog in the agent prompt.
|
|
2
|
+
//
|
|
3
|
+
// Two consumers:
|
|
4
|
+
// 1. The system-prompt builder injects a short HINT block (slugs only, no
|
|
5
|
+
// bodies, no descriptions) so the model knows skills exist and how to
|
|
6
|
+
// reach them — see buildSkillsHintBlock(). The full catalog (slug +
|
|
7
|
+
// condensed description) is reached via the `list_skills` tool.
|
|
8
|
+
// 2. The `list_skills` tool itself renders descriptions using
|
|
9
|
+
// condenseSkillDescription() — keeps the trigger-list tails out of the
|
|
10
|
+
// tool result, same way the legacy catalog did.
|
|
11
|
+
//
|
|
12
|
+
// Skill descriptions are authored for Claude Code's skill matcher, so many end
|
|
13
|
+
// with verbose "Trigger on: …" / "Activate when …" / "Activa cuando…" lists.
|
|
14
|
+
// Inside the super-agent prompt those tails are pure noise (it matches
|
|
15
|
+
// semantically, not by trigger string). Keep the first sentence only, drop
|
|
16
|
+
// the trigger/activation tail, and cap length.
|
|
17
|
+
|
|
18
|
+
const TRIGGER_MARKER =
|
|
19
|
+
/\s*(?:Trigger(?:s)? on|Triggers|TRIGGER|Activate (?:on|when|only)|Use this skill (?:whenever|when)|Use (?:it )?when|Triggers include|SKIP|Also (?:use|triggers)|Activa(?:r)? (?:cuando|en)|Disparadores|Usar cuando|Usá cuando|Se activa cuando)\b/i;
|
|
20
|
+
|
|
21
|
+
export function condenseSkillDescription(desc) {
|
|
22
|
+
if (!desc) return "(no description)";
|
|
23
|
+
const full = String(desc).replace(/\s+/g, " ").trim();
|
|
24
|
+
// Prefer the gist before any trigger/activation marker; but if a skill leads
|
|
25
|
+
// straight into "Activate ONLY when…" (no gist first), that head is empty —
|
|
26
|
+
// fall back to the first sentence of the full text so we keep real info.
|
|
27
|
+
let d = full.split(TRIGGER_MARKER)[0].trim();
|
|
28
|
+
if (d.length < 15) d = full;
|
|
29
|
+
// First sentence only, then cap length.
|
|
30
|
+
const firstStop = d.search(/\.(\s|$)/);
|
|
31
|
+
if (firstStop > 0) d = d.slice(0, firstStop + 1);
|
|
32
|
+
d = d.trim();
|
|
33
|
+
if (d.length > 160) d = d.slice(0, 157).trimEnd() + "…";
|
|
34
|
+
return d || "(no description)";
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Compact "skills exist, here's how to reach them" block injected into every
|
|
39
|
+
* super-agent system prompt. Lists slugs only (no descriptions, no bodies) so
|
|
40
|
+
* the agent knows which slugs are reachable without paying the full catalog's
|
|
41
|
+
* token cost. The model calls `list_skills` to see descriptions and
|
|
42
|
+
* `load_skill` to load a body.
|
|
43
|
+
*
|
|
44
|
+
* Returns "" when there are no skills.
|
|
45
|
+
*/
|
|
46
|
+
export function buildSkillsHintBlock(listSkills) {
|
|
47
|
+
let list = [];
|
|
48
|
+
try {
|
|
49
|
+
list = listSkills();
|
|
50
|
+
} catch {
|
|
51
|
+
/* empty */
|
|
52
|
+
}
|
|
53
|
+
if (!list.length) return "";
|
|
54
|
+
const slugs = list.map((s) => s.slug).filter(Boolean);
|
|
55
|
+
return [
|
|
56
|
+
"# Available skills (catalog on demand)",
|
|
57
|
+
`${slugs.length} skills are available. Bodies are NOT loaded. For details,`,
|
|
58
|
+
"call `list_skills` (catalog with one-line descriptions) and then",
|
|
59
|
+
"`load_skill({slug})` to load the body of the matching one. Match",
|
|
60
|
+
"semantically — never by trigger string. Don't load a skill unless the",
|
|
61
|
+
"current user request actually needs its exact syntax.",
|
|
62
|
+
"",
|
|
63
|
+
"Slugs: " + slugs.join(", "),
|
|
64
|
+
].join("\n");
|
|
65
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
// Public entrypoint for skills.
|
|
2
|
+
export { condenseSkillDescription, buildSkillsHintBlock } from "./catalog.js";
|
|
3
|
+
export { tryResolveSkillCommand } from "./trigger.js";
|
|
4
|
+
export { suggestSkillForPrompt, clearSkillVectorCache } from "./rag.js";
|
|
5
|
+
export { listSkills, loadSkill, SKILL_LOCATIONS } from "./loader.js";
|
|
6
|
+
|
|
@@ -31,9 +31,9 @@ import { fileURLToPath } from "node:url";
|
|
|
31
31
|
|
|
32
32
|
const __filename = fileURLToPath(import.meta.url);
|
|
33
33
|
const __dirname = path.dirname(__filename);
|
|
34
|
-
//
|
|
35
|
-
// Used to find the bundled skills/ folder at the repo root.
|
|
36
|
-
const PACKAGE_ROOT = path.resolve(__dirname, "..", "..", "..");
|
|
34
|
+
// Four levels up: __dirname = src/core/agent/skills/ → agent/ → core/ → src/
|
|
35
|
+
// → repo root. Used to find the bundled skills/ folder at the repo root.
|
|
36
|
+
const PACKAGE_ROOT = path.resolve(__dirname, "..", "..", "..", "..");
|
|
37
37
|
|
|
38
38
|
const RUNTIME_SKILLS_DIR = path.join(PACKAGE_ROOT, "src", "core", "runtime-skills");
|
|
39
39
|
const BUNDLED_SKILLS_DIR = path.join(PACKAGE_ROOT, "skills");
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
// Suggest a skill semantically when the user prompt looks like it would
|
|
2
|
+
// benefit from one — without paying the catalog's token cost every turn.
|
|
3
|
+
//
|
|
4
|
+
// On every turn we:
|
|
5
|
+
// 1. Embed the user prompt.
|
|
6
|
+
// 2. Embed each skill's condensed description (cached per-process by slug).
|
|
7
|
+
// 3. Pick the top match if its cosine ≥ THRESHOLD AND noticeably better
|
|
8
|
+
// than the runner-up (so a vague prompt doesn't drag a random skill in).
|
|
9
|
+
// 4. Return a SOFT HINT block — not a full skill body — that nudges the
|
|
10
|
+
// model to call `load_skill({slug})` if the gist matches.
|
|
11
|
+
//
|
|
12
|
+
// Soft, not hard:
|
|
13
|
+
// - We never inject the body; the model still has to decide and call.
|
|
14
|
+
// - We never block the request: any embedding error → "" return.
|
|
15
|
+
// - We never re-call the indexer; the embedder is the same one already
|
|
16
|
+
// selected by core/memory/embeddings.js.
|
|
17
|
+
//
|
|
18
|
+
// Costs: one extra embedOne(promptText) per turn. Skill description
|
|
19
|
+
// embeddings are cached in-process by (slug, source) so the cold cost is
|
|
20
|
+
// O(skills) once per process start.
|
|
21
|
+
import { embedOne, cosineSim } from "#core/memory/embeddings.js";
|
|
22
|
+
import { condenseSkillDescription } from "#core/agent/skills/index.js";
|
|
23
|
+
import { listSkills } from "./loader.js";
|
|
24
|
+
|
|
25
|
+
const SIM_THRESHOLD = 0.45; // below this, no suggestion
|
|
26
|
+
const MARGIN = 0.05; // top must beat runner-up by at least this
|
|
27
|
+
const PROMPT_LEN_FLOOR = 8; // skip "hola" / "ok" / single-word prompts
|
|
28
|
+
|
|
29
|
+
const cache = new Map(); // slug -> { vector, descHash }
|
|
30
|
+
|
|
31
|
+
function descHash(text) {
|
|
32
|
+
let h = 0;
|
|
33
|
+
const s = String(text || "");
|
|
34
|
+
for (let i = 0; i < s.length; i++) h = ((h << 5) - h + s.charCodeAt(i)) | 0;
|
|
35
|
+
return h;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async function ensureSkillVector(skill, opts) {
|
|
39
|
+
const desc = condenseSkillDescription(skill.description);
|
|
40
|
+
const h = descHash(desc);
|
|
41
|
+
const hit = cache.get(skill.slug);
|
|
42
|
+
if (hit && hit.descHash === h) return hit.vector;
|
|
43
|
+
const vector = await embedOne(desc, opts);
|
|
44
|
+
if (vector) cache.set(skill.slug, { vector, descHash: h });
|
|
45
|
+
return vector;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Returns "" when no confident match exists, or a one-paragraph hint that
|
|
50
|
+
* names the slug + the matched description. Callers append it to contextNote.
|
|
51
|
+
*/
|
|
52
|
+
export async function suggestSkillForPrompt(prompt, { projectPath, embedOpts } = {}) {
|
|
53
|
+
try {
|
|
54
|
+
const p = String(prompt || "").trim();
|
|
55
|
+
if (p.length < PROMPT_LEN_FLOOR) return "";
|
|
56
|
+
|
|
57
|
+
const skills = listSkills({ projectPath });
|
|
58
|
+
if (!skills.length) return "";
|
|
59
|
+
|
|
60
|
+
const promptVec = await embedOne(p, embedOpts);
|
|
61
|
+
if (!promptVec) return "";
|
|
62
|
+
|
|
63
|
+
const scored = [];
|
|
64
|
+
for (const skill of skills) {
|
|
65
|
+
const v = await ensureSkillVector(skill, embedOpts);
|
|
66
|
+
if (!v) continue;
|
|
67
|
+
scored.push({ slug: skill.slug, sim: cosineSim(promptVec, v) });
|
|
68
|
+
}
|
|
69
|
+
if (scored.length === 0) return "";
|
|
70
|
+
scored.sort((a, b) => b.sim - a.sim);
|
|
71
|
+
|
|
72
|
+
const top = scored[0];
|
|
73
|
+
const runner = scored[1] || { sim: 0 };
|
|
74
|
+
if (top.sim < SIM_THRESHOLD) return "";
|
|
75
|
+
if (top.sim - runner.sim < MARGIN) return "";
|
|
76
|
+
|
|
77
|
+
return [
|
|
78
|
+
"# Skill semantically relevant to this prompt",
|
|
79
|
+
`The skill \`${top.slug}\` matches what the user is asking about (sim ${top.sim.toFixed(2)}).`,
|
|
80
|
+
"If exact syntax/behaviour for that skill is needed, call `load_skill({slug:\"" + top.slug + "\"})`",
|
|
81
|
+
"BEFORE answering. If the user's question is actually about something else, ignore this hint.",
|
|
82
|
+
].join("\n");
|
|
83
|
+
} catch {
|
|
84
|
+
return "";
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Exposed for tests / cache hygiene if a caller wants to reset between runs.
|
|
89
|
+
export function clearSkillVectorCache() {
|
|
90
|
+
cache.clear();
|
|
91
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
// Interface-agnostic skill trigger.
|
|
2
|
+
//
|
|
3
|
+
// When a user message starts with `/<slug>` (e.g. "/apx-routine help me add one"),
|
|
4
|
+
// this helper resolves the slug against the skill catalog and pulls the body
|
|
5
|
+
// into a structured block to inject into the next turn — so the model has the
|
|
6
|
+
// exact syntax without paying for the catalog every turn.
|
|
7
|
+
//
|
|
8
|
+
// Returns:
|
|
9
|
+
// { handled: false } — message had no slash command
|
|
10
|
+
// { handled: true, prompt, contextNote, skill, rest }
|
|
11
|
+
// prompt: the user's text minus the slash command (or "tell me how to use <skill>"
|
|
12
|
+
// when only the slash command was sent)
|
|
13
|
+
// contextNote: a multi-line block ready to pass as `contextNote` to runSuperAgent
|
|
14
|
+
// skill: { slug, body, source } — the loaded skill
|
|
15
|
+
// rest: the user's text without the `/<slug>` prefix (handy for callers
|
|
16
|
+
// that want to render or transform it themselves)
|
|
17
|
+
//
|
|
18
|
+
// Resolution rules:
|
|
19
|
+
// - The first whitespace-separated token must start with `/`.
|
|
20
|
+
// - The slug after the slash is matched case-insensitively against listSkills().
|
|
21
|
+
// - Project-scoped skills (.apc/skills/) win when projectPath is provided.
|
|
22
|
+
// - An unknown slug falls through ({ handled: false }) so callers can choose
|
|
23
|
+
// to surface a "no such skill" message or pass through unchanged.
|
|
24
|
+
import { listSkills, loadSkill } from "./loader.js";
|
|
25
|
+
|
|
26
|
+
const SLASH_RE = /^\/([A-Za-z][A-Za-z0-9_-]*)\b/;
|
|
27
|
+
|
|
28
|
+
export function tryResolveSkillCommand(message, { projectPath } = {}) {
|
|
29
|
+
if (typeof message !== "string") return { handled: false };
|
|
30
|
+
const trimmed = message.replace(/^\s+/, "");
|
|
31
|
+
const m = trimmed.match(SLASH_RE);
|
|
32
|
+
if (!m) return { handled: false };
|
|
33
|
+
|
|
34
|
+
const slug = m[1].toLowerCase();
|
|
35
|
+
const rest = trimmed.slice(m[0].length).trimStart();
|
|
36
|
+
|
|
37
|
+
let skills = [];
|
|
38
|
+
try {
|
|
39
|
+
skills = listSkills({ projectPath });
|
|
40
|
+
} catch {
|
|
41
|
+
return { handled: false };
|
|
42
|
+
}
|
|
43
|
+
const match = skills.find((s) => s.slug.toLowerCase() === slug);
|
|
44
|
+
if (!match) return { handled: false };
|
|
45
|
+
|
|
46
|
+
let body = "";
|
|
47
|
+
try {
|
|
48
|
+
const loaded = loadSkill(match.slug, { projectPath });
|
|
49
|
+
body = loaded.body || "";
|
|
50
|
+
} catch {
|
|
51
|
+
body = "";
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const prompt = rest || `Use the **${match.slug}** skill to help me.`;
|
|
55
|
+
const contextNote = [
|
|
56
|
+
`# Skill loaded on demand: \`${match.slug}\``,
|
|
57
|
+
"The user invoked this skill explicitly with a `/slug` prefix. Use the",
|
|
58
|
+
"instructions below for this turn instead of guessing. Don't re-call",
|
|
59
|
+
"load_skill for the same slug — its body is right here.",
|
|
60
|
+
"",
|
|
61
|
+
body,
|
|
62
|
+
].join("\n");
|
|
63
|
+
|
|
64
|
+
return {
|
|
65
|
+
handled: true,
|
|
66
|
+
prompt,
|
|
67
|
+
contextNote,
|
|
68
|
+
skill: { slug: match.slug, body, source: match.source },
|
|
69
|
+
rest,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
// Super-agent: daemon-level action agent for Telegram, TUI, desktop, routines.
|
|
2
|
-
import { createToolSession, buildLazyToolsBlock, makeToolHandlers } from "
|
|
3
|
-
import { listSkills } from "
|
|
2
|
+
import { createToolSession, buildLazyToolsBlock, makeToolHandlers } from "#core/agent/tools/registry.js";
|
|
3
|
+
import { listSkills } from "#core/agent/skills/loader.js";
|
|
4
4
|
import {
|
|
5
5
|
runAgent,
|
|
6
6
|
buildSuperAgentSystem,
|
|
7
7
|
isSuperAgentEnabled,
|
|
8
8
|
buildIdentityBlock,
|
|
9
9
|
loadDefaultSystemPrompt,
|
|
10
|
-
} from "
|
|
11
|
-
import { resolveAgentName } from "
|
|
12
|
-
import { memoryBlockFor } from "
|
|
10
|
+
} from "#core/agent/index.js";
|
|
11
|
+
import { resolveAgentName } from "#core/identity/index.js";
|
|
12
|
+
import { memoryBlockFor } from "#core/memory/index.js";
|
|
13
13
|
|
|
14
14
|
export {
|
|
15
15
|
buildIdentityBlock,
|
package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/add-project.js
RENAMED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
|
-
import { readConfig, addProject as addProjectInConfig } from "
|
|
4
|
-
import { initApf } from "
|
|
5
|
-
import {
|
|
3
|
+
import { readConfig, addProject as addProjectInConfig } from "#core/config/index.js";
|
|
4
|
+
import { initApf } from "#core/apc/scaffold.js";
|
|
5
|
+
import { projectMeta } from "../helpers.js";
|
|
6
6
|
|
|
7
7
|
function isApcProject(absPath) {
|
|
8
8
|
return (
|
|
@@ -25,7 +25,6 @@ export default {
|
|
|
25
25
|
path: { type: "string", description: "absolute or relative filesystem path to add" },
|
|
26
26
|
name: { type: "string", description: "optional project name (used only when initializing a new APC project)" },
|
|
27
27
|
init: { type: "boolean", description: "auto-create AGENTS.md and .apc/project.json if missing (default true)" },
|
|
28
|
-
confirmed: confirmedProperty("true only after explicit user confirmation for this exact project registration"),
|
|
29
28
|
},
|
|
30
29
|
required: ["path"],
|
|
31
30
|
},
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
// Normalize a raw question entry into the canonical shape rendered by every
|
|
2
|
+
// surface (web InlineAskPanel, future desktop/telegram/CLI). The model can
|
|
3
|
+
// pass either a plain string (legacy) or a rich object with options.
|
|
4
|
+
function normalizeQuestion(q) {
|
|
5
|
+
if (typeof q === "string") {
|
|
6
|
+
return { question: q, options: [], multiSelect: false, allowText: true };
|
|
7
|
+
}
|
|
8
|
+
if (!q || typeof q !== "object") return null;
|
|
9
|
+
const text = typeof q.question === "string" ? q.question : "";
|
|
10
|
+
if (!text) return null;
|
|
11
|
+
const options = Array.isArray(q.options)
|
|
12
|
+
? q.options
|
|
13
|
+
.map((o) => {
|
|
14
|
+
if (typeof o === "string") return { label: o };
|
|
15
|
+
if (o && typeof o === "object" && typeof o.label === "string") {
|
|
16
|
+
return {
|
|
17
|
+
label: o.label,
|
|
18
|
+
description: typeof o.description === "string" ? o.description : undefined,
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
return null;
|
|
22
|
+
})
|
|
23
|
+
.filter(Boolean)
|
|
24
|
+
: [];
|
|
25
|
+
return {
|
|
26
|
+
question: text,
|
|
27
|
+
header: typeof q.header === "string" ? q.header : undefined,
|
|
28
|
+
options,
|
|
29
|
+
multiSelect: q.multiSelect === true,
|
|
30
|
+
// Free-text fallback: on by default. Set false explicitly to force a
|
|
31
|
+
// pick from `options`. Has no effect when options is empty.
|
|
32
|
+
allowText: q.allowText === false ? false : true,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export default {
|
|
37
|
+
name: "ask_questions",
|
|
38
|
+
schema: {
|
|
39
|
+
// type: "function" is REQUIRED at the top level — OpenAI and Groq reject
|
|
40
|
+
// schemas without it (Groq → 400 'tools.N.type': property 'type' is missing).
|
|
41
|
+
// Anthropic / Ollama tolerate its absence but the contract is clearer with it.
|
|
42
|
+
type: "function",
|
|
43
|
+
function: {
|
|
44
|
+
name: "ask_questions",
|
|
45
|
+
description:
|
|
46
|
+
"Ask the user one or more questions when you genuinely need input to proceed. " +
|
|
47
|
+
"Each question can be free-text OR a selectable list of options (single- or multi-select). " +
|
|
48
|
+
"Call this ONCE per turn — the loop hands control back to the user immediately.",
|
|
49
|
+
parameters: {
|
|
50
|
+
type: "object",
|
|
51
|
+
properties: {
|
|
52
|
+
questions: {
|
|
53
|
+
type: "array",
|
|
54
|
+
description:
|
|
55
|
+
"Questions for the user. Each item is an object with the question text " +
|
|
56
|
+
"and optional `options` for selectable answers (single- or multi-select). " +
|
|
57
|
+
"Leave `options` empty for free-text questions.",
|
|
58
|
+
items: {
|
|
59
|
+
type: "object",
|
|
60
|
+
properties: {
|
|
61
|
+
question: { type: "string", description: "The question text." },
|
|
62
|
+
header: {
|
|
63
|
+
type: "string",
|
|
64
|
+
description: "Optional short chip (≤12 chars) shown next to the question.",
|
|
65
|
+
},
|
|
66
|
+
options: {
|
|
67
|
+
type: "array",
|
|
68
|
+
description:
|
|
69
|
+
"Selectable answers. Omit or leave empty for a free-text question. " +
|
|
70
|
+
"Prefer 2–4 distinct, mutually-exclusive choices.",
|
|
71
|
+
items: {
|
|
72
|
+
type: "object",
|
|
73
|
+
properties: {
|
|
74
|
+
label: { type: "string", description: "Visible label." },
|
|
75
|
+
description: {
|
|
76
|
+
type: "string",
|
|
77
|
+
description: "Optional explanation shown under the label.",
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
required: ["label"],
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
multiSelect: {
|
|
84
|
+
type: "boolean",
|
|
85
|
+
description:
|
|
86
|
+
"true → user can pick several options (checkboxes). Default false (single-select).",
|
|
87
|
+
},
|
|
88
|
+
allowText: {
|
|
89
|
+
type: "boolean",
|
|
90
|
+
description:
|
|
91
|
+
"When options is non-empty, also show an 'Otro' free-text field. Default true.",
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
required: ["question"],
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
required: ["questions"],
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
},
|
|
102
|
+
makeHandler: () => async ({ questions }) => {
|
|
103
|
+
// Normalize so downstream code (UI panels, persistence) always sees the
|
|
104
|
+
// canonical shape. The agent loop treats this tool as turn-ending
|
|
105
|
+
// (see TURN_ENDING_TOOLS in src/core/agent/constants.js).
|
|
106
|
+
const normalized = Array.isArray(questions)
|
|
107
|
+
? questions.map(normalizeQuestion).filter(Boolean)
|
|
108
|
+
: [];
|
|
109
|
+
return {
|
|
110
|
+
status: "Questions presented to user. Waiting for input.",
|
|
111
|
+
count: normalized.length,
|
|
112
|
+
questions: normalized,
|
|
113
|
+
};
|
|
114
|
+
},
|
|
115
|
+
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { callEngine } from "
|
|
2
|
-
import { readAgents } from "
|
|
1
|
+
import { callEngine } from "#core/engines/index.js";
|
|
2
|
+
import { readAgents } from "#core/apc/parser.js";
|
|
3
3
|
import { buildAgentSystem, resolveProject } from "../helpers.js";
|
|
4
4
|
|
|
5
5
|
export default {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { resolveProject } from "../helpers.js";
|
|
2
2
|
|
|
3
3
|
export default {
|
|
4
4
|
name: "call_mcp",
|
|
@@ -14,7 +14,6 @@ export default {
|
|
|
14
14
|
mcp: { type: "string", description: "MCP server name" },
|
|
15
15
|
tool: { type: "string", description: "tool name on that MCP" },
|
|
16
16
|
args: { type: "object", description: "arguments object" },
|
|
17
|
-
confirmed: confirmedProperty("true only after explicit user confirmation for this exact MCP call"),
|
|
18
17
|
},
|
|
19
18
|
required: ["mcp", "tool"],
|
|
20
19
|
},
|
package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/call-runtime.js
RENAMED
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
|
-
import { loggerFor } from "
|
|
4
|
-
import { readAgents } from "
|
|
3
|
+
import { loggerFor } from "#core/logging.js";
|
|
4
|
+
import { readAgents } from "#core/apc/parser.js";
|
|
5
5
|
import {
|
|
6
|
-
buildApfHint,
|
|
7
6
|
closeRuntimeSession,
|
|
8
7
|
createRuntimeSession,
|
|
9
|
-
extractApfResult,
|
|
10
|
-
} from "
|
|
11
|
-
import {
|
|
8
|
+
extractRuntimeResult as extractApfResult,
|
|
9
|
+
} from "#core/stores/runtime-sessions.js";
|
|
10
|
+
import { buildRuntimeBridgeHint as buildApfHint } from "#core/agent/runtime-bridge.js";
|
|
11
|
+
import { detectAll } from "#host/daemon/env-detect.js";
|
|
12
12
|
import {
|
|
13
13
|
findEngineSessionById,
|
|
14
14
|
readEngineSessionContext,
|
|
15
|
-
} from "
|
|
16
|
-
import { runProcess } from "
|
|
17
|
-
import { getRuntime, RUNTIME_IDS } from "
|
|
18
|
-
import { buildAgentSystem,
|
|
15
|
+
} from "#core/stores/engine-sessions.js";
|
|
16
|
+
import { runProcess } from "#host/daemon/runtimes/_spawn.js";
|
|
17
|
+
import { getRuntime, RUNTIME_IDS } from "#host/daemon/runtimes/index.js";
|
|
18
|
+
import { buildAgentSystem, resolveProject } from "../helpers.js";
|
|
19
19
|
|
|
20
20
|
const log = loggerFor("call_runtime");
|
|
21
21
|
|
|
@@ -167,7 +167,6 @@ export default {
|
|
|
167
167
|
description: "Optional prior session id (claude/codex/apx) — APX prepends that session's title + last prompt to the prompt so the runtime has context.",
|
|
168
168
|
},
|
|
169
169
|
timeout_s: { type: "integer", description: "seconds before SIGTERM; default 300" },
|
|
170
|
-
confirmed: confirmedProperty("true only after explicit user confirmation for this exact runtime command"),
|
|
171
170
|
},
|
|
172
171
|
required: ["runtime", "prompt"],
|
|
173
172
|
},
|
package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/discover-tools.js
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// discover_tools — lazy tool discovery + activation.
|
|
2
2
|
//
|
|
3
|
-
//
|
|
3
|
+
// The super-agent only carries a small "base" set of tool
|
|
4
4
|
// schemas on lightweight channels (Telegram/desktop/deck) to stay under
|
|
5
5
|
// cheap-tier TPM caps. The rest (browser/Puppeteer, fetch, web_search, runtime,
|
|
6
6
|
// voice, …) exist but are NOT sent to the model by default. This tool is how
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
|
-
import {
|
|
2
|
+
import { resolveProject, safePathJoin } from "../helpers.js";
|
|
3
3
|
|
|
4
4
|
export default {
|
|
5
5
|
name: "edit_file",
|
|
@@ -16,7 +16,6 @@ export default {
|
|
|
16
16
|
search: { type: "string", description: "exact text to replace" },
|
|
17
17
|
replace: { type: "string", description: "replacement text" },
|
|
18
18
|
all: { type: "boolean", description: "replace all matches; default false replaces one match" },
|
|
19
|
-
confirmed: confirmedProperty("true only after explicit user confirmation for this exact file edit"),
|
|
20
19
|
},
|
|
21
20
|
required: ["path", "search", "replace"],
|
|
22
21
|
},
|
package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/import-agent.js
RENAMED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
|
-
import { readVaultAgents, VAULT_DIR } from "
|
|
4
|
-
import { addImportedAgent, ensureAgentDir } from "
|
|
5
|
-
import { ensureAgentRuntimeDir } from "
|
|
6
|
-
import {
|
|
3
|
+
import { readVaultAgents, VAULT_DIR } from "#core/apc/parser.js";
|
|
4
|
+
import { addImportedAgent, ensureAgentDir } from "#core/apc/scaffold.js";
|
|
5
|
+
import { ensureAgentRuntimeDir } from "#core/agent/memory.js";
|
|
6
|
+
import { projectMeta, resolveProject } from "../helpers.js";
|
|
7
7
|
|
|
8
8
|
export default {
|
|
9
9
|
name: "import_agent",
|
|
@@ -17,7 +17,6 @@ export default {
|
|
|
17
17
|
properties: {
|
|
18
18
|
project: { type: "string", description: "project id/name/path; omit or use 'default' for ~/.apx/projects/default" },
|
|
19
19
|
agent: { type: "string", description: "agent slug from list_vault_agents" },
|
|
20
|
-
confirmed: confirmedProperty("true only after explicit user confirmation for this exact import"),
|
|
21
20
|
},
|
|
22
21
|
required: ["agent"],
|
|
23
22
|
},
|
package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/list-skills.js
RENAMED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { listSkills, SKILL_LOCATIONS } from "
|
|
1
|
+
import { listSkills, SKILL_LOCATIONS } from "#core/agent/skills/loader.js";
|
|
2
|
+
import { condenseSkillDescription } from "#core/agent/skills/index.js";
|
|
2
3
|
|
|
3
4
|
export default {
|
|
4
5
|
name: "list_skills",
|
|
@@ -26,7 +27,11 @@ export default {
|
|
|
26
27
|
count: skills.length,
|
|
27
28
|
locations: SKILL_LOCATIONS,
|
|
28
29
|
project_path: project_path || null,
|
|
29
|
-
skills: skills.map(({ slug, source, description }) => ({
|
|
30
|
+
skills: skills.map(({ slug, source, description }) => ({
|
|
31
|
+
slug,
|
|
32
|
+
source,
|
|
33
|
+
description: condenseSkillDescription(description),
|
|
34
|
+
})),
|
|
30
35
|
};
|
|
31
36
|
},
|
|
32
37
|
};
|
package/src/{host/daemon/super-agent-tools/tools → core/agent/tools/handlers}/read-agent-memory.js
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import { resolveProject } from "../helpers.js";
|
|
3
|
-
import { agentMemoryPath, readAgentMemory } from "
|
|
3
|
+
import { agentMemoryPath, readAgentMemory } from "#core/agent/memory.js";
|
|
4
4
|
|
|
5
5
|
export default {
|
|
6
6
|
name: "read_agent_memory",
|