@livx.cc/agentx 0.99.110 → 0.99.112
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/cli.d.ts +6 -2
- package/dist/cli.js +93 -24
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +34 -11
- package/dist/index.js.map +1 -1
- package/dist/{secondChannel-3IPP3Qgh.d.ts → secondChannel-CJMY5EbL.d.ts} +6 -0
- package/package.json +2 -2
package/dist/cli.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
|
-
import { o as RouterState, H as Hooks, p as RunResult, R as ReasoningEffort, C as ChannelMode, A as Agent } from './secondChannel-
|
|
2
|
+
import { o as RouterState, H as Hooks, p as RunResult, R as ReasoningEffort, C as ChannelMode, A as Agent } from './secondChannel-CJMY5EbL.js';
|
|
3
3
|
import { IFilesystem } from '@livx.cc/wcli/core';
|
|
4
4
|
import { M as Message, U as UserQuestion, H as HostBridge, c as ContentPart, o as MessageContent } from './tools-DZHZIyxh.js';
|
|
5
5
|
|
|
@@ -375,5 +375,9 @@ declare function runTurn(agent: Agent, store: SessionStore, session: SessionData
|
|
|
375
375
|
}>;
|
|
376
376
|
/** A failed duplex turn's cause, for the host to show: the provider's message, and for a missing key what to set. */
|
|
377
377
|
declare function duplexError(e: unknown, reflexModel: string): string;
|
|
378
|
+
/** --keep-alive {type:'rollback'}: take back the turn that began at transcript index `start` — its user line, steers and
|
|
379
|
+
* (partial) reply leave this session and, on claude-code/*, Claude Code's own history too (rewindClaudeCodeSession) — so
|
|
380
|
+
* the next turn (a re-final's fuller text) runs warm, as if that one was never sent. Returns the messages dropped. */
|
|
381
|
+
declare function rollbackTurn(agent: Agent, store: Pick<SessionStore, 'save'>, session: SessionData, start: number): Promise<number>;
|
|
378
382
|
|
|
379
|
-
export { type PermMode, abortActiveTurn, apiKeysFromEnv, appendMemoryNote, cacheMultipliers, condenseReplay, costOf, duplexError, duplexModels, estimateTranscriptTokens, expandMentions, exportMarkdown, fmtUsd, formatHistory, formatStatus, formatTranscriptFull, jsonResult, loadBodifySecrets, loadInstallEnv, makeHost, mcpMentionResolver, mentionRefs, modelUsable, parseArgs, pastePathClassifier, readImageParts, readMultiline, resolvePermMode, runShellLine, runTurn, setMcpMentionResolver, summarizeResult, turnCost };
|
|
383
|
+
export { type PermMode, abortActiveTurn, apiKeysFromEnv, appendMemoryNote, cacheMultipliers, condenseReplay, costOf, duplexError, duplexModels, estimateTranscriptTokens, expandMentions, exportMarkdown, fmtUsd, formatHistory, formatStatus, formatTranscriptFull, jsonResult, loadBodifySecrets, loadInstallEnv, makeHost, mcpMentionResolver, mentionRefs, modelUsable, parseArgs, pastePathClassifier, readImageParts, readMultiline, resolvePermMode, rollbackTurn, runShellLine, runTurn, setMcpMentionResolver, summarizeResult, turnCost };
|
package/dist/cli.js
CHANGED
|
@@ -3432,7 +3432,7 @@ function copyTextToClipboard(text, platform2 = process.platform) {
|
|
|
3432
3432
|
|
|
3433
3433
|
// cli/cli.ts
|
|
3434
3434
|
import { join as join16, resolve as resolve5, basename as basename4, extname, dirname as dirname6 } from "path";
|
|
3435
|
-
import { AIClient as AIClient2, listModels, listProviders, getProviderFromModel, getModelInfo, resolveModel, isModelSupported, disposeCursorSessions, disposeClaudeCodeSessions } from "ai.libx.js";
|
|
3435
|
+
import { AIClient as AIClient2, listModels, listProviders, getProviderFromModel, getModelInfo, resolveModel, isModelSupported, disposeCursorSessions, disposeClaudeCodeSessions, rewindClaudeCodeSession } from "ai.libx.js";
|
|
3436
3436
|
|
|
3437
3437
|
// src/ccBridge.ts
|
|
3438
3438
|
var CC_BRIDGED = /* @__PURE__ */ new Set(["Recall", "Remember", "MemorySearch", "Forget"]);
|
|
@@ -5022,6 +5022,39 @@ var Agent = class _Agent {
|
|
|
5022
5022
|
* steers over its own channel (claude-code's warm InputQueue via `providerOptions.steer`). Non-text
|
|
5023
5023
|
* injections (images) stay queued for the step-boundary `drainInjections()` re-open — the text-only
|
|
5024
5024
|
* steer channel can't carry them. Consumed DURING chat(); no overlap with drainInjections() (post-call). */
|
|
5025
|
+
/** claude-code/*: the providerOptions every step adds (and prewarm, so the session it starts is the one step 1 reuses). */
|
|
5026
|
+
claudeCodePo() {
|
|
5027
|
+
const o = this.options;
|
|
5028
|
+
if (!o.model.startsWith("claude-code/")) return void 0;
|
|
5029
|
+
const po = { steer: () => this.drainPendingSteers() };
|
|
5030
|
+
const bridged = (t) => o.ccBridge === "all" || CC_BRIDGED.has(t.name);
|
|
5031
|
+
if (o.providerOptions?.claudeCodeSession && this.activeTools.some(bridged)) {
|
|
5032
|
+
this.ccServer ??= ccToolServer("agentx", () => this.activeTools.filter(bridged), (n, a) => this.ccExec(n, a));
|
|
5033
|
+
po.mcpServers = { ...o.providerOptions?.mcpServers, agentx: this.ccServer };
|
|
5034
|
+
}
|
|
5035
|
+
const denyTools = claudeCodeDisallowedTools(o.permissions);
|
|
5036
|
+
if (denyTools.length) {
|
|
5037
|
+
const prior = o.providerOptions?.disallowedTools ?? [];
|
|
5038
|
+
po.disallowedTools = [.../* @__PURE__ */ new Set([...prior, ...denyTools])];
|
|
5039
|
+
}
|
|
5040
|
+
return po;
|
|
5041
|
+
}
|
|
5042
|
+
/** claude-code/* warm session: start it now (its process, MCP handshakes) so the first turn doesn't pay for it. Its
|
|
5043
|
+
* system prompt is fixed at the start, so it is prepared here (no task hint) — memoized, the turns reuse the same one.
|
|
5044
|
+
* No model call; the transcript gains only that system message. Other models: nothing to warm. */
|
|
5045
|
+
async prewarm() {
|
|
5046
|
+
const o = this.options;
|
|
5047
|
+
if (!o.model.startsWith("claude-code/") || !o.providerOptions?.claudeCodeSession) return;
|
|
5048
|
+
await this.ensureFs();
|
|
5049
|
+
const systemPrompt = await this.prepare(), startCtx = await this.fireSessionStart();
|
|
5050
|
+
const sys = { role: "system", content: systemPrompt + (startCtx ? "\n\n" + startCtx : "") };
|
|
5051
|
+
if (this.transcript[0]?.role === "system") this.transcript[0] = sys;
|
|
5052
|
+
else this.transcript.unshift(sys);
|
|
5053
|
+
const po = this.claudeCodePo(), frag = reasoningToChatFragment(o.model, o.reasoning);
|
|
5054
|
+
const r = await o.ai.chat({ model: o.model, messages: this.trimContext(), tools: [], stream: true, ...frag, ...o.promptCache ? { promptCache: true } : {}, providerOptions: { ...frag.providerOptions, ...o.providerOptions, ...po, prewarm: true } });
|
|
5055
|
+
for await (const _ of r) {
|
|
5056
|
+
}
|
|
5057
|
+
}
|
|
5025
5058
|
drainPendingSteers() {
|
|
5026
5059
|
if (!this.pendingInjections.length) return [];
|
|
5027
5060
|
const texts = [];
|
|
@@ -5314,18 +5347,8 @@ var Agent = class _Agent {
|
|
|
5314
5347
|
}
|
|
5315
5348
|
};
|
|
5316
5349
|
const cursorPo = isCursorWithTools ? { toolTimeoutMs: effectiveToolTimeoutMs, toolExecutor: hostExec } : void 0;
|
|
5317
|
-
const claudeSteerPo =
|
|
5318
|
-
const bridged = (t) => o.ccBridge === "all" || CC_BRIDGED.has(t.name);
|
|
5319
|
-
if (claudeSteerPo && o.providerOptions?.claudeCodeSession && this.activeTools.some(bridged)) {
|
|
5320
|
-
this.ccServer ??= ccToolServer("agentx", () => this.activeTools.filter(bridged), (n, a) => this.ccExec(n, a));
|
|
5321
|
-
claudeSteerPo.mcpServers = { ...o.providerOptions?.mcpServers, agentx: this.ccServer };
|
|
5322
|
-
}
|
|
5350
|
+
const claudeSteerPo = this.claudeCodePo();
|
|
5323
5351
|
if (this.ccServer) this.ccExec = hostExec;
|
|
5324
|
-
const denyTools = o.model.startsWith("claude-code/") ? claudeCodeDisallowedTools(o.permissions) : [];
|
|
5325
|
-
if (denyTools.length) {
|
|
5326
|
-
const prior = o.providerOptions?.disallowedTools ?? [];
|
|
5327
|
-
claudeSteerPo.disallowedTools = [.../* @__PURE__ */ new Set([...prior, ...denyTools])];
|
|
5328
|
-
}
|
|
5329
5352
|
const cursorDeny = o.model.startsWith("cursor/") ? o.permissions?.denyRules(true) ?? [] : [];
|
|
5330
5353
|
if (cursorDeny.length)
|
|
5331
5354
|
throw new Error(`cursor/* cannot enforce --disallowedTools (${cursorDeny.join(", ")}): its native tools bypass them. Refusing to run \u2014 use a claude-code/* or API model, or drop --disallowedTools.`);
|
|
@@ -18837,7 +18860,10 @@ Flags:
|
|
|
18837
18860
|
(unconsumed steers come back as the result's \`unsteered\`)
|
|
18838
18861
|
--keep-alive with -p --input-format stream-json: stay up after a turn \u2014 each {"type":"user"} line while idle
|
|
18839
18862
|
is the NEXT turn (warm: same session, model connection and MCP servers), one {type:result}
|
|
18840
|
-
per turn;
|
|
18863
|
+
per turn; it boots (and warms a claude-code/* session) before the first line arrives;
|
|
18864
|
+
{"type":"abort"} stops the running turn (the next one is still warm); {"type":"rollback"}
|
|
18865
|
+
takes the last turn back (stopping it if running) \u2014 its user line and reply leave the
|
|
18866
|
+
session, Claude Code's own history included; stdin EOF exits
|
|
18841
18867
|
--output-format <f> headless output: text (default) | json (one result object) | stream-json (NDJSON events: {type:text|thinking}\u2026 then {type:result})
|
|
18842
18868
|
-v, --version print version and exit
|
|
18843
18869
|
-h, --help
|
|
@@ -22574,10 +22600,14 @@ async function channelServe(args, ai, cfg) {
|
|
|
22574
22600
|
sendTurn: (text, o) => out({ type: "turn", id: o.id, text, ...o.replaces ? { replaces: o.replaces } : {} }),
|
|
22575
22601
|
abortTurn: (id) => out({ type: "abort", id }),
|
|
22576
22602
|
onMetric: (m) => {
|
|
22577
|
-
if (m.name
|
|
22603
|
+
if (m.name !== "lang") out({ type: "metric", ...m });
|
|
22578
22604
|
}
|
|
22605
|
+
// (turn + fill too: the host's log shows which turns formed and which fill lines played)
|
|
22606
|
+
});
|
|
22607
|
+
const overlap2 = overlapResponder(ai, args.channelMode, (o) => {
|
|
22608
|
+
if (o.verdict === "cut") call.barge();
|
|
22609
|
+
out(o);
|
|
22579
22610
|
});
|
|
22580
|
-
const overlap2 = overlapResponder(ai, args.channelMode, out);
|
|
22581
22611
|
out({ type: "ready", model, channelMode: args.channelMode, softBarge: softBarge(args.channelMode), call: true, ...notes.length ? { notes } : {} });
|
|
22582
22612
|
const rl = createInterface({ input: process.stdin });
|
|
22583
22613
|
rl.on("line", (line) => {
|
|
@@ -22604,7 +22634,7 @@ async function channelServe(args, ai, cfg) {
|
|
|
22604
22634
|
}
|
|
22605
22635
|
function readStdinSteers(keepAlive = false) {
|
|
22606
22636
|
const early = [];
|
|
22607
|
-
let sink, got, closed = false;
|
|
22637
|
+
let sink, got, closed = false, started = false;
|
|
22608
22638
|
const first = new Promise((res) => {
|
|
22609
22639
|
got = res;
|
|
22610
22640
|
});
|
|
@@ -22620,7 +22650,17 @@ function readStdinSteers(keepAlive = false) {
|
|
|
22620
22650
|
activeTurn?.abort();
|
|
22621
22651
|
return;
|
|
22622
22652
|
}
|
|
22653
|
+
if (keepAlive && m?.type === "rollback") {
|
|
22654
|
+
if (!started) return;
|
|
22655
|
+
activeTurn?.abort();
|
|
22656
|
+
if (got) {
|
|
22657
|
+
got({ type: "rollback" });
|
|
22658
|
+
got = void 0;
|
|
22659
|
+
} else early.push({ type: "rollback" });
|
|
22660
|
+
return;
|
|
22661
|
+
}
|
|
22623
22662
|
if (m?.type !== "user" || typeof m.text !== "string" || !m.text.trim()) return;
|
|
22663
|
+
started = true;
|
|
22624
22664
|
if (got) {
|
|
22625
22665
|
got(m.text);
|
|
22626
22666
|
got = void 0;
|
|
@@ -22640,9 +22680,21 @@ function readStdinSteers(keepAlive = false) {
|
|
|
22640
22680
|
};
|
|
22641
22681
|
return { first, steer: (to) => {
|
|
22642
22682
|
sink = to;
|
|
22643
|
-
early
|
|
22683
|
+
while (typeof early[0] === "string") to(early.shift());
|
|
22644
22684
|
}, next };
|
|
22645
22685
|
}
|
|
22686
|
+
async function rollbackTurn(agent, store, session, start) {
|
|
22687
|
+
if (start < 0 || start > agent.transcript.length) return 0;
|
|
22688
|
+
const dropped = agent.transcript.length - start;
|
|
22689
|
+
agent.transcript.splice(start);
|
|
22690
|
+
session.messages = agent.transcript;
|
|
22691
|
+
session.meta.updated = Date.now();
|
|
22692
|
+
session.meta.cc = void 0;
|
|
22693
|
+
const cc = agent.options.providerOptions?.claudeCodeSession;
|
|
22694
|
+
if (typeof cc === "string" && agent.options.model.startsWith("claude-code/")) await rewindClaudeCodeSession(cc);
|
|
22695
|
+
store.save(session);
|
|
22696
|
+
return dropped;
|
|
22697
|
+
}
|
|
22646
22698
|
function readAllStdin() {
|
|
22647
22699
|
return new Promise((res) => {
|
|
22648
22700
|
let data = "";
|
|
@@ -22677,9 +22729,11 @@ async function main() {
|
|
|
22677
22729
|
}
|
|
22678
22730
|
if (args.debug) process.env.DEBUG ||= "*";
|
|
22679
22731
|
const steers = args.print && args.inputFormat && !args.task ? readStdinSteers(args.keepAlive) : void 0;
|
|
22680
|
-
|
|
22681
|
-
|
|
22682
|
-
if (
|
|
22732
|
+
const warmBoot = !!(steers && args.keepAlive);
|
|
22733
|
+
if (steers && !warmBoot) args.task = (await steers.first).trim();
|
|
22734
|
+
else if (warmBoot) {
|
|
22735
|
+
} else if (args.print && !args.task && !process.stdin.isTTY) args.task = (await readAllStdin()).trim();
|
|
22736
|
+
if (args.print && !args.task && !warmBoot) {
|
|
22683
22737
|
console.error(red(" -p: empty prompt (no task argument and nothing on stdin)"));
|
|
22684
22738
|
process.exit(2);
|
|
22685
22739
|
}
|
|
@@ -22746,8 +22800,8 @@ async function main() {
|
|
|
22746
22800
|
}
|
|
22747
22801
|
}
|
|
22748
22802
|
});
|
|
22749
|
-
if (args.task) {
|
|
22750
|
-
const compactArg = /^\/compact(?:\s+([\s\S]*))?$/.exec(args.task.trim());
|
|
22803
|
+
if (args.task || warmBoot) {
|
|
22804
|
+
const compactArg = /^\/compact(?:\s+([\s\S]*))?$/.exec((args.task ?? "").trim());
|
|
22751
22805
|
if (compactArg) {
|
|
22752
22806
|
const agent2 = await makeAgent(args, ai, cfg, [], []), store2 = new SessionStore(cwd), session2 = startSession(args, store2, agent2, cwd);
|
|
22753
22807
|
const est = (m) => estimateTranscriptTokens(m, agent2.options.keepRecentImages, agent2.options.imageInput?.(agent2.options.model) !== false);
|
|
@@ -22770,8 +22824,22 @@ async function main() {
|
|
|
22770
22824
|
process.once("SIGINT", () => activeTurn?.abort());
|
|
22771
22825
|
steers?.steer((text) => agent.inject(text));
|
|
22772
22826
|
const turn = (task) => runTurn(agent, store, session, task, void 0, cwd, autoRouteSend(args, agent, () => session, (m) => providerOptionsFor(m, cwd, cfg.mcpServers, mounted.map((x) => x.name))));
|
|
22773
|
-
if (
|
|
22774
|
-
|
|
22827
|
+
if (warmBoot && steers) {
|
|
22828
|
+
bindClaudeCodeSession(agent, session);
|
|
22829
|
+
await agent.prewarm().catch((e) => err(dim(` (prewarm failed: ${e?.message ?? e})
|
|
22830
|
+
`)));
|
|
22831
|
+
let start = -1;
|
|
22832
|
+
for (let line = await steers.first; ; line = await steers.next()) {
|
|
22833
|
+
if (typeof line !== "string") {
|
|
22834
|
+
const n = await rollbackTurn(agent, store, session, start);
|
|
22835
|
+
start = -1;
|
|
22836
|
+
err(dim(` \u21B6 rolled back the last turn (${n} message${n === 1 ? "" : "s"})
|
|
22837
|
+
`));
|
|
22838
|
+
continue;
|
|
22839
|
+
}
|
|
22840
|
+
const task = line.trim();
|
|
22841
|
+
if (!task) break;
|
|
22842
|
+
start = agent.transcript.length;
|
|
22775
22843
|
steers.steer((text) => agent.inject(text));
|
|
22776
22844
|
const { res: res2 } = await turn(task);
|
|
22777
22845
|
const left = agent.drainPendingSteers();
|
|
@@ -22841,6 +22909,7 @@ export {
|
|
|
22841
22909
|
readImageParts,
|
|
22842
22910
|
readMultiline,
|
|
22843
22911
|
resolvePermMode,
|
|
22912
|
+
rollbackTurn,
|
|
22844
22913
|
runShellLine,
|
|
22845
22914
|
runTurn,
|
|
22846
22915
|
setMcpMentionResolver,
|