@monoes/monomindcli 2.9.20 → 2.9.22
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/.claude/helpers/control-start.cjs +7 -1
- package/.claude/skills/mastermind-createorg/SKILL.md +26 -3
- package/dist/src/commands/events.d.ts +9 -0
- package/dist/src/commands/events.d.ts.map +1 -0
- package/dist/src/commands/events.js +89 -0
- package/dist/src/commands/events.js.map +1 -0
- package/dist/src/commands/index.d.ts +1 -1
- package/dist/src/commands/index.d.ts.map +1 -1
- package/dist/src/commands/index.js +2 -1
- package/dist/src/commands/index.js.map +1 -1
- package/dist/src/commands/org-observe.d.ts +21 -0
- package/dist/src/commands/org-observe.d.ts.map +1 -1
- package/dist/src/commands/org-observe.js +88 -6
- package/dist/src/commands/org-observe.js.map +1 -1
- package/dist/src/commands/org.d.ts.map +1 -1
- package/dist/src/commands/org.js +20 -0
- package/dist/src/commands/org.js.map +1 -1
- package/dist/src/orgrt/approvals.d.ts +16 -1
- package/dist/src/orgrt/approvals.d.ts.map +1 -1
- package/dist/src/orgrt/approvals.js +44 -2
- package/dist/src/orgrt/approvals.js.map +1 -1
- package/dist/src/orgrt/copilot-runner.d.ts +14 -0
- package/dist/src/orgrt/copilot-runner.d.ts.map +1 -0
- package/dist/src/orgrt/copilot-runner.js +250 -0
- package/dist/src/orgrt/copilot-runner.js.map +1 -0
- package/dist/src/orgrt/crush-runner.d.ts +24 -0
- package/dist/src/orgrt/crush-runner.d.ts.map +1 -0
- package/dist/src/orgrt/crush-runner.js +251 -0
- package/dist/src/orgrt/crush-runner.js.map +1 -0
- package/dist/src/orgrt/daemon.d.ts +40 -1
- package/dist/src/orgrt/daemon.d.ts.map +1 -1
- package/dist/src/orgrt/daemon.js +68 -4
- package/dist/src/orgrt/daemon.js.map +1 -1
- package/dist/src/orgrt/grok-runner.d.ts +18 -0
- package/dist/src/orgrt/grok-runner.d.ts.map +1 -0
- package/dist/src/orgrt/grok-runner.js +323 -0
- package/dist/src/orgrt/grok-runner.js.map +1 -0
- package/dist/src/orgrt/pi-rpc-runner.d.ts +68 -0
- package/dist/src/orgrt/pi-rpc-runner.d.ts.map +1 -0
- package/dist/src/orgrt/pi-rpc-runner.js +400 -0
- package/dist/src/orgrt/pi-rpc-runner.js.map +1 -0
- package/dist/src/orgrt/pi-runner.d.ts +16 -0
- package/dist/src/orgrt/pi-runner.d.ts.map +1 -0
- package/dist/src/orgrt/pi-runner.js +264 -0
- package/dist/src/orgrt/pi-runner.js.map +1 -0
- package/dist/src/orgrt/qwen-runner.d.ts +18 -0
- package/dist/src/orgrt/qwen-runner.d.ts.map +1 -0
- package/dist/src/orgrt/qwen-runner.js +267 -0
- package/dist/src/orgrt/qwen-runner.js.map +1 -0
- package/dist/src/orgrt/session.js +1 -1
- package/dist/src/orgrt/session.js.map +1 -1
- package/dist/src/orgrt/types.d.ts +21 -0
- package/dist/src/orgrt/types.d.ts.map +1 -1
- package/dist/src/orgrt/types.js +9 -2
- package/dist/src/orgrt/types.js.map +1 -1
- package/dist/src/orgrt/usage-proxy.d.ts +32 -0
- package/dist/src/orgrt/usage-proxy.d.ts.map +1 -0
- package/dist/src/orgrt/usage-proxy.js +226 -0
- package/dist/src/orgrt/usage-proxy.js.map +1 -0
- package/dist/src/ui/dashboard.html +63 -0
- package/dist/src/ui/orgs.html +8 -1
- package/dist/src/ui/routes-org.mjs +26 -0
- package/dist/src/utils/resource-governor.d.ts.map +1 -1
- package/dist/src/utils/resource-governor.js +11 -2
- package/dist/src/utils/resource-governor.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
|
@@ -1,10 +1,25 @@
|
|
|
1
1
|
import type { OrgDaemon } from './daemon.js';
|
|
2
|
+
/** Discard every approval — pending or resolved — left over from a previous
|
|
3
|
+
* run. Call on a fresh (non-resume) startOrg.
|
|
4
|
+
*
|
|
5
|
+
* approvals.json is keyed per-org, not per-run, and daemon.approvals is an
|
|
6
|
+
* in-memory Map that starts empty in every fresh CLI process. A pending
|
|
7
|
+
* approval queued by a role in a PREVIOUS run — never resolved before that
|
|
8
|
+
* run ended — otherwise survives on disk forever: it looks "pending" to
|
|
9
|
+
* anything reading the file directly (dashboard, status checks, even
|
|
10
|
+
* `org approve`'s own live-delivery-then-fallback path), but the role that
|
|
11
|
+
* requested it is gone and no live daemon will ever have a matching
|
|
12
|
+
* in-memory record for it, so `org approve`'s live path always 404s with
|
|
13
|
+
* "No pending approval found" and silently falls back to patching a ghost
|
|
14
|
+
* entry nobody is listening for. A fresh start means every previous
|
|
15
|
+
* approval is moot for this run. */
|
|
16
|
+
export declare function clearApprovalsForFreshStart(daemon: OrgDaemon, org: string): void;
|
|
2
17
|
/** Check if an action requires human approval (beforeTool hook for guardrails). Returns
|
|
3
18
|
* the approval decision: true = approved, false = denied, null = pending (requires human input).
|
|
4
19
|
*
|
|
5
20
|
* R5: serialized per-org via withApprovalLock() — concurrent checkApproval and
|
|
6
21
|
* setApproval calls previously raced on this.approvals + approvals.json. */
|
|
7
|
-
export declare function checkApproval(daemon: OrgDaemon, org: string, role: string,
|
|
22
|
+
export declare function checkApproval(daemon: OrgDaemon, org: string, role: string, rawAction: string): Promise<boolean | null>;
|
|
8
23
|
/** Approve or deny a pending action (called by dashboard or CLI).
|
|
9
24
|
* R5: serialized per-org via withApprovalLock(). */
|
|
10
25
|
export declare function setApproval(daemon: OrgDaemon, org: string, role: string, action: string, approved: boolean): Promise<{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"approvals.d.ts","sourceRoot":"","sources":["../../../src/orgrt/approvals.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"approvals.d.ts","sourceRoot":"","sources":["../../../src/orgrt/approvals.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAmB7C;;;;;;;;;;;;;qCAaqC;AACrC,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAIhF;AAED;;;;6EAI6E;AAC7E,wBAAgB,aAAa,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAmCtH;AAED;qDACqD;AACrD,wBAAsB,WAAW,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,GAAG,OAAO,CAAC;IAAE,EAAE,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAwBvK"}
|
|
@@ -1,21 +1,63 @@
|
|
|
1
1
|
// packages/@monomind/cli/src/orgrt/approvals.ts
|
|
2
2
|
// Extracted from daemon.ts — approval checking and setting for org tool calls.
|
|
3
3
|
import { join } from 'node:path';
|
|
4
|
-
import { mkdirSync } from 'node:fs';
|
|
4
|
+
import { existsSync, mkdirSync } from 'node:fs';
|
|
5
5
|
import { writeJsonFileAtomic } from '../utils/json-file.js';
|
|
6
6
|
import { ORG_DIR } from './types.js';
|
|
7
|
+
/** Custom org-runtime tools (org_complete, org_send, org_task, ...) are
|
|
8
|
+
* registered as an SDK MCP server named 'org' (createSdkMcpServer({ name:
|
|
9
|
+
* 'org', ... }) in agent-runner.ts), so the SDK always presents them to
|
|
10
|
+
* canUseTool/policy.decide under the namespaced form `mcp__org__<name>` —
|
|
11
|
+
* unlike genuine SDK built-ins (Bash/WebFetch/WebSearch), which always
|
|
12
|
+
* arrive as their bare name. checkApproval's sensitiveActions list (and any
|
|
13
|
+
* role's policy.autoApproveTools) is written against the bare, human-facing
|
|
14
|
+
* name — 'org_complete', not 'mcp__org__org_complete' — so without this,
|
|
15
|
+
* 'org_complete' NEVER matched and silently fell through to auto-approve
|
|
16
|
+
* unconditionally on every single call. Of the four originally-intended
|
|
17
|
+
* sensitive actions, the one whose approval mattered most (org_complete ends
|
|
18
|
+
* the entire run) was the one that was never actually gated. */
|
|
19
|
+
function normalizeToolAction(rawAction) {
|
|
20
|
+
const prefix = 'mcp__org__';
|
|
21
|
+
return rawAction.startsWith(prefix) ? rawAction.slice(prefix.length) : rawAction;
|
|
22
|
+
}
|
|
23
|
+
/** Discard every approval — pending or resolved — left over from a previous
|
|
24
|
+
* run. Call on a fresh (non-resume) startOrg.
|
|
25
|
+
*
|
|
26
|
+
* approvals.json is keyed per-org, not per-run, and daemon.approvals is an
|
|
27
|
+
* in-memory Map that starts empty in every fresh CLI process. A pending
|
|
28
|
+
* approval queued by a role in a PREVIOUS run — never resolved before that
|
|
29
|
+
* run ended — otherwise survives on disk forever: it looks "pending" to
|
|
30
|
+
* anything reading the file directly (dashboard, status checks, even
|
|
31
|
+
* `org approve`'s own live-delivery-then-fallback path), but the role that
|
|
32
|
+
* requested it is gone and no live daemon will ever have a matching
|
|
33
|
+
* in-memory record for it, so `org approve`'s live path always 404s with
|
|
34
|
+
* "No pending approval found" and silently falls back to patching a ghost
|
|
35
|
+
* entry nobody is listening for. A fresh start means every previous
|
|
36
|
+
* approval is moot for this run. */
|
|
37
|
+
export function clearApprovalsForFreshStart(daemon, org) {
|
|
38
|
+
daemon.approvals.delete(org);
|
|
39
|
+
const approvalsPath = join(daemon.root, ORG_DIR, org, 'approvals.json');
|
|
40
|
+
if (existsSync(approvalsPath))
|
|
41
|
+
writeJsonFileAtomic(approvalsPath, { approvals: [] });
|
|
42
|
+
}
|
|
7
43
|
/** Check if an action requires human approval (beforeTool hook for guardrails). Returns
|
|
8
44
|
* the approval decision: true = approved, false = denied, null = pending (requires human input).
|
|
9
45
|
*
|
|
10
46
|
* R5: serialized per-org via withApprovalLock() — concurrent checkApproval and
|
|
11
47
|
* setApproval calls previously raced on this.approvals + approvals.json. */
|
|
12
|
-
export function checkApproval(daemon, org, role,
|
|
48
|
+
export function checkApproval(daemon, org, role, rawAction) {
|
|
49
|
+
const action = normalizeToolAction(rawAction);
|
|
13
50
|
return withApprovalLock(daemon, org, async () => {
|
|
14
51
|
const pending = daemon.approvals.get(org) ?? [];
|
|
15
52
|
const existing = pending.find(a => a.roleId === role && a.action === action);
|
|
16
53
|
// If already approved/denied, return that decision
|
|
17
54
|
if (existing && existing.approved !== null)
|
|
18
55
|
return existing.approved;
|
|
56
|
+
// A role's policy.autoApproveTools can name specific sensitive actions it's
|
|
57
|
+
// pre-trusted for, skipping the human-approval pause entirely for those.
|
|
58
|
+
const roleDef = daemon.orgs.get(org)?.def.roles.find(r => r.id === role);
|
|
59
|
+
if (roleDef?.policy?.autoApproveTools?.includes(action))
|
|
60
|
+
return true;
|
|
19
61
|
// Require human approval for sensitive actions
|
|
20
62
|
const sensitiveActions = ['Bash', 'WebFetch', 'WebSearch', 'org_complete'];
|
|
21
63
|
if (sensitiveActions.includes(action)) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"approvals.js","sourceRoot":"","sources":["../../../src/orgrt/approvals.ts"],"names":[],"mappings":"AAAA,gDAAgD;AAChD,+EAA+E;AAC/E,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"approvals.js","sourceRoot":"","sources":["../../../src/orgrt/approvals.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { AgentRunner, AgentRunArgs, AgentMessage } from './agent-runner.js';
|
|
2
|
+
/** Pure NDJSON parser — exported for unit testing against fixture lines
|
|
3
|
+
* (copilot-runner.test.ts). */
|
|
4
|
+
export declare function parseCopilotEvents(lines: string[]): {
|
|
5
|
+
texts: string[];
|
|
6
|
+
rawTexts: string[];
|
|
7
|
+
};
|
|
8
|
+
export declare class CopilotAgentRunner implements AgentRunner {
|
|
9
|
+
private copilotBin?;
|
|
10
|
+
constructor(copilotBin?: string | undefined);
|
|
11
|
+
run(args: AgentRunArgs): AsyncIterable<AgentMessage>;
|
|
12
|
+
private runTurn;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=copilot-runner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"copilot-runner.d.ts","sourceRoot":"","sources":["../../../src/orgrt/copilot-runner.ts"],"names":[],"mappings":"AA+CA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AA+BjF;gCACgC;AAChC,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG;IAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;CAAE,CAqB3F;AAaD,qBAAa,kBAAmB,YAAW,WAAW;IACxC,OAAO,CAAC,UAAU,CAAC;IAA/B,YAAoB,UAAU,CAAC,EAAE,MAAM,YAAA,EAAI;IAEpC,GAAG,CAAC,IAAI,EAAE,YAAY,GAAG,aAAa,CAAC,YAAY,CAAC,CA+D1D;IAED,OAAO,CAAC,OAAO;CAgFhB"}
|
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
// packages/@monomind/cli/src/orgrt/copilot-runner.ts
|
|
2
|
+
/**
|
|
3
|
+
* CopilotAgentRunner — AgentRunner impl backed by the GitHub Copilot CLI
|
|
4
|
+
* (`copilot`, https://docs.github.com/en/copilot/reference/copilot-cli-reference).
|
|
5
|
+
*
|
|
6
|
+
* Architectural pattern: SAME as the other subprocess runners — spawn the
|
|
7
|
+
* CLI, parse its output, normalize to AgentMessage.
|
|
8
|
+
*
|
|
9
|
+
* Auth: GitHub's own device/browser login flow (`copilot` handles this
|
|
10
|
+
* itself on first run). No env vars set here.
|
|
11
|
+
*
|
|
12
|
+
* Subprocess protocol — per public docs, NOT byte-verified against a running
|
|
13
|
+
* binary:
|
|
14
|
+
* - Invocation: `copilot -p "<prompt>" --output-format json -s
|
|
15
|
+
* --allow-all-tools --no-ask-user [--model=<model>]`. `-s`
|
|
16
|
+
* (silent) suppresses the stats/decoration footer that otherwise mixes
|
|
17
|
+
* into stdout (documented GitHub issue: without `-s`, response text can
|
|
18
|
+
* be absent from plain stdout entirely — `--output-format json` + `-s`
|
|
19
|
+
* is the documented workaround). `--no-ask-user` disables the CLI's
|
|
20
|
+
* ask_user tool so a headless run can never block waiting on a question
|
|
21
|
+
* with no human to answer it — confirmed by cross-checking a second,
|
|
22
|
+
* independent public agentic-CLI wrapper's provider table, which lists
|
|
23
|
+
* the identical `-s --allow-all-tools --no-ask-user` combination for
|
|
24
|
+
* Copilot's non-interactive mode; this runner was missing `--no-ask-user`
|
|
25
|
+
* until that cross-check.
|
|
26
|
+
* - Output: NDJSON; assistant text arrives on `assistant.message`-shaped
|
|
27
|
+
* events. The exact full field list isn't published, so parseCopilotEvents
|
|
28
|
+
* tolerates a couple of plausible shapes (an explicit `type`/`kind` of
|
|
29
|
+
* 'assistant.message' or 'assistant' carrying `content`/`text`) and
|
|
30
|
+
* fails closed (no text extracted) on anything else, rather than
|
|
31
|
+
* guessing wrong and emitting garbage.
|
|
32
|
+
* - Session/resume: Copilot documents a `--resume=<id>` flag, but nothing
|
|
33
|
+
* in this runner's output parsing surfaces a session id to pass back in
|
|
34
|
+
* (the same gap the cross-check source above notes about its own
|
|
35
|
+
* integration), so resume can't be wired up yet — every mailbox prompt
|
|
36
|
+
* is a fresh `copilot -p` invocation, same disclosed limitation as
|
|
37
|
+
* CrushAgentRunner. Revisit if a session-id-bearing event/field is found.
|
|
38
|
+
* - Token usage: NOT documented for `--output-format json`, and Copilot
|
|
39
|
+
* CLI has no documented custom-base-URL override (it talks to GitHub's
|
|
40
|
+
* own Copilot backend, not a passthrough-able OpenAI/Anthropic
|
|
41
|
+
* endpoint), so this runner does not attempt usage-proxy accounting —
|
|
42
|
+
* it always reports 0 tokens. Revisit if GitHub documents a usage field
|
|
43
|
+
* or a proxyable endpoint later.
|
|
44
|
+
*
|
|
45
|
+
* Org tools — FENCE PROTOCOL: same approach as the other subprocess runners.
|
|
46
|
+
*/
|
|
47
|
+
import { spawn } from 'node:child_process';
|
|
48
|
+
import { buildToolProtocol, parseToolCalls, executeToolCall, formatToolResults, MAX_TOOL_ROUNDS, TOOL_CALL_RE } from './tool-fence.js';
|
|
49
|
+
const TURN_TIMEOUT_MS = 2 * 60 * 60 * 1000;
|
|
50
|
+
/** Distinct from TURN_TIMEOUT_MS: catches a hung first-run interactive prompt
|
|
51
|
+
* fast instead of waiting out the full turn timeout. Any output at all
|
|
52
|
+
* disarms it. Copilot CLI has a DOCUMENTED bug where its directory-trust
|
|
53
|
+
* and path-access prompts can hang indefinitely in CI/headless invocations
|
|
54
|
+
* with no way to answer them — this is the primary mitigation for copilot
|
|
55
|
+
* specifically, not just a defensive backstop. */
|
|
56
|
+
const STARTUP_GRACE_MS = 45_000;
|
|
57
|
+
function coerceText(v) {
|
|
58
|
+
if (typeof v === 'string')
|
|
59
|
+
return v;
|
|
60
|
+
if (Array.isArray(v)) {
|
|
61
|
+
return v
|
|
62
|
+
.filter((b) => !!b && typeof b === 'object' && b.type === 'text')
|
|
63
|
+
.map((b) => b.text)
|
|
64
|
+
.join('\n');
|
|
65
|
+
}
|
|
66
|
+
return undefined;
|
|
67
|
+
}
|
|
68
|
+
/** Pure NDJSON parser — exported for unit testing against fixture lines
|
|
69
|
+
* (copilot-runner.test.ts). */
|
|
70
|
+
export function parseCopilotEvents(lines) {
|
|
71
|
+
const rawTexts = [];
|
|
72
|
+
for (const line of lines) {
|
|
73
|
+
const trimmed = line.trim();
|
|
74
|
+
if (!trimmed || !trimmed.startsWith('{'))
|
|
75
|
+
continue;
|
|
76
|
+
let ev;
|
|
77
|
+
try {
|
|
78
|
+
ev = JSON.parse(trimmed);
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
const kind = ev.type ?? ev.kind;
|
|
84
|
+
if (kind === 'assistant.message' || kind === 'assistant') {
|
|
85
|
+
const text = coerceText(ev.content) ?? ev.text ?? coerceText(ev.message?.content) ?? ev.message?.text;
|
|
86
|
+
if (text)
|
|
87
|
+
rawTexts.push(text);
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
if (ev.role === 'assistant') {
|
|
91
|
+
const text = coerceText(ev.content) ?? ev.text;
|
|
92
|
+
if (text)
|
|
93
|
+
rawTexts.push(text);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
const texts = rawTexts.map((t) => t.replace(TOOL_CALL_RE, '').trim());
|
|
97
|
+
return { texts, rawTexts };
|
|
98
|
+
}
|
|
99
|
+
export class CopilotAgentRunner {
|
|
100
|
+
copilotBin;
|
|
101
|
+
constructor(copilotBin) {
|
|
102
|
+
this.copilotBin = copilotBin;
|
|
103
|
+
}
|
|
104
|
+
async *run(args) {
|
|
105
|
+
const bin = this.copilotBin || process.env.COPILOT_CLI_BIN || 'copilot';
|
|
106
|
+
try {
|
|
107
|
+
for await (const p of args.prompt) {
|
|
108
|
+
const text = typeof p === 'string' ? p : (p?.message?.content ?? String(p ?? ''));
|
|
109
|
+
let nextPrompt = `${args.systemPrompt}${buildToolProtocol(args.tools)}\n\n---\n\n${text}`;
|
|
110
|
+
for (let round = 0; round <= MAX_TOOL_ROUNDS; round++) {
|
|
111
|
+
const outcome = await this.runTurn(bin, nextPrompt, args);
|
|
112
|
+
if (outcome.hangSuspected) {
|
|
113
|
+
throw new Error(`CopilotAgentRunner: copilot produced no output within ${STARTUP_GRACE_MS / 1000}s and was ` +
|
|
114
|
+
'killed. This is a documented copilot CLI issue: its directory-trust/path-access prompts can ' +
|
|
115
|
+
'hang indefinitely in headless invocations with no way to answer them. Run `copilot` once ' +
|
|
116
|
+
'manually in a real terminal in this project to accept any prompts (and confirm --add-dir ' +
|
|
117
|
+
`covers every path it needs), then retry.${outcome.stderrTail ? `\nstderr: ${outcome.stderrTail.slice(-500)}` : ''}`);
|
|
118
|
+
}
|
|
119
|
+
if (outcome.exitCode !== 0) {
|
|
120
|
+
throw new Error(`CopilotAgentRunner: copilot failed (exit ${outcome.exitCode})` +
|
|
121
|
+
(outcome.timedOut ? ` — killed after exceeding the ${TURN_TIMEOUT_MS / 3_600_000}h turn timeout` : '') +
|
|
122
|
+
(outcome.stderrTail ? `\nstderr: ${outcome.stderrTail.slice(-500)}` : ''));
|
|
123
|
+
}
|
|
124
|
+
for (const t of outcome.texts) {
|
|
125
|
+
if (t.trim())
|
|
126
|
+
yield { type: 'assistant', text: t };
|
|
127
|
+
}
|
|
128
|
+
const malformed = [];
|
|
129
|
+
const calls = parseToolCalls(outcome.rawTexts, (raw, err) => malformed.push(`[monomind] ignored malformed tool_call fence (${err}): ${raw.slice(0, 200)}`));
|
|
130
|
+
for (const note of malformed)
|
|
131
|
+
yield { type: 'assistant', text: note };
|
|
132
|
+
if (calls.length === 0) {
|
|
133
|
+
yield { type: 'result', subtype: 'success', input_tokens: 0, output_tokens: 0 };
|
|
134
|
+
break;
|
|
135
|
+
}
|
|
136
|
+
if (round === MAX_TOOL_ROUNDS) {
|
|
137
|
+
yield { type: 'assistant', text: `[monomind] tool-call round cap (${MAX_TOOL_ROUNDS}) reached — dropping ${calls.length} pending tool call(s)` };
|
|
138
|
+
yield { type: 'result', subtype: 'success', input_tokens: 0, output_tokens: 0 };
|
|
139
|
+
break;
|
|
140
|
+
}
|
|
141
|
+
const results = [];
|
|
142
|
+
for (const call of calls)
|
|
143
|
+
results.push(await executeToolCall(args.tools, call, args.canUseTool));
|
|
144
|
+
nextPrompt = `${args.systemPrompt}${buildToolProtocol(args.tools)}\n\n---\n\n${formatToolResults(calls, results)}`;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
catch (err) {
|
|
149
|
+
if (err.code === 'ENOENT') {
|
|
150
|
+
throw new Error('CopilotAgentRunner requires the GitHub Copilot CLI (copilot) on PATH. ' +
|
|
151
|
+
'Install it: npm install -g @github/copilot, then run `copilot` once to ' +
|
|
152
|
+
'authenticate. Or unset the runtime to use Claude.');
|
|
153
|
+
}
|
|
154
|
+
throw err;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
runTurn(bin, prompt, args) {
|
|
158
|
+
return new Promise((resolve, reject) => {
|
|
159
|
+
const cliArgs = ['-p', prompt, '--output-format', 'json', '-s', '--allow-all-tools', '--no-ask-user'];
|
|
160
|
+
if (args.model)
|
|
161
|
+
cliArgs.push(`--model=${args.model}`);
|
|
162
|
+
cliArgs.push('--add-dir', args.cwd);
|
|
163
|
+
const child = spawn(bin, cliArgs, {
|
|
164
|
+
cwd: args.cwd,
|
|
165
|
+
env: { ...process.env, ...args.env },
|
|
166
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
167
|
+
});
|
|
168
|
+
let stderrTail = '';
|
|
169
|
+
child.stderr?.on('data', (c) => { stderrTail = (stderrTail + c.toString()).slice(-4000); });
|
|
170
|
+
let sawOutput = false;
|
|
171
|
+
let timedOut = false;
|
|
172
|
+
let hangSuspected = false;
|
|
173
|
+
const KILL_GRACE_MS = 5000;
|
|
174
|
+
let killTimer;
|
|
175
|
+
const timer = setTimeout(() => {
|
|
176
|
+
timedOut = true;
|
|
177
|
+
child.kill('SIGTERM');
|
|
178
|
+
killTimer = setTimeout(() => { try {
|
|
179
|
+
child.kill('SIGKILL');
|
|
180
|
+
}
|
|
181
|
+
catch { /* already gone */ } }, KILL_GRACE_MS);
|
|
182
|
+
killTimer.unref?.();
|
|
183
|
+
}, TURN_TIMEOUT_MS);
|
|
184
|
+
// See STARTUP_GRACE_MS — disarmed by the first stdout chunk below.
|
|
185
|
+
let hangTimer = setTimeout(() => {
|
|
186
|
+
hangSuspected = true;
|
|
187
|
+
child.kill('SIGTERM');
|
|
188
|
+
killTimer = setTimeout(() => { try {
|
|
189
|
+
child.kill('SIGKILL');
|
|
190
|
+
}
|
|
191
|
+
catch { /* already gone */ } }, KILL_GRACE_MS);
|
|
192
|
+
killTimer.unref?.();
|
|
193
|
+
}, STARTUP_GRACE_MS);
|
|
194
|
+
const exitPromise = new Promise((res, rej) => {
|
|
195
|
+
child.on('error', rej);
|
|
196
|
+
child.on('close', (code) => res(code ?? 1));
|
|
197
|
+
});
|
|
198
|
+
exitPromise.catch(() => { });
|
|
199
|
+
const readLines = (async () => {
|
|
200
|
+
const lines = [];
|
|
201
|
+
let buf = '';
|
|
202
|
+
for await (const chunk of child.stdout) {
|
|
203
|
+
if (!sawOutput) {
|
|
204
|
+
sawOutput = true;
|
|
205
|
+
if (hangTimer) {
|
|
206
|
+
clearTimeout(hangTimer);
|
|
207
|
+
hangTimer = undefined;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
buf += chunk.toString();
|
|
211
|
+
const parts = buf.split('\n');
|
|
212
|
+
buf = parts.pop() ?? '';
|
|
213
|
+
lines.push(...parts);
|
|
214
|
+
}
|
|
215
|
+
if (buf.trim())
|
|
216
|
+
lines.push(buf);
|
|
217
|
+
return lines;
|
|
218
|
+
})();
|
|
219
|
+
// Timer cleanup lives in a top-level .finally() (not nested inside a
|
|
220
|
+
// success-path .then()) so it runs on EITHER path — a stdout stream
|
|
221
|
+
// error would otherwise skip straight to reject() and leave the
|
|
222
|
+
// TURN_TIMEOUT_MS/hangTimer/killTimer timers running past the
|
|
223
|
+
// process's actual lifetime.
|
|
224
|
+
Promise.all([readLines, exitPromise])
|
|
225
|
+
.then(([lines, exitCode]) => {
|
|
226
|
+
const parsed = parseCopilotEvents(lines);
|
|
227
|
+
resolve({ texts: parsed.texts, rawTexts: parsed.rawTexts, exitCode, stderrTail, timedOut, hangSuspected });
|
|
228
|
+
}, (err) => {
|
|
229
|
+
// A stdout stream error (the reject path) means the process is
|
|
230
|
+
// still ALIVE and unmanaged — none of the timeout/hang timers
|
|
231
|
+
// would have fired to kill it. Without this, that error would
|
|
232
|
+
// orphan the child. child.kill() on an already-dead process is a
|
|
233
|
+
// documented no-op, so this is safe on every path.
|
|
234
|
+
try {
|
|
235
|
+
child.kill('SIGTERM');
|
|
236
|
+
}
|
|
237
|
+
catch { /* already gone */ }
|
|
238
|
+
reject(err);
|
|
239
|
+
})
|
|
240
|
+
.finally(() => {
|
|
241
|
+
clearTimeout(timer);
|
|
242
|
+
if (hangTimer)
|
|
243
|
+
clearTimeout(hangTimer);
|
|
244
|
+
if (killTimer)
|
|
245
|
+
clearTimeout(killTimer);
|
|
246
|
+
});
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
//# sourceMappingURL=copilot-runner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"copilot-runner.js","sourceRoot":"","sources":["../../../src/orgrt/copilot-runner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { AgentRunner, AgentRunArgs, AgentMessage } from './agent-runner.js';
|
|
2
|
+
/** Strip tool_call fences and normalize whitespace on crush's plain-text
|
|
3
|
+
* stdout. Exported for unit testing (crush-runner.test.ts). */
|
|
4
|
+
export declare function parseCrushOutput(stdout: string): {
|
|
5
|
+
text: string;
|
|
6
|
+
rawText: string;
|
|
7
|
+
};
|
|
8
|
+
export interface CrushAgentRunnerOptions {
|
|
9
|
+
crushBin?: string;
|
|
10
|
+
/** Enable usage-proxy accounting. Off by default since the base-URL env
|
|
11
|
+
* var it relies on is an unconfirmed guess (see file header). */
|
|
12
|
+
usageProxy?: {
|
|
13
|
+
upstreamBaseUrl: string;
|
|
14
|
+
baseUrlEnvVar?: string;
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
export declare class CrushAgentRunner implements AgentRunner {
|
|
18
|
+
private crushBin?;
|
|
19
|
+
private usageProxyOpts?;
|
|
20
|
+
constructor(opts?: CrushAgentRunnerOptions);
|
|
21
|
+
run(args: AgentRunArgs): AsyncIterable<AgentMessage>;
|
|
22
|
+
private runTurn;
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=crush-runner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crush-runner.d.ts","sourceRoot":"","sources":["../../../src/orgrt/crush-runner.ts"],"names":[],"mappings":"AAoDA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAWjF;gEACgE;AAChE,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAIlF;AAaD,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;sEACkE;IAClE,UAAU,CAAC,EAAE;QAAE,eAAe,EAAE,MAAM,CAAC;QAAC,aAAa,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAClE;AAED,qBAAa,gBAAiB,YAAW,WAAW;IAClD,OAAO,CAAC,QAAQ,CAAC,CAAS;IAC1B,OAAO,CAAC,cAAc,CAAC,CAAqD;IAE5E,YAAY,IAAI,GAAE,uBAA4B,EAQ7C;IAEM,GAAG,CAAC,IAAI,EAAE,YAAY,GAAG,aAAa,CAAC,YAAY,CAAC,CAyF1D;IAED,OAAO,CAAC,OAAO;CAuFhB"}
|