mastracode 0.26.0-alpha.5 → 0.26.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/CHANGELOG.md +133 -0
- package/dist/acp/agent.d.ts +4 -4
- package/dist/acp/agent.d.ts.map +1 -1
- package/dist/acp/event-mapper.d.ts +3 -3
- package/dist/acp/event-mapper.d.ts.map +1 -1
- package/dist/acp/server.d.ts +2 -2
- package/dist/acp/server.d.ts.map +1 -1
- package/dist/{acp-7DQDVR3M.js → acp-G5OLW7EV.js} +12 -12
- package/dist/acp-G5OLW7EV.js.map +1 -0
- package/dist/{acp-NTTZEFVN.cjs → acp-YSYEXVBE.cjs} +15 -15
- package/dist/acp-YSYEXVBE.cjs.map +1 -0
- package/dist/acp.cjs +2 -2
- package/dist/acp.js +1 -1
- package/dist/agents/instructions.d.ts.map +1 -1
- package/dist/agents/mastracode-gateway.d.ts +8 -1
- package/dist/agents/mastracode-gateway.d.ts.map +1 -1
- package/dist/agents/memory.d.ts +1 -1
- package/dist/agents/model.d.ts +1 -1
- package/dist/agents/modes/build.d.ts +2 -2
- package/dist/agents/modes/build.d.ts.map +1 -1
- package/dist/agents/modes/explore.d.ts +2 -2
- package/dist/agents/modes/explore.d.ts.map +1 -1
- package/dist/agents/modes/plan.d.ts +2 -2
- package/dist/agents/modes/plan.d.ts.map +1 -1
- package/dist/agents/prompts/plan.d.ts +5 -4
- package/dist/agents/prompts/plan.d.ts.map +1 -1
- package/dist/agents/thread-caveman-state.d.ts +2 -2
- package/dist/agents/thread-caveman-state.d.ts.map +1 -1
- package/dist/agents/tool-availability.d.ts +5 -1
- package/dist/agents/tool-availability.d.ts.map +1 -1
- package/dist/{chunk-QO4KIOLG.js → chunk-GT3A3LAA.js} +221 -117
- package/dist/chunk-GT3A3LAA.js.map +1 -0
- package/dist/{chunk-IU477VVQ.js → chunk-IFUIWWGJ.js} +8 -8
- package/dist/chunk-IFUIWWGJ.js.map +1 -0
- package/dist/{chunk-DVBJN36L.cjs → chunk-KGBCGF6C.cjs} +47 -23
- package/dist/chunk-KGBCGF6C.cjs.map +1 -0
- package/dist/{chunk-L67CU2OP.js → chunk-LUSQ75XP.js} +233 -136
- package/dist/chunk-LUSQ75XP.js.map +1 -0
- package/dist/{chunk-F3TKSK3C.js → chunk-NDCWIAKG.js} +43 -21
- package/dist/chunk-NDCWIAKG.js.map +1 -0
- package/dist/{chunk-UW25EMMX.cjs → chunk-NUKVNLFS.cjs} +1160 -1063
- package/dist/chunk-NUKVNLFS.cjs.map +1 -0
- package/dist/{chunk-DPRNPXVC.cjs → chunk-VBH3L4LD.cjs} +8 -8
- package/dist/chunk-VBH3L4LD.cjs.map +1 -0
- package/dist/{chunk-MUZ2ZLWN.cjs → chunk-Z3HFSXTB.cjs} +256 -152
- package/dist/chunk-Z3HFSXTB.cjs.map +1 -0
- package/dist/cli.cjs +33 -33
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +18 -18
- package/dist/cli.js.map +1 -1
- package/dist/evals/context-builder.d.ts +5 -5
- package/dist/evals/context-builder.d.ts.map +1 -1
- package/dist/headless.d.ts +3 -3
- package/dist/headless.d.ts.map +1 -1
- package/dist/index.cjs +10 -10
- package/dist/index.d.ts +36 -34
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/mcp/config.d.ts +6 -2
- package/dist/mcp/config.d.ts.map +1 -1
- package/dist/processors/plan-rejection-abort.d.ts.map +1 -1
- package/dist/tools/request-sandbox-access.d.ts.map +1 -1
- package/dist/tools/utils.d.ts +2 -2
- package/dist/tui/commands/api-keys.d.ts +15 -0
- package/dist/tui/commands/api-keys.d.ts.map +1 -1
- package/dist/tui/commands/clone.d.ts +1 -1
- package/dist/tui/commands/goal.d.ts +2 -2
- package/dist/tui/commands/goal.d.ts.map +1 -1
- package/dist/tui/commands/types.d.ts +3 -3
- package/dist/tui/commands/types.d.ts.map +1 -1
- package/dist/tui/components/assistant-message.d.ts +3 -3
- package/dist/tui/components/assistant-message.d.ts.map +1 -1
- package/dist/tui/components/help-overlay.d.ts +1 -1
- package/dist/tui/components/help-overlay.d.ts.map +1 -1
- package/dist/tui/components/login-selector.d.ts +1 -1
- package/dist/tui/components/om-progress.d.ts +2 -2
- package/dist/tui/components/om-progress.d.ts.map +1 -1
- package/dist/tui/components/plan-approval-inline.d.ts.map +1 -1
- package/dist/tui/components/task-progress.d.ts +1 -1
- package/dist/tui/components/thread-selector.d.ts +4 -4
- package/dist/tui/components/thread-selector.d.ts.map +1 -1
- package/dist/tui/event-dispatch.d.ts +3 -3
- package/dist/tui/event-dispatch.d.ts.map +1 -1
- package/dist/tui/handlers/agent-lifecycle.d.ts +1 -1
- package/dist/tui/handlers/agent-lifecycle.d.ts.map +1 -1
- package/dist/tui/handlers/message.d.ts +4 -4
- package/dist/tui/handlers/message.d.ts.map +1 -1
- package/dist/tui/handlers/prompts.d.ts +1 -1
- package/dist/tui/handlers/prompts.d.ts.map +1 -1
- package/dist/tui/handlers/types.d.ts +3 -2
- package/dist/tui/handlers/types.d.ts.map +1 -1
- package/dist/tui/mastra-tui.d.ts +3 -3
- package/dist/tui/mastra-tui.d.ts.map +1 -1
- package/dist/tui/render-messages.d.ts +4 -3
- package/dist/tui/render-messages.d.ts.map +1 -1
- package/dist/tui/setup.d.ts +1 -1
- package/dist/tui/setup.d.ts.map +1 -1
- package/dist/tui/state.d.ts +24 -10
- package/dist/tui/state.d.ts.map +1 -1
- package/dist/tui/status-line.d.ts.map +1 -1
- package/dist/tui.cjs +19 -19
- package/dist/tui.js +2 -2
- package/dist/utils/plan-diff.d.ts +25 -0
- package/dist/utils/plan-diff.d.ts.map +1 -0
- package/dist/utils/plans.d.ts +41 -12
- package/dist/utils/plans.d.ts.map +1 -1
- package/package.json +16 -16
- package/dist/acp-7DQDVR3M.js.map +0 -1
- package/dist/acp-NTTZEFVN.cjs.map +0 -1
- package/dist/chunk-DPRNPXVC.cjs.map +0 -1
- package/dist/chunk-DVBJN36L.cjs.map +0 -1
- package/dist/chunk-F3TKSK3C.js.map +0 -1
- package/dist/chunk-IU477VVQ.js.map +0 -1
- package/dist/chunk-L67CU2OP.js.map +0 -1
- package/dist/chunk-MUZ2ZLWN.cjs.map +0 -1
- package/dist/chunk-QO4KIOLG.js.map +0 -1
- package/dist/chunk-UW25EMMX.cjs.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { tintHex, mastra, theme, getMarkdownTheme, CHAT_INDENT, BOX_INDENT, getTermWidth, ensureTerminalGlyphContrast, TERM_WIDTH_BUFFER, getEditorTheme, loadSettings, MEMORY_GATEWAY_PROVIDER, getAvailableModePacks, resolveThreadActiveModelPackId, saveSettings, getAvailableOmPacks, ONBOARDING_VERSION, THREAD_ACTIVE_MODEL_PACK_ID_KEY, BOX_INDENT_STR, ThreadLockError,
|
|
1
|
+
import { tintHex, mastra, theme, getMarkdownTheme, CHAT_INDENT, BOX_INDENT, getTermWidth, ensureTerminalGlyphContrast, TERM_WIDTH_BUFFER, getEditorTheme, loadSettings, MEMORY_GATEWAY_PROVIDER, getAvailableModePacks, resolveThreadActiveModelPackId, saveSettings, getAvailableOmPacks, ONBOARDING_VERSION, THREAD_ACTIVE_MODEL_PACK_ID_KEY, BOX_INDENT_STR, ThreadLockError, resolvePlanPath, readPlanFile, getSelectListTheme, luminance, extendedColors, mastraBrand, MEMORY_GATEWAY_DEFAULT_URL, getThemeMode, applyThemeMode, createBrowserFromSettings, setProfileProvider, getCustomProviderId, OBSERVABILITY_AUTH_PREFIX, checkProfileProviderMismatch, getSettingsListTheme, approvePlanFile, toCustomProviderModelId } from './chunk-NDCWIAKG.js';
|
|
2
2
|
import { getOAuthProviders, detectProject, DEFAULT_CONFIG_DIR, getUserId, getCurrentGitBranchAsync, getUserName, PROVIDER_DEFAULT_MODELS } from './chunk-Z5EMG7I2.js';
|
|
3
3
|
import { MC_TOOLS, getToolCategory, TOOL_CATEGORIES } from './chunk-UOFNLVKF.js';
|
|
4
4
|
import { exec, spawn, execFile, execSync, execFileSync } from 'child_process';
|
|
@@ -10,7 +10,8 @@ import path4__default, { extname, join } from 'path';
|
|
|
10
10
|
import { fileURLToPath } from 'url';
|
|
11
11
|
import { randomUUID } from 'crypto';
|
|
12
12
|
import { formatSkillActivation } from '@mastra/core/workspace';
|
|
13
|
-
import { defaultOMProgressState, parseSubagentMeta
|
|
13
|
+
import { defaultOMProgressState, parseSubagentMeta } from '@mastra/core/agent-controller';
|
|
14
|
+
import { assignTaskIds } from '@mastra/core/signals';
|
|
14
15
|
import { TASKS_STATE_ID } from '@mastra/core/tools';
|
|
15
16
|
import stripAnsi2 from 'strip-ansi';
|
|
16
17
|
import { safeStringify } from '@mastra/core/utils';
|
|
@@ -1174,7 +1175,7 @@ function getInstallCommand(pm, version) {
|
|
|
1174
1175
|
}
|
|
1175
1176
|
function getCurrentVersion() {
|
|
1176
1177
|
{
|
|
1177
|
-
return "0.26.0
|
|
1178
|
+
return "0.26.0";
|
|
1178
1179
|
}
|
|
1179
1180
|
}
|
|
1180
1181
|
async function fetchLatestVersion() {
|
|
@@ -1933,7 +1934,7 @@ var GoalManager = class {
|
|
|
1933
1934
|
// ---------------------------------------------------------------------------
|
|
1934
1935
|
getAgent(state) {
|
|
1935
1936
|
try {
|
|
1936
|
-
return state.
|
|
1937
|
+
return state.controller.getCurrentAgent(state.session);
|
|
1937
1938
|
} catch {
|
|
1938
1939
|
return void 0;
|
|
1939
1940
|
}
|
|
@@ -2311,7 +2312,7 @@ function getJudgeDefaults() {
|
|
|
2311
2312
|
}
|
|
2312
2313
|
async function promptForJudgeDefaults(ctx, cancelMessage) {
|
|
2313
2314
|
const { state } = ctx;
|
|
2314
|
-
const availableModels = await state.
|
|
2315
|
+
const availableModels = await state.controller.listAvailableModels();
|
|
2315
2316
|
if (availableModels.length === 0) {
|
|
2316
2317
|
ctx.showError("No models available. Cannot set goal judge defaults.");
|
|
2317
2318
|
return null;
|
|
@@ -2644,7 +2645,7 @@ function describeShellPassthroughInvocation(invocation) {
|
|
|
2644
2645
|
function handleHelpCommand(ctx) {
|
|
2645
2646
|
const shellInvocation = resolveShellPassthroughInvocation("", loadSettings().shellPassthrough);
|
|
2646
2647
|
const text = buildHelpText({
|
|
2647
|
-
modes: ctx.
|
|
2648
|
+
modes: ctx.controller.listModes().length,
|
|
2648
2649
|
customSlashCommands: ctx.customSlashCommands,
|
|
2649
2650
|
shellModeLabel: describeShellPassthroughInvocation(shellInvocation)
|
|
2650
2651
|
});
|
|
@@ -3759,7 +3760,7 @@ function applyCurrentModeColorToRenderedTools(ctx) {
|
|
|
3759
3760
|
ctx.state.ui.requestRender();
|
|
3760
3761
|
}
|
|
3761
3762
|
async function handleModeCommand(ctx, args) {
|
|
3762
|
-
const modes = ctx.
|
|
3763
|
+
const modes = ctx.controller.listModes();
|
|
3763
3764
|
if (modes.length <= 1) {
|
|
3764
3765
|
ctx.showInfo("Only one mode available");
|
|
3765
3766
|
return;
|
|
@@ -4432,6 +4433,48 @@ var OMOutputComponent = class extends Container {
|
|
|
4432
4433
|
return "other";
|
|
4433
4434
|
}
|
|
4434
4435
|
};
|
|
4436
|
+
|
|
4437
|
+
// src/utils/plan-diff.ts
|
|
4438
|
+
function generatePlanDiff(oldText, newText) {
|
|
4439
|
+
const oldLines = oldText.split(/\r?\n/);
|
|
4440
|
+
const newLines = newText.split(/\r?\n/);
|
|
4441
|
+
const n = oldLines.length;
|
|
4442
|
+
const m = newLines.length;
|
|
4443
|
+
const lcs = Array.from({ length: n + 1 }, () => new Array(m + 1).fill(0));
|
|
4444
|
+
for (let i2 = n - 1; i2 >= 0; i2--) {
|
|
4445
|
+
for (let j2 = m - 1; j2 >= 0; j2--) {
|
|
4446
|
+
lcs[i2][j2] = oldLines[i2] === newLines[j2] ? lcs[i2 + 1][j2 + 1] + 1 : Math.max(lcs[i2 + 1][j2], lcs[i2][j2 + 1]);
|
|
4447
|
+
}
|
|
4448
|
+
}
|
|
4449
|
+
const entries = [];
|
|
4450
|
+
let i = 0;
|
|
4451
|
+
let j = 0;
|
|
4452
|
+
while (i < n && j < m) {
|
|
4453
|
+
if (oldLines[i] === newLines[j]) {
|
|
4454
|
+
entries.push({ type: "context", text: oldLines[i] });
|
|
4455
|
+
i++;
|
|
4456
|
+
j++;
|
|
4457
|
+
} else if (lcs[i + 1][j] >= lcs[i][j + 1]) {
|
|
4458
|
+
entries.push({ type: "removed", text: oldLines[i] });
|
|
4459
|
+
i++;
|
|
4460
|
+
} else {
|
|
4461
|
+
entries.push({ type: "added", text: newLines[j] });
|
|
4462
|
+
j++;
|
|
4463
|
+
}
|
|
4464
|
+
}
|
|
4465
|
+
while (i < n) entries.push({ type: "removed", text: oldLines[i++] });
|
|
4466
|
+
while (j < m) entries.push({ type: "added", text: newLines[j++] });
|
|
4467
|
+
return entries;
|
|
4468
|
+
}
|
|
4469
|
+
function shouldShowDiff(previousPlan, plan, maxChangedRatio = 0.5) {
|
|
4470
|
+
if (!previousPlan || previousPlan === plan) return false;
|
|
4471
|
+
const entries = generatePlanDiff(previousPlan, plan);
|
|
4472
|
+
const changed = entries.filter((e) => e.type !== "context").length;
|
|
4473
|
+
if (changed === 0) return false;
|
|
4474
|
+
return changed / Math.max(entries.length, 1) <= maxChangedRatio;
|
|
4475
|
+
}
|
|
4476
|
+
|
|
4477
|
+
// src/tui/components/plan-approval-inline.ts
|
|
4435
4478
|
var PlanContentBox = class {
|
|
4436
4479
|
constructor(plan) {
|
|
4437
4480
|
this.plan = plan;
|
|
@@ -4494,25 +4537,6 @@ var PlanDiffBox = class {
|
|
|
4494
4537
|
return [top, ...body, bottom];
|
|
4495
4538
|
}
|
|
4496
4539
|
};
|
|
4497
|
-
function generatePlanDiff(oldText, newText) {
|
|
4498
|
-
const oldLines = oldText.split("\n");
|
|
4499
|
-
const newLines = newText.split("\n");
|
|
4500
|
-
const entries = [];
|
|
4501
|
-
const maxLines = Math.max(oldLines.length, newLines.length);
|
|
4502
|
-
for (let i = 0; i < maxLines; i++) {
|
|
4503
|
-
if (i >= oldLines.length) {
|
|
4504
|
-
entries.push({ type: "added", text: newLines[i] });
|
|
4505
|
-
} else if (i >= newLines.length) {
|
|
4506
|
-
entries.push({ type: "removed", text: oldLines[i] });
|
|
4507
|
-
} else if (oldLines[i] !== newLines[i]) {
|
|
4508
|
-
entries.push({ type: "removed", text: oldLines[i] });
|
|
4509
|
-
entries.push({ type: "added", text: newLines[i] });
|
|
4510
|
-
} else {
|
|
4511
|
-
entries.push({ type: "context", text: oldLines[i] });
|
|
4512
|
-
}
|
|
4513
|
-
}
|
|
4514
|
-
return entries;
|
|
4515
|
-
}
|
|
4516
4540
|
var PlanApprovalInlineComponent = class _PlanApprovalInlineComponent extends Container {
|
|
4517
4541
|
constructor(options, ui) {
|
|
4518
4542
|
super();
|
|
@@ -4582,12 +4606,8 @@ var PlanApprovalInlineComponent = class _PlanApprovalInlineComponent extends Con
|
|
|
4582
4606
|
updateArgs(args) {
|
|
4583
4607
|
if (!args || typeof args !== "object" || this.resolved) return;
|
|
4584
4608
|
const partial = args;
|
|
4585
|
-
if (typeof partial.
|
|
4586
|
-
this.
|
|
4587
|
-
this.planFilename = getPlanFilename(this.planTitle);
|
|
4588
|
-
}
|
|
4589
|
-
if (typeof partial.plan === "string") {
|
|
4590
|
-
this.planContent = partial.plan;
|
|
4609
|
+
if (typeof partial.path === "string" && partial.path) {
|
|
4610
|
+
this.planFilename = partial.path;
|
|
4591
4611
|
}
|
|
4592
4612
|
if (this.mode === "streaming") {
|
|
4593
4613
|
this.renderStreaming();
|
|
@@ -4640,7 +4660,7 @@ var PlanApprovalInlineComponent = class _PlanApprovalInlineComponent extends Con
|
|
|
4640
4660
|
renderPlanHeader(prefix = "") {
|
|
4641
4661
|
this.contentBox.addChild(new Text(`${prefix}${theme.bold(theme.fg("accent", `Plan: ${this.planTitle}`))}`, 0, 0));
|
|
4642
4662
|
if (this.planFilename) {
|
|
4643
|
-
this.contentBox.addChild(new Text(theme.fg("dim",
|
|
4663
|
+
this.contentBox.addChild(new Text(theme.fg("dim", this.planFilename), 0, 0));
|
|
4644
4664
|
}
|
|
4645
4665
|
this.contentBox.addChild(new Spacer(1));
|
|
4646
4666
|
}
|
|
@@ -4711,7 +4731,7 @@ var PlanResultComponent = class extends Container {
|
|
|
4711
4731
|
const status = options.isApproved ? "Approved" : options.feedback ? "Changes requested" : "Rejected";
|
|
4712
4732
|
contentBox.addChild(new Text(theme.bold(theme.fg("accent", `Plan: ${options.title}`)), 0, 0));
|
|
4713
4733
|
if (options.planFilename) {
|
|
4714
|
-
contentBox.addChild(new Text(theme.fg("dim",
|
|
4734
|
+
contentBox.addChild(new Text(theme.fg("dim", options.planFilename), 0, 0));
|
|
4715
4735
|
}
|
|
4716
4736
|
contentBox.addChild(new Spacer(1));
|
|
4717
4737
|
contentBox.addChild(new PlanContentBox(options.plan));
|
|
@@ -8899,10 +8919,16 @@ async function renderExistingMessages(state) {
|
|
|
8899
8919
|
if (content.name === "submit_plan" && toolResult?.type === "tool_result") {
|
|
8900
8920
|
const args = content.args;
|
|
8901
8921
|
let resultText = "";
|
|
8922
|
+
let submittedPlan;
|
|
8902
8923
|
if (typeof toolResult.result === "string") {
|
|
8903
8924
|
resultText = toolResult.result;
|
|
8904
|
-
} else if (typeof toolResult.result === "object" && toolResult.result !== null
|
|
8905
|
-
|
|
8925
|
+
} else if (typeof toolResult.result === "object" && toolResult.result !== null) {
|
|
8926
|
+
if ("content" in toolResult.result && typeof toolResult.result.content === "string") {
|
|
8927
|
+
resultText = toolResult.result.content;
|
|
8928
|
+
}
|
|
8929
|
+
if ("submittedPlan" in toolResult.result && typeof toolResult.result.submittedPlan === "object") {
|
|
8930
|
+
submittedPlan = toolResult.result.submittedPlan;
|
|
8931
|
+
}
|
|
8906
8932
|
}
|
|
8907
8933
|
const isApproved = resultText.startsWith("Plan approved");
|
|
8908
8934
|
let feedback;
|
|
@@ -8910,17 +8936,24 @@ async function renderExistingMessages(state) {
|
|
|
8910
8936
|
const feedbackMatch = resultText.match(/User feedback:\s*(.+?)(?:\n|$)/);
|
|
8911
8937
|
feedback = feedbackMatch?.[1] || "Revision requested";
|
|
8912
8938
|
}
|
|
8913
|
-
|
|
8939
|
+
const submittedPath = submittedPlan?.path || args?.path;
|
|
8940
|
+
if (submittedPath) {
|
|
8941
|
+
const sessionState = state.session.state.get();
|
|
8942
|
+
const projectPath = sessionState?.projectPath;
|
|
8943
|
+
const recoverAbsPath = !submittedPlan?.plan ? resolvePlanPath(projectPath ?? process.cwd(), submittedPath) : void 0;
|
|
8944
|
+
const recovered = recoverAbsPath ? await readPlanFile(recoverAbsPath) : void 0;
|
|
8945
|
+
const planBody = submittedPlan?.plan ?? recovered?.plan ?? "";
|
|
8946
|
+
const planTitle = submittedPlan?.title || recovered?.title || "Implementation Plan";
|
|
8914
8947
|
const planResult = new PlanResultComponent({
|
|
8915
|
-
title:
|
|
8916
|
-
plan:
|
|
8917
|
-
planFilename:
|
|
8948
|
+
title: planTitle,
|
|
8949
|
+
plan: planBody,
|
|
8950
|
+
planFilename: submittedPath,
|
|
8918
8951
|
isApproved,
|
|
8919
8952
|
feedback
|
|
8920
8953
|
});
|
|
8921
8954
|
state.chatContainer.addChild(planResult);
|
|
8922
8955
|
replacedWithInline = true;
|
|
8923
|
-
state.previousPlanSnapshot = {
|
|
8956
|
+
state.previousPlanSnapshot = { path: submittedPath, plan: planBody };
|
|
8924
8957
|
}
|
|
8925
8958
|
}
|
|
8926
8959
|
if (!replacedWithInline) {
|
|
@@ -9047,8 +9080,8 @@ function escapeSkillBoundary(value) {
|
|
|
9047
9080
|
}
|
|
9048
9081
|
async function resolveWorkspace(ctx) {
|
|
9049
9082
|
let workspace = ctx.getResolvedWorkspace();
|
|
9050
|
-
if (!workspace && ctx.
|
|
9051
|
-
workspace = await ctx.
|
|
9083
|
+
if (!workspace && ctx.controller.hasWorkspace()) {
|
|
9084
|
+
workspace = await ctx.controller.resolveWorkspace({ session: ctx.state.session });
|
|
9052
9085
|
}
|
|
9053
9086
|
return workspace;
|
|
9054
9087
|
}
|
|
@@ -9418,13 +9451,13 @@ async function handleCloneCommand(ctx) {
|
|
|
9418
9451
|
|
|
9419
9452
|
// src/tui/commands/resource.ts
|
|
9420
9453
|
async function handleResourceCommand(ctx, args) {
|
|
9421
|
-
const { state,
|
|
9454
|
+
const { state, controller } = ctx;
|
|
9422
9455
|
const { session } = state;
|
|
9423
9456
|
const sub = args[0]?.trim();
|
|
9424
9457
|
const current = session.identity.getResourceId();
|
|
9425
9458
|
const defaultId = session.identity.getDefaultResourceId();
|
|
9426
9459
|
if (!sub) {
|
|
9427
|
-
const knownIds = await
|
|
9460
|
+
const knownIds = await controller.getKnownResourceIds(session);
|
|
9428
9461
|
const isOverridden = current !== defaultId;
|
|
9429
9462
|
const lines = [
|
|
9430
9463
|
`Current: ${current}${isOverridden ? ` (auto-detected: ${defaultId})` : ""}`,
|
|
@@ -9445,7 +9478,7 @@ async function handleResourceCommand(ctx, args) {
|
|
|
9445
9478
|
ctx.showInfo(`Already on resource: ${current}`);
|
|
9446
9479
|
return;
|
|
9447
9480
|
}
|
|
9448
|
-
await
|
|
9481
|
+
await controller.setResourceId(session, { resourceId: newId });
|
|
9449
9482
|
const threads = await session.thread.list();
|
|
9450
9483
|
const latest = [...threads].sort((a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime())[0];
|
|
9451
9484
|
if (latest) {
|
|
@@ -9964,7 +9997,7 @@ async function handleThreadsCommand(ctx) {
|
|
|
9964
9997
|
return;
|
|
9965
9998
|
}
|
|
9966
9999
|
if (thread.resourceId !== currentResourceId) {
|
|
9967
|
-
await state.
|
|
10000
|
+
await state.controller.setResourceId(state.session, { resourceId: thread.resourceId });
|
|
9968
10001
|
}
|
|
9969
10002
|
try {
|
|
9970
10003
|
await state.session.thread.switch({ threadId: thread.id });
|
|
@@ -10088,8 +10121,8 @@ async function handleThreadTagDirCommand(ctx) {
|
|
|
10088
10121
|
}
|
|
10089
10122
|
}
|
|
10090
10123
|
async function sandboxAddPath(ctx, rawPath) {
|
|
10091
|
-
const
|
|
10092
|
-
const currentPaths =
|
|
10124
|
+
const controllerWithState = ctx.state.session.state.get();
|
|
10125
|
+
const currentPaths = controllerWithState?.sandboxAllowedPaths ?? [];
|
|
10093
10126
|
const resolved = path4__default.resolve(rawPath);
|
|
10094
10127
|
if (currentPaths.includes(resolved)) {
|
|
10095
10128
|
ctx.showInfo(`Path already allowed: ${resolved}`);
|
|
@@ -10138,8 +10171,8 @@ async function showSandboxAddPrompt(ctx) {
|
|
|
10138
10171
|
});
|
|
10139
10172
|
}
|
|
10140
10173
|
async function handleSandboxCommand(ctx, args) {
|
|
10141
|
-
const
|
|
10142
|
-
const currentPaths =
|
|
10174
|
+
const agentControllerState = ctx.state.session.state.get();
|
|
10175
|
+
const currentPaths = agentControllerState?.sandboxAllowedPaths ?? [];
|
|
10143
10176
|
const subcommand = args[0]?.toLowerCase();
|
|
10144
10177
|
if (subcommand === "add" && args.length > 1) {
|
|
10145
10178
|
await sandboxAddPath(ctx, args.slice(1).join(" ").trim());
|
|
@@ -10693,7 +10726,7 @@ function updateStatusLine(state) {
|
|
|
10693
10726
|
const showOMMode = !isJudging && (isObserving || isReflecting);
|
|
10694
10727
|
let modeBadge = "";
|
|
10695
10728
|
let modeBadgeWidth = 0;
|
|
10696
|
-
const modes = state.
|
|
10729
|
+
const modes = state.controller.listModes();
|
|
10697
10730
|
const currentMode = modes.length > 1 ? state.session.mode.resolve() : void 0;
|
|
10698
10731
|
const judgeModeColor = mastra.blue;
|
|
10699
10732
|
const currentModeColor = currentMode?.metadata?.color;
|
|
@@ -10851,6 +10884,13 @@ function updateStatusLine(state) {
|
|
|
10851
10884
|
if (ref) {
|
|
10852
10885
|
parts.push({ plain: ref, styled: ref });
|
|
10853
10886
|
}
|
|
10887
|
+
if (state.tokensPerSec > 0) {
|
|
10888
|
+
const tpsLabel = `${state.tokensPerSec} tok/s`;
|
|
10889
|
+
parts.push({
|
|
10890
|
+
plain: tpsLabel,
|
|
10891
|
+
styled: theme.fg("dim", tpsLabel)
|
|
10892
|
+
});
|
|
10893
|
+
}
|
|
10854
10894
|
if (opts.showQueue && queuedLabel) {
|
|
10855
10895
|
parts.push({
|
|
10856
10896
|
plain: queuedLabel,
|
|
@@ -11027,7 +11067,7 @@ function deserializePack(input) {
|
|
|
11027
11067
|
}
|
|
11028
11068
|
}
|
|
11029
11069
|
async function selectModel(ctx, title, modeColor, currentModelId) {
|
|
11030
|
-
const availableModels = await ctx.state.
|
|
11070
|
+
const availableModels = await ctx.state.controller.listAvailableModels();
|
|
11031
11071
|
if (availableModels.length === 0) return void 0;
|
|
11032
11072
|
return new Promise((resolve3) => {
|
|
11033
11073
|
const selector = new ModelSelectorComponent({
|
|
@@ -11262,8 +11302,8 @@ function removeCustomPackFromSettings(settings, packId) {
|
|
|
11262
11302
|
}
|
|
11263
11303
|
}
|
|
11264
11304
|
async function applyPack(ctx, pack, previousPackId) {
|
|
11265
|
-
const
|
|
11266
|
-
const modes =
|
|
11305
|
+
const controller = ctx.state.controller;
|
|
11306
|
+
const modes = controller.listModes();
|
|
11267
11307
|
for (const mode of modes) {
|
|
11268
11308
|
const modelId = pack.models[mode.id];
|
|
11269
11309
|
if (modelId) {
|
|
@@ -11416,8 +11456,8 @@ async function askImportCollision(ctx, existingName) {
|
|
|
11416
11456
|
});
|
|
11417
11457
|
}
|
|
11418
11458
|
async function handleModelsPackCommand(ctx) {
|
|
11419
|
-
const
|
|
11420
|
-
const models = await
|
|
11459
|
+
const controller = ctx.state.controller;
|
|
11460
|
+
const models = await controller.listAvailableModels();
|
|
11421
11461
|
const hasEnv = (provider) => models.some((m) => m.provider === provider && m.hasApiKey);
|
|
11422
11462
|
const accessLevel = (storageProviderId) => {
|
|
11423
11463
|
const cred = ctx.authStorage?.get(storageProviderId);
|
|
@@ -11843,7 +11883,7 @@ var BUILT_IN_SUBAGENT_TYPES = [
|
|
|
11843
11883
|
}
|
|
11844
11884
|
];
|
|
11845
11885
|
async function showSubagentModelListForScope(ctx, scope, agentType, agentTypeLabel) {
|
|
11846
|
-
const availableModels = await ctx.state.
|
|
11886
|
+
const availableModels = await ctx.state.controller.listAvailableModels();
|
|
11847
11887
|
if (availableModels.length === 0) {
|
|
11848
11888
|
ctx.showInfo("No models available. Check your Mastra configuration.");
|
|
11849
11889
|
return;
|
|
@@ -11911,8 +11951,8 @@ async function showSubagentScopeThenList(ctx, agentType, agentTypeLabel) {
|
|
|
11911
11951
|
}
|
|
11912
11952
|
}
|
|
11913
11953
|
function getConfiguredSubagentTypes(ctx) {
|
|
11914
|
-
const
|
|
11915
|
-
const configuredSubagents =
|
|
11954
|
+
const controllerWithConfig = ctx.state.controller;
|
|
11955
|
+
const configuredSubagents = controllerWithConfig.config?.subagents;
|
|
11916
11956
|
return configuredSubagents && configuredSubagents.length > 0 ? configuredSubagents.map((subagent) => ({
|
|
11917
11957
|
id: subagent.id,
|
|
11918
11958
|
label: subagent.name,
|
|
@@ -12231,15 +12271,15 @@ function persistOmObserveAttachments(value) {
|
|
|
12231
12271
|
saveSettings(settings);
|
|
12232
12272
|
}
|
|
12233
12273
|
async function handleOMCommand(ctx) {
|
|
12234
|
-
const availableModels = await ctx.state.
|
|
12235
|
-
const
|
|
12274
|
+
const availableModels = await ctx.state.controller.listAvailableModels();
|
|
12275
|
+
const agentControllerState = ctx.state.session.state.get();
|
|
12236
12276
|
const config = {
|
|
12237
12277
|
observerModelId: ctx.state.session.om.observer.modelId() ?? "",
|
|
12238
12278
|
reflectorModelId: ctx.state.session.om.reflector.modelId() ?? "",
|
|
12239
12279
|
observationThreshold: ctx.state.session.om.observer.threshold() ?? 3e4,
|
|
12240
12280
|
reflectionThreshold: ctx.state.session.om.reflector.threshold() ?? 4e4,
|
|
12241
|
-
cavemanObservations:
|
|
12242
|
-
observeAttachments:
|
|
12281
|
+
cavemanObservations: agentControllerState?.cavemanObservations ?? false,
|
|
12282
|
+
observeAttachments: agentControllerState?.observeAttachments ?? "auto"
|
|
12243
12283
|
};
|
|
12244
12284
|
return new Promise((resolve3) => {
|
|
12245
12285
|
const settings = new OMSettingsComponent(
|
|
@@ -12648,12 +12688,17 @@ var SettingsComponent = class extends Box {
|
|
|
12648
12688
|
this.settingsList.handleInput(data);
|
|
12649
12689
|
}
|
|
12650
12690
|
};
|
|
12691
|
+
function getAuthProviderId(provider) {
|
|
12692
|
+
return provider === "openai" ? "openai-codex" : provider;
|
|
12693
|
+
}
|
|
12651
12694
|
function getProviderList(ctx, models) {
|
|
12652
12695
|
const seen = /* @__PURE__ */ new Map();
|
|
12653
12696
|
for (const model of models) {
|
|
12654
12697
|
if (seen.has(model.provider)) continue;
|
|
12655
12698
|
let source = "none";
|
|
12656
|
-
if (ctx.authStorage?.
|
|
12699
|
+
if (ctx.authStorage?.isLoggedIn(getAuthProviderId(model.provider))) {
|
|
12700
|
+
source = "oauth";
|
|
12701
|
+
} else if (ctx.authStorage?.hasStoredApiKey(model.provider)) {
|
|
12657
12702
|
source = "stored";
|
|
12658
12703
|
} else if (model.apiKeyEnvVar && process.env[model.apiKeyEnvVar]) {
|
|
12659
12704
|
source = "env";
|
|
@@ -12670,6 +12715,8 @@ function getProviderList(ctx, models) {
|
|
|
12670
12715
|
}
|
|
12671
12716
|
function statusLabel(info) {
|
|
12672
12717
|
switch (info.source) {
|
|
12718
|
+
case "oauth":
|
|
12719
|
+
return theme.fg("success", "\u2713") + theme.fg("dim", " (oauth)");
|
|
12673
12720
|
case "env":
|
|
12674
12721
|
return theme.fg("success", "\u2713") + theme.fg("dim", " (env)");
|
|
12675
12722
|
case "stored":
|
|
@@ -12685,7 +12732,7 @@ function buildItems(providers) {
|
|
|
12685
12732
|
}));
|
|
12686
12733
|
}
|
|
12687
12734
|
async function handleApiKeysCommand(ctx) {
|
|
12688
|
-
let models = await ctx.state.
|
|
12735
|
+
let models = await ctx.state.controller.listAvailableModels();
|
|
12689
12736
|
let providers = getProviderList(ctx, models);
|
|
12690
12737
|
if (providers.length === 0) {
|
|
12691
12738
|
ctx.showInfo("No model providers found.");
|
|
@@ -12700,7 +12747,9 @@ async function handleApiKeysCommand(ctx) {
|
|
|
12700
12747
|
const updateDetail = (providerName) => {
|
|
12701
12748
|
const info = providers.find((p) => p.provider === providerName);
|
|
12702
12749
|
if (!info) return;
|
|
12703
|
-
if (info.source === "
|
|
12750
|
+
if (info.source === "oauth") {
|
|
12751
|
+
detailText.setText(theme.fg("dim", " Authenticated via OAuth. Press Enter to add an API key override."));
|
|
12752
|
+
} else if (info.source === "env") {
|
|
12704
12753
|
detailText.setText(
|
|
12705
12754
|
theme.fg("dim", " Key set via environment variable. Press Enter to store a local override.")
|
|
12706
12755
|
);
|
|
@@ -12738,8 +12787,8 @@ async function handleApiKeysCommand(ctx) {
|
|
|
12738
12787
|
if (info.envVar && process.env[info.envVar] === storedKey) {
|
|
12739
12788
|
delete process.env[info.envVar];
|
|
12740
12789
|
}
|
|
12741
|
-
ctx.state.
|
|
12742
|
-
models = await ctx.state.
|
|
12790
|
+
ctx.state.controller.invalidateAvailableModelsCache();
|
|
12791
|
+
models = await ctx.state.controller.listAvailableModels();
|
|
12743
12792
|
providers = getProviderList(ctx, models);
|
|
12744
12793
|
ctx.showInfo(`API key removed for ${info.provider}`);
|
|
12745
12794
|
rebuildList();
|
|
@@ -13070,18 +13119,18 @@ Using the same profile across different providers can cause compatibility issues
|
|
|
13070
13119
|
]);
|
|
13071
13120
|
return proceed === "Yes";
|
|
13072
13121
|
}
|
|
13073
|
-
function resolveModeAgent(mode,
|
|
13122
|
+
function resolveModeAgent(mode, agentControllerState) {
|
|
13074
13123
|
const modeAgent = mode.agent;
|
|
13075
|
-
return typeof modeAgent === "function" ? modeAgent(
|
|
13124
|
+
return typeof modeAgent === "function" ? modeAgent(agentControllerState) : modeAgent;
|
|
13076
13125
|
}
|
|
13077
13126
|
function applyBrowserToAgents(ctx, browser, browserSettings) {
|
|
13078
|
-
const modes = ctx.
|
|
13079
|
-
let
|
|
13127
|
+
const modes = ctx.controller.listModes();
|
|
13128
|
+
let agentControllerState;
|
|
13080
13129
|
for (const mode of modes) {
|
|
13081
|
-
const agent = resolveModeAgent(mode,
|
|
13130
|
+
const agent = resolveModeAgent(mode, agentControllerState ??= ctx.state.session.state.get());
|
|
13082
13131
|
agent?.setBrowser?.(browser);
|
|
13083
13132
|
}
|
|
13084
|
-
ctx.
|
|
13133
|
+
ctx.controller.setBrowser?.(browser);
|
|
13085
13134
|
void ctx.state.session.state.set({ [ACTIVE_BROWSER_KEY]: browserSettings });
|
|
13086
13135
|
}
|
|
13087
13136
|
function getBrowserConfigKey(settings) {
|
|
@@ -14336,7 +14385,7 @@ async function handleFeedbackCommand(ctx, args) {
|
|
|
14336
14385
|
ctx.showError("No active session to attach feedback to.");
|
|
14337
14386
|
return;
|
|
14338
14387
|
}
|
|
14339
|
-
const mastra2 = ctx.
|
|
14388
|
+
const mastra2 = ctx.controller.getMastra();
|
|
14340
14389
|
const observability = mastra2?.observability;
|
|
14341
14390
|
if (!observability?.addFeedback) {
|
|
14342
14391
|
ctx.showError("Observability not configured \u2014 cannot save feedback.");
|
|
@@ -14970,8 +15019,8 @@ async function handleGoalSourceCommand(state, sourceName, args, ctx) {
|
|
|
14970
15019
|
if (goalSkill) {
|
|
14971
15020
|
try {
|
|
14972
15021
|
let workspace = ctx.getResolvedWorkspace();
|
|
14973
|
-
if (!workspace && ctx.
|
|
14974
|
-
workspace = await ctx.
|
|
15022
|
+
if (!workspace && ctx.controller?.hasWorkspace?.()) {
|
|
15023
|
+
workspace = await ctx.controller.resolveWorkspace({ session: ctx.state.session });
|
|
14975
15024
|
}
|
|
14976
15025
|
const skill = await workspace?.skills?.get(goalSkill.path || goalSkill.name);
|
|
14977
15026
|
if (!skill || skill.metadata?.goal !== true) {
|
|
@@ -14999,7 +15048,7 @@ async function handleCustomSlashCommand(state, command, args, ctx, displayText)
|
|
|
14999
15048
|
try {
|
|
15000
15049
|
const processedContent = await processSlashCommand(command, args, process.cwd());
|
|
15001
15050
|
if (processedContent.trim()) {
|
|
15002
|
-
const commandCtx = { ...ctx, state,
|
|
15051
|
+
const commandCtx = { ...ctx, state, controller: ctx.controller ?? state.controller };
|
|
15003
15052
|
if (!isCurrentThreadActive(commandCtx)) {
|
|
15004
15053
|
const slashComp = new SlashCommandComponent(command.name, processedContent.trim());
|
|
15005
15054
|
state.allSlashCommandComponents.push(slashComp);
|
|
@@ -15145,7 +15194,10 @@ function handleAgentAborted(ctx) {
|
|
|
15145
15194
|
if (state.gradientAnimator) {
|
|
15146
15195
|
state.gradientAnimator.fadeOut();
|
|
15147
15196
|
}
|
|
15148
|
-
if (state.
|
|
15197
|
+
if (state.planRejectionAbort) {
|
|
15198
|
+
state.streamingComponent = void 0;
|
|
15199
|
+
state.streamingMessage = void 0;
|
|
15200
|
+
} else if (state.streamingComponent && state.streamingMessage) {
|
|
15149
15201
|
state.streamingMessage.stopReason = "aborted";
|
|
15150
15202
|
state.streamingMessage.errorMessage = "Interrupted";
|
|
15151
15203
|
state.streamingComponent.updateContent(state.streamingMessage);
|
|
@@ -15155,6 +15207,7 @@ function handleAgentAborted(ctx) {
|
|
|
15155
15207
|
showError(state, "Interrupted");
|
|
15156
15208
|
}
|
|
15157
15209
|
state.userInitiatedAbort = false;
|
|
15210
|
+
state.planRejectionAbort = false;
|
|
15158
15211
|
if (state.activeGoalJudge) {
|
|
15159
15212
|
removeJudgeComponent(state, state.activeGoalJudge.component);
|
|
15160
15213
|
state.activeGoalJudge = void 0;
|
|
@@ -16014,7 +16067,7 @@ ${theme.fg("dim", `Reason: ${reason}`)}`,
|
|
|
16014
16067
|
ctx.notify("sandbox_access", `Sandbox access requested: ${requestedPath}`);
|
|
16015
16068
|
});
|
|
16016
16069
|
}
|
|
16017
|
-
async function approvePlan(ctx, toolCallId, title, plan) {
|
|
16070
|
+
async function approvePlan(ctx, toolCallId, title, plan, planPath, submittedPath) {
|
|
16018
16071
|
const { state } = ctx;
|
|
16019
16072
|
await state.session.state.set({
|
|
16020
16073
|
activePlan: {
|
|
@@ -16023,15 +16076,19 @@ async function approvePlan(ctx, toolCallId, title, plan) {
|
|
|
16023
16076
|
approvedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
16024
16077
|
}
|
|
16025
16078
|
});
|
|
16026
|
-
|
|
16027
|
-
|
|
16028
|
-
|
|
16029
|
-
|
|
16030
|
-
|
|
16031
|
-
|
|
16079
|
+
if (planPath) {
|
|
16080
|
+
await approvePlanFile({
|
|
16081
|
+
planPath,
|
|
16082
|
+
title,
|
|
16083
|
+
resourceId: state.session.identity.getResourceId()
|
|
16084
|
+
}).catch(() => {
|
|
16085
|
+
});
|
|
16086
|
+
}
|
|
16087
|
+
state.previousPlanSnapshot = void 0;
|
|
16088
|
+
state.lastSubmitPlanComponent = void 0;
|
|
16032
16089
|
await state.session.respondToToolSuspension({
|
|
16033
16090
|
toolCallId,
|
|
16034
|
-
resumeData: { action: "approved" }
|
|
16091
|
+
resumeData: { action: "approved", path: submittedPath, title, plan }
|
|
16035
16092
|
});
|
|
16036
16093
|
}
|
|
16037
16094
|
function formatPlanGoalObjective(title, plan) {
|
|
@@ -16039,34 +16096,42 @@ function formatPlanGoalObjective(title, plan) {
|
|
|
16039
16096
|
|
|
16040
16097
|
${plan}`;
|
|
16041
16098
|
}
|
|
16042
|
-
async function handlePlanApproval(ctx, toolCallId,
|
|
16099
|
+
async function handlePlanApproval(ctx, toolCallId, submittedPath) {
|
|
16043
16100
|
const { state } = ctx;
|
|
16044
|
-
const previousPlan = state.previousPlanSnapshot?.plan;
|
|
16045
|
-
state.previousPlanSnapshot = { title, plan };
|
|
16046
16101
|
const projectPath = state.session.state.get()?.projectPath;
|
|
16047
|
-
|
|
16048
|
-
|
|
16049
|
-
|
|
16102
|
+
const planPath = submittedPath ? resolvePlanPath(projectPath ?? process.cwd(), submittedPath) : void 0;
|
|
16103
|
+
const current = planPath ? await readPlanFile(planPath) : void 0;
|
|
16104
|
+
if (!current) {
|
|
16105
|
+
state.previousPlanSnapshot = void 0;
|
|
16106
|
+
}
|
|
16107
|
+
const plan = current?.plan ?? `\u26A0\uFE0F Could not read the plan file at \`${submittedPath}\`. Make sure it exists before submitting it.`;
|
|
16108
|
+
const resolvedTitle = current?.title || "Implementation Plan";
|
|
16109
|
+
const snapshotKey = submittedPath;
|
|
16110
|
+
const snapshot = state.previousPlanSnapshot;
|
|
16111
|
+
const snapshotPlan = snapshot && snapshot.path === snapshotKey ? snapshot.plan : void 0;
|
|
16112
|
+
const previousPlan = snapshotPlan && shouldShowDiff(snapshotPlan, plan) ? snapshotPlan : void 0;
|
|
16113
|
+
if (current) {
|
|
16114
|
+
state.previousPlanSnapshot = { path: snapshotKey, plan };
|
|
16050
16115
|
}
|
|
16051
16116
|
return new Promise((resolve3) => {
|
|
16052
|
-
const planFilename =
|
|
16117
|
+
const planFilename = snapshotKey;
|
|
16053
16118
|
const approvalOptions = {
|
|
16054
16119
|
toolCallId,
|
|
16055
|
-
title,
|
|
16120
|
+
title: resolvedTitle,
|
|
16056
16121
|
plan,
|
|
16057
16122
|
planFilename,
|
|
16058
16123
|
previousPlan,
|
|
16059
16124
|
onApprove: async () => {
|
|
16060
16125
|
state.activeInlinePlanApproval = void 0;
|
|
16061
16126
|
state.ui.setFocus(state.editor);
|
|
16062
|
-
await approvePlan(ctx, toolCallId,
|
|
16127
|
+
await approvePlan(ctx, toolCallId, resolvedTitle, plan, planPath, snapshotKey);
|
|
16063
16128
|
resolve3();
|
|
16064
16129
|
},
|
|
16065
16130
|
onGoal: async () => {
|
|
16066
16131
|
state.activeInlinePlanApproval = void 0;
|
|
16067
16132
|
state.ui.setFocus(state.editor);
|
|
16068
|
-
await approvePlan(ctx, toolCallId,
|
|
16069
|
-
const objective = formatPlanGoalObjective(
|
|
16133
|
+
await approvePlan(ctx, toolCallId, resolvedTitle, plan, planPath, snapshotKey);
|
|
16134
|
+
const objective = formatPlanGoalObjective(resolvedTitle, plan);
|
|
16070
16135
|
await ctx.startGoal(objective, "Goal cancelled.");
|
|
16071
16136
|
const goal = state.goalManager.getGoal();
|
|
16072
16137
|
if (goal?.id) {
|
|
@@ -16074,13 +16139,20 @@ async function handlePlanApproval(ctx, toolCallId, title, plan) {
|
|
|
16074
16139
|
}
|
|
16075
16140
|
resolve3();
|
|
16076
16141
|
},
|
|
16077
|
-
onReject:
|
|
16142
|
+
onReject: () => {
|
|
16078
16143
|
state.activeInlinePlanApproval = void 0;
|
|
16079
16144
|
state.ui.setFocus(state.editor);
|
|
16080
|
-
|
|
16081
|
-
|
|
16082
|
-
|
|
16083
|
-
|
|
16145
|
+
void (async () => {
|
|
16146
|
+
try {
|
|
16147
|
+
await state.session.respondToToolSuspension({
|
|
16148
|
+
toolCallId,
|
|
16149
|
+
resumeData: { action: "rejected", path: snapshotKey, title: resolvedTitle, plan }
|
|
16150
|
+
});
|
|
16151
|
+
} finally {
|
|
16152
|
+
state.planRejectionAbort = true;
|
|
16153
|
+
state.session.abort();
|
|
16154
|
+
}
|
|
16155
|
+
})();
|
|
16084
16156
|
resolve3();
|
|
16085
16157
|
}
|
|
16086
16158
|
};
|
|
@@ -16110,7 +16182,7 @@ async function handlePlanApproval(ctx, toolCallId, title, plan) {
|
|
|
16110
16182
|
state.ui.requestRender();
|
|
16111
16183
|
state.chatContainer.invalidate();
|
|
16112
16184
|
state.ui.setFocus(approvalComponent);
|
|
16113
|
-
ctx.notify("plan_approval", `Plan "${
|
|
16185
|
+
ctx.notify("plan_approval", `Plan "${resolvedTitle}" requires approval`);
|
|
16114
16186
|
});
|
|
16115
16187
|
}
|
|
16116
16188
|
|
|
@@ -16800,7 +16872,7 @@ function createTUIState(options) {
|
|
|
16800
16872
|
const editor = new CustomEditor(ui, getEditorTheme());
|
|
16801
16873
|
const result = {
|
|
16802
16874
|
// Core dependencies
|
|
16803
|
-
|
|
16875
|
+
controller: options.controller,
|
|
16804
16876
|
session: options.session,
|
|
16805
16877
|
options,
|
|
16806
16878
|
hookManager: options.hookManager,
|
|
@@ -16855,6 +16927,9 @@ function createTUIState(options) {
|
|
|
16855
16927
|
projectInfo: detectProject(process.cwd()),
|
|
16856
16928
|
modelAuthStatus: { hasAuth: true },
|
|
16857
16929
|
githubPrPollingActive: false,
|
|
16930
|
+
// Tokens/sec tracking
|
|
16931
|
+
decodeStartedAt: 0,
|
|
16932
|
+
tokensPerSec: 0,
|
|
16858
16933
|
// Goal loop
|
|
16859
16934
|
goalManager: new GoalManager(),
|
|
16860
16935
|
planStartedGoalId: void 0,
|
|
@@ -16865,7 +16940,8 @@ function createTUIState(options) {
|
|
|
16865
16940
|
pendingImages: [],
|
|
16866
16941
|
// Abort tracking
|
|
16867
16942
|
lastCtrlCTime: 0,
|
|
16868
|
-
userInitiatedAbort: false
|
|
16943
|
+
userInitiatedAbort: false,
|
|
16944
|
+
planRejectionAbort: false
|
|
16869
16945
|
};
|
|
16870
16946
|
editor.getModeColor = () => {
|
|
16871
16947
|
if (result.activeGoalJudge) {
|
|
@@ -16884,9 +16960,12 @@ function trackInteractivePrompt(ectx, promptType, properties) {
|
|
|
16884
16960
|
async function dispatchEvent(event, ectx, state) {
|
|
16885
16961
|
switch (event.type) {
|
|
16886
16962
|
case "agent_start":
|
|
16963
|
+
state.tokensPerSec = 0;
|
|
16964
|
+
state.decodeStartedAt = 0;
|
|
16887
16965
|
handleAgentStart(ectx);
|
|
16888
16966
|
break;
|
|
16889
16967
|
case "agent_end":
|
|
16968
|
+
state.decodeStartedAt = 0;
|
|
16890
16969
|
if (event.reason === "aborted") {
|
|
16891
16970
|
handleAgentAborted(ectx);
|
|
16892
16971
|
} else if (event.reason === "error") {
|
|
@@ -16899,6 +16978,9 @@ async function dispatchEvent(event, ectx, state) {
|
|
|
16899
16978
|
handleMessageStart(ectx, event.message);
|
|
16900
16979
|
break;
|
|
16901
16980
|
case "message_update":
|
|
16981
|
+
if (state.decodeStartedAt === 0) {
|
|
16982
|
+
state.decodeStartedAt = Date.now();
|
|
16983
|
+
}
|
|
16902
16984
|
handleMessageUpdate(ectx, event.message);
|
|
16903
16985
|
break;
|
|
16904
16986
|
case "message_end":
|
|
@@ -16961,7 +17043,7 @@ async function dispatchEvent(event, ectx, state) {
|
|
|
16961
17043
|
}
|
|
16962
17044
|
state.taskToolInsertIndex = -1;
|
|
16963
17045
|
await ectx.renderExistingMessages();
|
|
16964
|
-
await state.
|
|
17046
|
+
await state.controller.loadOMProgress(state.session);
|
|
16965
17047
|
getCurrentGitBranchAsync(state.projectInfo.rootPath).then((freshBranch) => {
|
|
16966
17048
|
if (freshBranch) {
|
|
16967
17049
|
state.projectInfo.gitBranch = freshBranch;
|
|
@@ -17010,8 +17092,23 @@ async function dispatchEvent(event, ectx, state) {
|
|
|
17010
17092
|
state.taskToolInsertIndex = -1;
|
|
17011
17093
|
break;
|
|
17012
17094
|
}
|
|
17013
|
-
case "usage_update":
|
|
17095
|
+
case "usage_update": {
|
|
17096
|
+
const now = Date.now();
|
|
17097
|
+
const stepTokens = (event.usage.completionTokens ?? 0) + (event.usage.reasoningTokens ?? 0);
|
|
17098
|
+
if (state.decodeStartedAt > 0 && stepTokens > 0) {
|
|
17099
|
+
const decodeSec = (now - state.decodeStartedAt) / 1e3;
|
|
17100
|
+
if (decodeSec > 0) {
|
|
17101
|
+
const instantaneous = stepTokens / decodeSec;
|
|
17102
|
+
const alpha = 0.3;
|
|
17103
|
+
const ema = state.tokensPerSec > 0 ? alpha * instantaneous + (1 - alpha) * state.tokensPerSec : instantaneous;
|
|
17104
|
+
state.tokensPerSec = Math.round(ema);
|
|
17105
|
+
}
|
|
17106
|
+
}
|
|
17107
|
+
state.decodeStartedAt = 0;
|
|
17108
|
+
ectx.updateStatusLine();
|
|
17109
|
+
state.ui.requestRender();
|
|
17014
17110
|
break;
|
|
17111
|
+
}
|
|
17015
17112
|
// Observational Memory events
|
|
17016
17113
|
case "om_status":
|
|
17017
17114
|
break;
|
|
@@ -17152,7 +17249,7 @@ async function dispatchEvent(event, ectx, state) {
|
|
|
17152
17249
|
payload.selectionMode
|
|
17153
17250
|
);
|
|
17154
17251
|
} else if (event.toolName === "submit_plan") {
|
|
17155
|
-
await handlePlanApproval(ectx, event.toolCallId, String(payload.
|
|
17252
|
+
await handlePlanApproval(ectx, event.toolCallId, String(payload.path ?? ""));
|
|
17156
17253
|
}
|
|
17157
17254
|
break;
|
|
17158
17255
|
}
|
|
@@ -17565,7 +17662,7 @@ function setupKeyboardShortcuts(state, callbacks) {
|
|
|
17565
17662
|
showInfo(state, "Resolve the plan approval first");
|
|
17566
17663
|
return;
|
|
17567
17664
|
}
|
|
17568
|
-
const modes = state.
|
|
17665
|
+
const modes = state.controller.listModes();
|
|
17569
17666
|
if (modes.length <= 1) return;
|
|
17570
17667
|
const currentId = state.session.mode.get();
|
|
17571
17668
|
const currentIndex = modes.findIndex((m) => m.id === currentId);
|
|
@@ -17634,7 +17731,7 @@ function buildLayout(state, refreshModelAuthStatus) {
|
|
|
17634
17731
|
].filter(Boolean).map((line) => theme.fg("muted", line)).join("\n");
|
|
17635
17732
|
const sep = theme.fg("dim", " \xB7 ");
|
|
17636
17733
|
const hintParts = [];
|
|
17637
|
-
if (state.
|
|
17734
|
+
if (state.controller.listModes().length > 1) {
|
|
17638
17735
|
hintParts.push(`${theme.fg("accent", "\u21E7+Tab")} ${theme.fg("muted", "cycle modes")}`);
|
|
17639
17736
|
}
|
|
17640
17737
|
hintParts.push(`${theme.fg("accent", "/help")} ${theme.fg("muted", "info & shortcuts")}`);
|
|
@@ -17749,7 +17846,7 @@ function setupAutocomplete(state) {
|
|
|
17749
17846
|
{ name: "exit", description: "Exit the TUI" },
|
|
17750
17847
|
{ name: "help", description: "Show available commands" }
|
|
17751
17848
|
];
|
|
17752
|
-
const modes = state.
|
|
17849
|
+
const modes = state.controller.listModes();
|
|
17753
17850
|
if (modes.length > 1) {
|
|
17754
17851
|
slashCommands.push({ name: "mode", description: "Switch agent mode" });
|
|
17755
17852
|
}
|
|
@@ -17800,9 +17897,9 @@ async function loadCustomSlashCommands(state) {
|
|
|
17800
17897
|
}
|
|
17801
17898
|
async function loadSkillCommands(state) {
|
|
17802
17899
|
try {
|
|
17803
|
-
let workspace = state.
|
|
17804
|
-
if (!workspace && state.
|
|
17805
|
-
workspace = await state.
|
|
17900
|
+
let workspace = state.controller.getWorkspace() ?? state.workspace;
|
|
17901
|
+
if (!workspace && state.controller.hasWorkspace()) {
|
|
17902
|
+
workspace = await state.controller.resolveWorkspace({ session: state.session });
|
|
17806
17903
|
}
|
|
17807
17904
|
if (!workspace?.skills) {
|
|
17808
17905
|
state.skillCommands = [];
|
|
@@ -17849,7 +17946,7 @@ function setupKeyHandlers(state, callbacks) {
|
|
|
17849
17946
|
process.off("SIGINT", sigintHandler);
|
|
17850
17947
|
};
|
|
17851
17948
|
}
|
|
17852
|
-
function
|
|
17949
|
+
function subscribeToAgentController(state, handleEvent) {
|
|
17853
17950
|
let eventQueue = Promise.resolve();
|
|
17854
17951
|
const listener = (event) => {
|
|
17855
17952
|
eventQueue = eventQueue.then(async () => {
|
|
@@ -18348,7 +18445,7 @@ var MastraTUI = class _MastraTUI {
|
|
|
18348
18445
|
}
|
|
18349
18446
|
/**
|
|
18350
18447
|
* Fire off a message without blocking the main loop.
|
|
18351
|
-
* Errors are handled via
|
|
18448
|
+
* Errors are handled via controller events.
|
|
18352
18449
|
*/
|
|
18353
18450
|
fireMessage(content, images) {
|
|
18354
18451
|
this.clearIdleCounter();
|
|
@@ -18516,8 +18613,8 @@ var MastraTUI = class _MastraTUI {
|
|
|
18516
18613
|
// ===========================================================================
|
|
18517
18614
|
async init() {
|
|
18518
18615
|
if (this.state.isInitialized) return;
|
|
18519
|
-
await this.state.
|
|
18520
|
-
await this.state.
|
|
18616
|
+
await this.state.controller.init();
|
|
18617
|
+
await this.state.controller.getMastra()?.startWorkers();
|
|
18521
18618
|
await loadCustomSlashCommands(this.state);
|
|
18522
18619
|
setupAutocomplete(this.state);
|
|
18523
18620
|
refreshSkillsAutocomplete(this.state).catch((err) => {
|
|
@@ -18532,12 +18629,12 @@ var MastraTUI = class _MastraTUI {
|
|
|
18532
18629
|
});
|
|
18533
18630
|
this.state.ui.start();
|
|
18534
18631
|
await promptForThreadSelection(this.state);
|
|
18535
|
-
|
|
18632
|
+
subscribeToAgentController(this.state, (event) => this.handleEvent(event));
|
|
18536
18633
|
const escState = this.state.session.state.get();
|
|
18537
18634
|
if (escState?.escapeAsCancel === false) {
|
|
18538
18635
|
this.state.editor.escapeEnabled = false;
|
|
18539
18636
|
}
|
|
18540
|
-
await this.state.
|
|
18637
|
+
await this.state.controller.loadOMProgress(this.state.session);
|
|
18541
18638
|
await syncInitialThreadState(this.state);
|
|
18542
18639
|
this.state.isInitialized = true;
|
|
18543
18640
|
if (this.state.mcpManager?.hasServers()) {
|
|
@@ -18569,7 +18666,7 @@ var MastraTUI = class _MastraTUI {
|
|
|
18569
18666
|
}, UPDATE_RECHECK_INTERVAL_MS);
|
|
18570
18667
|
}
|
|
18571
18668
|
async refreshModelAuthStatus() {
|
|
18572
|
-
this.state.modelAuthStatus = await this.state.
|
|
18669
|
+
this.state.modelAuthStatus = await this.state.controller.getCurrentModelAuthStatus(this.state.session);
|
|
18573
18670
|
updateStatusLine(this.state);
|
|
18574
18671
|
}
|
|
18575
18672
|
startIdleCounter(idleStartedAt = Date.now(), now = Date.now()) {
|
|
@@ -18631,7 +18728,7 @@ var MastraTUI = class _MastraTUI {
|
|
|
18631
18728
|
}
|
|
18632
18729
|
try {
|
|
18633
18730
|
await dispatchEvent(event, this.getEventContext(), this.state);
|
|
18634
|
-
this.
|
|
18731
|
+
this.captureAgentControllerAnalytics(event);
|
|
18635
18732
|
if (event.type === "thread_created") {
|
|
18636
18733
|
await this.syncThreadActivePackMetadata(event.thread);
|
|
18637
18734
|
} else if (event.type === "thread_changed") {
|
|
@@ -18652,7 +18749,7 @@ var MastraTUI = class _MastraTUI {
|
|
|
18652
18749
|
}
|
|
18653
18750
|
}
|
|
18654
18751
|
}
|
|
18655
|
-
|
|
18752
|
+
captureAgentControllerAnalytics(event) {
|
|
18656
18753
|
const analytics = this.state.analytics;
|
|
18657
18754
|
if (!analytics) {
|
|
18658
18755
|
return;
|
|
@@ -18688,12 +18785,12 @@ var MastraTUI = class _MastraTUI {
|
|
|
18688
18785
|
}
|
|
18689
18786
|
}
|
|
18690
18787
|
emitErrorFeedback(errorMessage) {
|
|
18691
|
-
const
|
|
18788
|
+
const controller = this.state.controller;
|
|
18692
18789
|
const traceId = this.state.session.run.getTraceId() ?? void 0;
|
|
18693
18790
|
const runId = this.state.session.getCurrentRunId() ?? void 0;
|
|
18694
18791
|
const threadId = this.state.session.thread.getId() ?? void 0;
|
|
18695
18792
|
if (!traceId && !runId && !threadId) return;
|
|
18696
|
-
const mastra2 =
|
|
18793
|
+
const mastra2 = controller.getMastra();
|
|
18697
18794
|
const observability = mastra2?.observability;
|
|
18698
18795
|
if (!observability?.addFeedback) return;
|
|
18699
18796
|
const comment = errorMessage.length > 500 ? errorMessage.slice(0, 500) + "\u2026" : errorMessage;
|
|
@@ -18747,7 +18844,7 @@ var MastraTUI = class _MastraTUI {
|
|
|
18747
18844
|
child.kill();
|
|
18748
18845
|
}
|
|
18749
18846
|
async buildProviderAccess() {
|
|
18750
|
-
const models = await this.state.
|
|
18847
|
+
const models = await this.state.controller.listAvailableModels();
|
|
18751
18848
|
const hasEnv = (provider) => models.some((m) => m.provider === provider && m.hasApiKey);
|
|
18752
18849
|
const accessLevel = (storageProviderId) => {
|
|
18753
18850
|
const cred = this.state.authStorage?.get(storageProviderId);
|
|
@@ -18891,10 +18988,10 @@ var MastraTUI = class _MastraTUI {
|
|
|
18891
18988
|
});
|
|
18892
18989
|
}
|
|
18893
18990
|
/**
|
|
18894
|
-
* Get the workspace, preferring
|
|
18991
|
+
* Get the workspace, preferring controller-owned workspace over the direct option.
|
|
18895
18992
|
*/
|
|
18896
18993
|
getResolvedWorkspace() {
|
|
18897
|
-
return this.state.
|
|
18994
|
+
return this.state.controller.getWorkspace() ?? this.state.workspace;
|
|
18898
18995
|
}
|
|
18899
18996
|
// ===========================================================================
|
|
18900
18997
|
// Observational Memory Settings
|
|
@@ -18908,7 +19005,7 @@ var MastraTUI = class _MastraTUI {
|
|
|
18908
19005
|
buildCommandContext() {
|
|
18909
19006
|
return {
|
|
18910
19007
|
state: this.state,
|
|
18911
|
-
|
|
19008
|
+
controller: this.state.controller,
|
|
18912
19009
|
session: this.state.session,
|
|
18913
19010
|
hookManager: this.state.hookManager,
|
|
18914
19011
|
mcpManager: this.state.mcpManager,
|
|
@@ -19073,7 +19170,7 @@ var MastraTUI = class _MastraTUI {
|
|
|
19073
19170
|
});
|
|
19074
19171
|
},
|
|
19075
19172
|
onSelectModel: async (title, modeColor) => {
|
|
19076
|
-
const availableModels = await this.state.
|
|
19173
|
+
const availableModels = await this.state.controller.listAvailableModels();
|
|
19077
19174
|
if (availableModels.length === 0) return void 0;
|
|
19078
19175
|
return new Promise((resolveModel) => {
|
|
19079
19176
|
const selector = new ModelSelectorComponent({
|
|
@@ -19103,9 +19200,9 @@ var MastraTUI = class _MastraTUI {
|
|
|
19103
19200
|
});
|
|
19104
19201
|
}
|
|
19105
19202
|
async applyOnboardingResult(result) {
|
|
19106
|
-
const
|
|
19203
|
+
const controller = this.state.controller;
|
|
19107
19204
|
const modePack = result.modePack;
|
|
19108
|
-
const modes =
|
|
19205
|
+
const modes = controller.listModes();
|
|
19109
19206
|
for (const mode of modes) {
|
|
19110
19207
|
const modelId = modePack.models[mode.id];
|
|
19111
19208
|
if (modelId) {
|
|
@@ -19339,5 +19436,5 @@ Would you like to update now?`;
|
|
|
19339
19436
|
};
|
|
19340
19437
|
|
|
19341
19438
|
export { AssistantMessageComponent, LoginDialogComponent, LoginSelectorComponent, MastraTUI, ModelSelectorComponent, OMProgressComponent, ToolExecutionComponentEnhanced, UserMessageComponent, createTUIState, detectTerminalTheme, formatOMStatus, getCurrentVersion };
|
|
19342
|
-
//# sourceMappingURL=chunk-
|
|
19343
|
-
//# sourceMappingURL=chunk-
|
|
19439
|
+
//# sourceMappingURL=chunk-LUSQ75XP.js.map
|
|
19440
|
+
//# sourceMappingURL=chunk-LUSQ75XP.js.map
|