@agentprojectcontext/apx 1.33.1 → 1.34.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 +4 -3
- 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 +2 -1
- 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/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/tools/handlers/add-project.js +5 -2
- package/src/core/agent/tools/handlers/call-runtime.js +3 -2
- 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 +138 -0
- package/src/core/agent/tools/registry-bridge.js +6 -14
- package/src/core/agent/tools/registry.js +68 -65
- 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 +3 -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 +95 -0
- package/src/core/runtime-skills/apx-mcp/SKILL.md +116 -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/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 +3 -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/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 +36 -55
- package/src/interfaces/web/dist/assets/index-DdmSRtsz.css +1 -0
- package/src/interfaces/web/dist/assets/index-M4FspaCH.js +613 -0
- package/src/interfaces/web/dist/assets/index-M4FspaCH.js.map +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 +16 -3
- 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 +5 -4
- 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/i18n/en.ts +174 -7
- package/src/interfaces/web/src/i18n/es.ts +179 -15
- package/src/interfaces/web/src/lib/api/mcps.ts +25 -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/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 +5 -0
- 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/{skills → src/core/runtime-skills}/apx-agency-agents/SKILL.md +0 -0
- /package/{skills → src/core/runtime-skills}/apx-agent/SKILL.md +0 -0
- /package/{skills → src/core/runtime-skills}/apx-mcp-builder/SKILL.md +0 -0
- /package/{skills → src/core/runtime-skills}/apx-project/SKILL.md +0 -0
- /package/{skills → src/core/runtime-skills}/apx-routine/SKILL.md +0 -0
- /package/{skills → src/core/runtime-skills}/apx-runtime/SKILL.md +0 -0
- /package/{skills → src/core/runtime-skills}/apx-sessions/SKILL.md +0 -0
- /package/{skills → src/core/runtime-skills}/apx-skill-builder/SKILL.md +0 -0
- /package/{skills → src/core/runtime-skills}/apx-task/SKILL.md +0 -0
- /package/{skills → src/core/runtime-skills}/apx-telegram/SKILL.md +0 -0
- /package/{skills → src/core/runtime-skills}/apx-voice/SKILL.md +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
|
@@ -16,6 +16,7 @@ import { runSuperAgent } from "#core/agent/super-agent.js";
|
|
|
16
16
|
import { appendSuperAgentErrorTrace } from "./shared.js";
|
|
17
17
|
import { createWebConfirmAdapter } from "#core/confirmation/adapters/web.js";
|
|
18
18
|
import { CHANNELS } from "#core/constants/channels.js";
|
|
19
|
+
import { CODE_MODES, DEFAULT_CODE_MODE } from "#core/constants/code-modes.js";
|
|
19
20
|
import {
|
|
20
21
|
listCodeSessions,
|
|
21
22
|
getCodeSession,
|
|
@@ -23,181 +24,28 @@ import {
|
|
|
23
24
|
updateCodeSession,
|
|
24
25
|
removeCodeSession,
|
|
25
26
|
appendTurn,
|
|
27
|
+
codeSessionHistory,
|
|
26
28
|
} from "#core/stores/code-sessions.js";
|
|
29
|
+
import { makeTurnAccumulator } from "#core/agent/stream/turn-accumulator.js";
|
|
27
30
|
import { captureBaseline, diffAgainstBaseline, initGitRepo } from "#core/git-baseline.js";
|
|
28
31
|
import { loggerFor } from "#core/logging.js";
|
|
29
32
|
import { readAgents } from "#core/apc/parser.js";
|
|
33
|
+
import { CODE_PLAN_TOOLS, CODE_BUILD_TOOLS } from "#core/agent/tools/names.js";
|
|
34
|
+
import { codeModeGuidance } from "#core/agent/prompts/modes/index.js";
|
|
30
35
|
|
|
31
36
|
const log = loggerFor("code");
|
|
32
37
|
|
|
33
|
-
//
|
|
34
|
-
//
|
|
35
|
-
//
|
|
36
|
-
|
|
37
|
-
"read_file",
|
|
38
|
-
"list_files",
|
|
39
|
-
"search_files",
|
|
40
|
-
"grep",
|
|
41
|
-
"glob",
|
|
42
|
-
"list_projects",
|
|
43
|
-
"list_agents",
|
|
44
|
-
"list_mcps",
|
|
45
|
-
"read_agent_memory",
|
|
46
|
-
"read_self_memory",
|
|
47
|
-
"search_sessions",
|
|
48
|
-
"search_messages",
|
|
49
|
-
"tail_messages",
|
|
50
|
-
"list_skills",
|
|
51
|
-
"load_skill",
|
|
52
|
-
"list_tasks",
|
|
53
|
-
"ask_questions",
|
|
54
|
-
"fetch",
|
|
55
|
-
"search",
|
|
56
|
-
];
|
|
57
|
-
|
|
38
|
+
// Mode-specific tool allow-lists and prompt fragments are owned by core/:
|
|
39
|
+
// - tool names + plan/build lists → #core/agent/tools/names.js
|
|
40
|
+
// - per-mode guidance text → #core/agent/prompts/modes/*.md
|
|
41
|
+
// This file just picks the right pair for the request.
|
|
58
42
|
function modeGuidanceFor(mode) {
|
|
59
|
-
|
|
60
|
-
return [
|
|
61
|
-
"MODE: plan. Investigate the codebase (read/list/search/grep) and propose",
|
|
62
|
-
"an approach with the EXACT changes you would make (files + diffs/snippets).",
|
|
63
|
-
"Do NOT write or edit files and do NOT run mutating shell commands — your",
|
|
64
|
-
"editing tools are disabled in this mode. End with a concise, ordered plan.",
|
|
65
|
-
].join(" ");
|
|
66
|
-
}
|
|
67
|
-
return [
|
|
68
|
-
"MODE: build. Make the changes directly using your file and shell tools",
|
|
69
|
-
"(read_file, write_file, edit_file, run_shell, …). Do not ask for",
|
|
70
|
-
"confirmation and do not stop after one step — keep calling tools until the",
|
|
71
|
-
"entire task is done, then briefly summarize what you changed and why.",
|
|
72
|
-
"Prefer surgical edits over rewrites.",
|
|
73
|
-
"When the user asks for a reusable script, snippet, or 'artifact' (something",
|
|
74
|
-
"they want to keep and run later), put it under `artifacts/<name>` inside",
|
|
75
|
-
"the project — it then shows up in the Artifacts tab. Don't drop reusable",
|
|
76
|
-
"scripts at the project root.",
|
|
77
|
-
"If a parameter you need is missing (API key, app id, target URL, …), call",
|
|
78
|
-
"`ask_questions` ONCE with all your questions and stop — control returns",
|
|
79
|
-
"to the user. Do not call ask_questions again in the same turn; you'll just",
|
|
80
|
-
"get the same blank state back. Each question can be a string (free-text",
|
|
81
|
-
"answer) OR an object {question, options:[{label, description}], multiSelect}",
|
|
82
|
-
"for choices. Prefer 2–4 mutually-exclusive options when a question has a",
|
|
83
|
-
"natural shortlist (yes/no, which-of-these, …); leave options empty for",
|
|
84
|
-
"open-ended answers (API keys, names, free-form ideas).",
|
|
85
|
-
"If the previous assistant turn already asked these same questions and the",
|
|
86
|
-
"current user message is the compiled answers, DO NOT call ask_questions",
|
|
87
|
-
"again — process the answers and proceed with the task.",
|
|
88
|
-
].join(" ");
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
// Build the [{role, content}] history the super-agent expects from the stored
|
|
92
|
-
// rich transcript: flatten each turn's text parts. Tool parts are normally
|
|
93
|
-
// internal, but ask_questions is special — without surfacing it the model
|
|
94
|
-
// loses track that it ALREADY asked, sees the user's compiled-answer reply
|
|
95
|
-
// as a fresh request, and asks again forever. We render a one-line synthetic
|
|
96
|
-
// summary of each ask_questions call so the next turn's context shows
|
|
97
|
-
// "I asked X, the user replied Y" naturally.
|
|
98
|
-
function summarizeAskQuestionsPart(part) {
|
|
99
|
-
const raw = part?.args?.questions;
|
|
100
|
-
if (!Array.isArray(raw) || raw.length === 0) return null;
|
|
101
|
-
const lines = raw
|
|
102
|
-
.map((q) => {
|
|
103
|
-
if (typeof q === "string") return `- ${q}`;
|
|
104
|
-
if (!q || typeof q !== "object" || typeof q.question !== "string") return null;
|
|
105
|
-
const opts = Array.isArray(q.options) ? q.options : [];
|
|
106
|
-
const optStr = opts
|
|
107
|
-
.map((o) => (typeof o === "string" ? o : (o && typeof o.label === "string" ? o.label : "")))
|
|
108
|
-
.filter(Boolean)
|
|
109
|
-
.join(", ");
|
|
110
|
-
return optStr ? `- ${q.question} (opciones: ${optStr})` : `- ${q.question}`;
|
|
111
|
-
})
|
|
112
|
-
.filter(Boolean);
|
|
113
|
-
if (lines.length === 0) return null;
|
|
114
|
-
return `[ask_questions]\n${lines.join("\n")}`;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
function historyFrom(session) {
|
|
118
|
-
return (session.messages || []).map((m) => {
|
|
119
|
-
const chunks = [];
|
|
120
|
-
for (const p of m.parts || []) {
|
|
121
|
-
if (!p) continue;
|
|
122
|
-
if (p.kind === "text" && p.text) chunks.push(p.text);
|
|
123
|
-
else if (p.kind === "tool" && p.tool === "ask_questions") {
|
|
124
|
-
const summary = summarizeAskQuestionsPart(p);
|
|
125
|
-
if (summary) chunks.push(summary);
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
return { role: m.role, content: chunks.join("\n\n").trim() };
|
|
129
|
-
});
|
|
43
|
+
return codeModeGuidance(mode);
|
|
130
44
|
}
|
|
131
45
|
|
|
132
|
-
//
|
|
133
|
-
//
|
|
134
|
-
//
|
|
135
|
-
function makeTurnAccumulator() {
|
|
136
|
-
const parts = [];
|
|
137
|
-
const notes = [];
|
|
138
|
-
let model = null;
|
|
139
|
-
let usage = null;
|
|
140
|
-
const findTool = (id) => parts.find((p) => p.kind === "tool" && p.id === id);
|
|
141
|
-
return {
|
|
142
|
-
apply(ev) {
|
|
143
|
-
switch (ev?.type) {
|
|
144
|
-
case "model_start":
|
|
145
|
-
if (ev.model) model = ev.model;
|
|
146
|
-
break;
|
|
147
|
-
case "model_routed":
|
|
148
|
-
if (ev.model) model = ev.model;
|
|
149
|
-
if (ev.from_fallback) notes.push(`routing fell back → ${ev.model}`);
|
|
150
|
-
break;
|
|
151
|
-
case "engine_failed":
|
|
152
|
-
notes.push(`engine ${ev.model || "?"} failed → ${ev.retry_with || "retry"}`);
|
|
153
|
-
break;
|
|
154
|
-
case "model_retry":
|
|
155
|
-
notes.push(`retry (${ev.reason || "?"})`);
|
|
156
|
-
break;
|
|
157
|
-
case "tools_suppressed":
|
|
158
|
-
notes.push(`tools suppressed: ${(ev.tools || []).join(", ")}`);
|
|
159
|
-
break;
|
|
160
|
-
case "assistant_text":
|
|
161
|
-
if (ev.text) parts.push({ kind: "text", text: ev.text });
|
|
162
|
-
break;
|
|
163
|
-
case "tool_start":
|
|
164
|
-
if (ev.trace)
|
|
165
|
-
parts.push({
|
|
166
|
-
kind: "tool",
|
|
167
|
-
id: ev.trace.id,
|
|
168
|
-
tool: ev.trace.tool,
|
|
169
|
-
args: ev.trace.args,
|
|
170
|
-
status: "running",
|
|
171
|
-
});
|
|
172
|
-
break;
|
|
173
|
-
case "tool_deduped": {
|
|
174
|
-
const t = ev.trace && findTool(ev.trace.id);
|
|
175
|
-
if (t) t.status = "deduped";
|
|
176
|
-
break;
|
|
177
|
-
}
|
|
178
|
-
case "tool_result": {
|
|
179
|
-
const t = ev.trace && findTool(ev.trace.id);
|
|
180
|
-
if (t) {
|
|
181
|
-
t.result = ev.trace.result;
|
|
182
|
-
const errored =
|
|
183
|
-
ev.trace.result && typeof ev.trace.result === "object" && ev.trace.result.error;
|
|
184
|
-
t.status = errored ? "error" : t.status === "deduped" ? "deduped" : "done";
|
|
185
|
-
}
|
|
186
|
-
break;
|
|
187
|
-
}
|
|
188
|
-
case "final":
|
|
189
|
-
usage = ev.result?.usage ?? usage;
|
|
190
|
-
if (!model) model = ev.result?.name || null;
|
|
191
|
-
break;
|
|
192
|
-
default:
|
|
193
|
-
break;
|
|
194
|
-
}
|
|
195
|
-
},
|
|
196
|
-
build() {
|
|
197
|
-
return { parts, notes, model, usage };
|
|
198
|
-
},
|
|
199
|
-
};
|
|
200
|
-
}
|
|
46
|
+
// History flattening + stream-event accumulator now live in core/ — see
|
|
47
|
+
// codeSessionHistory() (transcript → engine messages) and makeTurnAccumulator()
|
|
48
|
+
// (stream events → persistable ChatParts) imported above.
|
|
201
49
|
|
|
202
50
|
export function register(app, { projects, project, config, registries, plugins }) {
|
|
203
51
|
const findProject = (req, res) => project(req, res);
|
|
@@ -290,8 +138,8 @@ export function register(app, { projects, project, config, registries, plugins }
|
|
|
290
138
|
const { prompt } = req.body || {};
|
|
291
139
|
if (!prompt) return res.status(400).json({ error: "prompt required" });
|
|
292
140
|
|
|
293
|
-
const mode = session.mode ===
|
|
294
|
-
const previousMessages =
|
|
141
|
+
const mode = session.mode === CODE_MODES.PLAN ? CODE_MODES.PLAN : DEFAULT_CODE_MODE;
|
|
142
|
+
const previousMessages = codeSessionHistory(session);
|
|
295
143
|
|
|
296
144
|
// If a project agent is selected, inject its system prompt as a suffix so
|
|
297
145
|
// the super-agent's tool loop runs with the agent's personality/context.
|
|
@@ -340,7 +188,7 @@ export function register(app, { projects, project, config, registries, plugins }
|
|
|
340
188
|
previousMessages,
|
|
341
189
|
systemSuffix: agentSystemSuffix,
|
|
342
190
|
overrideModel: session.model || undefined,
|
|
343
|
-
allowedTools: mode ===
|
|
191
|
+
allowedTools: mode === CODE_MODES.PLAN ? CODE_PLAN_TOOLS : CODE_BUILD_TOOLS,
|
|
344
192
|
// Coding tasks are multi-step: give the loop a high safety ceiling so it
|
|
345
193
|
// can chain 20-30+ tools (read → edit → run → verify …) and a real
|
|
346
194
|
// output budget for substantial code / explanations per turn. The
|
|
@@ -351,7 +199,7 @@ export function register(app, { projects, project, config, registries, plugins }
|
|
|
351
199
|
// Build mode = the model must keep calling tools until it calls `finish`.
|
|
352
200
|
// Plan mode is read-only investigation that ends with a written plan, so
|
|
353
201
|
// it keeps the normal "text ends the turn" behavior.
|
|
354
|
-
completionContract: mode ===
|
|
202
|
+
completionContract: mode === CODE_MODES.BUILD,
|
|
355
203
|
onEvent,
|
|
356
204
|
requestConfirmation: createWebConfirmAdapter({ onEvent }),
|
|
357
205
|
});
|
|
@@ -10,10 +10,9 @@ import {
|
|
|
10
10
|
setDottedKey,
|
|
11
11
|
unsetDottedKey,
|
|
12
12
|
} from "../project-config.js";
|
|
13
|
+
import { apcProjectFile, apcProjectConfigFile } from "#core/apc/paths.js";
|
|
13
14
|
|
|
14
|
-
|
|
15
|
-
return path.join(root, ".apc", "project.json");
|
|
16
|
-
}
|
|
15
|
+
const projectJsonPath = apcProjectFile;
|
|
17
16
|
|
|
18
17
|
function readProjectJson(root) {
|
|
19
18
|
const p = projectJsonPath(root);
|
|
@@ -34,7 +33,7 @@ export function register(app, { projects, project }) {
|
|
|
34
33
|
res.json({
|
|
35
34
|
effective: p.config || {},
|
|
36
35
|
project_only: readProjectConfig(p.path),
|
|
37
|
-
project_config_path:
|
|
36
|
+
project_config_path: apcProjectConfigFile(p.path),
|
|
38
37
|
apc_project: readProjectJson(p.path),
|
|
39
38
|
project_json_path: projectJsonPath(p.path),
|
|
40
39
|
});
|
|
@@ -4,12 +4,10 @@
|
|
|
4
4
|
// POST /projects/:pid/agents/:slug/compact
|
|
5
5
|
// POST /projects/:pid/agents/:slug/conversations/:id/compact
|
|
6
6
|
// POST /projects/:pid/send (agent-to-agent)
|
|
7
|
-
import fs from "node:fs";
|
|
8
|
-
import path from "node:path";
|
|
9
7
|
import { readAgents } from "#core/apc/parser.js";
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
8
|
+
import { listConversations, readConversation } from "#core/stores/conversations.js";
|
|
9
|
+
import { compactConversation } from "#core/stores/conversations-compactor.js";
|
|
10
|
+
import { replyAsAgent } from "#core/agent/a2a/reply.js";
|
|
13
11
|
import { nowIso } from "./shared.js";
|
|
14
12
|
|
|
15
13
|
export function register(app, { project, config }) {
|
|
@@ -102,30 +100,11 @@ export function register(app, { project, config }) {
|
|
|
102
100
|
let reply = null;
|
|
103
101
|
if (deliver && toAgent.fields.Model) {
|
|
104
102
|
try {
|
|
105
|
-
const
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
parts.push(
|
|
111
|
-
`You are ${toAgent.slug}. You just received a message from ${fromAgent.slug}. Reply concisely.`
|
|
112
|
-
);
|
|
113
|
-
const memPath = path.join(
|
|
114
|
-
p.path,
|
|
115
|
-
".apc",
|
|
116
|
-
"agents",
|
|
117
|
-
toAgent.slug,
|
|
118
|
-
"memory.md"
|
|
119
|
-
);
|
|
120
|
-
if (fs.existsSync(memPath))
|
|
121
|
-
parts.push("## Memory\n" + fs.readFileSync(memPath, "utf8"));
|
|
122
|
-
|
|
123
|
-
const result = await callEngine({
|
|
124
|
-
modelId: toAgent.fields.Model,
|
|
125
|
-
system: parts.join("\n\n"),
|
|
126
|
-
messages: [
|
|
127
|
-
{ role: "user", content: `From ${fromAgent.slug}:\n\n${body}` },
|
|
128
|
-
],
|
|
103
|
+
const result = await replyAsAgent({
|
|
104
|
+
projectPath: p.path,
|
|
105
|
+
toAgent,
|
|
106
|
+
fromAgent,
|
|
107
|
+
body,
|
|
129
108
|
config: p.config || config,
|
|
130
109
|
});
|
|
131
110
|
|