@agentconnect.md/daemon 1.0.0-rc.240 → 1.0.0-rc.242
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{acp-host-M9PGQrVJ.js → acp-host-iKdfasdN.js} +715 -15
- package/dist/acp-host-iKdfasdN.js.map +1 -0
- package/dist/{agent-list-LnizWro3.js → agent-list-aVWm-4ru.js} +2 -2
- package/dist/{agent-list-LnizWro3.js.map → agent-list-aVWm-4ru.js.map} +1 -1
- package/dist/{chat-CeThir-Y.js → chat-hWjORIJV.js} +7 -4
- package/dist/chat-hWjORIJV.js.map +1 -0
- package/dist/index.js +4 -4
- package/dist/{load-agents-C3pJSVeT.js → load-agents-Dt8ZYMsH.js} +6 -1
- package/dist/load-agents-Dt8ZYMsH.js.map +1 -0
- package/dist/{login-CoeR7Gr0.js → login-BKn49aay.js} +4 -4
- package/dist/{login-CoeR7Gr0.js.map → login-BKn49aay.js.map} +1 -1
- package/dist/{run-foreground-Cdxkfe7g.js → run-foreground-CLPgcMuB.js} +26 -419
- package/dist/{run-foreground-Cdxkfe7g.js.map → run-foreground-CLPgcMuB.js.map} +1 -1
- package/dist/run-foreground-V9zo7E1r.js +2 -0
- package/package.json +1 -1
- package/dist/acp-host-M9PGQrVJ.js.map +0 -1
- package/dist/chat-CeThir-Y.js.map +0 -1
- package/dist/load-agents-C3pJSVeT.js.map +0 -1
- package/dist/run-foreground-B8NoERhV.js +0 -2
|
@@ -3,16 +3,16 @@ import { n as require_ms, t as require_src$3 } from "./src-DDtlVutj.js";
|
|
|
3
3
|
import { n as init_esm_shims, t as __dirname } from "./esm-shims-DxGcm4Hw.js";
|
|
4
4
|
import { t as DAEMON_VERSION } from "./version-DGaRXjBK.js";
|
|
5
5
|
import { C as _coercedNumber, T as NEVER, a as array, d as literal, f as looseObject, i as any, m as object, o as boolean, p as number$1, t as ZodNumber, v as string, x as url$4 } from "./schemas-CQkO9hC5.js";
|
|
6
|
-
import { a as agentChildEnv, i as selectAgent, n as findAgentFiles, o as loadConfig, r as loadAgents, s as persistDaemonId } from "./load-agents-
|
|
6
|
+
import { a as agentChildEnv, i as selectAgent, n as findAgentFiles, o as loadConfig, r as loadAgents, s as persistDaemonId } from "./load-agents-Dt8ZYMsH.js";
|
|
7
7
|
import { l as resolveRoot, o as mcpSocketPath, u as statePath } from "./paths-DEcUO8lC.js";
|
|
8
|
-
import { C as resolveRuntimes, S as
|
|
8
|
+
import { A as toolsForIntegrations, C as decodeRelayDaemonFrame, D as MAX_FRAME_BYTES, E as encode, M as cachedRuntimeVersions, N as resolveRuntimes, O as RESERVED_MCP_SERVER_NAME, S as buildRelayDaemonFrame, T as decodeEnvelope, _ as writeMemoryFile, a as initGitInjection, b as RELAY_DAEMON_SUBPROTOCOL, c as simpleGit, d as memoryProviderFor, f as MemoryConflictError, g as resolveInMemoryDir, h as listMemory, i as prepareWorkspace, j as cachedRuntimeNames, k as MEMORY_TOOL_NAMES, l as createMemoryProvider, m as MemoryTooLargeError, n as installedRuntimes, o as probeGitVersion, p as MemoryPathError, r as prefetchWorkspace, s as sessionGitEnv, t as AcpHost, u as memoryKindOf, w as buildEnvelope, x as RELAY_DAEMON_WS_PATH, y as normalizeGitUrl } from "./acp-host-iKdfasdN.js";
|
|
9
9
|
import { i as GitCredentialCache, n as gitcredSocketPath, r as writeGitcredShim, t as GitCredServer } from "./gitcred-server-Dcsq6QJe.js";
|
|
10
10
|
import { B as ToolListChangedNotificationSchema, D as ListPromptsResultSchema, E as ListChangedOptionsBaseSchema, F as PromptListChangedNotificationSchema, G as isZ4Schema, H as isJSONRPCRequest, I as ReadResourceResultSchema, J as encodeFrame, K as safeParse, L as ResourceListChangedNotificationSchema, M as ListToolsResultSchema, O as ListResourceTemplatesResultSchema, P as McpError, R as SUPPORTED_PROTOCOL_VERSIONS, S as InitializeResultSchema, T as LATEST_PROTOCOL_VERSION, U as isJSONRPCResultResponse, V as isInitializedNotification, W as getObjectShape, _ as ElicitResultSchema, a as AjvJsonSchemaValidator, b as GetPromptResultSchema, c as mergeCapabilities, d as CompleteResultSchema, f as CreateMessageRequestSchema, g as ElicitRequestSchema, h as CreateTaskResultSchema, i as assertToolsCallTaskCapability, k as ListResourcesResultSchema, m as CreateMessageResultWithToolsSchema, n as serializeMessage, o as require_fast_deep_equal, p as CreateMessageResultSchema, q as decodeFrames, r as assertClientRequestTaskCapability, s as Protocol, t as ReadBuffer, u as CallToolResultSchema, v as EmptyResultSchema, w as JSONRPCMessageSchema, y as ErrorCode } from "./stdio-DnS8WcXi.js";
|
|
11
11
|
import { URL as URL$1 } from "url";
|
|
12
12
|
import * as tls from "tls";
|
|
13
13
|
import * as net$5 from "net";
|
|
14
14
|
import * as path$16 from "node:path";
|
|
15
|
-
import { dirname,
|
|
15
|
+
import { dirname, join, relative, resolve, sep } from "node:path";
|
|
16
16
|
import * as http$8 from "http";
|
|
17
17
|
import { Agent } from "https";
|
|
18
18
|
import { chmodSync, existsSync, mkdirSync, mkdtempSync, promises, readFileSync, rmSync, stat, unwatchFile, watch, watchFile, writeFileSync } from "node:fs";
|
|
@@ -4121,150 +4121,6 @@ function compareEntries(a, b) {
|
|
|
4121
4121
|
return a.name < b.name ? -1 : a.name > b.name ? 1 : 0;
|
|
4122
4122
|
}
|
|
4123
4123
|
//#endregion
|
|
4124
|
-
//#region src/agents/memory.ts
|
|
4125
|
-
/**
|
|
4126
|
-
* Agent memory — a DIRECTORY at the agent's ROOT (`<agent-root>/memory/`), OUTSIDE
|
|
4127
|
-
* the workspace so it survives a workspace reset / re-clone and is never committed
|
|
4128
|
-
* into a github-workspace repo.
|
|
4129
|
-
*
|
|
4130
|
-
* Index-plus-topics shape (the structure Claude Code's auto-memory uses): a lean
|
|
4131
|
-
* `MEMORY.md` index — injected into the prompt every session, so it must stay small
|
|
4132
|
-
* — plus any number of `<topic>.md` files the agent reads on demand. The agent
|
|
4133
|
-
* maintains it via the `readMemory` / `writeMemory` / `listMemory` MCP tools; the
|
|
4134
|
-
* daemon serves the same directory to the CP for the console.
|
|
4135
|
-
*
|
|
4136
|
-
* SECURITY: topic paths are agent/console-supplied, so every path is contained to
|
|
4137
|
-
* the memory dir — absolute paths and `..` escapes are rejected, and the resolved
|
|
4138
|
-
* path is re-checked so a symlink can't smuggle a target out. Flat by design (one
|
|
4139
|
-
* level): a topic is a file directly under `memory/`, no nested dirs.
|
|
4140
|
-
*/
|
|
4141
|
-
const MEMORY_DIRNAME = "memory";
|
|
4142
|
-
/** Max bytes of the index injected into the prompt each session — keeps a large
|
|
4143
|
-
* memory from swelling the context (mirrors Claude Code's 25 KB entrypoint cap). */
|
|
4144
|
-
const MAX_INDEX_INJECT_BYTES = 25e3;
|
|
4145
|
-
/** Hard cap on a single memory file. Injected/read every session, so an unbounded
|
|
4146
|
-
* file would swell the prompt and the wire; writes over this are rejected. */
|
|
4147
|
-
const MAX_MEMORY_FILE_BYTES = 256e3;
|
|
4148
|
-
/** Raised when a memory path escapes the memory dir. Surfaces as `BAD_PAYLOAD`. */
|
|
4149
|
-
var MemoryPathError = class extends Error {
|
|
4150
|
-
constructor(message) {
|
|
4151
|
-
super(message);
|
|
4152
|
-
this.name = "MemoryPathError";
|
|
4153
|
-
}
|
|
4154
|
-
};
|
|
4155
|
-
/** Raised when a write exceeds {@link MAX_MEMORY_FILE_BYTES}. `BAD_PAYLOAD`. */
|
|
4156
|
-
var MemoryTooLargeError = class extends Error {
|
|
4157
|
-
constructor(message) {
|
|
4158
|
-
super(message);
|
|
4159
|
-
this.name = "MemoryTooLargeError";
|
|
4160
|
-
}
|
|
4161
|
-
};
|
|
4162
|
-
/** Raised when an `ifMatchMtime` precondition fails (the file changed under the
|
|
4163
|
-
* writer — e.g. a console edit racing a newer agent write). Surfaces as CONFLICT. */
|
|
4164
|
-
var MemoryConflictError = class extends Error {
|
|
4165
|
-
constructor(message) {
|
|
4166
|
-
super(message);
|
|
4167
|
-
this.name = "MemoryConflictError";
|
|
4168
|
-
}
|
|
4169
|
-
};
|
|
4170
|
-
/** The memory directory for an agent, given its root dir (where agent.json lives). */
|
|
4171
|
-
function memoryDir(agentDir) {
|
|
4172
|
-
return join(agentDir, MEMORY_DIRNAME);
|
|
4173
|
-
}
|
|
4174
|
-
/** Resolve a memory-dir-relative path to an absolute one, contained to the dir.
|
|
4175
|
-
* Rejects absolute paths, `..` escapes, and any nested directory (flat only). */
|
|
4176
|
-
function resolveInMemoryDir(agentDir, relPath) {
|
|
4177
|
-
if (isAbsolute(relPath)) throw new MemoryPathError("absolute paths are not allowed");
|
|
4178
|
-
const dir = memoryDir(agentDir);
|
|
4179
|
-
const abs = resolve(dir, relPath);
|
|
4180
|
-
if (abs !== dir && !abs.startsWith(dir + sep)) throw new MemoryPathError("path escapes the memory dir");
|
|
4181
|
-
const rel = abs.slice(dir.length + 1);
|
|
4182
|
-
if (rel.includes(sep)) throw new MemoryPathError("memory is a flat directory (no subdirectories)");
|
|
4183
|
-
if (rel.length === 0) throw new MemoryPathError("a file name is required");
|
|
4184
|
-
return abs;
|
|
4185
|
-
}
|
|
4186
|
-
/** Seed `<agent-root>/memory/MEMORY.md` with a header if the dir/index is absent
|
|
4187
|
-
* (idempotent). Called at session start so a brand-new agent always has an index. */
|
|
4188
|
-
function ensureMemory(agentDir, agentName) {
|
|
4189
|
-
const dir = memoryDir(agentDir);
|
|
4190
|
-
mkdirSync(dir, { recursive: true });
|
|
4191
|
-
const index = join(dir, MEMORY_INDEX);
|
|
4192
|
-
if (!existsSync(index)) writeFileSync(index, `# ${agentName} memory\n\nYour long-term memory index. Keep it short — link out to topic files (e.g. \`[deploys](deploys.md)\`) for detail and read them on demand with the readMemory tool.\n`);
|
|
4193
|
-
}
|
|
4194
|
-
/** Read the memory index (`MEMORY.md`) for prompt injection, trimmed to the inject
|
|
4195
|
-
* cap so a large index can't blow up the prompt; '' when absent. */
|
|
4196
|
-
async function readIndex(agentDir) {
|
|
4197
|
-
const text = await readMemoryFile(agentDir, MEMORY_INDEX);
|
|
4198
|
-
if (Buffer.byteLength(text) <= 25e3) return text;
|
|
4199
|
-
return Buffer.from(text, "utf8").subarray(0, MAX_INDEX_INJECT_BYTES).toString("utf8") + "\n\n[…memory index truncated — trim MEMORY.md]";
|
|
4200
|
-
}
|
|
4201
|
-
/** Read a memory file's text; '' when it does not exist (never throws on ENOENT). */
|
|
4202
|
-
async function readMemoryFile(agentDir, relPath) {
|
|
4203
|
-
const abs = resolveInMemoryDir(agentDir, relPath);
|
|
4204
|
-
try {
|
|
4205
|
-
return await promises.readFile(abs, "utf8");
|
|
4206
|
-
} catch (err) {
|
|
4207
|
-
if (err.code === "ENOENT") return "";
|
|
4208
|
-
throw err;
|
|
4209
|
-
}
|
|
4210
|
-
}
|
|
4211
|
-
/** Overwrite a memory file with `content` (creating the dir if needed). Atomic
|
|
4212
|
-
* (tmp + rename) so a concurrent read never sees a partial file.
|
|
4213
|
-
*
|
|
4214
|
-
* - Rejects content over {@link MAX_MEMORY_FILE_BYTES} ({@link MemoryTooLargeError}).
|
|
4215
|
-
* - `ifMatchMtime` (optimistic concurrency): when given, the current file's mtime
|
|
4216
|
-
* must equal it, else {@link MemoryConflictError} — so a console edit can't
|
|
4217
|
-
* clobber a newer write. A brand-new file (no mtime) matches `ifMatchMtime`
|
|
4218
|
-
* only when the caller passes none (or the empty string). */
|
|
4219
|
-
async function writeMemoryFile(agentDir, relPath, content, ifMatchMtime) {
|
|
4220
|
-
if (Buffer.byteLength(content) > 256e3) throw new MemoryTooLargeError(`memory file exceeds the ${MAX_MEMORY_FILE_BYTES}-byte limit`);
|
|
4221
|
-
const abs = resolveInMemoryDir(agentDir, relPath);
|
|
4222
|
-
if (ifMatchMtime) {
|
|
4223
|
-
let current = null;
|
|
4224
|
-
try {
|
|
4225
|
-
current = (await promises.stat(abs)).mtime.toISOString();
|
|
4226
|
-
} catch (err) {
|
|
4227
|
-
if (err.code !== "ENOENT") throw err;
|
|
4228
|
-
}
|
|
4229
|
-
if (current !== ifMatchMtime) throw new MemoryConflictError("the memory file changed since it was read; reload and retry");
|
|
4230
|
-
}
|
|
4231
|
-
await promises.mkdir(memoryDir(agentDir), { recursive: true });
|
|
4232
|
-
const tmp = `${abs}.tmp`;
|
|
4233
|
-
await promises.writeFile(tmp, content, "utf8");
|
|
4234
|
-
await promises.rename(tmp, abs);
|
|
4235
|
-
const st = await promises.stat(abs);
|
|
4236
|
-
return {
|
|
4237
|
-
size: st.size,
|
|
4238
|
-
mtime: st.mtime.toISOString()
|
|
4239
|
-
};
|
|
4240
|
-
}
|
|
4241
|
-
/** List the files in the memory dir (flat; index + topics), sorted with the index
|
|
4242
|
-
* first. Empty when the dir does not exist. `.tmp` write artifacts are skipped. */
|
|
4243
|
-
async function listMemory(agentDir) {
|
|
4244
|
-
const dir = memoryDir(agentDir);
|
|
4245
|
-
let dirents;
|
|
4246
|
-
try {
|
|
4247
|
-
dirents = await promises.readdir(dir, { withFileTypes: true });
|
|
4248
|
-
} catch (err) {
|
|
4249
|
-
if (err.code === "ENOENT") return [];
|
|
4250
|
-
throw err;
|
|
4251
|
-
}
|
|
4252
|
-
const files = [];
|
|
4253
|
-
for (const d of dirents) {
|
|
4254
|
-
if (!d.isFile() || d.name.endsWith(".tmp")) continue;
|
|
4255
|
-
try {
|
|
4256
|
-
const st = await promises.stat(join(dir, d.name));
|
|
4257
|
-
files.push({
|
|
4258
|
-
name: d.name,
|
|
4259
|
-
size: st.size,
|
|
4260
|
-
mtime: st.mtime.toISOString()
|
|
4261
|
-
});
|
|
4262
|
-
} catch {}
|
|
4263
|
-
}
|
|
4264
|
-
files.sort((a, b) => a.name === "MEMORY.md" ? -1 : b.name === "MEMORY.md" ? 1 : a.name.localeCompare(b.name));
|
|
4265
|
-
return files;
|
|
4266
|
-
}
|
|
4267
|
-
//#endregion
|
|
4268
4124
|
//#region src/cp/memory-reader.ts
|
|
4269
4125
|
/**
|
|
4270
4126
|
* `MemoryReader` — the seam answering the CP's `memory/list`, `memory/read` and
|
|
@@ -6413,6 +6269,7 @@ function hostSpawnSig(a) {
|
|
|
6413
6269
|
executionMode: a.executionMode,
|
|
6414
6270
|
fastMode: a.fastMode,
|
|
6415
6271
|
permissionMode: a.permissionMode,
|
|
6272
|
+
memory: a.memory?.provider,
|
|
6416
6273
|
env: a.runtimeOverrides?.env
|
|
6417
6274
|
});
|
|
6418
6275
|
}
|
|
@@ -6965,6 +6822,10 @@ var SessionManager = class {
|
|
|
6965
6822
|
let rec = this.deps.store.getSession(key);
|
|
6966
6823
|
const host = await this.deps.hostFor(agentId);
|
|
6967
6824
|
const effortOverride = this.deps.store.getEffortOverride(key);
|
|
6825
|
+
const memoryIndex = (await this.deps.memory.injectAtSessionStart({ agentId })).trim();
|
|
6826
|
+
const memoryAppend = memoryIndex ? `# Your memory\nThis is your memory INDEX from earlier sessions. Read a linked topic file with the \`readMemory\` tool when relevant; revise memory with \`writeMemory\`.\n\n${memoryIndex}` : "";
|
|
6827
|
+
const usesMeta = host.usesMetaSystemPrompt?.() ?? false;
|
|
6828
|
+
const metaMemory = usesMeta ? memoryAppend || void 0 : void 0;
|
|
6968
6829
|
let created = false;
|
|
6969
6830
|
if (!rec || !rec.acpSessionId) {
|
|
6970
6831
|
const cwd = await prepareWorkspace(agent);
|
|
@@ -6973,7 +6834,7 @@ var SessionManager = class {
|
|
|
6973
6834
|
channel: msg.channel,
|
|
6974
6835
|
thread
|
|
6975
6836
|
}) ?? [];
|
|
6976
|
-
const acpSessionId = await host.newSession(cwd, mcpServers, effortOverride);
|
|
6837
|
+
const acpSessionId = await host.newSession(cwd, mcpServers, effortOverride, metaMemory);
|
|
6977
6838
|
created = true;
|
|
6978
6839
|
rec = {
|
|
6979
6840
|
key,
|
|
@@ -7004,7 +6865,7 @@ var SessionManager = class {
|
|
|
7004
6865
|
} catch {}
|
|
7005
6866
|
}
|
|
7006
6867
|
if (!resumed) {
|
|
7007
|
-
const acpSessionId = await host.newSession(cwd, mcpServers, effortOverride);
|
|
6868
|
+
const acpSessionId = await host.newSession(cwd, mcpServers, effortOverride, metaMemory);
|
|
7008
6869
|
created = true;
|
|
7009
6870
|
rec = {
|
|
7010
6871
|
...rec,
|
|
@@ -7042,13 +6903,6 @@ var SessionManager = class {
|
|
|
7042
6903
|
text: `${head}\n${ctxText}`
|
|
7043
6904
|
});
|
|
7044
6905
|
}
|
|
7045
|
-
if (created) {
|
|
7046
|
-
const index = (await this.deps.memory.injectAtSessionStart({ agentId })).trim();
|
|
7047
|
-
if (index) blocks.push({
|
|
7048
|
-
type: "text",
|
|
7049
|
-
text: `# Your memory\nThis is your memory INDEX from earlier sessions. Read a linked topic file with the \`readMemory\` tool when relevant; revise memory with \`writeMemory\`.\n\n${index}`
|
|
7050
|
-
});
|
|
7051
|
-
}
|
|
7052
6906
|
blocks.push({
|
|
7053
6907
|
type: "text",
|
|
7054
6908
|
text: msg.text
|
|
@@ -7061,11 +6915,11 @@ var SessionManager = class {
|
|
|
7061
6915
|
});
|
|
7062
6916
|
blocks.push(...attBlocks);
|
|
7063
6917
|
}
|
|
7064
|
-
if (created) {
|
|
7065
|
-
const
|
|
7066
|
-
if (
|
|
6918
|
+
if (created && !usesMeta) {
|
|
6919
|
+
const combined = [host.inlineSystemPrompt?.(), memoryAppend].filter(Boolean).join("\n\n");
|
|
6920
|
+
if (combined) blocks.unshift({
|
|
7067
6921
|
type: "text",
|
|
7068
|
-
text:
|
|
6922
|
+
text: combined
|
|
7069
6923
|
});
|
|
7070
6924
|
}
|
|
7071
6925
|
rec.lastDeliveredTs = ts;
|
|
@@ -10826,203 +10680,6 @@ function resolveAgentMcpServers(opts) {
|
|
|
10826
10680
|
return out;
|
|
10827
10681
|
}
|
|
10828
10682
|
//#endregion
|
|
10829
|
-
//#region src/mcp/tools.ts
|
|
10830
|
-
const obj = (properties, required = []) => ({
|
|
10831
|
-
type: "object",
|
|
10832
|
-
properties,
|
|
10833
|
-
required,
|
|
10834
|
-
additionalProperties: false
|
|
10835
|
-
});
|
|
10836
|
-
/**
|
|
10837
|
-
* Tools injected when an agent has a Slack integration. `sendSlackMessage` is
|
|
10838
|
-
* the active-messaging tool from the design (token held by the daemon, invisible
|
|
10839
|
-
* to the model); the rest are channel/user read helpers.
|
|
10840
|
-
*/
|
|
10841
|
-
const SLACK_TOOLS = [
|
|
10842
|
-
{
|
|
10843
|
-
name: "sendSlackMessage",
|
|
10844
|
-
description: "Send a message to a Slack channel. Omit `channel` to post in the channel this conversation is happening in. Omit `thread` to reply in the current thread; pass an empty string to post to the channel root instead.",
|
|
10845
|
-
inputSchema: obj({
|
|
10846
|
-
text: {
|
|
10847
|
-
type: "string",
|
|
10848
|
-
description: "Message body, in standard Markdown (CommonMark/GFM). Use `**bold**`, `~~strikethrough~~`, `# headings`, tables, etc. — Slack renders standard Markdown natively (do NOT use single-char Slack mrkdwn like `*bold*` or `~strike~`)."
|
|
10849
|
-
},
|
|
10850
|
-
channel: {
|
|
10851
|
-
type: "string",
|
|
10852
|
-
description: "Target channel ID (e.g. C0123ABC). Defaults to the current channel."
|
|
10853
|
-
},
|
|
10854
|
-
thread: {
|
|
10855
|
-
type: "string",
|
|
10856
|
-
description: "Thread timestamp to reply under. Defaults to the current thread; \"\" posts to the channel root."
|
|
10857
|
-
}
|
|
10858
|
-
}, ["text"])
|
|
10859
|
-
},
|
|
10860
|
-
{
|
|
10861
|
-
name: "getCurrentChannel",
|
|
10862
|
-
description: "Return the Slack channel (and thread) this conversation is bound to, including the channel name when available.",
|
|
10863
|
-
inputSchema: obj({})
|
|
10864
|
-
},
|
|
10865
|
-
{
|
|
10866
|
-
name: "listChannelMembers",
|
|
10867
|
-
description: "List the users and bots in a channel (id, name, is_bot). Omit `channel` to list members of the current channel.",
|
|
10868
|
-
inputSchema: obj({ channel: {
|
|
10869
|
-
type: "string",
|
|
10870
|
-
description: "Channel ID. Defaults to the current channel."
|
|
10871
|
-
} })
|
|
10872
|
-
},
|
|
10873
|
-
{
|
|
10874
|
-
name: "listChannels",
|
|
10875
|
-
description: "List the public/private channels the bot is a member of and can post to.",
|
|
10876
|
-
inputSchema: obj({})
|
|
10877
|
-
},
|
|
10878
|
-
{
|
|
10879
|
-
name: "getUserProfile",
|
|
10880
|
-
description: "Look up a Slack user or bot by id, returning their display name, real name, and bot flag.",
|
|
10881
|
-
inputSchema: obj({ user: {
|
|
10882
|
-
type: "string",
|
|
10883
|
-
description: "User ID (e.g. U0123ABC)."
|
|
10884
|
-
} }, ["user"])
|
|
10885
|
-
},
|
|
10886
|
-
{
|
|
10887
|
-
name: "readSlackFile",
|
|
10888
|
-
description: "Fetch the contents of a file shared in Slack, using the bot credentials. You do NOT have direct network access to Slack's private file URLs (they require the bot token) — use this tool instead of curl/fetch. Pass the file's `url` (the `url_private` / `uri` from a shared attachment or resource link). Images are returned as viewable image content; text files as text. Supply `mimeType` when known for correct handling.",
|
|
10889
|
-
inputSchema: obj({
|
|
10890
|
-
url: {
|
|
10891
|
-
type: "string",
|
|
10892
|
-
description: "The file's url_private (or url_private_download) / resource-link uri."
|
|
10893
|
-
},
|
|
10894
|
-
mimeType: {
|
|
10895
|
-
type: "string",
|
|
10896
|
-
description: "Optional MIME type hint, e.g. image/png or text/plain."
|
|
10897
|
-
}
|
|
10898
|
-
}, ["url"])
|
|
10899
|
-
}
|
|
10900
|
-
];
|
|
10901
|
-
/**
|
|
10902
|
-
* Tools injected when an agent has a Telegram integration. Mirrors the Slack set
|
|
10903
|
-
* but for the Telegram data model: `channel` is a chat id (e.g. -1001234567890),
|
|
10904
|
-
* `thread` is a forum-topic `message_thread_id`, and there is no `listChannels`
|
|
10905
|
-
* (a bot cannot enumerate the chats it belongs to).
|
|
10906
|
-
*/
|
|
10907
|
-
const TELEGRAM_TOOLS = [
|
|
10908
|
-
{
|
|
10909
|
-
name: "sendTelegramMessage",
|
|
10910
|
-
description: "Send a message to a Telegram chat. Omit `channel` to post in the chat this conversation is happening in. Omit `thread` to reply in the current forum topic; pass an empty string to post outside any topic.",
|
|
10911
|
-
inputSchema: obj({
|
|
10912
|
-
text: {
|
|
10913
|
-
type: "string",
|
|
10914
|
-
description: "Message body, in standard Markdown (CommonMark/GFM). Use `**bold**`, `*italic*`, `` `code` ``, `[links](url)`, lists, etc. — the daemon converts it to Telegram formatting and escapes special characters for you, so write plain Markdown (do NOT pre-escape with backslashes)."
|
|
10915
|
-
},
|
|
10916
|
-
channel: {
|
|
10917
|
-
type: "string",
|
|
10918
|
-
description: "Target chat id (e.g. -1001234567890, or a positive id for a private chat). Defaults to the current chat."
|
|
10919
|
-
},
|
|
10920
|
-
thread: {
|
|
10921
|
-
type: "string",
|
|
10922
|
-
description: "Forum-topic message_thread_id to reply under. Defaults to the current topic; \"\" posts outside any topic."
|
|
10923
|
-
}
|
|
10924
|
-
}, ["text"])
|
|
10925
|
-
},
|
|
10926
|
-
{
|
|
10927
|
-
name: "getCurrentChannel",
|
|
10928
|
-
description: "Return the Telegram chat (and forum topic) this conversation is bound to, including the chat title when available.",
|
|
10929
|
-
inputSchema: obj({})
|
|
10930
|
-
},
|
|
10931
|
-
{
|
|
10932
|
-
name: "listChannelMembers",
|
|
10933
|
-
description: "List the users and bots in a chat (id, name, is_bot). Omit `channel` to list members of the current chat. Note: Telegram only exposes administrators for large groups.",
|
|
10934
|
-
inputSchema: obj({ channel: {
|
|
10935
|
-
type: "string",
|
|
10936
|
-
description: "Chat id. Defaults to the current chat."
|
|
10937
|
-
} })
|
|
10938
|
-
},
|
|
10939
|
-
{
|
|
10940
|
-
name: "getUserProfile",
|
|
10941
|
-
description: "Look up a Telegram user or bot by id, returning their display name, username, and bot flag.",
|
|
10942
|
-
inputSchema: obj({ user: {
|
|
10943
|
-
type: "string",
|
|
10944
|
-
description: "Numeric user id (e.g. 12345678)."
|
|
10945
|
-
} }, ["user"])
|
|
10946
|
-
},
|
|
10947
|
-
{
|
|
10948
|
-
name: "readTelegramFile",
|
|
10949
|
-
description: "Fetch the contents of a file shared in Telegram, using the bot credentials. You do NOT have direct network access to Telegram's file storage — use this tool instead of curl/fetch. Pass the file's `url` (the `file_id` from a shared attachment or the `uri` of a resource link). Images are returned as viewable image content; text files as text. Supply `mimeType` when known for correct handling.",
|
|
10950
|
-
inputSchema: obj({
|
|
10951
|
-
url: {
|
|
10952
|
-
type: "string",
|
|
10953
|
-
description: "The shared file's Telegram file_id (or resource-link uri)."
|
|
10954
|
-
},
|
|
10955
|
-
mimeType: {
|
|
10956
|
-
type: "string",
|
|
10957
|
-
description: "Optional MIME type hint, e.g. image/png or text/plain."
|
|
10958
|
-
}
|
|
10959
|
-
}, ["url"])
|
|
10960
|
-
}
|
|
10961
|
-
];
|
|
10962
|
-
/**
|
|
10963
|
-
* The agent's long-term memory tools — available to EVERY agent regardless of
|
|
10964
|
-
* integrations. Memory is a directory (`<agent-root>/memory/`) with a `MEMORY.md`
|
|
10965
|
-
* index (injected into the prompt each session) plus `<topic>.md` files the agent
|
|
10966
|
-
* reads on demand. Keep the index short; move detail into topic files.
|
|
10967
|
-
*/
|
|
10968
|
-
const MEMORY_TOOLS = [
|
|
10969
|
-
{
|
|
10970
|
-
name: "listMemory",
|
|
10971
|
-
description: "List your memory files — the MEMORY.md index plus any topic files you have written. Use this to discover what you have stored before reading or updating it.",
|
|
10972
|
-
inputSchema: obj({})
|
|
10973
|
-
},
|
|
10974
|
-
{
|
|
10975
|
-
name: "readMemory",
|
|
10976
|
-
description: "Read one of your memory files. Omit `path` (or pass \"MEMORY.md\") to read the index; pass a topic file name (e.g. \"deploys.md\") to read that topic. The index is already shown to you at the start of each session — use this to pull the detail behind an index entry when it is relevant.",
|
|
10977
|
-
inputSchema: obj({ path: {
|
|
10978
|
-
type: "string",
|
|
10979
|
-
description: "Memory file name (e.g. \"deploys.md\"). Defaults to the MEMORY.md index."
|
|
10980
|
-
} })
|
|
10981
|
-
},
|
|
10982
|
-
{
|
|
10983
|
-
name: "writeMemory",
|
|
10984
|
-
description: "Save one of your memory files (whole-file overwrite). Omit `path` to write the MEMORY.md index; pass a topic file name (e.g. \"deploys.md\") for a topic. Keep the INDEX short — a scannable list that links to topic files (e.g. \"- [deploys](deploys.md) — how we ship\"); put the actual detail in the topic files. Use for durable facts across sessions: conventions, decisions, who to ask, things you had to re-learn. A flat directory — no subfolders in the path.",
|
|
10985
|
-
inputSchema: obj({
|
|
10986
|
-
path: {
|
|
10987
|
-
type: "string",
|
|
10988
|
-
description: "Memory file name (e.g. \"deploys.md\"). Defaults to the MEMORY.md index. No subdirectories."
|
|
10989
|
-
},
|
|
10990
|
-
content: {
|
|
10991
|
-
type: "string",
|
|
10992
|
-
description: "The full new file contents, in Markdown. Replaces the file."
|
|
10993
|
-
}
|
|
10994
|
-
}, ["content"])
|
|
10995
|
-
}
|
|
10996
|
-
];
|
|
10997
|
-
/** Names of every tool this module can inject — handy for routing/validation. */
|
|
10998
|
-
const ALL_TOOL_NAMES = [...new Set([
|
|
10999
|
-
...SLACK_TOOLS,
|
|
11000
|
-
...TELEGRAM_TOOLS,
|
|
11001
|
-
...MEMORY_TOOLS
|
|
11002
|
-
].map((t) => t.name))];
|
|
11003
|
-
/**
|
|
11004
|
-
* The default MCP tool set for an agent. The memory tools are always present
|
|
11005
|
-
* (every agent has memory); the platform tools are gated by the agent's
|
|
11006
|
-
* integrations. Deduped by name so an agent bridging both platforms doesn't get
|
|
11007
|
-
* the shared read helpers (getCurrentChannel/listChannelMembers/getUserProfile)
|
|
11008
|
-
* twice — the first platform's variant wins, and both behave identically.
|
|
11009
|
-
*/
|
|
11010
|
-
function toolsForIntegrations(integrations) {
|
|
11011
|
-
const tools = [];
|
|
11012
|
-
const seen = /* @__PURE__ */ new Set();
|
|
11013
|
-
const add = (set) => {
|
|
11014
|
-
for (const t of set) {
|
|
11015
|
-
if (seen.has(t.name)) continue;
|
|
11016
|
-
seen.add(t.name);
|
|
11017
|
-
tools.push(t);
|
|
11018
|
-
}
|
|
11019
|
-
};
|
|
11020
|
-
add(MEMORY_TOOLS);
|
|
11021
|
-
if (integrations.some((i) => i.platform === "slack")) add(SLACK_TOOLS);
|
|
11022
|
-
if (integrations.some((i) => i.platform === "telegram")) add(TELEGRAM_TOOLS);
|
|
11023
|
-
return tools;
|
|
11024
|
-
}
|
|
11025
|
-
//#endregion
|
|
11026
10683
|
//#region src/router/routing-table.ts
|
|
11027
10684
|
const KIND_ORDER = [
|
|
11028
10685
|
"mention",
|
|
@@ -197403,65 +197060,6 @@ function createSessionReader(store, workspaceUrlFor) {
|
|
|
197403
197060
|
};
|
|
197404
197061
|
}
|
|
197405
197062
|
//#endregion
|
|
197406
|
-
//#region src/agents/memory-provider.ts
|
|
197407
|
-
/**
|
|
197408
|
-
* `managed` memory: our `<agent-root>/memory/` directory. A thin, behavior-neutral
|
|
197409
|
-
* facade over `agents/memory.ts` — every method delegates to the existing primitive
|
|
197410
|
-
* and lets its error classes (`MemoryPathError` / `MemoryTooLargeError` /
|
|
197411
|
-
* `MemoryConflictError`) propagate raw, so the MCP + CP error mappings are unchanged.
|
|
197412
|
-
*/
|
|
197413
|
-
var ManagedMemoryProvider = class {
|
|
197414
|
-
agentDirByAgent;
|
|
197415
|
-
kind = "managed";
|
|
197416
|
-
/** `agentDirByAgent` resolves an agent id → its root dir (which holds `memory/`),
|
|
197417
|
-
* or undefined for an unknown agent — the same resolver the pre-provider call
|
|
197418
|
-
* sites used. */
|
|
197419
|
-
constructor(agentDirByAgent) {
|
|
197420
|
-
this.agentDirByAgent = agentDirByAgent;
|
|
197421
|
-
}
|
|
197422
|
-
dirFor(agentId) {
|
|
197423
|
-
const dir = this.agentDirByAgent(agentId);
|
|
197424
|
-
if (!dir) throw new Error(`unknown agent ${agentId}`);
|
|
197425
|
-
return dir;
|
|
197426
|
-
}
|
|
197427
|
-
runtimeEnv(_runtime) {
|
|
197428
|
-
return {};
|
|
197429
|
-
}
|
|
197430
|
-
ensure(scope, agentName) {
|
|
197431
|
-
ensureMemory(this.dirFor(scope.agentId), agentName);
|
|
197432
|
-
}
|
|
197433
|
-
async injectAtSessionStart(scope) {
|
|
197434
|
-
return readIndex(this.dirFor(scope.agentId));
|
|
197435
|
-
}
|
|
197436
|
-
async recordTurn(_scope, _turn) {}
|
|
197437
|
-
tools() {
|
|
197438
|
-
return MEMORY_TOOLS;
|
|
197439
|
-
}
|
|
197440
|
-
async list(scope) {
|
|
197441
|
-
return listMemory(this.dirFor(scope.agentId));
|
|
197442
|
-
}
|
|
197443
|
-
async read(scope, path) {
|
|
197444
|
-
return {
|
|
197445
|
-
path,
|
|
197446
|
-
content: await readMemoryFile(this.dirFor(scope.agentId), path)
|
|
197447
|
-
};
|
|
197448
|
-
}
|
|
197449
|
-
async write(scope, path, content, ifMatch) {
|
|
197450
|
-
const { size, mtime } = await writeMemoryFile(this.dirFor(scope.agentId), path, content, ifMatch);
|
|
197451
|
-
return {
|
|
197452
|
-
ok: true,
|
|
197453
|
-
path,
|
|
197454
|
-
size,
|
|
197455
|
-
mtime
|
|
197456
|
-
};
|
|
197457
|
-
}
|
|
197458
|
-
};
|
|
197459
|
-
/** Build the daemon's memory provider. Managed today; the config-driven selection
|
|
197460
|
-
* between native/managed/external is a later phase. */
|
|
197461
|
-
function createManagedMemoryProvider(agentDirByAgent) {
|
|
197462
|
-
return new ManagedMemoryProvider(agentDirByAgent);
|
|
197463
|
-
}
|
|
197464
|
-
//#endregion
|
|
197465
197063
|
//#region src/cp/workspace-git.ts
|
|
197466
197064
|
/**
|
|
197467
197065
|
* `WorkspaceGit` — the seam answering the CP's `workspace/gitstatus` and
|
|
@@ -197651,6 +197249,7 @@ function applySpecFields(raw, spec, opts) {
|
|
|
197651
197249
|
else raw.permissionMode = spec.permissionMode;
|
|
197652
197250
|
if (spec.pause !== void 0) raw.pause = spec.pause;
|
|
197653
197251
|
if (spec.mcpServers !== void 0) raw.mcpServers = spec.mcpServers;
|
|
197252
|
+
if (spec.memory !== void 0) raw.memory = spec.memory;
|
|
197654
197253
|
if (spec.outputMode !== void 0) {
|
|
197655
197254
|
const out = typeof raw.output === "object" && raw.output !== null ? raw.output : {};
|
|
197656
197255
|
out.mode = spec.outputMode;
|
|
@@ -213774,7 +213373,13 @@ var Daemon = class Daemon {
|
|
|
213774
213373
|
opts;
|
|
213775
213374
|
store;
|
|
213776
213375
|
mcp;
|
|
213777
|
-
memory =
|
|
213376
|
+
memory = createMemoryProvider((id) => this.agents.get(id)?.dir, (id) => {
|
|
213377
|
+
const a = this.agents.get(id);
|
|
213378
|
+
return a ? this.runtimes[a.runtime] : void 0;
|
|
213379
|
+
}, (id) => {
|
|
213380
|
+
const a = this.agents.get(id);
|
|
213381
|
+
return a ? memoryKindOf(a) : "managed";
|
|
213382
|
+
});
|
|
213778
213383
|
gitCreds;
|
|
213779
213384
|
gitCredServer;
|
|
213780
213385
|
agents = /* @__PURE__ */ new Map();
|
|
@@ -213936,7 +213541,8 @@ var Daemon = class Daemon {
|
|
|
213936
213541
|
memory: this.memory,
|
|
213937
213542
|
mcpServersFor: ({ agent, channel, thread }) => {
|
|
213938
213543
|
const servers = [];
|
|
213939
|
-
|
|
213544
|
+
let tools = toolsForIntegrations(agent.integrations);
|
|
213545
|
+
if (memoryKindOf(agent) === "native") tools = tools.filter((t) => !MEMORY_TOOL_NAMES.has(t.name));
|
|
213940
213546
|
const integrationId = agent.integrations[0]?.id;
|
|
213941
213547
|
if (tools.length > 0) {
|
|
213942
213548
|
const token = this.mcp.register({
|
|
@@ -214385,6 +213991,7 @@ var Daemon = class Daemon {
|
|
|
214385
213991
|
env: {
|
|
214386
213992
|
...agentChildEnv(agent),
|
|
214387
213993
|
...cpRuntimeEnv(agent),
|
|
213994
|
+
...memoryProviderFor(agent, runtime).runtimeEnv(),
|
|
214388
213995
|
...agent.workspace.mode === "git-repo" && agent.workspace.gitCredential === "github-app" ? sessionGitEnv(agent.id) : {}
|
|
214389
213996
|
},
|
|
214390
213997
|
configPrefs: {
|
|
@@ -216501,4 +216108,4 @@ async function runForeground(opts, deps = {}) {
|
|
|
216501
216108
|
//#endregion
|
|
216502
216109
|
export { ClientTransport as i, CP_SUBPROTOCOL as n, CP_WS_PATH as r, runForeground as t };
|
|
216503
216110
|
|
|
216504
|
-
//# sourceMappingURL=run-foreground-
|
|
216111
|
+
//# sourceMappingURL=run-foreground-CLPgcMuB.js.map
|