@agentprojectcontext/apx 1.33.1 → 1.35.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/skills/apx/SKILL.md +49 -61
- package/src/core/agent/a2a/reply.js +48 -0
- package/src/core/agent/build-agent-system.js +136 -59
- package/src/core/agent/channels/voice-context.js +98 -0
- package/src/core/agent/memory.js +2 -1
- package/src/core/agent/prompt-builder.js +178 -124
- package/src/core/agent/prompts/channels/code.md +12 -10
- package/src/core/agent/prompts/channels/desktop.md +5 -32
- package/src/core/agent/prompts/channels/telegram.md +4 -15
- package/src/core/agent/prompts/channels/web_code.md +11 -11
- package/src/core/agent/prompts/core/agent-base.md +24 -0
- package/src/core/agent/prompts/core/project-agent.md +11 -0
- package/src/core/agent/prompts/core/super-agent.md +21 -0
- package/src/core/agent/prompts/discipline/action.md +10 -0
- package/src/core/agent/prompts/discipline/single-segment.md +6 -0
- package/src/core/agent/prompts/discipline/two-segment.md +11 -0
- package/src/core/agent/prompts/modes/code-build.md +1 -0
- package/src/core/agent/prompts/modes/code-plan.md +1 -0
- package/src/core/agent/prompts/modes/index.js +28 -0
- package/src/core/agent/self-memory.js +43 -1
- package/src/core/agent/skills/index-store.js +307 -0
- package/src/core/agent/skills/index.js +15 -1
- package/src/core/agent/skills/inspector.js +317 -0
- package/src/core/agent/skills/loader.js +22 -18
- package/src/core/agent/stream/turn-accumulator.js +73 -0
- package/src/core/agent/suggestions.js +37 -0
- package/src/core/agent/super-agent.js +7 -1
- package/src/core/agent/tools/handlers/_git.js +50 -0
- package/src/core/agent/tools/handlers/add-project.js +5 -2
- package/src/core/agent/tools/handlers/call-runtime.js +3 -2
- package/src/core/agent/tools/handlers/git-diff.js +44 -0
- package/src/core/agent/tools/handlers/git-log.js +38 -0
- package/src/core/agent/tools/handlers/git-show.js +34 -0
- package/src/core/agent/tools/handlers/git-status.js +61 -0
- package/src/core/agent/tools/handlers/transcribe-audio.js +1 -1
- package/src/core/agent/tools/helpers.js +2 -2
- package/src/core/agent/tools/names.js +169 -0
- package/src/core/agent/tools/registry-bridge.js +6 -14
- package/src/core/agent/tools/registry.js +103 -69
- package/src/core/apc/context-copy.js +27 -0
- package/src/core/apc/notes.js +19 -0
- package/src/core/apc/parser.js +12 -5
- package/src/core/apc/paths.js +87 -0
- package/src/core/apc/scaffold.js +82 -76
- package/src/core/apc/skill-sync.js +10 -0
- package/src/{host/daemon/plugins → core/channels}/telegram/dispatch.js +38 -16
- package/src/core/config/index.js +24 -2
- package/src/core/config/redact.js +95 -0
- package/src/core/constants/channels.js +2 -0
- package/src/core/constants/code-modes.js +10 -0
- package/src/core/constants/index.js +1 -0
- package/src/core/deck/manifest.js +186 -0
- package/src/core/engines/catalog.js +83 -0
- package/src/core/{tools → http-tools}/browser.js +0 -1
- package/src/core/{tools → http-tools}/fetch.js +0 -1
- package/src/core/{tools → http-tools}/glob.js +0 -1
- package/src/core/{tools → http-tools}/grep.js +0 -1
- package/src/core/{tools → http-tools}/registry.js +0 -1
- package/src/core/{tools → http-tools}/search.js +0 -1
- package/src/core/i18n/en.js +9 -0
- package/src/core/i18n/es.js +12 -0
- package/src/core/i18n/index.js +54 -0
- package/src/core/i18n/pt.js +9 -0
- package/src/core/identity/telegram.js +2 -1
- package/src/core/mcp/runner.js +272 -14
- package/src/core/mcp/sources.js +3 -2
- package/src/core/routines/index.js +16 -0
- package/src/{host/daemon/routines.js → core/routines/runner.js} +36 -103
- package/src/core/runtime-skills/apc-context/SKILL.md +159 -0
- package/src/core/runtime-skills/apx/SKILL.md +83 -0
- package/src/core/runtime-skills/apx-agency-agents/SKILL.md +125 -0
- package/src/core/runtime-skills/apx-agent/SKILL.md +97 -0
- package/src/core/runtime-skills/apx-mcp/SKILL.md +111 -0
- package/src/core/runtime-skills/apx-mcp-builder/SKILL.md +169 -0
- package/{skills → src/core/runtime-skills}/apx-project/SKILL.md +20 -29
- package/src/core/runtime-skills/apx-routine/SKILL.md +127 -0
- package/src/core/runtime-skills/apx-runtime/SKILL.md +99 -0
- package/src/core/runtime-skills/apx-sessions/SKILL.md +232 -0
- package/src/core/runtime-skills/apx-skill-builder/SKILL.md +129 -0
- package/{skills → src/core/runtime-skills}/apx-task/SKILL.md +18 -21
- package/src/core/runtime-skills/apx-telegram/SKILL.md +120 -0
- package/src/core/runtime-skills/apx-voice/SKILL.md +117 -0
- package/src/core/runtime-skills/{claude-code.md → claude-code/SKILL.md} +1 -0
- package/src/core/runtime-skills/{codex-cli.md → codex-cli/SKILL.md} +1 -0
- package/src/core/runtime-skills/{opencode-cli.md → opencode-cli/SKILL.md} +1 -0
- package/src/core/runtime-skills/{openrouter.md → openrouter/SKILL.md} +1 -0
- package/src/{host/daemon/env-detect.js → core/runtimes/detect.js} +1 -1
- package/src/core/stores/code-sessions.js +50 -2
- package/src/core/stores/routine-memory.js +1 -1
- package/src/core/stores/sessions-search.js +121 -0
- package/src/core/stores/sessions.js +38 -0
- package/src/core/vars/index.js +14 -0
- package/src/core/vars/interpolate.js +86 -0
- package/src/core/vars/sources.js +151 -0
- package/src/core/voice/audio-decode.js +38 -0
- package/src/core/voice/transcription.js +225 -0
- package/src/host/daemon/api/admin-config.js +5 -82
- package/src/host/daemon/api/agents.js +5 -5
- package/src/host/daemon/api/code.js +17 -169
- package/src/host/daemon/api/config.js +3 -4
- package/src/host/daemon/api/conversations.js +8 -29
- package/src/host/daemon/api/deck.js +37 -404
- package/src/host/daemon/api/engines.js +1 -80
- package/src/host/daemon/api/exec.js +1 -1
- package/src/host/daemon/api/mcps.js +32 -0
- package/src/host/daemon/api/routines.js +1 -1
- package/src/host/daemon/api/runtimes.js +4 -3
- package/src/host/daemon/api/sessions-search.js +24 -140
- package/src/host/daemon/api/sessions.js +12 -30
- package/src/host/daemon/api/shared.js +2 -1
- package/src/host/daemon/api/skills.js +140 -6
- package/src/host/daemon/api/super-agent.js +56 -1
- package/src/host/daemon/api/telegram.js +1 -11
- package/src/host/daemon/api/tools.js +6 -6
- package/src/host/daemon/api/transcribe.js +2 -2
- package/src/host/daemon/api/vars.js +137 -0
- package/src/host/daemon/api/voice.js +13 -290
- package/src/host/daemon/api.js +2 -0
- package/src/host/daemon/db.js +6 -6
- package/src/host/daemon/deck-exec.js +148 -0
- package/src/host/daemon/index.js +20 -3
- package/src/host/daemon/plugins/telegram/index.js +9 -9
- package/src/host/daemon/routines-scheduler.js +64 -0
- package/src/host/daemon/smoke.js +3 -2
- package/src/host/daemon/whisper-server.js +225 -0
- package/src/interfaces/cli/branding.js +53 -0
- package/src/interfaces/cli/commands/agent.js +3 -2
- package/src/interfaces/cli/commands/command.js +2 -3
- package/src/interfaces/cli/commands/messages.js +6 -2
- package/src/interfaces/cli/commands/pair.js +5 -4
- package/src/interfaces/cli/commands/search.js +1 -1
- package/src/interfaces/cli/commands/sessions.js +3 -2
- package/src/interfaces/cli/commands/skills.js +290 -55
- package/src/interfaces/cli/index.js +84 -2
- package/src/interfaces/web/dist/assets/index-C0fm31dY.js +618 -0
- package/src/interfaces/web/dist/assets/index-C0fm31dY.js.map +1 -0
- package/src/interfaces/web/dist/assets/index-UcAqlBO6.css +1 -0
- package/src/interfaces/web/dist/index.html +2 -2
- package/src/interfaces/web/package-lock.json +182 -182
- package/src/interfaces/web/src/components/ModelCombobox.tsx +2 -1
- package/src/interfaces/web/src/components/TelegramChannelDialog.tsx +1 -1
- package/src/interfaces/web/src/components/chat/AskAnswersCard.tsx +76 -0
- package/src/interfaces/web/src/components/chat/MessageBubble.tsx +37 -4
- package/src/interfaces/web/src/components/chat/MessageList.tsx +23 -1
- package/src/interfaces/web/src/components/chat/ModelPicker.tsx +3 -1
- package/src/interfaces/web/src/components/code/CodeArtifactsTab.tsx +4 -4
- package/src/interfaces/web/src/components/code/CodeChangesTab.tsx +1 -1
- package/src/interfaces/web/src/components/code/CodeFileTree.tsx +3 -2
- package/src/interfaces/web/src/components/code/CodeFileViewer.tsx +3 -2
- package/src/interfaces/web/src/components/code/CodeTerminal.tsx +3 -2
- package/src/interfaces/web/src/components/config/GlobalConfigEditor.tsx +2 -1
- package/src/interfaces/web/src/components/deck/WidgetRow.tsx +2 -1
- package/src/interfaces/web/src/components/inputs/KeyValueList.tsx +93 -0
- package/src/interfaces/web/src/components/inputs/VarTokenInput.tsx +449 -0
- package/src/interfaces/web/src/components/settings/DefaultRouterCard.tsx +2 -1
- package/src/interfaces/web/src/components/settings/EnginesPanel.tsx +2 -2
- package/src/interfaces/web/src/components/settings/MemoryPanel.tsx +73 -4
- package/src/interfaces/web/src/components/settings/SkillsInspectorPanel.tsx +222 -0
- package/src/interfaces/web/src/components/settings/providers/ProviderCard.tsx +3 -2
- package/src/interfaces/web/src/components/settings/providers/ProviderModal.tsx +3 -2
- package/src/interfaces/web/src/components/ui/chat-input.tsx +5 -4
- package/src/interfaces/web/src/components/ui/sidebar.tsx +3 -2
- package/src/interfaces/web/src/components/voice/VoiceProviderModal.tsx +2 -1
- package/src/interfaces/web/src/constants/index.ts +1 -1
- package/src/interfaces/web/src/hooks/useChat.ts +19 -0
- package/src/interfaces/web/src/i18n/en.ts +175 -7
- package/src/interfaces/web/src/i18n/es.ts +180 -15
- package/src/interfaces/web/src/lib/api/mcps.ts +25 -0
- package/src/interfaces/web/src/lib/api/skills.ts +70 -0
- package/src/interfaces/web/src/lib/api/vars.ts +38 -0
- package/src/interfaces/web/src/lib/api.ts +1 -0
- package/src/interfaces/web/src/screens/ProjectScreen.tsx +8 -31
- package/src/interfaces/web/src/screens/SettingsScreen.tsx +6 -2
- package/src/interfaces/web/src/screens/modules/CodeScreen.tsx +1 -1
- package/src/interfaces/web/src/screens/modules/DeckScreen.tsx +4 -3
- package/src/interfaces/web/src/screens/modules/DesktopScreen.tsx +7 -6
- package/src/interfaces/web/src/screens/modules/VoiceScreen.tsx +4 -3
- package/src/interfaces/web/src/screens/project/AgentDetailScreen.tsx +1 -1
- package/src/interfaces/web/src/screens/project/ConfigTab.tsx +132 -1
- package/src/interfaces/web/src/screens/project/McpsTab.tsx +549 -104
- package/src/interfaces/web/src/screens/project/RoutinesTab.tsx +1 -1
- package/src/interfaces/web/src/screens/project/VarsTab.tsx +300 -0
- package/src/interfaces/web/src/types/daemon.ts +15 -0
- package/skills/apx-agency-agents/SKILL.md +0 -141
- package/skills/apx-agent/SKILL.md +0 -100
- package/skills/apx-mcp-builder/SKILL.md +0 -183
- package/skills/apx-routine/SKILL.md +0 -140
- package/skills/apx-runtime/SKILL.md +0 -117
- package/skills/apx-sessions/SKILL.md +0 -281
- package/skills/apx-skill-builder/SKILL.md +0 -153
- package/skills/apx-telegram/SKILL.md +0 -131
- package/skills/apx-voice/SKILL.md +0 -137
- package/src/core/agent/prompts/action-discipline.md +0 -24
- package/src/core/agent/prompts/super-agent-base.md +0 -42
- package/src/host/daemon/transcription.js +0 -538
- package/src/host/daemon/whisper-transcribe.py +0 -73
- package/src/interfaces/web/dist/assets/index-Aaiw8BZN.css +0 -1
- package/src/interfaces/web/dist/assets/index-DPqtjDjh.js +0 -602
- package/src/interfaces/web/dist/assets/index-DPqtjDjh.js.map +0 -1
- /package/src/{host/daemon → core/apc}/projects-helpers.js +0 -0
- /package/src/{host/daemon/plugins → core/channels}/telegram/ask.js +0 -0
- /package/src/{host/daemon/plugins → core/channels}/telegram/helpers.js +0 -0
- /package/src/{host/daemon/plugins → core/channels}/telegram/media.js +0 -0
- /package/src/core/{tools → http-tools}/index.js +0 -0
- /package/src/{host/daemon/compact.js → core/stores/conversations-compactor.js} +0 -0
- /package/src/{host/daemon → core/stores}/conversations.js +0 -0
- /package/src/{host/daemon → core/util}/thinking.js +0 -0
|
@@ -1,77 +1,85 @@
|
|
|
1
|
-
//
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
//
|
|
1
|
+
// Unified prompt builder for ANY agent (super-agent OR project agent).
|
|
2
|
+
//
|
|
3
|
+
// The system prompt is assembled from layered fragments:
|
|
4
|
+
//
|
|
5
|
+
// 1. core/agent-base.md common: tool usage, memory, hard rules — applies to every agent
|
|
6
|
+
// 2. core/super-agent.md OR core/project-agent.md — the role delta
|
|
7
|
+
// 3. # Agent profile identity (name, personality, owner, language)
|
|
8
|
+
// 4. # Project / context project pin, registered projects index, AGENTS.md
|
|
9
|
+
// 5. # Memory self-memory or relevant memory block, active threads
|
|
10
|
+
// 6. # Channel channel-specific formatting rules
|
|
11
|
+
// 7. # Discipline action.md + (two-segment OR single-segment) + voice mode
|
|
12
|
+
// 8. # Suffix channel-specific format directives (suggestions JSON, etc.)
|
|
13
|
+
//
|
|
14
|
+
// Sections are dropped when empty (no project context for super-agent on a
|
|
15
|
+
// generic CLI call, no self-memory for project agents, etc.).
|
|
7
16
|
import fs from "node:fs";
|
|
8
17
|
import path from "node:path";
|
|
9
18
|
import { fileURLToPath } from "node:url";
|
|
10
19
|
import { readIdentity } from "../identity/index.js";
|
|
20
|
+
import { agentsMdFile } from "../apc/paths.js";
|
|
11
21
|
import { readSelfMemoryForPrompt } from "./self-memory.js";
|
|
12
22
|
import { buildSkillsHintBlock } from "./skills/catalog.js";
|
|
23
|
+
import { CHANNELS } from "#core/constants/channels.js";
|
|
13
24
|
|
|
14
25
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
15
26
|
const PROMPTS_DIR = path.join(__dirname, "prompts");
|
|
16
|
-
const BASE_PROMPT_PATH = path.join(PROMPTS_DIR, "super-agent-base.md");
|
|
17
27
|
|
|
18
|
-
//
|
|
19
|
-
// (
|
|
20
|
-
|
|
21
|
-
.readFileSync(path.join(PROMPTS_DIR, "action-discipline.md"), "utf8")
|
|
22
|
-
.trimEnd();
|
|
23
|
-
|
|
24
|
-
const promptCache = new Map();
|
|
25
|
-
|
|
26
|
-
/** @deprecated use super-agent-base.md */
|
|
27
|
-
const LEGACY_PROMPT_PATH = path.join(PROMPTS_DIR, "super-agent-default.md");
|
|
28
|
-
|
|
29
|
-
// Channels are SURFACES (where the user is). Voice is NOT a channel — it's a
|
|
30
|
-
// MODE that layers on top of a surface (see buildVoiceModeBlock); a spoken deck
|
|
31
|
-
// turn is channel "deck" + voice mode, not its own channel.
|
|
28
|
+
// Channels are SURFACES. Voice is NOT a channel — it's a MODE that layers on
|
|
29
|
+
// top of a surface (see buildVoiceModeBlock); a spoken deck turn is channel
|
|
30
|
+
// "deck" + voice mode, not its own channel.
|
|
32
31
|
const CHANNEL_PROMPT_FILES = {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
32
|
+
[CHANNELS.TELEGRAM]: "channels/telegram.md",
|
|
33
|
+
[CHANNELS.CLI]: "channels/cli.md",
|
|
34
|
+
[CHANNELS.ROUTINE]: "channels/routine.md",
|
|
35
|
+
[CHANNELS.API]: "channels/api.md",
|
|
36
|
+
[CHANNELS.WEB]: "channels/web.md",
|
|
37
|
+
[CHANNELS.WEB_SIDEBAR]: "channels/web_sidebar.md",
|
|
38
|
+
[CHANNELS.WEB_CODE]: "channels/web_code.md",
|
|
39
|
+
[CHANNELS.DECK]: "channels/deck.md",
|
|
40
|
+
[CHANNELS.DESKTOP]: "channels/desktop.md",
|
|
41
|
+
[CHANNELS.CODE]: "channels/code.md",
|
|
43
42
|
};
|
|
44
43
|
|
|
45
|
-
//
|
|
46
|
-
//
|
|
47
|
-
|
|
44
|
+
// Channels where the user CAN see two text segments per turn (chat history is
|
|
45
|
+
// visible). Voice / single-surface channels get single-segment discipline.
|
|
46
|
+
const TWO_SEGMENT_CHANNELS = new Set([
|
|
47
|
+
CHANNELS.TELEGRAM,
|
|
48
|
+
CHANNELS.WEB,
|
|
49
|
+
CHANNELS.WEB_SIDEBAR,
|
|
50
|
+
CHANNELS.WEB_CODE,
|
|
51
|
+
CHANNELS.CODE,
|
|
52
|
+
CHANNELS.API,
|
|
53
|
+
CHANNELS.CLI,
|
|
54
|
+
]);
|
|
55
|
+
|
|
48
56
|
const VOICE_MODE_FILE = "modes/voice.md";
|
|
49
57
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
return "";
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
+
// ---------------------------------------------------------------------------
|
|
59
|
+
// Prompt loading
|
|
60
|
+
// ---------------------------------------------------------------------------
|
|
61
|
+
|
|
62
|
+
const promptCache = new Map();
|
|
58
63
|
|
|
59
64
|
export function loadPrompt(relativePath) {
|
|
60
65
|
const key = relativePath.replace(/\\/g, "/");
|
|
61
66
|
if (promptCache.has(key)) return promptCache.get(key);
|
|
62
|
-
const
|
|
63
|
-
const text = fs.readFileSync(full, "utf8");
|
|
67
|
+
const text = fs.readFileSync(path.join(PROMPTS_DIR, key), "utf8").trimEnd();
|
|
64
68
|
promptCache.set(key, text);
|
|
65
69
|
return text;
|
|
66
70
|
}
|
|
67
71
|
|
|
72
|
+
const AGENT_BASE = loadPrompt("core/agent-base.md");
|
|
73
|
+
const SUPER_AGENT_ROLE = loadPrompt("core/super-agent.md");
|
|
74
|
+
const PROJECT_AGENT_ROLE = loadPrompt("core/project-agent.md");
|
|
75
|
+
const ACTION_DISCIPLINE = loadPrompt("discipline/action.md");
|
|
76
|
+
const TWO_SEGMENT = loadPrompt("discipline/two-segment.md");
|
|
77
|
+
const SINGLE_SEGMENT = loadPrompt("discipline/single-segment.md");
|
|
78
|
+
|
|
79
|
+
// Back-compat shim — a few callers/tests still want the raw default prompt.
|
|
68
80
|
export function loadDefaultSystemPrompt() {
|
|
69
|
-
|
|
70
|
-
if (fs.existsSync(LEGACY_PROMPT_PATH)) return loadPrompt("super-agent-default.md");
|
|
71
|
-
throw new Error("super-agent base prompt not found");
|
|
81
|
+
return [AGENT_BASE, SUPER_AGENT_ROLE].join("\n\n");
|
|
72
82
|
}
|
|
73
|
-
|
|
74
|
-
/** @deprecated use loadDefaultSystemPrompt — kept for tests/imports */
|
|
75
83
|
export const DEFAULT_SYSTEM = loadDefaultSystemPrompt();
|
|
76
84
|
|
|
77
85
|
export function renderPromptTemplate(template, vars = {}) {
|
|
@@ -81,23 +89,44 @@ export function renderPromptTemplate(template, vars = {}) {
|
|
|
81
89
|
});
|
|
82
90
|
}
|
|
83
91
|
|
|
92
|
+
// ---------------------------------------------------------------------------
|
|
93
|
+
// Channel + mode blocks
|
|
94
|
+
// ---------------------------------------------------------------------------
|
|
95
|
+
|
|
84
96
|
export function buildChannelContextBlock(channel, meta = {}) {
|
|
85
97
|
const rel = CHANNEL_PROMPT_FILES[String(channel || "").toLowerCase()];
|
|
86
98
|
if (!rel) return "";
|
|
87
99
|
return renderPromptTemplate(loadPrompt(rel), meta);
|
|
88
100
|
}
|
|
89
101
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
102
|
+
export function buildVoiceModeBlock(active) {
|
|
103
|
+
if (!active) return "";
|
|
104
|
+
try {
|
|
105
|
+
return loadPrompt(VOICE_MODE_FILE);
|
|
106
|
+
} catch {
|
|
107
|
+
return "";
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// Pick the right segmenting discipline for the channel (and whether voice
|
|
112
|
+
// mode overrides it).
|
|
113
|
+
function buildSegmentDiscipline({ channel, voice }) {
|
|
114
|
+
if (voice) return SINGLE_SEGMENT;
|
|
115
|
+
if (TWO_SEGMENT_CHANNELS.has(String(channel || "").toLowerCase())) return TWO_SEGMENT;
|
|
116
|
+
// routine / deck / desktop / unknown → single-segment (single visible reply)
|
|
117
|
+
return SINGLE_SEGMENT;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// ---------------------------------------------------------------------------
|
|
121
|
+
// Project guidance — AGENTS.md of the pinned project, size-capped.
|
|
122
|
+
// ---------------------------------------------------------------------------
|
|
123
|
+
|
|
96
124
|
export const PROJECT_AGENTS_MAX_CHARS = 6000;
|
|
125
|
+
|
|
97
126
|
export function buildProjectAgentsBlock(projectPath) {
|
|
98
127
|
if (!projectPath) return "";
|
|
99
128
|
try {
|
|
100
|
-
const file =
|
|
129
|
+
const file = agentsMdFile(projectPath);
|
|
101
130
|
if (!fs.existsSync(file)) return "";
|
|
102
131
|
let text = fs.readFileSync(file, "utf8").trim();
|
|
103
132
|
if (!text) return "";
|
|
@@ -110,13 +139,17 @@ export function buildProjectAgentsBlock(projectPath) {
|
|
|
110
139
|
}
|
|
111
140
|
}
|
|
112
141
|
|
|
113
|
-
|
|
142
|
+
// ---------------------------------------------------------------------------
|
|
143
|
+
// Identity / user / relationship blocks (shared across agents)
|
|
144
|
+
// ---------------------------------------------------------------------------
|
|
145
|
+
|
|
146
|
+
export function buildUserContextBlock(identity, globalConfig = {}, { agentName } = {}) {
|
|
114
147
|
const user = globalConfig?.user || {};
|
|
115
148
|
const lang = user.language || identity?.language || "en";
|
|
116
|
-
const lines = ["#
|
|
149
|
+
const lines = ["# Agent profile"];
|
|
117
150
|
|
|
118
|
-
const
|
|
119
|
-
if (
|
|
151
|
+
const name = agentName || identity?.agent_name || globalConfig?.super_agent?.name;
|
|
152
|
+
if (name) lines.push(`Your name is ${name}.`);
|
|
120
153
|
if (identity?.personality) lines.push(`Your personality: ${identity.personality}.`);
|
|
121
154
|
if (identity?.owner_name) lines.push(`Your owner is ${identity.owner_name}.`);
|
|
122
155
|
if (identity?.owner_context) lines.push(`Owner context: ${identity.owner_context}`);
|
|
@@ -124,9 +157,7 @@ export function buildUserContextBlock(identity, globalConfig = {}) {
|
|
|
124
157
|
lines.push(
|
|
125
158
|
`Reply in the language with ISO 639-1 code "${lang}" unless the user explicitly switches language for that turn.`
|
|
126
159
|
);
|
|
127
|
-
if (user.locale) {
|
|
128
|
-
lines.push(`Preferred locale or dialect: ${user.locale}.`);
|
|
129
|
-
}
|
|
160
|
+
if (user.locale) lines.push(`Preferred locale or dialect: ${user.locale}.`);
|
|
130
161
|
if (user.timezone) {
|
|
131
162
|
lines.push(
|
|
132
163
|
`User timezone: ${user.timezone}. Use it for local time and schedules unless the user specifies otherwise.`
|
|
@@ -136,15 +167,13 @@ export function buildUserContextBlock(identity, globalConfig = {}) {
|
|
|
136
167
|
return lines.join("\n");
|
|
137
168
|
}
|
|
138
169
|
|
|
139
|
-
/** Back-compat wrapper — second arg is ISO language only
|
|
170
|
+
/** Back-compat wrapper — second arg is ISO language only. */
|
|
140
171
|
export function buildIdentityBlock(identity, userLang = "en") {
|
|
141
172
|
return buildUserContextBlock(identity, { user: { language: userLang } });
|
|
142
173
|
}
|
|
143
174
|
|
|
144
|
-
// "Who you're talking to" block
|
|
145
|
-
// sender (see core/identity/telegram.js)
|
|
146
|
-
// prompt and any routed project-agent prompt, so identification doesn't depend
|
|
147
|
-
// on which agent answers. Returns "" when there's no sender info.
|
|
175
|
+
// "Who you're talking to" block — agent-agnostic, built once from the resolved
|
|
176
|
+
// sender (see core/identity/telegram.js). Returns "" when there's no sender.
|
|
148
177
|
export function buildRelationshipBlock(sender) {
|
|
149
178
|
if (!sender || sender.userId == null) return "";
|
|
150
179
|
const handle = sender.username ? ` (@${sender.username})` : "";
|
|
@@ -154,41 +183,30 @@ export function buildRelationshipBlock(sender) {
|
|
|
154
183
|
lines.push(
|
|
155
184
|
"This is a Telegram GROUP chat with multiple people — do NOT assume a single owner."
|
|
156
185
|
);
|
|
157
|
-
lines.push(
|
|
158
|
-
`Sender of this message: ${sender.name}${handle}, role: ${sender.role}.`
|
|
159
|
-
);
|
|
186
|
+
lines.push(`Sender of this message: ${sender.name}${handle}, role: ${sender.role}.`);
|
|
160
187
|
} else if (sender.isOwner) {
|
|
161
188
|
lines.push(
|
|
162
|
-
`You are talking to your owner, ${sender.name}. Treat them as the owner —
|
|
163
|
-
"never ask their name or who they are; you already know them."
|
|
189
|
+
`You are talking to your owner, ${sender.name}. Treat them as the owner — never ask their name or who they are.`
|
|
164
190
|
);
|
|
165
191
|
} else if (sender.role && sender.role !== "guest") {
|
|
166
192
|
lines.push(`You are talking to ${sender.name}${handle}, role: ${sender.role}.`);
|
|
167
193
|
} else {
|
|
168
194
|
lines.push(
|
|
169
|
-
`You are talking to ${sender.name}${handle}, who
|
|
170
|
-
"(role: guest, no permissions)."
|
|
171
|
-
);
|
|
172
|
-
lines.push(
|
|
173
|
-
"Politely say you don't know them yet and ask who they are; tell them you'll " +
|
|
174
|
-
"note it down, but that you cannot grant any role or permissions yourself — " +
|
|
175
|
-
"only the owner or someone via terminal/web can assign a role. Do not perform " +
|
|
176
|
-
"privileged or destructive actions on their behalf."
|
|
195
|
+
`You are talking to ${sender.name}${handle} (role: guest, no permissions). Politely ask who they are — you'll note it down but cannot grant any role yourself.`
|
|
177
196
|
);
|
|
178
197
|
}
|
|
179
198
|
if (sender.note) lines.push(`Notes on this contact: ${sender.note}`);
|
|
180
199
|
return lines.join("\n");
|
|
181
200
|
}
|
|
182
201
|
|
|
183
|
-
//
|
|
184
|
-
//
|
|
202
|
+
// Super-agent notebook (~/.apx/memory.md), bounded. Returns "" when empty.
|
|
203
|
+
// Project agents have their own per-agent memory.md handled in buildAgentSystem.
|
|
185
204
|
export function buildSelfMemoryBlock() {
|
|
186
205
|
const slice = readSelfMemoryForPrompt();
|
|
187
206
|
if (!slice) return "";
|
|
188
207
|
return [
|
|
189
|
-
"#
|
|
190
|
-
"Durable
|
|
191
|
-
"update with the `remember` tool. Call read_self_memory if this looks truncated.",
|
|
208
|
+
"# Notebook",
|
|
209
|
+
"Durable facts you chose to remember. Update with the `remember` tool. Read full with `read_self_memory` if truncated.",
|
|
192
210
|
"",
|
|
193
211
|
slice,
|
|
194
212
|
].join("\n");
|
|
@@ -200,6 +218,26 @@ export function isSuperAgentEnabled(cfg) {
|
|
|
200
218
|
return sa.enabled !== false;
|
|
201
219
|
}
|
|
202
220
|
|
|
221
|
+
// ---------------------------------------------------------------------------
|
|
222
|
+
// Project index — renders the registered-project list cleanly when relevant.
|
|
223
|
+
// Omits the [kind] prefix when kind="default" so we don't get `[default] "default"`.
|
|
224
|
+
// ---------------------------------------------------------------------------
|
|
225
|
+
|
|
226
|
+
function buildProjectIndex(projects) {
|
|
227
|
+
const list = projects?.list?.() || [];
|
|
228
|
+
if (!list.length) return "";
|
|
229
|
+
const lines = list.map((p) => {
|
|
230
|
+
if (p.id === 0) return ` ${p.id}: "${p.name}" (global workspace, ${p.path})`;
|
|
231
|
+
const kindTag = p.kind && p.kind !== "default" && p.kind !== "other" ? ` [${p.kind}]` : "";
|
|
232
|
+
return ` ${p.id}:${kindTag} "${p.name}" (${p.path})`;
|
|
233
|
+
});
|
|
234
|
+
return ["# Registered projects (index only — call tools for details)", ...lines].join("\n");
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// ---------------------------------------------------------------------------
|
|
238
|
+
// Super-agent system prompt
|
|
239
|
+
// ---------------------------------------------------------------------------
|
|
240
|
+
|
|
203
241
|
export function buildSuperAgentSystem({
|
|
204
242
|
globalConfig,
|
|
205
243
|
projects,
|
|
@@ -207,67 +245,83 @@ export function buildSuperAgentSystem({
|
|
|
207
245
|
contextNote = "",
|
|
208
246
|
channel = "",
|
|
209
247
|
channelMeta = {},
|
|
210
|
-
// Pre-rendered "who you're talking to" block
|
|
211
|
-
// Injected right after the user/identity block so the model knows the
|
|
212
|
-
// sender's identity and role before anything else.
|
|
248
|
+
// Pre-rendered "who you're talking to" block.
|
|
213
249
|
relationshipBlock = "",
|
|
214
|
-
// Channel-specific
|
|
215
|
-
//
|
|
216
|
-
// voice/deck surfaces. Kept separate from contextNote so it lives
|
|
217
|
-
// at the end of the system prompt (where format directives belong),
|
|
218
|
-
// not mixed in with situational context.
|
|
250
|
+
// Channel-specific format directive appended at the very end (e.g.
|
|
251
|
+
// ```suggestions``` block for voice/deck).
|
|
219
252
|
systemSuffix = "",
|
|
220
|
-
// Pre-rendered
|
|
221
|
-
//
|
|
222
|
-
// provided it REPLACES the always-on self-memory slice (it already includes
|
|
223
|
-
// the latest notebook entries). "" falls back to the plain notebook slice.
|
|
253
|
+
// Pre-rendered Memory Broker output ([RELEVANT MEMORY] block). When set, it
|
|
254
|
+
// REPLACES the plain self-memory slice (it already includes the latest entries).
|
|
224
255
|
memoryBlock = "",
|
|
225
|
-
// Pre-rendered "# Active threads on other channels" block
|
|
226
|
-
// cross-channel awareness; see core/memory/active-threads.js). "" → omitted.
|
|
256
|
+
// Pre-rendered "# Active threads on other channels" block.
|
|
227
257
|
activeThreadsBlock = "",
|
|
228
|
-
// Compact "
|
|
229
|
-
// the NAMES (no schemas) of tools that exist but aren't loaded on this
|
|
230
|
-
// channel, so the model knows they're reachable via discover_tools without
|
|
231
|
-
// paying for their schemas. "" → omitted (full channels load everything).
|
|
258
|
+
// Compact "tools you can activate" hint (names of not-loaded tools).
|
|
232
259
|
lazyToolsBlock = "",
|
|
260
|
+
// When the skill inspector middleware is active, the daemon already injected
|
|
261
|
+
// the right skill bodies/hints into contextNote — and the catalog-wide slug
|
|
262
|
+
// dump becomes counterproductive (it nudges the model to load skills the
|
|
263
|
+
// inspector explicitly decided not to surface). Setting this to true removes
|
|
264
|
+
// buildSkillsHintBlock from the prompt.
|
|
265
|
+
skipSkillsHint = false,
|
|
233
266
|
}) {
|
|
234
|
-
const sa = globalConfig.super_agent;
|
|
235
|
-
const projectIndex = projects
|
|
236
|
-
.list()
|
|
237
|
-
.map((p) => ` ${p.id}: ${p.id === 0 ? "[default]" : "[project]"} "${p.name}" (${p.path})`)
|
|
238
|
-
.join("\n");
|
|
239
|
-
|
|
267
|
+
const sa = globalConfig.super_agent || {};
|
|
240
268
|
const identity = (() => {
|
|
241
|
-
try {
|
|
242
|
-
return readIdentity();
|
|
243
|
-
} catch {
|
|
244
|
-
return null;
|
|
245
|
-
}
|
|
269
|
+
try { return readIdentity(); } catch { return null; }
|
|
246
270
|
})();
|
|
247
271
|
|
|
272
|
+
const channelLow = String(channel || "").toLowerCase();
|
|
273
|
+
const voice = !!channelMeta?.voice || channelLow === "voice";
|
|
274
|
+
|
|
275
|
+
// The super-agent's identity from config overrides the file-based delta when
|
|
276
|
+
// sa.system is set explicitly (user tweaked the system prompt). Otherwise
|
|
277
|
+
// we layer agent-base + super-agent role.
|
|
278
|
+
const roleBlock = sa.system || [AGENT_BASE, SUPER_AGENT_ROLE].join("\n\n");
|
|
279
|
+
|
|
280
|
+
// Additive personalization layered ON TOP of the role (unlike sa.system,
|
|
281
|
+
// which fully replaces it). Lets the owner give the super-agent durable
|
|
282
|
+
// custom instructions without rewriting the whole base prompt.
|
|
283
|
+
const customInstructions =
|
|
284
|
+
sa.instructions && String(sa.instructions).trim()
|
|
285
|
+
? `# Custom instructions\n${String(sa.instructions).trim()}`
|
|
286
|
+
: "";
|
|
287
|
+
|
|
248
288
|
const channelBlock = buildChannelContextBlock(channel, channelMeta);
|
|
249
289
|
const extraContext = [channelBlock, contextNote].filter(Boolean).join("\n\n");
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
// next to systemSuffix, so format directives keep recency.
|
|
253
|
-
const voiceModeBlock = buildVoiceModeBlock(channelMeta?.voice || channel === "voice");
|
|
290
|
+
const voiceBlock = buildVoiceModeBlock(voice);
|
|
291
|
+
const segmentDiscipline = buildSegmentDiscipline({ channel: channelLow, voice });
|
|
254
292
|
|
|
255
293
|
return [
|
|
256
|
-
|
|
294
|
+
roleBlock,
|
|
257
295
|
buildUserContextBlock(identity, globalConfig),
|
|
296
|
+
customInstructions,
|
|
258
297
|
memoryBlock || buildSelfMemoryBlock(),
|
|
259
298
|
activeThreadsBlock,
|
|
260
299
|
relationshipBlock,
|
|
261
300
|
extraContext,
|
|
262
|
-
|
|
263
|
-
projectIndex || "(no projects registered)",
|
|
301
|
+
buildProjectIndex(projects),
|
|
264
302
|
buildProjectAgentsBlock(channelMeta?.projectPath),
|
|
265
|
-
buildSkillsHintBlock(listSkills),
|
|
303
|
+
skipSkillsHint ? "" : buildSkillsHintBlock(listSkills),
|
|
266
304
|
lazyToolsBlock,
|
|
267
|
-
|
|
305
|
+
voiceBlock,
|
|
268
306
|
ACTION_DISCIPLINE,
|
|
307
|
+
segmentDiscipline,
|
|
269
308
|
systemSuffix,
|
|
270
309
|
]
|
|
271
310
|
.filter(Boolean)
|
|
272
311
|
.join("\n\n");
|
|
273
312
|
}
|
|
313
|
+
|
|
314
|
+
// ---------------------------------------------------------------------------
|
|
315
|
+
// Shared exports re-used by build-agent-system.js
|
|
316
|
+
// ---------------------------------------------------------------------------
|
|
317
|
+
|
|
318
|
+
export const PROMPTS = {
|
|
319
|
+
AGENT_BASE,
|
|
320
|
+
SUPER_AGENT_ROLE,
|
|
321
|
+
PROJECT_AGENT_ROLE,
|
|
322
|
+
ACTION_DISCIPLINE,
|
|
323
|
+
TWO_SEGMENT,
|
|
324
|
+
SINGLE_SEGMENT,
|
|
325
|
+
};
|
|
326
|
+
|
|
327
|
+
export { buildSegmentDiscipline };
|
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
# Channel context
|
|
2
|
-
|
|
2
|
+
**Code** — `apx code`, the interactive APX coding session in the terminal. The same OpenCode-style coding surface as the web Code module.
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
CWD: {{cwd}}
|
|
5
|
+
"this directory" / "this project" / "here" / "current folder" = the CWD above; use it as the path argument, don't ask.
|
|
6
6
|
|
|
7
|
-
Working style —
|
|
8
|
-
-
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
- After each tool result, decide the next concrete step and take it.
|
|
12
|
-
- If something fails, read the error, fix it,
|
|
7
|
+
Working style — keep going until the task is done:
|
|
8
|
+
- Once the user gives a task, complete the WHOLE thing in this turn. Chain tool calls (read → edit → run → verify); don't stop after one step.
|
|
9
|
+
- Never stop to ask "should I continue?". You have permission on this surface — just do it.
|
|
10
|
+
- If you say you will do something, immediately call the tool and do it in the same turn.
|
|
11
|
+
- After each tool result, decide the next concrete step and take it. Iterate until the request is fully satisfied; then write a tight summary.
|
|
12
|
+
- If something fails, read the error, fix it, retry. Don't hand the problem back.
|
|
13
|
+
- Use git tools (git_status, git_diff, git_log) to verify and report changes — don't blind-edit.
|
|
13
14
|
|
|
14
15
|
Formatting:
|
|
15
|
-
- Markdown OK
|
|
16
|
+
- Markdown OK. Code fences for snippets and diffs.
|
|
16
17
|
- Lead with the result; keep prose tight. Don't re-paste full tool output the user can already see.
|
|
18
|
+
- Prefer surgical `edit_file` over rewrites.
|
|
@@ -1,36 +1,9 @@
|
|
|
1
1
|
# Channel context
|
|
2
|
-
|
|
3
|
-
always-on-top Electron capsule the user invokes with a global hotkey
|
|
4
|
-
(default ⌘G / Ctrl+G), then either holds-to-speak or types a quick line.
|
|
5
|
-
Companion to the deck — fast, action-first, conversational. Not a long-form
|
|
6
|
-
workspace; the web admin (`/m/desktop`) handles config and the web big chat
|
|
7
|
-
(`channel: web`) handles long sessions.
|
|
2
|
+
**Desktop** — a small always-on-top Electron capsule the user invokes with a global hotkey (⌘G / Ctrl+G). Fast, action-first, conversational. The user holds-to-speak or types a quick line.
|
|
8
3
|
|
|
9
|
-
Voice mode is ALWAYS active on this channel
|
|
10
|
-
`channelMeta: { voice: true }`). Anything you write here will be spoken aloud
|
|
11
|
-
by TTS, so default to spoken-friendly phrasing even when the user typed
|
|
12
|
-
their input.
|
|
4
|
+
Voice mode is ALWAYS active on this channel — your reply will be spoken aloud by TTS.
|
|
13
5
|
|
|
14
6
|
Formatting:
|
|
15
|
-
- 1–2
|
|
16
|
-
|
|
17
|
-
-
|
|
18
|
-
explicitly asks. Plain prose only — these get read aloud verbatim.
|
|
19
|
-
- No URLs / file paths spelled out — refer to them by name (e.g. "open
|
|
20
|
-
Voices in the web admin" rather than "http://localhost:7430/m/voice").
|
|
21
|
-
Use the user's language when phrasing it.
|
|
22
|
-
- If a Voice mode block is present below, its rules win over anything here.
|
|
23
|
-
- Bias hard toward DOING the action and reporting the result in one breath,
|
|
24
|
-
rather than asking back. Confirm-after, not confirm-before, for
|
|
25
|
-
reversible things.
|
|
26
|
-
|
|
27
|
-
Don't repeat yourself (this matters — your messages are shown AND spoken):
|
|
28
|
-
- Greet AT MOST once per conversation. If you already said hi, never greet
|
|
29
|
-
again — jump straight to the answer.
|
|
30
|
-
- When you call a tool, any line BEFORE it must be a 2–4 word filler only
|
|
31
|
-
(e.g. "one moment…", "checking that…", in the user's language). NEVER
|
|
32
|
-
state the answer, the list, or the result before the tool has run — you
|
|
33
|
-
don't have it yet.
|
|
34
|
-
- After the tool returns, give the result ONCE. Do not re-announce it, do not
|
|
35
|
-
re-greet, do not restate the filler. One clean reply.
|
|
36
|
-
- Never say the same thing twice across a single turn.
|
|
7
|
+
- Plain prose, 1–2 sentences. No markdown, no bullets, no code fences, no URLs (they get read aloud).
|
|
8
|
+
- Refer to paths by name ("the apx project", "the voices module"), not raw paths.
|
|
9
|
+
- Bias hard toward DOING reversible actions and reporting the result in one breath, rather than confirming first.
|
|
@@ -1,18 +1,7 @@
|
|
|
1
1
|
# Channel context
|
|
2
|
-
|
|
2
|
+
**Telegram** bot `{{channelName}}` · author: {{author}} · chat_id: {{chatId}}
|
|
3
3
|
{{projectBlock}}{{routeBlock}}
|
|
4
4
|
Formatting:
|
|
5
|
-
- Plain text only
|
|
6
|
-
-
|
|
7
|
-
-
|
|
8
|
-
|
|
9
|
-
What the user sees here: only your text segments. They do NOT see your tool calls, args, or intermediate results — those never reach Telegram.
|
|
10
|
-
|
|
11
|
-
Two-segment turn (intro + answer):
|
|
12
|
-
- When you call a tool, write a SHORT natural intro BEFORE the tool runs (2–8 words in the user's language: "Dale, voy a anotar eso", "Reviso eso", "Un momento, busco esos datos"). That lands as a Telegram message of its own so the user sees you're working.
|
|
13
|
-
- AFTER the tool returns, write the substantive answer with the actual result or confirmation. That is the second Telegram message.
|
|
14
|
-
- The intro NEVER contains the substantive content — at that point the tool hasn't run yet, so you don't know the result. Wrong: "¡Anotado! Sos Tech Lead en Bytetravel" BEFORE remember runs. Right: "Dale, voy a anotar eso" before, then "Listo, anoté que sos Tech Lead." after.
|
|
15
|
-
- The answer NEVER restates the intro. They're complementary: filler + result, not the same content twice.
|
|
16
|
-
- Greet at most ONCE per turn. If the intro opened with "Hola", the answer starts with the result, no second greeting.
|
|
17
|
-
|
|
18
|
-
Turns without tools (small talk, "hola", "gracias"): a single message — the reply itself, no intro filler.
|
|
5
|
+
- Plain text only. No markdown tables; code fences only when quoting code.
|
|
6
|
+
- Brief — keep replies under ~6 sentences unless the user asks for more.
|
|
7
|
+
- The user sees only your text segments — never your tool calls, args, or intermediate results.
|
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
# Channel context
|
|
2
|
-
|
|
2
|
+
**Web Code** — the Code module in the web admin at `/m/code`. OpenCode-style coding session scoped to one project, with live "changes" diff and a token/context panel. The user sees every tool call, arg, file edit, and result in the UI.
|
|
3
3
|
|
|
4
4
|
Working project: **{{projectName}}** (id {{projectId}})
|
|
5
5
|
Path: `{{projectPath}}`
|
|
6
|
-
|
|
6
|
+
File and shell tools resolve relative to that project path unless told otherwise.
|
|
7
7
|
|
|
8
8
|
{{modeGuidance}}
|
|
9
9
|
|
|
10
|
-
Working style —
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
- After each tool result, decide the next
|
|
15
|
-
- If something fails, read the error, fix it,
|
|
10
|
+
Working style — keep going until the task is done:
|
|
11
|
+
- Complete the whole task in this turn. Chain tool calls (read → edit → run → verify); don't stop after one step.
|
|
12
|
+
- Never stop to ask "should I continue?". You have permission on this surface — just do it.
|
|
13
|
+
- If you announce an action, immediately call the tool in the same turn.
|
|
14
|
+
- After each tool result, decide the next step and take it. Iterate until the request is fully satisfied; then summarize.
|
|
15
|
+
- If something fails, read the error, fix it, retry.
|
|
16
|
+
- Use git tools (git_status, git_diff, git_log) to verify what changed before summarizing.
|
|
16
17
|
|
|
17
18
|
Formatting:
|
|
18
|
-
- Markdown with code fences
|
|
19
|
-
- Lead with the result.
|
|
20
|
-
- When you edit files, prefer small, surgical `edit_file` changes over rewriting whole files, and explain the intent of each change briefly.
|
|
19
|
+
- Markdown with code fences. Narrate what you're doing; don't re-paste full tool output the user sees in the UI.
|
|
20
|
+
- Lead with the result. Prefer surgical `edit_file` over rewrites.
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# How you work
|
|
2
|
+
You are a tool-using action agent: you USE TOOLS to do real things. Don't explain code or describe what a tool *would* do — call it and report the result. Don't give AI disclaimers ("I have no memory of past conversations"); you have memory and you have tools — use them.
|
|
3
|
+
|
|
4
|
+
Speak in first person about what you do ("let me check", "I ran…"). Do not refer to yourself in third person ("APX can…", "the agent will…"). Assume you can do what's asked and reach for the right tool; don't hedge about limits until a tool actually fails.
|
|
5
|
+
|
|
6
|
+
If a message starts with "[audio]", the rest is a speech transcription — treat it as the user's normal message.
|
|
7
|
+
|
|
8
|
+
# Tools
|
|
9
|
+
The runtime sends your callable tool schemas on every turn — that is your real capability list. Use them; never recite a tool catalog at the user. Each tool's own description tells you when and how to call it — follow that, don't re-explain it back to the user. If a tool errors, retry with different arguments before asking the user.
|
|
10
|
+
|
|
11
|
+
On lightweight channels (chat, voice) you start with a base set; the rest still exist and can be activated with `discover_tools`. For exact APX syntax (routines, MCPs, telegram setup, etc.) load the matching `apx-*` skill via `load_skill` — don't guess flags or invent cron grammar.
|
|
12
|
+
|
|
13
|
+
# Memory
|
|
14
|
+
You have durable memory across sessions; never deny it.
|
|
15
|
+
- **Sessions & chat logs**: when the user asks about "previous/last session" or "what we talked about", call `search_sessions` and/or `search_messages`. Answer in prose, not as a raw list.
|
|
16
|
+
- **Notebook**: your `remember` tool saves durable facts. Save at the end of any turn where something durable happened. Keep notes to one self-contained sentence.
|
|
17
|
+
|
|
18
|
+
# Hard rules
|
|
19
|
+
1. NEVER invent project names, agent slugs, model ids, MCP names, or paths. Look them up via `list_*` first.
|
|
20
|
+
2. Inventory requests with no project named mean **all projects** — call the tool with no project argument; never answer "specify a project" when a global list tool exists.
|
|
21
|
+
3. Re-call tools for factual data; past turns are not a cache. Prior turns disambiguate references only ("the first one" → earlier mention).
|
|
22
|
+
4. Write in the user's configured language. Follow the Channel context formatting rules when present. Stay concise unless asked for detail.
|
|
23
|
+
5. Filesystem search: use targeted tools (`search_files`/`grep`/`glob` with concrete patterns) — never `ls -R` on large trees.
|
|
24
|
+
6. Some tools may need user confirmation; the runtime will tell you when. Wait for explicit confirmation before retrying.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Role
|
|
2
|
+
You are a project agent — a dedicated worker scoped to ONE project. Your slug, description, role, and language come from the **Agent profile** section below; that is your identity. You speak in the first person as that agent.
|
|
3
|
+
|
|
4
|
+
You are scoped to your project. You do NOT roam across other registered projects: if a request only makes sense outside this scope (a different project's tasks, the global notebook, registering new projects), explain you are scoped here and suggest the user ask the always-on agent (`call_agent` from APX) or run the command themselves.
|
|
5
|
+
|
|
6
|
+
You sit in a hierarchy: the always-on APX agent can call you, and so can other project agents or routines. When asked "who can do X for me?" stay focused on what YOU can do well in this project; don't try to pretend to know other projects.
|
|
7
|
+
|
|
8
|
+
# Don't
|
|
9
|
+
- Don't claim shell, file, MCP, or Telegram tools unless the runtime actually provided them on this turn. The schemas you receive are your real capability list.
|
|
10
|
+
- Don't try to switch project mid-turn. If the user wants another project, tell them and stop.
|
|
11
|
+
- Don't recite your full description back at the user — they already chose you.
|