@dimi-agent/cli 0.6.1 → 0.6.3
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/main.mjs +232 -93
- package/package.json +3 -3
package/dist/main.mjs
CHANGED
|
@@ -224811,17 +224811,22 @@ var init_sdk_rpc_client = __esmMin((() => {
|
|
|
224811
224811
|
}
|
|
224812
224812
|
/**
|
|
224813
224813
|
* Build one canonical v2 resume snapshot from the live restored scopes.
|
|
224814
|
-
* Replay is the
|
|
224815
|
-
*
|
|
224814
|
+
* Replay is the full message history folded from the agent's wire journal —
|
|
224815
|
+
* NOT the live context memory, which after a compaction collapses into
|
|
224816
|
+
* `[...keptUserMessages, compaction_summary]` and would lose the compacted
|
|
224817
|
+
* prefix. `context` keeps the folded (live) context for token accounting;
|
|
224818
|
+
* task and todo state come from their owning services instead of a second
|
|
224819
|
+
* pass over the wire journal.
|
|
224816
224820
|
*/
|
|
224817
224821
|
async resumedAgentState(session, agent, type, replayTurnLimit) {
|
|
224818
224822
|
const facade = this.klient.session(session.id).agent(agent.id);
|
|
224819
224823
|
const ctx = session.accessor.get(ISessionContext);
|
|
224820
|
-
const [context, plan, usage, tasks] = await Promise.all([
|
|
224824
|
+
const [context, plan, usage, tasks, replay] = await Promise.all([
|
|
224821
224825
|
facade.getContext(),
|
|
224822
224826
|
facade.getPlan(),
|
|
224823
224827
|
facade.getUsage(),
|
|
224824
|
-
facade.getTasks({ activeOnly: false })
|
|
224828
|
+
facade.getTasks({ activeOnly: false }),
|
|
224829
|
+
this.buildReplayFromWire(agent)
|
|
224825
224830
|
]);
|
|
224826
224831
|
const profile = agent.accessor.get(IAgentProfileService).data();
|
|
224827
224832
|
return {
|
|
@@ -224835,11 +224840,7 @@ var init_sdk_rpc_client = __esmMin((() => {
|
|
|
224835
224840
|
systemPrompt: profile.systemPrompt
|
|
224836
224841
|
},
|
|
224837
224842
|
context,
|
|
224838
|
-
replay: limitAgentReplayByTurns(
|
|
224839
|
-
type: "message",
|
|
224840
|
-
message,
|
|
224841
|
-
time
|
|
224842
|
-
})), replayTurnLimit),
|
|
224843
|
+
replay: limitAgentReplayByTurns(replay, replayTurnLimit),
|
|
224843
224844
|
permission: {
|
|
224844
224845
|
mode: agent.accessor.get(IAgentPermissionModeService).mode,
|
|
224845
224846
|
rules: [...agent.accessor.get(IAgentPermissionRulesService).rules]
|
|
@@ -224853,6 +224854,63 @@ var init_sdk_rpc_client = __esmMin((() => {
|
|
|
224853
224854
|
};
|
|
224854
224855
|
}
|
|
224855
224856
|
/**
|
|
224857
|
+
* Fold the agent's full message history from its wire journal.
|
|
224858
|
+
*
|
|
224859
|
+
* The wire journal is the source of truth for message history: it keeps
|
|
224860
|
+
* every `context.append_message` / `context.append_loop_event` record, and
|
|
224861
|
+
* a `context.apply_compaction` record only marks a compaction point instead
|
|
224862
|
+
* of rewriting the past. Folding it yields the complete pre-compaction
|
|
224863
|
+
* history with a summary marker at each compaction, which is what replay
|
|
224864
|
+
* should render. The live context memory (`facade.getContext()`) is the
|
|
224865
|
+
* model's folded context and is deliberately NOT used here — it would hide
|
|
224866
|
+
* everything compacted away.
|
|
224867
|
+
*/
|
|
224868
|
+
async buildReplayFromWire(agent) {
|
|
224869
|
+
await agent.accessor.get(IWireService).flush();
|
|
224870
|
+
const scope = agent.accessor.get(IAgentScopeContext).scope();
|
|
224871
|
+
const reducer = createContextTranscriptReducer();
|
|
224872
|
+
const applyCompactionRecords = [];
|
|
224873
|
+
for await (const record of this.engineAccessor.get(IAppendLogStore).read(scope, AGENT_WIRE_RECORD_KEY)) {
|
|
224874
|
+
if (record.type === "context.apply_compaction") applyCompactionRecords.push(record);
|
|
224875
|
+
reducer.add(record);
|
|
224876
|
+
}
|
|
224877
|
+
const { entries, times } = reducer.result();
|
|
224878
|
+
const replay = [];
|
|
224879
|
+
let compactionIndex = 0;
|
|
224880
|
+
for (let i = 0; i < entries.length; i++) {
|
|
224881
|
+
const message = entries[i];
|
|
224882
|
+
const time = times[i];
|
|
224883
|
+
if (message.origin?.kind === "compaction_summary") {
|
|
224884
|
+
const record = applyCompactionRecords[compactionIndex];
|
|
224885
|
+
compactionIndex += 1;
|
|
224886
|
+
if (record !== void 0) {
|
|
224887
|
+
const compaction = readContextCompactionRecord(record);
|
|
224888
|
+
replay.push({
|
|
224889
|
+
type: "compaction",
|
|
224890
|
+
result: {
|
|
224891
|
+
summary: compaction.summary,
|
|
224892
|
+
contextSummary: compaction.contextSummary,
|
|
224893
|
+
compactedCount: compaction.compactedCount,
|
|
224894
|
+
tokensBefore: compaction.tokensBefore,
|
|
224895
|
+
tokensAfter: compaction.tokensAfter,
|
|
224896
|
+
keptUserMessageCount: compaction.keptUserMessageCount,
|
|
224897
|
+
keptHeadUserMessageCount: compaction.keptHeadUserMessageCount,
|
|
224898
|
+
droppedCount: compaction.droppedCount
|
|
224899
|
+
},
|
|
224900
|
+
time: time ?? 0
|
|
224901
|
+
});
|
|
224902
|
+
continue;
|
|
224903
|
+
}
|
|
224904
|
+
}
|
|
224905
|
+
replay.push({
|
|
224906
|
+
type: "message",
|
|
224907
|
+
message,
|
|
224908
|
+
time: time ?? 0
|
|
224909
|
+
});
|
|
224910
|
+
}
|
|
224911
|
+
return replay;
|
|
224912
|
+
}
|
|
224913
|
+
/**
|
|
224856
224914
|
* Every v2 workspace-id bucket addressing `workDir` (already normalized):
|
|
224857
224915
|
* the registered workspace's alias set when the catalog knows the root, or
|
|
224858
224916
|
* the freshly minted bucket key for index-only sessions (mirrors how v1's
|
|
@@ -378194,6 +378252,21 @@ var init_tool_call = __esmMin((() => {
|
|
|
378194
378252
|
get toolCallView() {
|
|
378195
378253
|
return this.toolCall;
|
|
378196
378254
|
}
|
|
378255
|
+
/**
|
|
378256
|
+
* Whether this call has reached a terminal state. Ordinary tools finish when
|
|
378257
|
+
* their result lands; agent and read cards derive their phase from events
|
|
378258
|
+
* (subagent lifecycle / read status), falling back to the result. Used by
|
|
378259
|
+
* transcript folding to avoid collapsing calls the user still needs to
|
|
378260
|
+
* watch (a running agent would otherwise disappear into the summary line).
|
|
378261
|
+
*/
|
|
378262
|
+
isFinished() {
|
|
378263
|
+
if (this.toolCall.name === "Agent" || this.toolCall.name === "AgentSwarm") {
|
|
378264
|
+
const phase = this.getSubagentSnapshot().phase;
|
|
378265
|
+
return phase === "done" || phase === "failed" || phase === "backgrounded";
|
|
378266
|
+
}
|
|
378267
|
+
if (this.toolCall.name === "Read") return this.getReadSnapshot().phase !== "pending";
|
|
378268
|
+
return this.result !== void 0;
|
|
378269
|
+
}
|
|
378197
378270
|
/** Notifies the listener when internal state changes, if a group is attached. */
|
|
378198
378271
|
notifySnapshotChange() {
|
|
378199
378272
|
this.onSnapshotChange?.();
|
|
@@ -386868,6 +386941,10 @@ var init_session_replay = __esmMin((() => {
|
|
|
386868
386941
|
return;
|
|
386869
386942
|
}
|
|
386870
386943
|
if (message.origin?.kind === "injection") return;
|
|
386944
|
+
if (message.origin?.kind === "compaction_summary") {
|
|
386945
|
+
this.renderCompactionSummary(context, message);
|
|
386946
|
+
return;
|
|
386947
|
+
}
|
|
386871
386948
|
if (message.origin?.kind === "task") {
|
|
386872
386949
|
this.flushAssistant(context);
|
|
386873
386950
|
const info = this.host.sessionEventHandler.backgroundTasks.get(message.origin.taskId);
|
|
@@ -387036,6 +387113,21 @@ var init_session_replay = __esmMin((() => {
|
|
|
387036
387113
|
}
|
|
387037
387114
|
});
|
|
387038
387115
|
}
|
|
387116
|
+
/**
|
|
387117
|
+
* Render a `compaction_summary` user message folded into the model context
|
|
387118
|
+
* (the resume snapshot's context history carries it after compaction). The
|
|
387119
|
+
* message text is the model-facing summary; token counts are unknown here,
|
|
387120
|
+
* so only the summary is surfaced. The snapshot is still rebuilt from the
|
|
387121
|
+
* wire journal on resume (see `resumedAgentState`), so this branch is a
|
|
387122
|
+
* fallback for snapshots that were built from a folded context.
|
|
387123
|
+
*/
|
|
387124
|
+
renderCompactionSummary(context, message) {
|
|
387125
|
+
this.flushAssistant(context);
|
|
387126
|
+
this.host.appendTranscriptEntry({
|
|
387127
|
+
...replayEntry(context, "status", "Compaction complete", "plain"),
|
|
387128
|
+
compactionData: { summary: contentPartsToText(message.content) }
|
|
387129
|
+
});
|
|
387130
|
+
}
|
|
387039
387131
|
renderHookResult(context, message) {
|
|
387040
387132
|
if (message.origin?.kind !== "hook_result") return;
|
|
387041
387133
|
this.flushAssistant(context);
|
|
@@ -387216,6 +387308,82 @@ var init_terminal_notification = __esmMin((() => {
|
|
|
387216
387308
|
init_terminal();
|
|
387217
387309
|
}));
|
|
387218
387310
|
//#endregion
|
|
387311
|
+
//#region src/tui/utils/transcript-window.ts
|
|
387312
|
+
/**
|
|
387313
|
+
* Read a non-negative integer env var, falling back to `fallback` when it is
|
|
387314
|
+
* unset, empty, negative, or not an integer. `0` is a valid value (call sites
|
|
387315
|
+
* treat it as "feature disabled").
|
|
387316
|
+
*/
|
|
387317
|
+
function readEnvInt(name, fallback) {
|
|
387318
|
+
const raw = process.env[name];
|
|
387319
|
+
if (raw === void 0 || raw.trim() === "") return fallback;
|
|
387320
|
+
const value = Number(raw);
|
|
387321
|
+
if (!Number.isInteger(value) || value < 0) return fallback;
|
|
387322
|
+
return value;
|
|
387323
|
+
}
|
|
387324
|
+
/**
|
|
387325
|
+
* Group consecutive entries into turns by `turnId`. Entries with the same
|
|
387326
|
+
* non-undefined `turnId` that are adjacent belong to the same turn.
|
|
387327
|
+
*
|
|
387328
|
+
* Entries with an undefined `turnId` are buffered and attached to the *next*
|
|
387329
|
+
* defined turn. This matters because a user message is appended (with
|
|
387330
|
+
* `turnId: undefined`) before its turn actually starts, so without this
|
|
387331
|
+
* buffering every user message would become its own single-entry turn at the
|
|
387332
|
+
* front and get trimmed first. Any undefined entries left at the tail (no
|
|
387333
|
+
* following turn) become their own turn.
|
|
387334
|
+
*/
|
|
387335
|
+
function groupTurns(entries) {
|
|
387336
|
+
const turns = [];
|
|
387337
|
+
let current;
|
|
387338
|
+
let pendingUndefined = [];
|
|
387339
|
+
for (const entry of entries) {
|
|
387340
|
+
const turnId = entry.turnId;
|
|
387341
|
+
if (turnId === void 0) {
|
|
387342
|
+
pendingUndefined.push(entry);
|
|
387343
|
+
continue;
|
|
387344
|
+
}
|
|
387345
|
+
if (current !== void 0 && current.turnId === turnId) current.entries.push(entry);
|
|
387346
|
+
else {
|
|
387347
|
+
current = {
|
|
387348
|
+
turnId,
|
|
387349
|
+
entries: [...pendingUndefined, entry]
|
|
387350
|
+
};
|
|
387351
|
+
pendingUndefined = [];
|
|
387352
|
+
turns.push(current);
|
|
387353
|
+
}
|
|
387354
|
+
}
|
|
387355
|
+
if (pendingUndefined.length > 0) turns.push({
|
|
387356
|
+
turnId: void 0,
|
|
387357
|
+
entries: pendingUndefined
|
|
387358
|
+
});
|
|
387359
|
+
return turns;
|
|
387360
|
+
}
|
|
387361
|
+
/**
|
|
387362
|
+
* Decide which entries to destroy so the remaining turns fit within
|
|
387363
|
+
* `maxTurns`. Returns an empty set when the turn count is within
|
|
387364
|
+
* `maxTurns + hysteresis`. Oldest turns are removed first; the most recent
|
|
387365
|
+
* turn is never removed (it is the active / just-finished turn).
|
|
387366
|
+
*/
|
|
387367
|
+
function turnsToTrim(turns, maxTurns, hysteresis) {
|
|
387368
|
+
const toRemove = /* @__PURE__ */ new Set();
|
|
387369
|
+
if (turns.length <= maxTurns + hysteresis) return toRemove;
|
|
387370
|
+
let remaining = turns.length;
|
|
387371
|
+
for (let i = 0; i < turns.length - 1 && remaining > maxTurns; i++) {
|
|
387372
|
+
const turn = turns[i];
|
|
387373
|
+
for (const entry of turn.entries) toRemove.add(entry);
|
|
387374
|
+
remaining--;
|
|
387375
|
+
}
|
|
387376
|
+
return toRemove;
|
|
387377
|
+
}
|
|
387378
|
+
var TRANSCRIPT_MAX_TURNS, TRANSCRIPT_EXPAND_TURNS, TRANSCRIPT_HYSTERESIS, TRANSCRIPT_KEEP_RECENT_STEPS, TRANSCRIPT_KEEP_TRAILING_TOOL_CALLS;
|
|
387379
|
+
var init_transcript_window = __esmMin((() => {
|
|
387380
|
+
TRANSCRIPT_MAX_TURNS = readEnvInt("DIMI_CODE_TUI_MAX_TURNS", 15);
|
|
387381
|
+
TRANSCRIPT_EXPAND_TURNS = readEnvInt("DIMI_CODE_TUI_EXPAND_TURNS", 3);
|
|
387382
|
+
TRANSCRIPT_HYSTERESIS = readEnvInt("DIMI_CODE_TUI_HYSTERESIS", 5);
|
|
387383
|
+
TRANSCRIPT_KEEP_RECENT_STEPS = readEnvInt("DIMI_CODE_TUI_KEEP_RECENT_STEPS", 30);
|
|
387384
|
+
TRANSCRIPT_KEEP_TRAILING_TOOL_CALLS = readEnvInt("DIMI_CODE_TUI_KEEP_TRAILING_TOOL_CALLS", 2);
|
|
387385
|
+
}));
|
|
387386
|
+
//#endregion
|
|
387219
387387
|
//#region src/tui/controllers/streaming-ui.ts
|
|
387220
387388
|
var StreamingUIController;
|
|
387221
387389
|
var init_streaming_ui = __esmMin((() => {
|
|
@@ -387231,6 +387399,7 @@ var init_streaming_ui = __esmMin((() => {
|
|
|
387231
387399
|
init_event_payload();
|
|
387232
387400
|
init_terminal_notification();
|
|
387233
387401
|
init_transcript_id();
|
|
387402
|
+
init_transcript_window();
|
|
387234
387403
|
StreamingUIController = class {
|
|
387235
387404
|
host;
|
|
387236
387405
|
flushTimer;
|
|
@@ -387714,6 +387883,7 @@ var init_streaming_ui = __esmMin((() => {
|
|
|
387714
387883
|
state.transcriptContainer.addChild(tc);
|
|
387715
387884
|
state.ui.requestRender();
|
|
387716
387885
|
}
|
|
387886
|
+
this.host.foldTrailingToolCalls(TRANSCRIPT_KEEP_TRAILING_TOOL_CALLS);
|
|
387717
387887
|
if (toolCall.name === "ExitPlanMode" && typeof toolCall.args["plan"] !== "string") {
|
|
387718
387888
|
const session = this.host.requireSession();
|
|
387719
387889
|
(async () => {
|
|
@@ -390462,81 +390632,6 @@ var init_tmux_keyboard = __esmMin((() => {
|
|
|
390462
390632
|
TMUX_EXTENDED_KEYS_FORMAT_XTERM_WARNING = "tmux extended-keys-format is xterm. Dimi works best with csi-u. Add `set -g extended-keys-format csi-u` to ~/.tmux.conf and restart tmux.";
|
|
390463
390633
|
}));
|
|
390464
390634
|
//#endregion
|
|
390465
|
-
//#region src/tui/utils/transcript-window.ts
|
|
390466
|
-
/**
|
|
390467
|
-
* Read a non-negative integer env var, falling back to `fallback` when it is
|
|
390468
|
-
* unset, empty, negative, or not an integer. `0` is a valid value (call sites
|
|
390469
|
-
* treat it as "feature disabled").
|
|
390470
|
-
*/
|
|
390471
|
-
function readEnvInt(name, fallback) {
|
|
390472
|
-
const raw = process.env[name];
|
|
390473
|
-
if (raw === void 0 || raw.trim() === "") return fallback;
|
|
390474
|
-
const value = Number(raw);
|
|
390475
|
-
if (!Number.isInteger(value) || value < 0) return fallback;
|
|
390476
|
-
return value;
|
|
390477
|
-
}
|
|
390478
|
-
/**
|
|
390479
|
-
* Group consecutive entries into turns by `turnId`. Entries with the same
|
|
390480
|
-
* non-undefined `turnId` that are adjacent belong to the same turn.
|
|
390481
|
-
*
|
|
390482
|
-
* Entries with an undefined `turnId` are buffered and attached to the *next*
|
|
390483
|
-
* defined turn. This matters because a user message is appended (with
|
|
390484
|
-
* `turnId: undefined`) before its turn actually starts, so without this
|
|
390485
|
-
* buffering every user message would become its own single-entry turn at the
|
|
390486
|
-
* front and get trimmed first. Any undefined entries left at the tail (no
|
|
390487
|
-
* following turn) become their own turn.
|
|
390488
|
-
*/
|
|
390489
|
-
function groupTurns(entries) {
|
|
390490
|
-
const turns = [];
|
|
390491
|
-
let current;
|
|
390492
|
-
let pendingUndefined = [];
|
|
390493
|
-
for (const entry of entries) {
|
|
390494
|
-
const turnId = entry.turnId;
|
|
390495
|
-
if (turnId === void 0) {
|
|
390496
|
-
pendingUndefined.push(entry);
|
|
390497
|
-
continue;
|
|
390498
|
-
}
|
|
390499
|
-
if (current !== void 0 && current.turnId === turnId) current.entries.push(entry);
|
|
390500
|
-
else {
|
|
390501
|
-
current = {
|
|
390502
|
-
turnId,
|
|
390503
|
-
entries: [...pendingUndefined, entry]
|
|
390504
|
-
};
|
|
390505
|
-
pendingUndefined = [];
|
|
390506
|
-
turns.push(current);
|
|
390507
|
-
}
|
|
390508
|
-
}
|
|
390509
|
-
if (pendingUndefined.length > 0) turns.push({
|
|
390510
|
-
turnId: void 0,
|
|
390511
|
-
entries: pendingUndefined
|
|
390512
|
-
});
|
|
390513
|
-
return turns;
|
|
390514
|
-
}
|
|
390515
|
-
/**
|
|
390516
|
-
* Decide which entries to destroy so the remaining turns fit within
|
|
390517
|
-
* `maxTurns`. Returns an empty set when the turn count is within
|
|
390518
|
-
* `maxTurns + hysteresis`. Oldest turns are removed first; the most recent
|
|
390519
|
-
* turn is never removed (it is the active / just-finished turn).
|
|
390520
|
-
*/
|
|
390521
|
-
function turnsToTrim(turns, maxTurns, hysteresis) {
|
|
390522
|
-
const toRemove = /* @__PURE__ */ new Set();
|
|
390523
|
-
if (turns.length <= maxTurns + hysteresis) return toRemove;
|
|
390524
|
-
let remaining = turns.length;
|
|
390525
|
-
for (let i = 0; i < turns.length - 1 && remaining > maxTurns; i++) {
|
|
390526
|
-
const turn = turns[i];
|
|
390527
|
-
for (const entry of turn.entries) toRemove.add(entry);
|
|
390528
|
-
remaining--;
|
|
390529
|
-
}
|
|
390530
|
-
return toRemove;
|
|
390531
|
-
}
|
|
390532
|
-
var TRANSCRIPT_MAX_TURNS, TRANSCRIPT_EXPAND_TURNS, TRANSCRIPT_HYSTERESIS, TRANSCRIPT_KEEP_RECENT_STEPS;
|
|
390533
|
-
var init_transcript_window = __esmMin((() => {
|
|
390534
|
-
TRANSCRIPT_MAX_TURNS = readEnvInt("DIMI_CODE_TUI_MAX_TURNS", 15);
|
|
390535
|
-
TRANSCRIPT_EXPAND_TURNS = readEnvInt("DIMI_CODE_TUI_EXPAND_TURNS", 3);
|
|
390536
|
-
TRANSCRIPT_HYSTERESIS = readEnvInt("DIMI_CODE_TUI_HYSTERESIS", 5);
|
|
390537
|
-
TRANSCRIPT_KEEP_RECENT_STEPS = readEnvInt("DIMI_CODE_TUI_KEEP_RECENT_STEPS", 30);
|
|
390538
|
-
}));
|
|
390539
|
-
//#endregion
|
|
390540
390635
|
//#region src/tui/dimi-tui.ts
|
|
390541
390636
|
function loadingTipKind(mode) {
|
|
390542
390637
|
if (mode === "waiting" || mode === "tool") return "moon";
|
|
@@ -391895,6 +391990,7 @@ var init_dimi_tui = __esmMin((() => {
|
|
|
391895
391990
|
markTranscriptComponent(component, entry);
|
|
391896
391991
|
this.state.transcriptContainer.addChild(component);
|
|
391897
391992
|
}
|
|
391993
|
+
if (entry.kind === "tool_call") this.foldTrailingToolCalls(TRANSCRIPT_KEEP_TRAILING_TOOL_CALLS);
|
|
391898
391994
|
const trimmed = this.trimTranscriptWindow();
|
|
391899
391995
|
const merged = this.mergeCurrentTurnSteps();
|
|
391900
391996
|
if (component || trimmed || merged) this.state.ui.requestRender();
|
|
@@ -391999,6 +392095,21 @@ var init_dimi_tui = __esmMin((() => {
|
|
|
391999
392095
|
return this.foldCurrentTurnSteps(TRANSCRIPT_KEEP_RECENT_STEPS);
|
|
392000
392096
|
}
|
|
392001
392097
|
collapseTrailingToolCalls() {
|
|
392098
|
+
this.foldTrailingToolCalls(0);
|
|
392099
|
+
}
|
|
392100
|
+
/**
|
|
392101
|
+
* Fold the trailing contiguous run of tool calls, keeping the most recent
|
|
392102
|
+
* `keepExpanded` calls expanded. `keepExpanded = 0` collapses the whole run
|
|
392103
|
+
* (used when visible content follows, e.g. an assistant message or turn
|
|
392104
|
+
* end); a positive cap folds progressively while the run is still growing
|
|
392105
|
+
* so older calls merge into the summary immediately instead of staying
|
|
392106
|
+
* expanded until the run ends.
|
|
392107
|
+
*
|
|
392108
|
+
* Only finished calls fold — a call that is still running (streaming args,
|
|
392109
|
+
* a live subagent, a pending read) stays visible because its progress is
|
|
392110
|
+
* live information the user is watching.
|
|
392111
|
+
*/
|
|
392112
|
+
foldTrailingToolCalls(keepExpanded) {
|
|
392002
392113
|
const children = this.state.transcriptContainer.children;
|
|
392003
392114
|
let start = children.length;
|
|
392004
392115
|
const toolCalls = [];
|
|
@@ -392020,21 +392131,49 @@ var init_dimi_tui = __esmMin((() => {
|
|
|
392020
392131
|
const standaloneNames = new Set(["AllDone", "WaitFor"]);
|
|
392021
392132
|
const standaloneCalls = new Set(toolCalls.filter((call) => standaloneNames.has(call.toolCallView.name)));
|
|
392022
392133
|
const sequenceCalls = toolCalls.filter((call) => !standaloneCalls.has(call));
|
|
392134
|
+
if (sequenceCalls.length === 0) return;
|
|
392135
|
+
const foldCount = sequenceCalls.length - keepExpanded;
|
|
392136
|
+
if (foldCount <= 0) return;
|
|
392023
392137
|
const components = children.slice(start);
|
|
392024
392138
|
const standalone = [];
|
|
392025
392139
|
const sequenceComponents = [];
|
|
392140
|
+
const keptComponents = [];
|
|
392141
|
+
let remainingToFold = foldCount;
|
|
392142
|
+
let stoppedAtUnfinished = false;
|
|
392026
392143
|
for (const component of components) {
|
|
392027
|
-
if (
|
|
392028
|
-
|
|
392029
|
-
component.clear();
|
|
392144
|
+
if (stoppedAtUnfinished) {
|
|
392145
|
+
keptComponents.push(component);
|
|
392030
392146
|
continue;
|
|
392031
392147
|
}
|
|
392032
|
-
if (component instanceof ToolCallComponent && standaloneCalls.has(component))
|
|
392033
|
-
|
|
392034
|
-
|
|
392035
|
-
|
|
392036
|
-
|
|
392037
|
-
|
|
392148
|
+
if (component instanceof ToolCallComponent && standaloneCalls.has(component)) {
|
|
392149
|
+
standalone.push(component);
|
|
392150
|
+
continue;
|
|
392151
|
+
}
|
|
392152
|
+
const calls = toolCallsIn(component);
|
|
392153
|
+
const callCount = calls?.filter((call) => !standaloneCalls.has(call)).length ?? 0;
|
|
392154
|
+
const hasUnfinished = calls?.some((call) => !call.isFinished()) ?? false;
|
|
392155
|
+
if (remainingToFold > 0 && hasUnfinished) {
|
|
392156
|
+
keptComponents.push(component);
|
|
392157
|
+
stoppedAtUnfinished = true;
|
|
392158
|
+
continue;
|
|
392159
|
+
}
|
|
392160
|
+
if (remainingToFold > 0) {
|
|
392161
|
+
if (component instanceof ToolCallSequenceComponent) {
|
|
392162
|
+
sequenceComponents.push(...component.children);
|
|
392163
|
+
component.clear();
|
|
392164
|
+
} else sequenceComponents.push(component);
|
|
392165
|
+
remainingToFold -= callCount;
|
|
392166
|
+
} else keptComponents.push(component);
|
|
392167
|
+
}
|
|
392168
|
+
if (sequenceComponents.length === 0) return;
|
|
392169
|
+
const foldedCalls = [];
|
|
392170
|
+
for (const component of sequenceComponents) {
|
|
392171
|
+
const componentCalls = toolCallsIn(component);
|
|
392172
|
+
if (componentCalls !== void 0) foldedCalls.push(...componentCalls.filter((call) => !standaloneCalls.has(call)));
|
|
392173
|
+
}
|
|
392174
|
+
if (foldedCalls.length === 0) return;
|
|
392175
|
+
const sequence = new ToolCallSequenceComponent(sequenceComponents, foldedCalls, this.state.toolDisplayMode);
|
|
392176
|
+
children.splice(start, components.length, sequence, ...standalone, ...keptComponents);
|
|
392038
392177
|
this.state.transcriptContainer.invalidate();
|
|
392039
392178
|
}
|
|
392040
392179
|
foldCurrentTurnSteps(keepSteps) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dimi-agent/cli",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.3",
|
|
4
4
|
"description": "The Starting Point for Next-Gen Agents",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"agent",
|
|
@@ -60,12 +60,12 @@
|
|
|
60
60
|
"tsx": "^4.21.0",
|
|
61
61
|
"yazl": "^3.3.1",
|
|
62
62
|
"zod": "^4.3.6",
|
|
63
|
-
"@dimi-agent/
|
|
63
|
+
"@dimi-agent/dimi-oauth": "^0.1.0",
|
|
64
64
|
"@dimi-agent/dimi-telemetry": "^0.1.0",
|
|
65
|
+
"@dimi-agent/agent-core-v2": "^0.1.0",
|
|
65
66
|
"@dimi-agent/dimi-sdk": "^0.2.0",
|
|
66
67
|
"@dimi-agent/dimi-web": "^0.1.0",
|
|
67
68
|
"@dimi-agent/kap-server": "^0.1.0",
|
|
68
|
-
"@dimi-agent/dimi-oauth": "^0.1.0",
|
|
69
69
|
"@dimi-agent/pi-tui": "^0.1.0",
|
|
70
70
|
"@dimi-agent/remote": "^0.1.0"
|
|
71
71
|
},
|