@mingyuxu/core 0.1.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.
Files changed (66) hide show
  1. package/README.md +7 -0
  2. package/dist/coding/agent.d.ts +64 -0
  3. package/dist/coding/agent.d.ts.map +1 -0
  4. package/dist/coding/agent.js +179 -0
  5. package/dist/coding/agent.js.map +1 -0
  6. package/dist/coding/tools.d.ts +45 -0
  7. package/dist/coding/tools.d.ts.map +1 -0
  8. package/dist/coding/tools.js +327 -0
  9. package/dist/coding/tools.js.map +1 -0
  10. package/dist/commander.d.ts +108 -0
  11. package/dist/commander.d.ts.map +1 -0
  12. package/dist/commander.js +246 -0
  13. package/dist/commander.js.map +1 -0
  14. package/dist/extensions.d.ts +26 -0
  15. package/dist/extensions.d.ts.map +1 -0
  16. package/dist/extensions.js +66 -0
  17. package/dist/extensions.js.map +1 -0
  18. package/dist/goal-loop.d.ts +30 -0
  19. package/dist/goal-loop.d.ts.map +1 -0
  20. package/dist/goal-loop.js +96 -0
  21. package/dist/goal-loop.js.map +1 -0
  22. package/dist/hooks.d.ts +17 -0
  23. package/dist/hooks.d.ts.map +1 -0
  24. package/dist/hooks.js +44 -0
  25. package/dist/hooks.js.map +1 -0
  26. package/dist/index.d.ts +33 -0
  27. package/dist/index.d.ts.map +1 -0
  28. package/dist/index.js +20 -0
  29. package/dist/index.js.map +1 -0
  30. package/dist/loop.d.ts +42 -0
  31. package/dist/loop.d.ts.map +1 -0
  32. package/dist/loop.js +86 -0
  33. package/dist/loop.js.map +1 -0
  34. package/dist/orchestrator.d.ts +48 -0
  35. package/dist/orchestrator.d.ts.map +1 -0
  36. package/dist/orchestrator.js +194 -0
  37. package/dist/orchestrator.js.map +1 -0
  38. package/dist/reconcile.d.ts +5 -0
  39. package/dist/reconcile.d.ts.map +1 -0
  40. package/dist/reconcile.js +28 -0
  41. package/dist/reconcile.js.map +1 -0
  42. package/dist/sandbox.d.ts +14 -0
  43. package/dist/sandbox.d.ts.map +1 -0
  44. package/dist/sandbox.js +36 -0
  45. package/dist/sandbox.js.map +1 -0
  46. package/dist/session.d.ts +43 -0
  47. package/dist/session.d.ts.map +1 -0
  48. package/dist/session.js +104 -0
  49. package/dist/session.js.map +1 -0
  50. package/dist/subagents/dispatch.d.ts +34 -0
  51. package/dist/subagents/dispatch.d.ts.map +1 -0
  52. package/dist/subagents/dispatch.js +80 -0
  53. package/dist/subagents/dispatch.js.map +1 -0
  54. package/dist/task-graph.d.ts +32 -0
  55. package/dist/task-graph.d.ts.map +1 -0
  56. package/dist/task-graph.js +77 -0
  57. package/dist/task-graph.js.map +1 -0
  58. package/dist/tools.d.ts +24 -0
  59. package/dist/tools.d.ts.map +1 -0
  60. package/dist/tools.js +54 -0
  61. package/dist/tools.js.map +1 -0
  62. package/dist/workspace.d.ts +92 -0
  63. package/dist/workspace.d.ts.map +1 -0
  64. package/dist/workspace.js +346 -0
  65. package/dist/workspace.js.map +1 -0
  66. package/package.json +34 -0
