-
sessions.size 在此之前没有任何人过问。一次心跳泄漏就攒到过 82 个进程 / 17.5 GB(约 215MB/个),而批 4 刚把公司级并行放开(单公司上限 20)—— 机器上同时能起多少完全没有闸门,正是最容易失控的时刻。 AGENT_MAX_SESSIONS,缺省 12,**调用时读不是模块加载时快照**(快照一次就 意味着改配置要重启才生效,而且不报错 —— company-paths.js 顶上那条教训)。 非法值(0/负数/非整数)回落缺省,不当成无限。 满了怎么办:**回收最久没用的空闲会话,而不是直接拒绝**。session 是可复用的 池化资源,杀掉一个空闲的只是让它下次冷启动几秒;拒绝会让一个本来能跑的任务 因为资源原因失败 —— 那是把可恢复的代价换成不可恢复的。 只有一个空闲的都没有(全部在途)时才抛 SessionPoolFullError。刻意抛而不是 静默放行 —— 静默超出正是这个仓库栽过的那一类「超出去但不报错」。 两个实现细节: - 腾位置发生在 createConnection **之前**:起完再判等于该拦的那个已经起来了 - 空闲态用显式的 idleSince 时间戳记,不去戳 IdleTimer 的私有 _timer; getOrCreate 复用时清空它(在途 = 不可被挑走) - _evictForRoom 故意不 await reset():腾位置只需要把它从 Map 摘掉, 子进程收尾可以后台走完;await 的话一次腾位要串行等一次进程退出 守卫:server/tests/unit/session-pool-max.test.js(5 例,不起真进程, 只验判据本身:挑最久空闲的、在途的不许动、全在途就抛、没满不动、非法配置回落) 全量:129 文件 / 1245 测试全绿。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
-
SessionPool 此前只有三条回收路径:换新会话 / reset() / killActive()。「正常跑完」和 「不可重试的报错」都不在其中,而 getKey 里带了 taskId —— 每个图节点一个新 key,于是 一节点一进程、永不释放,且**不报错**。实测 23 小时漏出 7 个图执行进程。 修法与 agent-chat 侧同一套:调用开始时停表(getOrCreate 里 cancel),调用结束时上弦 (agent-manager 两个出口调 armIdle),计时器只在没有在途请求的间隙走,所以再长的单次 生成也不会被 TTL 打断。旋钮共用 AGENT_SESSION_IDLE_MS(默认 30 分钟)。 守卫:server/tests/unit/session-pool-idle-reclaim.test.js Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
-
设计见 docs/done/system-design/28-agent-registry-unification.md。 改造前 Agent 本体散在三处(system/agents/ 11 个、system/templates/ 50 个、 data/companies/{id}/agents/ 17 个),同一个 AgentScaffold 被三个 baseDir 实例化。 后果是同一角色在 N 家公司下有 N 份互不相干的副本,模板更新不会同步; org-coder / org-planner 这类走 hireFromBaseMetaAgent 造出来的本体 legacy_path 指回自己公司目录,永远无法被第二家公司复用。 本次: - G1 单一注册表:system/templates/ 整体并入 system/agents/,base → _base。 7 个同名 id 逐个裁决,被丢弃的一份归档到 docs/_archive/ 而非删除。 source_kind(template/global_agent/company_hired) → origin(builtin/created)。 - G2 运行态下沉:CLI 的 cwd 从本体根改为 system/agents/{aid}/{cid}/{taskId}/。 memory / conversations 落公司态 {aid}/{cid}/,按公司隔离不串。 sessionPool 的 key 含 (companyId, taskId),两家公司调同一 agent 不复用会话。 - G2b 产物不下沉:交付物仍落 data/companies/{cid}/,system/agents/ 只留运行痕迹。 写入边界按链路分叉——graph 节点走节点私有目录(被 indexNodeOutputs 索引), chat 走公司 workspace,同一提示词里不再出现两条互斥指令。 - G3 公司只存引用:data/companies/{id}/agents/ 删除,新增 company_agents 关联表。 不复用 org_graph_nodes——后者是执行流图,work 层本体被雇时不写它,天生覆盖不全。 - G4 缺则创建:本体缺失时从 _base 复制骨架进 system/agents/{id}/, agent-creator 填 agent.md/soul.md 后才从 draft 转 active(哨兵判据, 骨架未填时哨兵仍在,不许被 hire)。产物即刻是全系统可复用的本体。 新增 server/services/agent-locator.js 收编原先散在 6 处的寻址逻辑。 边界守卫(graph-engine)的豁免从「本体根上五个文件名」放宽为整棵 system/agents/: 新本体的骨架本来就要进 git,gitignore 挡不住 ?? system/agents/{newId}/, 旧判据会把一个真正成功的招聘节点判成 boundary_escape fail。 存量迁移见 scripts/migrate-agent-registry.js(幂等,备份到 data/_migration-backup-*)。 真 Claude CLI E2E 已验证:新建公司 → orggraph-planning 自动规划 → 自动招聘 org-planner/org-coder/org-validator 三节点流水线; data/companies/{cid}/agents/ 不存在,company_agents 4 行, system_agents 56→56(零新建私有本体,纯复用),git status 零增量。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
-
- Agent as Micro-Container: each agent lives in data/agents/{id}/ with full encapsulation - Persona vs Capability split: agent.md (identity) + .claude/skills/main_skill/SKILL.md (workflow) - Conversations co-located: data/agents/{id}/conversations/ replaces global dir - Meta Skills renamed: meta_hunt, meta_digest, meta_creator, meta_evolving, meta_benchmark, meta_research - Dynamic Hot-Reload: AgentManager.getAgentConfig() falls back to filesystem scan - Parallel Sub-Agent orchestration via Promise.all with multi-terminal UI - Removed SQLite dependency, global skills/ directory, and legacy conversations/ - Full architecture docs: 18-local-filesystem-first-agent-encapsulation.md