@enderfga/claw-orchestrator 5.0.0 → 5.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.
- package/README.md +5 -5
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.js +1 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/models.d.ts +1 -1
- package/dist/src/models.js +31 -3
- package/dist/src/models.js.map +1 -1
- package/dist/src/persistent-cursor-session.js +6 -1
- package/dist/src/persistent-cursor-session.js.map +1 -1
- package/dist/src/persistent-grok-session.d.ts +40 -0
- package/dist/src/persistent-grok-session.js +197 -0
- package/dist/src/persistent-grok-session.js.map +1 -0
- package/dist/src/session-manager.js +5 -0
- package/dist/src/session-manager.js.map +1 -1
- package/dist/src/types.d.ts +4 -1
- package/dist/src/types.js +15 -1
- package/dist/src/types.js.map +1 -1
- package/package.json +1 -1
- package/skills/SKILL.md +5 -5
- package/skills/references/acp.md +1 -1
- package/skills/references/autoloop.md +9 -7
- package/skills/references/cli.md +3 -2
- package/skills/references/getting-started.md +1 -1
- package/skills/references/multi-engine.md +58 -4
- package/skills/references/observability.md +3 -2
- package/skills/references/openai-compat.md +2 -2
- package/skills/references/sessions.md +2 -2
- package/skills/references/tools.md +2 -2
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Grok Build (xAI) session wrapper.
|
|
3
|
+
*
|
|
4
|
+
* One-shot per send: `grok -p <msg> --output-format json`, which prints a single
|
|
5
|
+
* JSON object and exits. That object is unusually complete for this engine class
|
|
6
|
+
* — it carries the reply, a terminal `stopReason`, a resumable `sessionId`, real
|
|
7
|
+
* token usage, the model that actually answered, and the engine's own
|
|
8
|
+
* `total_cost_usd`.
|
|
9
|
+
*
|
|
10
|
+
* Two consequences shape this file:
|
|
11
|
+
*
|
|
12
|
+
* 1. **Cost is passed through, not priced.** Every other engine here multiplies
|
|
13
|
+
* token counts by a rate in `models.ts`, which is the metadata that rots
|
|
14
|
+
* silently between releases. Grok reports what it charged, so this wrapper
|
|
15
|
+
* writes that number into `_stats.costUsd` directly and the registry is never
|
|
16
|
+
* consulted for it. The run ledger and the `maxBudgetUsd` gate both read that
|
|
17
|
+
* field, so both get the engine's own figure.
|
|
18
|
+
* 2. **The binary is `grok`, never `agent`.** xAI's installer also symlinks the
|
|
19
|
+
* generic `agent` name, which Cursor's CLI already used; whichever installer
|
|
20
|
+
* ran last wins. Both wrappers now name the vendor-specific binary so the
|
|
21
|
+
* engine you asked for is the engine you get.
|
|
22
|
+
*
|
|
23
|
+
* Usage and cost are per-turn, not cumulative over the thread — verified against
|
|
24
|
+
* 1.0.5 by resuming a session and reading the second turn (29,711 in / $0.0597,
|
|
25
|
+
* then 70 in / $0.0152). Accumulating them is therefore correct here, unlike
|
|
26
|
+
* codex, where the same-looking field is a running total.
|
|
27
|
+
*/
|
|
28
|
+
import { spawn } from 'node:child_process';
|
|
29
|
+
import { sanitizeSecrets } from './sanitize.js';
|
|
30
|
+
import { BaseOneShotSession } from './base-oneshot-session.js';
|
|
31
|
+
import { SESSION_EVENT } from './constants.js';
|
|
32
|
+
export class PersistentGrokSession extends BaseOneShotSession {
|
|
33
|
+
/** Grok's own session UUID, captured from turn 1 and replayed via `--resume`. */
|
|
34
|
+
grokSessionId;
|
|
35
|
+
constructor(config, grokBin) {
|
|
36
|
+
super(config, grokBin || process.env.GROK_BIN || 'grok', {
|
|
37
|
+
enginePrefix: 'grok',
|
|
38
|
+
defaultModel: 'grok-4.6',
|
|
39
|
+
defaultModelDisplay: 'grok-4.6',
|
|
40
|
+
supportsCachedTokens: true,
|
|
41
|
+
engineDisplayName: 'Grok Build',
|
|
42
|
+
});
|
|
43
|
+
// Same shape cursor and opencode use: the real id is surfaced through
|
|
44
|
+
// `sessionId` behind a `grok-live-` prefix so SessionManager can persist it,
|
|
45
|
+
// and the prefix is stripped again on the way back in. A synthetic wrapper id
|
|
46
|
+
// (`grok-<ts>-<rand>`) must never be handed to `--resume`.
|
|
47
|
+
if (config.resumeSessionId && !/^grok-\d+-/.test(config.resumeSessionId)) {
|
|
48
|
+
this.grokSessionId = config.resumeSessionId.replace(/^grok-live-/, '');
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
_buildArgs(message, options) {
|
|
52
|
+
const args = ['-p', message, '--output-format', 'json'];
|
|
53
|
+
if (this.options.cwd)
|
|
54
|
+
args.push('--cwd', this.options.cwd);
|
|
55
|
+
// Resume grok's own thread rather than starting fresh. `--continue` is
|
|
56
|
+
// deliberately not used: it means "the most recent session for this cwd",
|
|
57
|
+
// which collides between concurrent sessions on the same project.
|
|
58
|
+
if (this.grokSessionId)
|
|
59
|
+
args.push('--resume', this.grokSessionId);
|
|
60
|
+
const model = this.options.resolvedModel || this.options.model;
|
|
61
|
+
if (model)
|
|
62
|
+
args.push('--model', this.resolveModel(model.replace(/^grok\//, '')));
|
|
63
|
+
// grok's --permission-mode vocabulary is the same set as ours, so this is a
|
|
64
|
+
// passthrough rather than a mapping. 'manual' is ours alone; grok calls the
|
|
65
|
+
// equivalent 'default'.
|
|
66
|
+
const mode = this.options.permissionMode === 'manual' ? 'default' : this.options.permissionMode;
|
|
67
|
+
if (mode)
|
|
68
|
+
args.push('--permission-mode', mode);
|
|
69
|
+
const effort = options.effort ?? this.options.effort;
|
|
70
|
+
if (effort && effort !== 'auto') {
|
|
71
|
+
// grok takes low|medium|high; the two higher aliases in our union clamp.
|
|
72
|
+
args.push('--effort', effort === 'max' || effort === 'xhigh' ? 'high' : effort);
|
|
73
|
+
}
|
|
74
|
+
if (this.options.maxTurns)
|
|
75
|
+
args.push('--max-turns', String(this.options.maxTurns));
|
|
76
|
+
if (this.options.systemPrompt)
|
|
77
|
+
args.push('--system-prompt-override', this.options.systemPrompt);
|
|
78
|
+
return args;
|
|
79
|
+
}
|
|
80
|
+
_run(message, options) {
|
|
81
|
+
// Read-only is refused rather than approximated. grok exposes --permission-mode
|
|
82
|
+
// plan and --deny rules, but plan mode alone is model-cooperative — the same
|
|
83
|
+
// shape that let an adversarial prompt write through Cursor's plan mode — and
|
|
84
|
+
// the deny rules have not been put through the write × shell × subagent ×
|
|
85
|
+
// resumed-turn matrix this project requires before a read-only claim. Failing
|
|
86
|
+
// loudly beats a session that believes it cannot write and can.
|
|
87
|
+
if (this.options.sandboxMode === 'read-only') {
|
|
88
|
+
return Promise.reject(new Error('Grok sessions do not support sandboxMode: read-only yet — its enforcement has not been ' +
|
|
89
|
+
'adversarially verified, and this engine will not claim a boundary it has not proven. ' +
|
|
90
|
+
'Use a different engine for read-only work.'));
|
|
91
|
+
}
|
|
92
|
+
const args = this._buildArgs(message, options);
|
|
93
|
+
const timeout = options.timeout || 300_000;
|
|
94
|
+
return new Promise((resolve, reject) => {
|
|
95
|
+
let stdout = '';
|
|
96
|
+
let stderr = '';
|
|
97
|
+
let settled = false;
|
|
98
|
+
const proc = spawn(this.engineBin, args, {
|
|
99
|
+
cwd: this.options.cwd,
|
|
100
|
+
env: { ...process.env },
|
|
101
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
102
|
+
});
|
|
103
|
+
this.currentProc = proc;
|
|
104
|
+
proc.stdin?.end();
|
|
105
|
+
const timer = setTimeout(() => {
|
|
106
|
+
if (!settled) {
|
|
107
|
+
settled = true;
|
|
108
|
+
proc.kill('SIGKILL');
|
|
109
|
+
reject(new Error('Timeout waiting for Grok response'));
|
|
110
|
+
}
|
|
111
|
+
}, timeout);
|
|
112
|
+
proc.stdout?.on('data', (d) => {
|
|
113
|
+
stdout += d.toString();
|
|
114
|
+
});
|
|
115
|
+
proc.stderr?.on('data', (d) => {
|
|
116
|
+
const sanitized = sanitizeSecrets(d.toString());
|
|
117
|
+
stderr += sanitized;
|
|
118
|
+
this.emit(SESSION_EVENT.LOG, `[grok-stderr] ${sanitized}`);
|
|
119
|
+
});
|
|
120
|
+
proc.on('error', (err) => {
|
|
121
|
+
clearTimeout(timer);
|
|
122
|
+
this.currentProc = null;
|
|
123
|
+
if (!settled) {
|
|
124
|
+
settled = true;
|
|
125
|
+
reject(err);
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
proc.on('close', (code) => {
|
|
129
|
+
clearTimeout(timer);
|
|
130
|
+
this.currentProc = null;
|
|
131
|
+
if (settled)
|
|
132
|
+
return;
|
|
133
|
+
settled = true;
|
|
134
|
+
let parsed;
|
|
135
|
+
try {
|
|
136
|
+
const trimmed = stdout.trim();
|
|
137
|
+
if (trimmed)
|
|
138
|
+
parsed = JSON.parse(trimmed);
|
|
139
|
+
}
|
|
140
|
+
catch {
|
|
141
|
+
parsed = undefined;
|
|
142
|
+
}
|
|
143
|
+
// A turn that produced no parseable result object failed, whatever the
|
|
144
|
+
// exit code says: there is no reply to hand back.
|
|
145
|
+
const turnError = parsed?.error?.trim() ||
|
|
146
|
+
(!parsed ? stderr.trim() || `Grok exited with code ${code} and no JSON result` : undefined);
|
|
147
|
+
if (parsed?.sessionId) {
|
|
148
|
+
this.grokSessionId = parsed.sessionId;
|
|
149
|
+
if (!this.sessionId?.startsWith('grok-live-'))
|
|
150
|
+
this.sessionId = `grok-live-${parsed.sessionId}`;
|
|
151
|
+
}
|
|
152
|
+
const text = parsed?.text ?? '';
|
|
153
|
+
const ok = !turnError && code === 0 && parsed?.stopReason !== 'error';
|
|
154
|
+
this._recordTurnComplete(ok);
|
|
155
|
+
const usage = parsed?.usage;
|
|
156
|
+
if (usage) {
|
|
157
|
+
// Per-turn values (see the file header), so accumulate.
|
|
158
|
+
this._stats.tokensIn += usage.input_tokens ?? 0;
|
|
159
|
+
this._stats.tokensOut += usage.output_tokens ?? 0;
|
|
160
|
+
this._stats.cachedTokens += usage.cache_read_input_tokens ?? 0;
|
|
161
|
+
this._reportTurnInputTokens(usage.input_tokens ?? 0);
|
|
162
|
+
}
|
|
163
|
+
// Engine-reported spend, not a registry lookup — see the file header.
|
|
164
|
+
if (typeof parsed?.total_cost_usd === 'number' && Number.isFinite(parsed.total_cost_usd)) {
|
|
165
|
+
this._stats.costUsd += parsed.total_cost_usd;
|
|
166
|
+
}
|
|
167
|
+
this._addHistory({ text, code });
|
|
168
|
+
if (text) {
|
|
169
|
+
try {
|
|
170
|
+
options.callbacks?.onText?.(text);
|
|
171
|
+
}
|
|
172
|
+
catch {
|
|
173
|
+
/* user callback */
|
|
174
|
+
}
|
|
175
|
+
this.emit(SESSION_EVENT.TEXT, text);
|
|
176
|
+
}
|
|
177
|
+
const event = {
|
|
178
|
+
type: 'result',
|
|
179
|
+
result: text,
|
|
180
|
+
stop_reason: ok ? 'end_turn' : 'error',
|
|
181
|
+
session_id: this.grokSessionId,
|
|
182
|
+
};
|
|
183
|
+
this.emit(SESSION_EVENT.RESULT, event);
|
|
184
|
+
this.emit(SESSION_EVENT.TURN_COMPLETE, event);
|
|
185
|
+
if (turnError)
|
|
186
|
+
reject(new Error(turnError));
|
|
187
|
+
else
|
|
188
|
+
resolve({ text, event });
|
|
189
|
+
});
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
/** Grok's resumable session id, surfaced through getStats(). */
|
|
193
|
+
getStats() {
|
|
194
|
+
return { ...super.getStats(), grokSessionId: this.grokSessionId };
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
//# sourceMappingURL=persistent-grok-session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"persistent-grok-session.js","sourceRoot":"","sources":["../../src/persistent-grok-session.ts"],"names":[],"mappings":"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"}
|
|
@@ -112,6 +112,7 @@ import { PersistentGeminiSession } from './persistent-gemini-session.js';
|
|
|
112
112
|
import { PersistentCodexSession } from './persistent-codex-session.js';
|
|
113
113
|
import { PersistentCodexAppServerSession } from './persistent-codex-app-session.js';
|
|
114
114
|
import { PersistentCursorSession } from './persistent-cursor-session.js';
|
|
115
|
+
import { PersistentGrokSession } from './persistent-grok-session.js';
|
|
115
116
|
import { PersistentOpencodeSession } from './persistent-opencode-session.js';
|
|
116
117
|
import { PersistentAgySession } from './persistent-agy-session.js';
|
|
117
118
|
import { PersistentCustomSession } from './persistent-custom-session.js';
|
|
@@ -1862,6 +1863,8 @@ export class SessionManager {
|
|
|
1862
1863
|
return isAgyConversationId(id) ? id : undefined;
|
|
1863
1864
|
if (engine === 'codex')
|
|
1864
1865
|
return id && !/^codex-\d+-/.test(id) ? id : undefined;
|
|
1866
|
+
if (engine === 'grok')
|
|
1867
|
+
return id && !/^grok-\d+-/.test(id) ? id : undefined;
|
|
1865
1868
|
return id;
|
|
1866
1869
|
}
|
|
1867
1870
|
_listMdFiles(dir) {
|
|
@@ -1888,6 +1891,8 @@ export class SessionManager {
|
|
|
1888
1891
|
return new PersistentCodexAppServerSession(config, process.env.CODEX_BIN);
|
|
1889
1892
|
case 'cursor':
|
|
1890
1893
|
return new PersistentCursorSession(config, process.env.CURSOR_BIN);
|
|
1894
|
+
case 'grok':
|
|
1895
|
+
return new PersistentGrokSession(config, process.env.GROK_BIN);
|
|
1891
1896
|
case 'opencode':
|
|
1892
1897
|
return new PersistentOpencodeSession(config, process.env.OPENCODE_BIN);
|
|
1893
1898
|
case 'custom':
|