@@ -0,0 +1,96 @@
1
+ /**
2
+ * 目标驱动构建循环(v2 架构)—— 收敛条件不是「走完相位」,而是「自评达到标准」。
3
+ * build-attempt(拆规则/定方案/出候选) → 自评 → 达标? → 未达标则反思迭代重评 → 达标→交人(HITL)→冻结
4
+ * 与旧 BuildLoop 的区别:停机看自评体系(agent.selfEvaluate 返回 met),未达标走 agent.reflect 反思。
5
+ * build-attempt 阶段复用 advanceOnePhase(reconcile/预算/错误归约不重造);自评+反思是新的外层循环。
6
+ */
7
+ import { BudgetExceeded, LLMError } from "@mingyuxu/ai";
8
+ import { advanceOnePhase, AWAITING_APPROVAL, FROZEN, BUDGET_EXCEEDED, LLM_ERROR } from "./loop.js";
9
+ import { TERMINAL } from "./session.js";
10
+ export const STANDARD_NOT_MET = "standard_not_met"; // 反思到顶仍未达自评标准(交人裁决)
11
+ export const NEEDS_HUMAN_EVAL = "needs_human_eval"; // 无评测体系可判达标 → 只能交人
12
+ const BUILD_PHASES = ["analyze", "observe", "propose"];
13
+ export class GoalLoop {
14
+ agent;
15
+ policy;
16
+ constructor(agent, policy) {
17
+ this.agent = agent;
18
+ this.policy = policy;
19
+ }
20
+ async run(session, _opts = {}) {
21
+ const ws = this.agent.workspace;
22
+ // ── 冻结再入:达标后 session.phase="freeze",批准后来到这里执行冻结 ──
23
+ if (session.phase === TERMINAL)
24
+ return this.stop(session, FROZEN, 0);
25
+ if (session.phase === "freeze") {
26
+ if (!session.approved)
27
+ return this.stop(session, AWAITING_APPROVAL, 0);
28
+ try {
29
+ await this.agent.runPhase(session);
30
+ } // freeze()(机器门:桩审计/grounding + 需已批准)
31
+ catch (e) {
32
+ throw e;
33
+ } // 机器门拒绝上抛给 CLI 显示
34
+ session.phase = TERMINAL;
35
+ session.event(ws, "phase_advanced", { to: TERMINAL }, this.agent.now());
36
+ session.save(ws, this.agent.now());
37
+ return this.stop(session, FROZEN, 0);
38
+ }
39
+ // ── build attempt:推进到 test 边界(复用相位原语的 reconcile/错误归约)──
40
+ while (BUILD_PHASES.includes(session.phase)) {
41
+ const res = await advanceOnePhase(this.agent, session);
42
+ if (!res.ok)
43
+ return this.stop(session, res.reason, 0);
44
+ }
45
+ // ── 自评 → 反思 外层循环:达标才停 ──
46
+ const maxReflect = Number(this.policy.loop?.max_reflect_iterations ?? 3);
47
+ let iter = 0;
48
+ while (true) {
49
+ let ev;
50
+ try {
51
+ ev = await this.agent.selfEvaluate(session);
52
+ }
53
+ catch (e) {
54
+ if (e instanceof BudgetExceeded) {
55
+ session.event(ws, "budget_exceeded", {}, this.agent.now());
56
+ return this.stop(session, BUDGET_EXCEEDED, iter);
57
+ }
58
+ if (e instanceof LLMError) {
59
+ session.event(ws, "llm_error", {}, this.agent.now());
60
+ return this.stop(session, LLM_ERROR, iter);
61
+ }
62
+ throw e;
63
+ }
64
+ session.event(ws, "self_eval", { iter, met: ev.met, summary: ev.summary }, this.agent.now());
65
+ if (ev.met === true) { // 达标 → 交人(HITL)
66
+ session.phase = "freeze";
67
+ session.save(ws, this.agent.now());
68
+ return this.stop(session, AWAITING_APPROVAL, iter);
69
+ }
70
+ if (ev.met === null) { // 无评测体系可判 → 交人裁决
71
+ session.phase = "freeze";
72
+ session.save(ws, this.agent.now());
73
+ return this.stop(session, NEEDS_HUMAN_EVAL, iter);
74
+ }
75
+ if (iter >= maxReflect) { // 反思到顶仍不达标 → 交人
76
+ session.phase = "freeze";
77
+ session.save(ws, this.agent.now());
78
+ return this.stop(session, STANDARD_NOT_MET, iter);
79
+ }
80
+ iter += 1;
81
+ const rr = await this.agent.reflect(session); // 反思迭代:读 trace 归因 → 定向修改
82
+ session.event(ws, "reflect", { iter, revised: rr.revised, note: rr.note }, this.agent.now());
83
+ if (!rr.revised) { // 改无可改 → 别空转,交人
84
+ session.phase = "freeze";
85
+ session.save(ws, this.agent.now());
86
+ return this.stop(session, STANDARD_NOT_MET, iter);
87
+ }
88
+ }
89
+ }
90
+ stop(session, reason, iterations) {
91
+ session.save(this.agent.workspace, this.agent.now());
92
+ session.event(this.agent.workspace, "goal_loop_stopped", { reason }, this.agent.now());
93
+ return { stop: reason, phase: session.phase, iterations };
94
+ }
95
+ }
96
+ //# sourceMappingURL=goal-loop.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"goal-loop.js","sourceRoot":"","sources":["../src/goal-loop.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ export declare const HOOK_POINTS: readonly ["pre_phase", "post_phase", "on_llm_call", "on_artifact", "on_stop", "on_heartbeat"];
2
+ export type HookPoint = (typeof HOOK_POINTS)[number];
3
+ export type HookFn = (payload: Record<string, unknown>) => void;
4
+ export declare class HookBus {
5
+ private shellHooks;
6
+ private timeoutMs;
7
+ private handlers;
8
+ failures: {
9
+ point: string;
10
+ error: string;
11
+ }[];
12
+ constructor(shellHooks?: Record<string, string[]>, // {point: [命令...]},payload 从 stdin 喂
13
+ timeoutMs?: number);
14
+ register(point: HookPoint, fn: HookFn): void;
15
+ emit(point: string, payload: Record<string, unknown>): void;
16
+ }
17
+ //# sourceMappingURL=hooks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../src/hooks.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,WAAW,+FAEd,CAAC;AACX,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC;AACrD,MAAM,MAAM,MAAM,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;AAEhE,qBAAa,OAAO;IAKhB,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,SAAS;IALnB,OAAO,CAAC,QAAQ,CAAkC;IAClD,QAAQ,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAM;gBAGxC,UAAU,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAM,EAAI,qCAAqC;IAClF,SAAS,SAAS;IAG5B,QAAQ,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI;IAK5C,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;CAW5D"}
package/dist/hooks.js ADDED
@@ -0,0 +1,44 @@
1
+ /**
2
+ * hook 机制 —— 生命周期扩展点,观测/联动不侵入内核流程。
3
+ * 六点位:pre_phase / post_phase / on_llm_call / on_artifact / on_stop / on_heartbeat。
4
+ * hook 失败只记账不炸主流程。从 Python tracing/hooks.py 移植(python 回调面)。
5
+ */
6
+ import { execFileSync } from "node:child_process";
7
+ export const HOOK_POINTS = [
8
+ "pre_phase", "post_phase", "on_llm_call", "on_artifact", "on_stop", "on_heartbeat",
9
+ ];
10
+ export class HookBus {
11
+ shellHooks;
12
+ timeoutMs;
13
+ handlers = new Map();
14
+ failures = [];
15
+ constructor(shellHooks = {}, // {point: [命令...]},payload 从 stdin 喂
16
+ timeoutMs = 30_000) {
17
+ this.shellHooks = shellHooks;
18
+ this.timeoutMs = timeoutMs;
19
+ }
20
+ register(point, fn) {
21
+ if (!HOOK_POINTS.includes(point))
22
+ throw new Error(`未知 hook 点位: ${point}`);
23
+ (this.handlers.get(point) ?? this.handlers.set(point, []).get(point)).push(fn);
24
+ }
25
+ emit(point, payload) {
26
+ for (const fn of this.handlers.get(point) ?? []) {
27
+ try {
28
+ fn(payload);
29
+ }
30
+ catch (e) {
31
+ this.failures.push({ point, error: `${e.name}: ${e.message}` });
32
+ }
33
+ }
34
+ for (const cmd of this.shellHooks[point] ?? []) { // shell hook:payload JSON 从 stdin 传
35
+ try {
36
+ execFileSync("/bin/sh", ["-c", cmd], { input: JSON.stringify(payload), timeout: this.timeoutMs, env: { ...process.env, KC_HOOK_POINT: point } });
37
+ }
38
+ catch (e) {
39
+ this.failures.push({ point, error: `shell: ${e.message}` });
40
+ }
41
+ }
42
+ }
43
+ }
44
+ //# sourceMappingURL=hooks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks.js","sourceRoot":"","sources":["../src/hooks.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,WAAW,EAAE,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,SAAS,EAAE,cAAc;CAC1E,CAAC;AAIX,MAAM,OAAO,OAAO;IAKR;IACA;IALF,QAAQ,GAAG,IAAI,GAAG,EAAuB,CAAC;IAClD,QAAQ,GAAuC,EAAE,CAAC;IAElD,YACU,aAAuC,EAAE,EAAI,qCAAqC;IAClF,YAAY,MAAM;QADlB,eAAU,GAAV,UAAU,CAA+B;QACzC,cAAS,GAAT,SAAS,CAAS;IACzB,CAAC;IAEJ,QAAQ,CAAC,KAAgB,EAAE,EAAU;QACnC,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,KAAK,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,eAAe,KAAK,EAAE,CAAC,CAAC;QAC1E,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,KAAK,CAAE,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAClF,CAAC;IAED,IAAI,CAAC,KAAa,EAAE,OAAgC;QAClD,KAAK,MAAM,EAAE,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAkB,CAAC,IAAI,EAAE,EAAE,CAAC;YAC7D,IAAI,CAAC;gBAAC,EAAE,CAAC,OAAO,CAAC,CAAC;YAAC,CAAC;YACpB,OAAO,CAAC,EAAE,CAAC;gBAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,GAAI,CAAW,CAAC,IAAI,KAAM,CAAW,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;YAAC,CAAC;QACtG,CAAC;QACD,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC,CAAK,oCAAoC;YACxF,IAAI,CAAC;gBACH,YAAY,CAAC,SAAS,EAAE,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,SAAS,EAAE,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,aAAa,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;YACnJ,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,UAAW,CAAW,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;YAAC,CAAC;QACzF,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * @mingyuxu/core —— 通用 agent 运行时(对标 @earendil-works/pi-agent-core)。
3
+ * 不认识"核查"——只提供通用能力。领域(核查)作为扩展从 check 层插进来。依赖:只 @mingyuxu/ai。
4
+ */
5
+ export { ToolRegistry, ToolDenied } from "./tools.js";
6
+ export type { ToolFn, ToolLog } from "./tools.js";
7
+ export { ExtensionRegistry, loadExtensions } from "./extensions.js";
8
+ export type { Skill } from "./extensions.js";
9
+ export { reconcile, PHASE_MINIMUM } from "./reconcile.js";
10
+ export { Session, PHASES, TERMINAL, IDENTITY } from "./session.js";
11
+ export type { SessionData } from "./session.js";
12
+ export { HookBus, HOOK_POINTS } from "./hooks.js";
13
+ export type { HookPoint, HookFn } from "./hooks.js";
14
+ export { advanceOnePhase, BuildLoop, FROZEN, PHASE_CHECKPOINT, AWAITING_APPROVAL, RECONCILE_FAILED, BUDGET_EXCEEDED, STUCK, MAX_STEPS, LLM_ERROR, INTERRUPTED, } from "./loop.js";
15
+ export type { Agent, StepResult, LoopResult } from "./loop.js";
16
+ export { GoalLoop, STANDARD_NOT_MET, NEEDS_HUMAN_EVAL } from "./goal-loop.js";
17
+ export type { GoalAgent, GoalResult } from "./goal-loop.js";
18
+ export { Orchestrator, PLAYBOOK, ORCH_SYSTEM, mockDecide } from "./orchestrator.js";
19
+ export type { OrchestratorAgent, Decision, DecideFn, Say } from "./orchestrator.js";
20
+ export { Commander, COMMANDER_SYSTEM, mockCommanderDecide } from "./commander.js";
21
+ export type { CommanderAgent, CommanderAction, CommanderDecision, CommanderDecide, CommanderEvent, CommanderResult, CommanderStep, CommanderStepStatus, CommanderOp, AgentPlan, Capability, CapabilityResult, PromotionState, } from "./commander.js";
22
+ export { lintBrief, spawnSubagent, pollSubagent, waitSubagent, killSubagent } from "./subagents/dispatch.js";
23
+ export type { TypedBrief, SubagentHandle } from "./subagents/dispatch.js";
24
+ export { Sandbox, SandboxViolation } from "./sandbox.js";
25
+ export { CodeAgent, CODE_AGENT_SYSTEM } from "./coding/agent.js";
26
+ export type { CodeAgentOptions, CodeAgentEvent } from "./coding/agent.js";
27
+ export { codingTools, defaultExec, READ_FILE, LIST_DIR, GLOB, GREP, WRITE_FILE, EDIT_FILE, BASH, ASK_MODEL, SPAWN_AGENT, } from "./coding/tools.js";
28
+ export type { CodingTool, ToolContext, ApprovalGate, ExecFn } from "./coding/tools.js";
29
+ export { WorkspaceManager } from "./workspace.js";
30
+ export type { WorkspaceMeta, WorkspaceStatus, WorkspacePaths, WorkspaceEvent, CreateWorkspaceOptions, WorkspaceLease, } from "./workspace.js";
31
+ export { validateTaskGraph, readyTasks, applyGoalPatch } from "./task-graph.js";
32
+ export type { TaskGraph, TaskNode, TaskNodeStatus, GoalPatch } from "./task-graph.js";
33
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACtD,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACpE,YAAY,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC1D,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACnE,YAAY,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAClD,YAAY,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AACpD,OAAO,EACL,eAAe,EAAE,SAAS,EAC1B,MAAM,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,gBAAgB,EAC7D,eAAe,EAAE,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,WAAW,GAC1D,MAAM,WAAW,CAAC;AACnB,YAAY,EAAE,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAC/D,OAAO,EAAE,QAAQ,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAC9E,YAAY,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACpF,YAAY,EAAE,iBAAiB,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAC;AACpF,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAClF,YAAY,EACV,cAAc,EAAE,eAAe,EAAE,iBAAiB,EAAE,eAAe,EAAE,cAAc,EACnF,eAAe,EAAE,aAAa,EAAE,mBAAmB,EAAE,WAAW,EAAE,SAAS,EAC3E,UAAU,EAAE,gBAAgB,EAAE,cAAc,GAC7C,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC7G,YAAY,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAC1E,OAAO,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACzD,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACjE,YAAY,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAC1E,OAAO,EACL,WAAW,EAAE,WAAW,EACxB,SAAS,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,GACrF,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AACvF,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,YAAY,EACV,aAAa,EAAE,eAAe,EAAE,cAAc,EAAE,cAAc,EAAE,sBAAsB,EACtF,cAAc,GACf,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,iBAAiB,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAChF,YAAY,EAAE,SAAS,EAAE,QAAQ,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,20 @@
1
+ /**
2
+ * @mingyuxu/core —— 通用 agent 运行时(对标 @earendil-works/pi-agent-core)。
3
+ * 不认识"核查"——只提供通用能力。领域(核查)作为扩展从 check 层插进来。依赖:只 @mingyuxu/ai。
4
+ */
5
+ export { ToolRegistry, ToolDenied } from "./tools.js";
6
+ export { ExtensionRegistry, loadExtensions } from "./extensions.js";
7
+ export { reconcile, PHASE_MINIMUM } from "./reconcile.js";
8
+ export { Session, PHASES, TERMINAL, IDENTITY } from "./session.js";
9
+ export { HookBus, HOOK_POINTS } from "./hooks.js";
10
+ export { advanceOnePhase, BuildLoop, FROZEN, PHASE_CHECKPOINT, AWAITING_APPROVAL, RECONCILE_FAILED, BUDGET_EXCEEDED, STUCK, MAX_STEPS, LLM_ERROR, INTERRUPTED, } from "./loop.js";
11
+ export { GoalLoop, STANDARD_NOT_MET, NEEDS_HUMAN_EVAL } from "./goal-loop.js";
12
+ export { Orchestrator, PLAYBOOK, ORCH_SYSTEM, mockDecide } from "./orchestrator.js";
13
+ export { Commander, COMMANDER_SYSTEM, mockCommanderDecide } from "./commander.js";
14
+ export { lintBrief, spawnSubagent, pollSubagent, waitSubagent, killSubagent } from "./subagents/dispatch.js";
15
+ export { Sandbox, SandboxViolation } from "./sandbox.js";
16
+ export { CodeAgent, CODE_AGENT_SYSTEM } from "./coding/agent.js";
17
+ export { codingTools, defaultExec, READ_FILE, LIST_DIR, GLOB, GREP, WRITE_FILE, EDIT_FILE, BASH, ASK_MODEL, SPAWN_AGENT, } from "./coding/tools.js";
18
+ export { WorkspaceManager } from "./workspace.js";
19
+ export { validateTaskGraph, readyTasks, applyGoalPatch } from "./task-graph.js";
20
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAEtD,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEpE,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC1D,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAEnE,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAElD,OAAO,EACL,eAAe,EAAE,SAAS,EAC1B,MAAM,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,gBAAgB,EAC7D,eAAe,EAAE,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,WAAW,GAC1D,MAAM,WAAW,CAAC;AAEnB,OAAO,EAAE,QAAQ,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAE9E,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAEpF,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAMlF,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAE7G,OAAO,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACzD,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAEjE,OAAO,EACL,WAAW,EAAE,WAAW,EACxB,SAAS,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,GACrF,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAKlD,OAAO,EAAE,iBAAiB,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC"}
package/dist/loop.d.ts ADDED
@@ -0,0 +1,42 @@
1
+ import { Session } from "./session.js";
2
+ export declare const FROZEN = "frozen";
3
+ export declare const PHASE_CHECKPOINT = "phase_checkpoint";
4
+ export declare const AWAITING_APPROVAL = "awaiting_approval";
5
+ export declare const RECONCILE_FAILED = "reconcile_failed";
6
+ export declare const BUDGET_EXCEEDED = "budget_exceeded";
7
+ export declare const STUCK = "stuck";
8
+ export declare const MAX_STEPS = "max_steps";
9
+ export declare const LLM_ERROR = "llm_error";
10
+ export declare const INTERRUPTED = "interrupted";
11
+ /** core 依赖的 agent 契约(check 提供具体实现)——分层单向:core 不认识核查。 */
12
+ export interface Agent {
13
+ workspace: string;
14
+ now(): number;
15
+ runPhase(session: Session): void | Promise<void>;
16
+ }
17
+ export interface StepResult {
18
+ ok: boolean;
19
+ reason: string;
20
+ phase: string;
21
+ ran: boolean;
22
+ nextPhase?: string;
23
+ missing?: string[];
24
+ }
25
+ export declare function advanceOnePhase(agent: Agent, session: Session): Promise<StepResult>;
26
+ export interface LoopResult {
27
+ stop: string;
28
+ phase: string;
29
+ steps: number;
30
+ missing?: string[];
31
+ }
32
+ /** 无人值守驱动器:沿相位推进;相位边界按 auto 决定停不停;freeze 永远等 approve。 */
33
+ export declare class BuildLoop {
34
+ private agent;
35
+ private policy;
36
+ constructor(agent: Agent, policy: Record<string, any>);
37
+ run(session: Session, opts?: {
38
+ auto?: boolean;
39
+ }): Promise<LoopResult>;
40
+ private stop;
41
+ }
42
+ //# sourceMappingURL=loop.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loop.d.ts","sourceRoot":"","sources":["../src/loop.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,OAAO,EAAY,MAAM,cAAc,CAAC;AAGjD,eAAO,MAAM,MAAM,WAAW,CAAC;AAC/B,eAAO,MAAM,gBAAgB,qBAAqB,CAAC;AACnD,eAAO,MAAM,iBAAiB,sBAAsB,CAAC;AACrD,eAAO,MAAM,gBAAgB,qBAAqB,CAAC;AACnD,eAAO,MAAM,eAAe,oBAAoB,CAAC;AACjD,eAAO,MAAM,KAAK,UAAU,CAAC;AAC7B,eAAO,MAAM,SAAS,cAAc,CAAC;AACrC,eAAO,MAAM,SAAS,cAAc,CAAC;AACrC,eAAO,MAAM,WAAW,gBAAgB,CAAC;AAEzC,wDAAwD;AACxD,MAAM,WAAW,KAAK;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,IAAI,MAAM,CAAC;IACd,QAAQ,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAClD;AAED,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,OAAO,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,wBAAsB,eAAe,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC,CA8BzF;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,yDAAyD;AACzD,qBAAa,SAAS;IAElB,OAAO,CAAC,KAAK;IACb,OAAO,CAAC,MAAM;gBADN,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IAG/B,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,GAAE;QAAE,IAAI,CAAC,EAAE,OAAO,CAAA;KAAO,GAAG,OAAO,CAAC,UAAU,CAAC;IAmB/E,OAAO,CAAC,IAAI;CAKb"}
package/dist/loop.js ADDED
@@ -0,0 +1,86 @@
1
+ /**
2
+ * 长时程推进循环 + 单相位原语(对标 pi-agent-core 的 agent-loop)。
3
+ * advanceOnePhase 是 BuildLoop 与 Orchestrator 共用的原语(单相位语义只一处实现)。
4
+ * 从 Python loop.py 忠实移植(BudgetExceeded/LLMError 归约为停止原因,不炸进程)。
5
+ */
6
+ import { BudgetExceeded, LLMError } from "@mingyuxu/ai";
7
+ import { reconcile } from "./reconcile.js";
8
+ import { TERMINAL } from "./session.js";
9
+ // 停止原因
10
+ export const FROZEN = "frozen";
11
+ export const PHASE_CHECKPOINT = "phase_checkpoint";
12
+ export const AWAITING_APPROVAL = "awaiting_approval";
13
+ export const RECONCILE_FAILED = "reconcile_failed";
14
+ export const BUDGET_EXCEEDED = "budget_exceeded";
15
+ export const STUCK = "stuck";
16
+ export const MAX_STEPS = "max_steps";
17
+ export const LLM_ERROR = "llm_error";
18
+ export const INTERRUPTED = "interrupted";
19
+ export async function advanceOnePhase(agent, session) {
20
+ const ws = agent.workspace;
21
+ const phase = session.phase;
22
+ const before = session.lastProgressAt;
23
+ try {
24
+ await agent.runPhase(session);
25
+ }
26
+ catch (e) {
27
+ if (e instanceof BudgetExceeded) {
28
+ session.event(ws, "budget_exceeded", { error: String(e) }, agent.now());
29
+ return { ok: false, reason: BUDGET_EXCEEDED, phase, ran: false };
30
+ }
31
+ if (e instanceof LLMError) { // 瞬时故障:落账可续跑,不炸进程
32
+ session.event(ws, "llm_error", { error: String(e) }, agent.now());
33
+ return { ok: false, reason: LLM_ERROR, phase, ran: false };
34
+ }
35
+ throw e; // 机器门拒绝(桩审计/grounding)等 → 上抛给调用方
36
+ }
37
+ const missing = reconcile(session.home(ws), phase, session.artifacts[phase] ?? []);
38
+ if (missing.length) {
39
+ session.event(ws, "ghost_completion", { missing }, agent.now());
40
+ session.save(ws, agent.now());
41
+ return { ok: false, reason: RECONCILE_FAILED, phase, ran: true, missing };
42
+ }
43
+ if (session.lastProgressAt <= before) {
44
+ return { ok: false, reason: STUCK, phase, ran: true };
45
+ }
46
+ session.phase = session.nextPhase();
47
+ session.event(ws, "phase_advanced", { to: session.phase }, agent.now());
48
+ session.save(ws, agent.now());
49
+ return { ok: true, reason: "", phase, ran: true, nextPhase: session.phase };
50
+ }
51
+ /** 无人值守驱动器:沿相位推进;相位边界按 auto 决定停不停;freeze 永远等 approve。 */
52
+ export class BuildLoop {
53
+ agent;
54
+ policy;
55
+ constructor(agent, policy) {
56
+ this.agent = agent;
57
+ this.policy = policy;
58
+ }
59
+ async run(session, opts = {}) {
60
+ const auto = opts.auto ?? false;
61
+ const maxSteps = Number(this.policy.steps.builder_loop_max_steps);
62
+ let steps = 0;
63
+ while (session.phase !== TERMINAL) {
64
+ if (steps >= maxSteps)
65
+ return this.stop(session, MAX_STEPS, steps);
66
+ if (session.phase === "freeze" && !session.approved) {
67
+ return this.stop(session, AWAITING_APPROVAL, steps);
68
+ }
69
+ const res = await advanceOnePhase(this.agent, session);
70
+ if (res.ran)
71
+ steps += 1;
72
+ if (!res.ok)
73
+ return this.stop(session, res.reason, steps, res.missing);
74
+ if (!auto && session.phase !== TERMINAL) {
75
+ return this.stop(session, PHASE_CHECKPOINT, steps);
76
+ }
77
+ }
78
+ return this.stop(session, FROZEN, steps);
79
+ }
80
+ stop(session, reason, steps, missing) {
81
+ session.save(this.agent.workspace, this.agent.now());
82
+ session.event(this.agent.workspace, "loop_stopped", { reason }, this.agent.now());
83
+ return { stop: reason, phase: session.phase, steps, ...(missing ? { missing } : {}) };
84
+ }
85
+ }
86
+ //# sourceMappingURL=loop.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loop.js","sourceRoot":"","sources":["../src/loop.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAW,QAAQ,EAAE,MAAM,cAAc,CAAC;AAEjD,OAAO;AACP,MAAM,CAAC,MAAM,MAAM,GAAG,QAAQ,CAAC;AAC/B,MAAM,CAAC,MAAM,gBAAgB,GAAG,kBAAkB,CAAC;AACnD,MAAM,CAAC,MAAM,iBAAiB,GAAG,mBAAmB,CAAC;AACrD,MAAM,CAAC,MAAM,gBAAgB,GAAG,kBAAkB,CAAC;AACnD,MAAM,CAAC,MAAM,eAAe,GAAG,iBAAiB,CAAC;AACjD,MAAM,CAAC,MAAM,KAAK,GAAG,OAAO,CAAC;AAC7B,MAAM,CAAC,MAAM,SAAS,GAAG,WAAW,CAAC;AACrC,MAAM,CAAC,MAAM,SAAS,GAAG,WAAW,CAAC;AACrC,MAAM,CAAC,MAAM,WAAW,GAAG,aAAa,CAAC;AAkBzC,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,KAAY,EAAE,OAAgB;IAClE,MAAM,EAAE,GAAG,KAAK,CAAC,SAAS,CAAC;IAC3B,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;IAC5B,MAAM,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IACtC,IAAI,CAAC;QACH,MAAM,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IAChC,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,IAAI,CAAC,YAAY,cAAc,EAAE,CAAC;YAChC,OAAO,CAAC,KAAK,CAAC,EAAE,EAAE,iBAAiB,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC;YACxE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC;QACnE,CAAC;QACD,IAAI,CAAC,YAAY,QAAQ,EAAE,CAAC,CAAY,kBAAkB;YACxD,OAAO,CAAC,KAAK,CAAC,EAAE,EAAE,WAAW,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC;YAClE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC;QAC7D,CAAC;QACD,MAAM,CAAC,CAAC,CAAgC,iCAAiC;IAC3E,CAAC;IACD,MAAM,OAAO,GAAG,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;IACnF,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACnB,OAAO,CAAC,KAAK,CAAC,EAAE,EAAE,kBAAkB,EAAE,EAAE,OAAO,EAAE,EAAE,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC;QAChE,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC;QAC9B,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,gBAAgB,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;IAC5E,CAAC;IACD,IAAI,OAAO,CAAC,cAAc,IAAI,MAAM,EAAE,CAAC;QACrC,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC;IACxD,CAAC;IACD,OAAO,CAAC,KAAK,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IACpC,OAAO,CAAC,KAAK,CAAC,EAAE,EAAE,gBAAgB,EAAE,EAAE,EAAE,EAAE,OAAO,CAAC,KAAK,EAAE,EAAE,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC;IACxE,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC;IAC9B,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC;AAC9E,CAAC;AASD,yDAAyD;AACzD,MAAM,OAAO,SAAS;IAEV;IACA;IAFV,YACU,KAAY,EACZ,MAA2B;QAD3B,UAAK,GAAL,KAAK,CAAO;QACZ,WAAM,GAAN,MAAM,CAAqB;IAClC,CAAC;IAEJ,KAAK,CAAC,GAAG,CAAC,OAAgB,EAAE,OAA2B,EAAE;QACvD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,KAAK,CAAC;QAChC,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC;QAClE,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,OAAO,OAAO,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;YAClC,IAAI,KAAK,IAAI,QAAQ;gBAAE,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;YACnE,IAAI,OAAO,CAAC,KAAK,KAAK,QAAQ,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC;gBACpD,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,iBAAiB,EAAE,KAAK,CAAC,CAAC;YACtD,CAAC;YACD,MAAM,GAAG,GAAG,MAAM,eAAe,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;YACvD,IAAI,GAAG,CAAC,GAAG;gBAAE,KAAK,IAAI,CAAC,CAAC;YACxB,IAAI,CAAC,GAAG,CAAC,EAAE;gBAAE,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;YACvE,IAAI,CAAC,IAAI,IAAI,OAAO,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;gBACxC,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,gBAAgB,EAAE,KAAK,CAAC,CAAC;YACrD,CAAC;QACH,CAAC;QACD,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;IAC3C,CAAC;IAEO,IAAI,CAAC,OAAgB,EAAE,MAAc,EAAE,KAAa,EAAE,OAAkB;QAC9E,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC;QACrD,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,cAAc,EAAE,EAAE,MAAM,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC;QAClF,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,KAAK,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;IACxF,CAAC;CACF"}
@@ -0,0 +1,48 @@
1
+ import { type ToolRegistry } from "./tools.js";
2
+ import { type Agent } from "./loop.js";
3
+ import { Session } from "./session.js";
4
+ export declare const PLAYBOOK: Record<string, [string, string, string]>;
5
+ export interface OrchestratorAgent extends Agent {
6
+ tools: ToolRegistry;
7
+ ledgerSummary(): Record<string, unknown>;
8
+ llm: {
9
+ mode: string;
10
+ completeJson(system: string, user: string): Promise<Record<string, unknown>>;
11
+ };
12
+ }
13
+ export interface Decision {
14
+ narration?: string;
15
+ action?: {
16
+ kind?: string;
17
+ text?: string;
18
+ tool?: string;
19
+ args?: Record<string, unknown>;
20
+ };
21
+ }
22
+ export type DecideFn = (session: Session, userMsg: string, obs: string | null) => Promise<Decision> | Decision;
23
+ export type Say = (role: string, text: string) => void;
24
+ export declare class Orchestrator {
25
+ private agent;
26
+ private maxSteps;
27
+ private tailN;
28
+ private decide;
29
+ private instructions;
30
+ constructor(agent: OrchestratorAgent, policy: Record<string, any>, // policy.orchestrator.{max_steps_per_turn,transcript_tail_n}
31
+ opts?: {
32
+ decideFn?: DecideFn;
33
+ instructions?: string;
34
+ });
35
+ turn(session: Session, userMsg: string, say?: Say): Promise<{
36
+ stop: string;
37
+ steps: number;
38
+ }>;
39
+ private doTool;
40
+ private doAdvance;
41
+ private gateReady;
42
+ private gateSummary;
43
+ private llmDecide;
44
+ }
45
+ export declare const ORCH_SYSTEM: string;
46
+ /** mock 决策器:无模型也能走通闭环(确定性、可测)。 */
47
+ export declare function mockDecide(_session: Session, userMsg: string, obs: string | null): Decision;
48
+ //# sourceMappingURL=orchestrator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"orchestrator.d.ts","sourceRoot":"","sources":["../src/orchestrator.ts"],"names":[],"mappings":"AAOA,OAAO,EAAc,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAE3D,OAAO,EAAmB,KAAK,KAAK,EAAE,MAAM,WAAW,CAAC;AACxD,OAAO,EAAE,OAAO,EAAoB,MAAM,cAAc,CAAC;AAEzD,eAAO,MAAM,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAO7D,CAAC;AAEF,MAAM,WAAW,iBAAkB,SAAQ,KAAK;IAC9C,KAAK,EAAE,YAAY,CAAC;IACpB,aAAa,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACzC,GAAG,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA;KAAE,CAAC;CACrG;AAED,MAAM,WAAW,QAAQ;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAC;CAC1F;AACD,MAAM,MAAM,QAAQ,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,KAAK,OAAO,CAAC,QAAQ,CAAC,GAAG,QAAQ,CAAC;AAC/G,MAAM,MAAM,GAAG,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;AAEvD,qBAAa,YAAY;IAQrB,OAAO,CAAC,KAAK;IAPf,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,MAAM,CAAW;IAEzB,OAAO,CAAC,YAAY,CAAS;gBAGnB,KAAK,EAAE,iBAAiB,EAChC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAW,6DAA6D;IACnG,IAAI,GAAE;QAAE,QAAQ,CAAC,EAAE,QAAQ,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAA;KAAO;IAQrD,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,GAAE,GAAc,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;YAuD9F,MAAM;YAaN,SAAS;IAavB,OAAO,CAAC,SAAS;IAYjB,OAAO,CAAC,WAAW;YAUL,SAAS;CAgBxB;AAED,eAAO,MAAM,WAAW,QAK0B,CAAC;AAEnD,kCAAkC;AAClC,wBAAgB,UAAU,CAAC,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,QAAQ,CAuB3F"}
@@ -0,0 +1,194 @@
1
+ /**
2
+ * 意图层 Orchestrator —— 主 agent:narrate → 决策 → 观察 → 循环,直到交还用户。
3
+ * 决策五选一:reply / ask / tool / advance / propose_gate。失控三重顶:白名单+预算+步数。
4
+ * 从 Python orchestrator.py 移植。real 走 LLM 决策器、mock 走确定性关键词决策器(同一执行路径)。
5
+ */
6
+ import { existsSync, readFileSync } from "node:fs";
7
+ import { join } from "node:path";
8
+ import { ToolDenied } from "./tools.js";
9
+ import { BudgetExceeded } from "@mingyuxu/ai";
10
+ import { advanceOnePhase } from "./loop.js";
11
+ import { PHASES, TERMINAL } from "./session.js";
12
+ export const PLAYBOOK = {
13
+ analyze: ["① 分析规则", "把规则拆成原子核查目标", "展示目标清单,请用户确认/删/改"],
14
+ observe: ["② 观察样本", "用样本修锚点 + researcher 查领域知识", "汇报锚点命中与领域发现"],
15
+ propose: ["③ 出方案", "多 proposer 出候选生产线", "展示候选对比,确认后才推进"],
16
+ test: ["④ 测试", "bake-off 打分 + refine 回改 + 对抗验证据", "展示排名/召回/评审页再谈冻结"],
17
+ freeze: ["⑤ 冻结", "晋升门(桩审计+grounding+人工批准)", "摊开门禁状态,等人工 approve"],
18
+ [TERMINAL]: ["已冻结", "生产线可直接调用", "kcagent run <场景> <文档>"],
19
+ };
20
+ export class Orchestrator {
21
+ agent;
22
+ maxSteps;
23
+ tailN;
24
+ decide;
25
+ instructions;
26
+ constructor(agent, policy, // policy.orchestrator.{max_steps_per_turn,transcript_tail_n}
27
+ opts = {}) {
28
+ this.agent = agent;
29
+ this.maxSteps = Number(policy.orchestrator?.max_steps_per_turn ?? 6);
30
+ this.tailN = Number(policy.orchestrator?.transcript_tail_n ?? 20);
31
+ this.instructions = opts.instructions ?? "";
32
+ this.decide = opts.decideFn ?? (this.agent.llm.mode === "real" ? this.llmDecide.bind(this) : mockDecide);
33
+ }
34
+ async turn(session, userMsg, say = () => { }) {
35
+ const ws = this.agent.workspace;
36
+ session.transcriptAppend(ws, "user", userMsg);
37
+ let obs = null;
38
+ for (let step = 0; step < this.maxSteps; step++) {
39
+ let decision;
40
+ try {
41
+ decision = await this.decide(session, userMsg, obs);
42
+ }
43
+ catch (e) {
44
+ say("agent", `(决策器不可用:${e.name})`);
45
+ return { stop: "decider_error", steps: step };
46
+ }
47
+ const narration = (decision.narration ?? "").trim();
48
+ if (narration) {
49
+ say("think", narration);
50
+ session.transcriptAppend(ws, "think", narration);
51
+ }
52
+ const act = decision.action ?? {};
53
+ const kind = act.kind ?? "reply";
54
+ if (kind === "reply" || kind === "ask") {
55
+ const text = (act.text ?? "").trim() || "(无话可说)";
56
+ say("agent", text);
57
+ session.transcriptAppend(ws, "agent", text);
58
+ return { stop: kind, steps: step + 1 };
59
+ }
60
+ if (kind === "propose_gate") {
61
+ const [ready, why] = this.gateReady(session);
62
+ if (!ready) {
63
+ obs = `晋升门未就绪:${why}。先把④测试补完(show_report 可看现状)。`;
64
+ session.transcriptAppend(ws, "obs", obs);
65
+ continue;
66
+ }
67
+ const summary = this.gateSummary(session);
68
+ say("agent", summary);
69
+ session.transcriptAppend(ws, "agent", summary);
70
+ return { stop: "gate_proposed", steps: step + 1 };
71
+ }
72
+ if (kind === "advance") {
73
+ obs = await this.doAdvance(session);
74
+ session.transcriptAppend(ws, "obs", obs);
75
+ continue;
76
+ }
77
+ if (kind === "tool") {
78
+ obs = await this.doTool(session, act);
79
+ session.transcriptAppend(ws, "obs", obs);
80
+ continue;
81
+ }
82
+ obs = `未知动作 kind=${kind}`;
83
+ session.transcriptAppend(ws, "obs", obs);
84
+ }
85
+ say("agent", "这一轮动作到顶了,先停下等你。(进度都在盘上)");
86
+ return { stop: "max_steps", steps: this.maxSteps };
87
+ }
88
+ async doTool(session, act) {
89
+ const name = act.tool ?? "";
90
+ try {
91
+ let out = this.agent.tools.call(name, { ...(act.args ?? {}), session });
92
+ if (out instanceof Promise)
93
+ out = await out; // 工具可异步(如 revise_targets 调 LLM)
94
+ return typeof out === "string" ? out : JSON.stringify(out).slice(0, 2000);
95
+ }
96
+ catch (e) {
97
+ if (e instanceof ToolDenied)
98
+ return `工具被拒(白名单):${e.message}`;
99
+ if (e instanceof BudgetExceeded)
100
+ return `预算熔断:${e.message}`;
101
+ return `工具 ${name} 失败:${e.name}: ${e.message}`;
102
+ }
103
+ }
104
+ async doAdvance(session) {
105
+ if (session.phase === TERMINAL)
106
+ return "已经冻结完成,无相位可推进。";
107
+ if (session.phase === "freeze" && !session.approved) {
108
+ const [ready, why] = this.gateReady(session);
109
+ return "到晋升门了。" + (ready ? this.gateSummary(session) : `但门未就绪:${why}`);
110
+ }
111
+ const res = await advanceOnePhase(this.agent, session);
112
+ if (!res.ok)
113
+ return `相位 ${res.phase} 未推进:${res.reason}`;
114
+ const done = PLAYBOOK[res.phase]?.[0] ?? res.phase;
115
+ const next = PLAYBOOK[res.nextPhase]?.[0] ?? res.nextPhase;
116
+ return `✓ ${done} 完成,进入 ${next}。建议:${PLAYBOOK[res.phase]?.[2] ?? ""}`;
117
+ }
118
+ gateReady(session) {
119
+ const home = session.home(this.agent.workspace);
120
+ if (!["freeze", "test"].includes(session.phase))
121
+ return [false, `当前相位 ${session.phase},还没走到测试/冻结`];
122
+ const report = join(home, "build", "test_report.json");
123
+ if (!existsSync(report))
124
+ return [false, "缺 build/test_report.json(④测试没跑)"];
125
+ const rep = JSON.parse(readFileSync(report, "utf-8"));
126
+ if (rep.ranking?.length && !existsSync(join(home, "build", "review.html"))) {
127
+ return [false, "缺 build/review.html(评审页没出)"];
128
+ }
129
+ return [true, ""];
130
+ }
131
+ gateSummary(session) {
132
+ let report = "";
133
+ try {
134
+ report = this.agent.tools.call("show_report", { session });
135
+ }
136
+ catch {
137
+ report = "(测试报告不可读)";
138
+ }
139
+ return ["———— 晋升门 ————", report, "", "批准冻结是人工专属动作:确认无误后输入 approve(我无权替你批)。"].join("\n");
140
+ }
141
+ async llmDecide(session, userMsg, obs) {
142
+ const ctx = {
143
+ phase: session.phase,
144
+ playbook: PLAYBOOK,
145
+ phases_order: PHASES,
146
+ artifacts: session.artifacts,
147
+ approved: session.approved,
148
+ tools: this.agent.tools.names(),
149
+ transcript_tail: session.transcriptTail(this.agent.workspace, this.tailN),
150
+ user_message: userMsg,
151
+ last_observation: obs ?? "",
152
+ budget: this.agent.ledgerSummary(),
153
+ };
154
+ const system = this.instructions ? `${this.instructions}\n\n${ORCH_SYSTEM}` : ORCH_SYSTEM;
155
+ return (await this.agent.llm.completeJson(system, JSON.stringify(ctx)));
156
+ }
157
+ }
158
+ export const ORCH_SYSTEM = "你是核查生产线构建的主 agent(意图层)。每轮输出一个 JSON 决策:" +
159
+ '{"narration":"先说你准备做什么、为什么","action":{"kind":"reply|ask|tool|advance|propose_gate",' +
160
+ '"text":"对用户说的话","tool":"工具名","args":{}}}。五步是默认计划不是铁轨,用户可改道;' +
161
+ "用户要删/改目标时调 revise_targets(args.drop=[编号] 或 args.feedback=调整要求);" +
162
+ "propose_gate 前须有测试报告;冻结永远等人工 approve。只输出 JSON。";
163
+ /** mock 决策器:无模型也能走通闭环(确定性、可测)。 */
164
+ export function mockDecide(_session, userMsg, obs) {
165
+ if (obs !== null)
166
+ return { narration: "把刚才的结果交还给你。", action: { kind: "reply", text: obs } };
167
+ const has = (...kws) => kws.some((k) => userMsg.includes(k));
168
+ if (has("目标"))
169
+ return { narration: "你想看核查目标——调 show_targets。", action: { kind: "tool", tool: "show_targets" } };
170
+ if (has("方案", "候选", "skill"))
171
+ return { narration: "你想看候选生产线——调 show_specs。", action: { kind: "tool", tool: "show_specs" } };
172
+ if (has("报告", "评测", "测试", "结果"))
173
+ return { narration: "你想看评测结果——调 show_report。", action: { kind: "tool", tool: "show_report" } };
174
+ {
175
+ const dropM = userMsg.match(/删.*?(\d+)/g);
176
+ if (dropM) {
177
+ const nums = (userMsg.match(/\d+/g) ?? []).map(Number);
178
+ return { narration: `按你的要求删掉第 ${nums.join("、")} 个目标。`, action: { kind: "tool", tool: "revise_targets", args: { drop: nums } } };
179
+ }
180
+ if (has("改判据", "改目标", "修订", "只保留", "收紧", "放宽", "调整")) {
181
+ return { narration: "按你的调整要求修订目标清单。", action: { kind: "tool", tool: "revise_targets", args: { feedback: userMsg } } };
182
+ }
183
+ }
184
+ if (has("冻结", "批准", "上线", "固化"))
185
+ return { narration: "你想冻结——先过就绪门再摊开晋升门。", action: { kind: "propose_gate" } };
186
+ if (has("继续", "推进", "下一步", "开始"))
187
+ return { narration: "推进一个相位。", action: { kind: "advance" } };
188
+ const [title, what, review] = PLAYBOOK[_session.phase] ?? [_session.phase, "", ""];
189
+ return {
190
+ narration: "没匹配到明确意图,报个状态。",
191
+ action: { kind: "reply", text: `当前在 ${title}(${what})。可以说:继续 / 看目标 / 看方案 / 看报告 / 冻结。建议:${review}` },
192
+ };
193
+ }
194
+ //# sourceMappingURL=orchestrator.js.map