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 { getPlansDir, setAuthStorage, loadSettings, MEMORY_GATEWAY_PROVIDER, getAvailableModePacks, getAvailableOmPacks, resolveModelDefaults, resolveOmRoleModel, releaseThreadLock, acquireThreadLock, saveSettings, OBSERVABILITY_AUTH_PREFIX, mastra, getCustomProviderId, getEffectiveThinkingLevel, createCodexMiddleware, THINKING_LEVEL_TO_REASONING_EFFORT, buildOpenAICodexOAuthFetch, openaiCodexProvider } from './chunk-
|
|
1
|
+
import { getLocalPlansRelativeDir, getPlansDir, setAuthStorage, loadSettings, MEMORY_GATEWAY_PROVIDER, getAvailableModePacks, getAvailableOmPacks, resolveModelDefaults, resolveOmRoleModel, releaseThreadLock, acquireThreadLock, saveSettings, OBSERVABILITY_AUTH_PREFIX, mastra, getCustomProviderId, getEffectiveThinkingLevel, createCodexMiddleware, THINKING_LEVEL_TO_REASONING_EFFORT, buildOpenAICodexOAuthFetch, openaiCodexProvider, isPlanFilePath } from './chunk-NDCWIAKG.js';
|
|
2
2
|
import { AuthStorage, DEFAULT_OM_MODEL_ID, DEFAULT_CONFIG_DIR, validateConfigDirName, detectProject, getResourceIdOverride, getStorageConfig, getObservabilityDatabasePath, getVectorDatabasePath, getCurrentGitBranchAsync, getOmScope, DEFAULT_REF_THRESHOLD, DEFAULT_OBS_THRESHOLD, getGitHubCopilotBaseUrl, fetchCopilotModels, getDatabasePath, COPILOT_HEADERS, getAppDataDir } from './chunk-Z5EMG7I2.js';
|
|
3
3
|
import { getToolCategory, MC_TOOLS, TOOL_NAME_OVERRIDES } from './chunk-UOFNLVKF.js';
|
|
4
4
|
import { createHash } from 'crypto';
|
|
@@ -7,7 +7,7 @@ import os__default, { hostname, homedir } from 'os';
|
|
|
7
7
|
import * as path from 'path';
|
|
8
8
|
import path__default, { normalize, join, dirname } from 'path';
|
|
9
9
|
import { Agent } from '@mastra/core/agent';
|
|
10
|
-
import {
|
|
10
|
+
import { AgentController } from '@mastra/core/agent-controller';
|
|
11
11
|
import { PROVIDER_REGISTRY, MastraModelGateway, MastraGateway, ModelRouterLanguageModel, GATEWAY_AUTH_HEADER, GatewayRegistry } from '@mastra/core/llm';
|
|
12
12
|
import { Mastra } from '@mastra/core/mastra';
|
|
13
13
|
import { StreamErrorRetryProcessor, PrefillErrorHandler, ProviderHistoryCompat, AgentsMDInjector, isBadRequestError } from '@mastra/core/processors';
|
|
@@ -21,7 +21,7 @@ import { Observability, SensitiveDataFilter, MastraStorageExporter, MastraPlatfo
|
|
|
21
21
|
import { spawn, execFile } from 'child_process';
|
|
22
22
|
import { createTavilySearchTool, createTavilyExtractTool } from '@mastra/tavily';
|
|
23
23
|
import { estimateTokenCount, sliceByTokens } from 'tokenx';
|
|
24
|
-
import { LocalFilesystem, createWorkspaceTools, Workspace, LocalSandbox } from '@mastra/core/workspace';
|
|
24
|
+
import { LocalFilesystem, createWorkspaceTools, Workspace, LocalSandbox, WORKSPACE_TOOLS } from '@mastra/core/workspace';
|
|
25
25
|
import { z } from 'zod';
|
|
26
26
|
import * as fs from 'fs';
|
|
27
27
|
import fs__default, { readFileSync, existsSync, mkdirSync, writeFileSync, renameSync } from 'fs';
|
|
@@ -316,7 +316,10 @@ When something breaks:
|
|
|
316
316
|
`;
|
|
317
317
|
|
|
318
318
|
// src/agents/prompts/plan.ts
|
|
319
|
-
|
|
319
|
+
function planModePrompt(_ctx) {
|
|
320
|
+
const plansDir = getLocalPlansRelativeDir();
|
|
321
|
+
const examplePath = `${plansDir}/add-dark-mode.md`;
|
|
322
|
+
return `
|
|
320
323
|
# Plan Mode \u2014 READ-ONLY (except plan files)
|
|
321
324
|
|
|
322
325
|
You are in PLAN mode. Your job is to explore the codebase and design an implementation plan \u2014 NOT to make changes to the project.
|
|
@@ -329,7 +332,7 @@ This mode is **read-only for project files**. You must NOT modify the project.
|
|
|
329
332
|
- Do NOT run commands that change state (no git commit, no npm install, no file creation)
|
|
330
333
|
- Do NOT run build commands, tests, or scripts that have side effects
|
|
331
334
|
|
|
332
|
-
The ONE exception is
|
|
335
|
+
The ONE exception is plan files: you CAN create and edit markdown files inside \`${plansDir}/\` (e.g. \`${examplePath}\`). You may NOT write anywhere else.
|
|
333
336
|
|
|
334
337
|
If the user asks you to make changes while in Plan mode, explain that you're in read-only mode and they should switch to Build mode (\`/mode build\`) first.
|
|
335
338
|
|
|
@@ -375,24 +378,25 @@ For each step:
|
|
|
375
378
|
|
|
376
379
|
## Plan File Workflow
|
|
377
380
|
|
|
378
|
-
|
|
381
|
+
Write each plan to its own markdown file under \`${plansDir}/\` (e.g. \`${examplePath}\`). Start the file with a \`# Title\` heading describing the plan.
|
|
379
382
|
|
|
380
|
-
1. **First submission**: Write your plan to
|
|
381
|
-
2. **Reading**: Use \`view\` to read
|
|
383
|
+
1. **First submission**: Write your plan to a file under \`${plansDir}/\` using \`write_file\`, then call \`submit_plan\` with the \`path\` to that file.
|
|
384
|
+
2. **Reading**: Use \`view\` to read a plan file.
|
|
382
385
|
3. **Editing**: Use \`string_replace_lsp\` for targeted edits to specific sections.
|
|
383
386
|
|
|
387
|
+
**Reuse the same file while you keep iterating on the same plan.** Only create a NEW file when you're starting a genuinely different plan \u2014 that keeps each plan available to look back at and keeps revision diffs meaningful.
|
|
388
|
+
|
|
384
389
|
## IMMEDIATE ACTION: Write plan file, then call submit_plan
|
|
385
390
|
|
|
386
391
|
As soon as your plan is complete:
|
|
387
|
-
1. Write it to
|
|
388
|
-
2. Call \`submit_plan\` with the
|
|
392
|
+
1. Write it to a file under \`${plansDir}/\` using \`write_file\`
|
|
393
|
+
2. Call \`submit_plan\` with the \`path\` to that file
|
|
389
394
|
|
|
390
|
-
**CRITICAL:** Do NOT generate a long text response describing your plan. The plan content belongs in the file
|
|
395
|
+
**CRITICAL:** Do NOT generate a long text response describing your plan. The plan content belongs in the plan file, not in your text output or the \`submit_plan\` arguments.
|
|
391
396
|
|
|
392
397
|
\`\`\`javascript
|
|
393
398
|
submit_plan({
|
|
394
|
-
|
|
395
|
-
plan: "your full plan in markdown"
|
|
399
|
+
path: "${examplePath}"
|
|
396
400
|
})
|
|
397
401
|
\`\`\`
|
|
398
402
|
|
|
@@ -404,17 +408,16 @@ The user will see the plan rendered inline and can:
|
|
|
404
408
|
## Revision Workflow
|
|
405
409
|
|
|
406
410
|
If the user requests changes, you will be stopped immediately. Wait for their next message \u2014 it will contain their revision feedback. When you receive it:
|
|
407
|
-
1. Use \`view\` to read
|
|
411
|
+
1. Use \`view\` to read the SAME plan file
|
|
408
412
|
2. Use \`string_replace_lsp\` to make targeted edits based on feedback
|
|
409
413
|
3. Use \`view\` to re-read the updated file
|
|
410
|
-
4. Call \`submit_plan\` again with the
|
|
414
|
+
4. Call \`submit_plan\` again with the same \`path\` \u2014 editing the file alone does NOT resubmit it
|
|
411
415
|
|
|
412
|
-
The user will see a diff of what changed between the previous and revised plan. Use \`string_replace_lsp\` for targeted edits so the diff is clear and meaningful \u2014 do NOT rewrite the entire plan from scratch for small changes.
|
|
413
|
-
|
|
414
|
-
**IMPORTANT**: If a plan file already exists in \`.mastracode/plans/\`, you previously submitted a plan that was rejected. Read it to see your previous attempt before revising.
|
|
416
|
+
The user will see a diff of what changed between the previous and revised plan. Use \`string_replace_lsp\` for targeted edits so the diff is clear and meaningful \u2014 do NOT rewrite the entire plan from scratch for small changes, and do NOT move the plan to a new file for a revision.
|
|
415
417
|
|
|
416
418
|
Do NOT start implementing until the plan is approved.
|
|
417
419
|
`;
|
|
420
|
+
}
|
|
418
421
|
|
|
419
422
|
// src/agents/prompts/fast.ts
|
|
420
423
|
var fastModePrompt = `
|
|
@@ -505,10 +508,62 @@ Error: ${r.error}`);
|
|
|
505
508
|
}
|
|
506
509
|
});
|
|
507
510
|
}
|
|
508
|
-
|
|
509
|
-
|
|
511
|
+
var PLAN_MODE_WRITE_TOOL_NAMES = /* @__PURE__ */ new Set([
|
|
512
|
+
WORKSPACE_TOOLS.FILESYSTEM.WRITE_FILE,
|
|
513
|
+
WORKSPACE_TOOLS.FILESYSTEM.EDIT_FILE
|
|
514
|
+
]);
|
|
515
|
+
function getRequestContextValue(requestContext, key) {
|
|
516
|
+
if (!requestContext) return void 0;
|
|
517
|
+
if (typeof requestContext.get === "function") {
|
|
518
|
+
return requestContext.get(key);
|
|
519
|
+
}
|
|
520
|
+
return requestContext[key];
|
|
521
|
+
}
|
|
522
|
+
function getHarnessContext(context) {
|
|
523
|
+
const requestContext = context?.requestContext;
|
|
524
|
+
const harness = getRequestContextValue(requestContext, "harness");
|
|
525
|
+
return harness && typeof harness === "object" ? harness : void 0;
|
|
526
|
+
}
|
|
527
|
+
function getHarnessState(harness) {
|
|
528
|
+
const state = harness?.session?.state?.get?.();
|
|
529
|
+
return state && typeof state === "object" ? state : void 0;
|
|
530
|
+
}
|
|
531
|
+
function getHarnessModeId(harness) {
|
|
532
|
+
const modeId = harness?.session?.modeId ?? getHarnessState(harness)?.modeId;
|
|
533
|
+
return typeof modeId === "string" ? modeId : void 0;
|
|
534
|
+
}
|
|
535
|
+
function getHarnessProjectPath(harness) {
|
|
536
|
+
const projectPath = getHarnessState(harness)?.projectPath;
|
|
537
|
+
return typeof projectPath === "string" ? projectPath : void 0;
|
|
538
|
+
}
|
|
539
|
+
function getToolInputPath(input) {
|
|
540
|
+
const toolPath = input?.path;
|
|
541
|
+
return typeof toolPath === "string" ? toolPath : void 0;
|
|
542
|
+
}
|
|
543
|
+
var PLAN_DIR_HINT = `${getLocalPlansRelativeDir()}/`;
|
|
544
|
+
function guardPlanModePlanFileWrites({ workspaceToolName, input, context }) {
|
|
545
|
+
if (!PLAN_MODE_WRITE_TOOL_NAMES.has(workspaceToolName)) return;
|
|
546
|
+
const harness = getHarnessContext(context);
|
|
547
|
+
if (getHarnessModeId(harness) !== "plan") return;
|
|
548
|
+
const projectPath = getHarnessProjectPath(harness);
|
|
549
|
+
const inputPath = getToolInputPath(input);
|
|
550
|
+
if (!projectPath || !inputPath) {
|
|
551
|
+
return {
|
|
552
|
+
proceed: false,
|
|
553
|
+
output: `Plan mode can only write plan files inside ${PLAN_DIR_HINT}.`
|
|
554
|
+
};
|
|
555
|
+
}
|
|
556
|
+
if (isPlanFilePath(projectPath, inputPath)) return;
|
|
557
|
+
return {
|
|
558
|
+
proceed: false,
|
|
559
|
+
output: `Plan mode can only write plan files inside ${PLAN_DIR_HINT}. Refusing to edit ${inputPath}.`
|
|
560
|
+
};
|
|
561
|
+
}
|
|
510
562
|
var MASTRACODE_WORKSPACE_TOOLS = {
|
|
511
|
-
...TOOL_NAME_OVERRIDES
|
|
563
|
+
...TOOL_NAME_OVERRIDES,
|
|
564
|
+
hooks: {
|
|
565
|
+
beforeToolCall: guardPlanModePlanFileWrites
|
|
566
|
+
}
|
|
512
567
|
};
|
|
513
568
|
var PLAN_MODE_AVAILABLE_TOOLS = [
|
|
514
569
|
// Read-only exploration tools
|
|
@@ -517,9 +572,8 @@ var PLAN_MODE_AVAILABLE_TOOLS = [
|
|
|
517
572
|
MC_TOOLS.SEARCH_CONTENT,
|
|
518
573
|
MC_TOOLS.FILE_STAT,
|
|
519
574
|
MC_TOOLS.LSP_INSPECT,
|
|
520
|
-
// Plan file writing
|
|
521
|
-
//
|
|
522
|
-
// scope writes to .mastracode/plans/)
|
|
575
|
+
// Plan file writing. Tool hooks enforce that these can only write `.md`
|
|
576
|
+
// files inside `.mastracode/plans/` while the session is in plan mode.
|
|
523
577
|
MC_TOOLS.WRITE_FILE,
|
|
524
578
|
MC_TOOLS.STRING_REPLACE_LSP,
|
|
525
579
|
// Plan delivery tools
|
|
@@ -623,7 +677,7 @@ function detectPackageRunner(projectPath) {
|
|
|
623
677
|
return "npx --yes";
|
|
624
678
|
}
|
|
625
679
|
function getDynamicWorkspace({ requestContext, mastra: mastra2 }) {
|
|
626
|
-
const ctx = requestContext.get("
|
|
680
|
+
const ctx = requestContext.get("controller");
|
|
627
681
|
const state = ctx?.getState();
|
|
628
682
|
const rawProjectPath = state?.projectPath;
|
|
629
683
|
if (!rawProjectPath) {
|
|
@@ -695,8 +749,8 @@ function isPathAllowed(targetPath, projectRoot, allowedPaths = []) {
|
|
|
695
749
|
return roots.some((root) => resolved === root || resolved.startsWith(root + path.sep));
|
|
696
750
|
}
|
|
697
751
|
function getAllowedPathsFromContext(toolContext) {
|
|
698
|
-
const
|
|
699
|
-
const state =
|
|
752
|
+
const agentControllerCtx = toolContext?.requestContext?.get("controller");
|
|
753
|
+
const state = agentControllerCtx?.getState?.() ?? agentControllerCtx?.session?.state?.get?.();
|
|
700
754
|
const projectPath = state?.projectPath ? path.resolve(state.projectPath) : process.cwd();
|
|
701
755
|
const configDir = state?.configDir ?? DEFAULT_CONFIG_DIR;
|
|
702
756
|
const skillPaths = buildSkillPaths(projectPath, configDir);
|
|
@@ -726,7 +780,7 @@ var requestSandboxAccessTool = createTool({
|
|
|
726
780
|
resumeSchema: z.union([z.string(), z.array(z.string())]),
|
|
727
781
|
execute: async ({ path: requestedPath, reason }, context) => {
|
|
728
782
|
try {
|
|
729
|
-
const
|
|
783
|
+
const agentControllerCtx = context?.requestContext?.get("controller");
|
|
730
784
|
const expanded = expandTilde(requestedPath);
|
|
731
785
|
const absolutePath = path.isAbsolute(expanded) ? expanded : path.resolve(process.cwd(), expanded);
|
|
732
786
|
const projectRoot = process.cwd();
|
|
@@ -752,13 +806,13 @@ var requestSandboxAccessTool = createTool({
|
|
|
752
806
|
const answerText = Array.isArray(resumeData) ? resumeData.join(", ") : String(resumeData);
|
|
753
807
|
const approved = answerText.toLowerCase().startsWith("y") || answerText.toLowerCase() === "approve";
|
|
754
808
|
if (approved) {
|
|
755
|
-
const currentAllowed =
|
|
809
|
+
const currentAllowed = agentControllerCtx?.getState()?.sandboxAllowedPaths ?? [];
|
|
756
810
|
if (!currentAllowed.includes(absolutePath)) {
|
|
757
|
-
await
|
|
811
|
+
await agentControllerCtx?.setState({
|
|
758
812
|
sandboxAllowedPaths: [...currentAllowed, absolutePath]
|
|
759
813
|
});
|
|
760
814
|
}
|
|
761
|
-
const fs4 =
|
|
815
|
+
const fs4 = agentControllerCtx?.workspace?.filesystem ?? context?.workspace?.filesystem;
|
|
762
816
|
if (fs4 instanceof LocalFilesystem) {
|
|
763
817
|
fs4.setAllowedPaths((prev) => [...prev, absolutePath]);
|
|
764
818
|
}
|
|
@@ -1033,14 +1087,14 @@ ${patchToolGuidance}
|
|
|
1033
1087
|
- Call this tool when your plan is complete. Do NOT just describe your plan in text \u2014 you MUST call this tool.
|
|
1034
1088
|
- The plan will be rendered as markdown and the user can approve, reject, or request changes.
|
|
1035
1089
|
- On approval, the system automatically switches to the default mode so you can implement.
|
|
1036
|
-
- Takes
|
|
1090
|
+
- Takes one argument: \`path\` (the plan markdown file you wrote under \`.mastracode/plans/\`). Do NOT pass the plan body \u2014 it lives in the file.`);
|
|
1037
1091
|
}
|
|
1038
1092
|
if (modeId === "plan") {
|
|
1039
1093
|
sections.push(`
|
|
1040
|
-
**Plan file access** \u2014 Your plan lives in \`.mastracode/plans/\`
|
|
1094
|
+
**Plan file access** \u2014 Your plan lives in a markdown file under \`.mastracode/plans/\` (e.g. \`add-dark-mode-toggle.md\`)
|
|
1041
1095
|
- Use \`write_file\` to create the plan file, \`view\` to read it, and \`string_replace_lsp\` for targeted edits.
|
|
1042
|
-
- On first submission: write the plan to the file, then call \`submit_plan\`.
|
|
1043
|
-
- On revision: read the existing file, edit specific sections, re-read, then call \`submit_plan\` with
|
|
1096
|
+
- On first submission: write the plan to the file, then call \`submit_plan\` with its \`path\`.
|
|
1097
|
+
- On revision: read the existing file, edit specific sections, re-read, then call \`submit_plan\` with the same \`path\`.
|
|
1044
1098
|
- If a plan file already exists, you previously submitted it \u2014 read it before revising.`);
|
|
1045
1099
|
}
|
|
1046
1100
|
if (!denied.has("subagent")) {
|
|
@@ -1093,9 +1147,9 @@ function buildFullPrompt(ctx) {
|
|
|
1093
1147
|
|
|
1094
1148
|
// src/agents/instructions.ts
|
|
1095
1149
|
async function getDynamicInstructions({ requestContext }) {
|
|
1096
|
-
const
|
|
1097
|
-
const state =
|
|
1098
|
-
const modeId =
|
|
1150
|
+
const agentControllerContext = requestContext.get("controller");
|
|
1151
|
+
const state = agentControllerContext?.getState();
|
|
1152
|
+
const modeId = agentControllerContext?.session?.modeId ?? "build";
|
|
1099
1153
|
const projectPath = state?.projectPath ?? process.cwd();
|
|
1100
1154
|
const promptCtx = {
|
|
1101
1155
|
projectPath,
|
|
@@ -1105,7 +1159,7 @@ async function getDynamicInstructions({ requestContext }) {
|
|
|
1105
1159
|
commonBinaries: await detectCommonBinariesAsync(),
|
|
1106
1160
|
date: (/* @__PURE__ */ new Date()).toISOString().split("T")[0],
|
|
1107
1161
|
mode: modeId,
|
|
1108
|
-
modelId:
|
|
1162
|
+
modelId: agentControllerContext?.session?.modelId || void 0,
|
|
1109
1163
|
activePlan: state?.activePlan ?? null,
|
|
1110
1164
|
modeId,
|
|
1111
1165
|
currentDate: (/* @__PURE__ */ new Date()).toISOString().split("T")[0],
|
|
@@ -1668,6 +1722,29 @@ var MastraCodeGateway = class _MastraCodeGateway extends MastraModelGateway {
|
|
|
1668
1722
|
static getMemoryGatewayApiKey() {
|
|
1669
1723
|
return authStorage.getStoredApiKey(MEMORY_GATEWAY_PROVIDER) ?? process.env["MASTRA_GATEWAY_API_KEY"];
|
|
1670
1724
|
}
|
|
1725
|
+
/**
|
|
1726
|
+
* Claim an unprefixed model id (e.g. a bare `anthropic/...`) when this gateway
|
|
1727
|
+
* can authenticate it via OAuth or a stored/env credential. This lets the
|
|
1728
|
+
* shared gateway router select MastraCode for auth resolution, so the status
|
|
1729
|
+
* bar and `/api-keys` reflect OAuth logins instead of only checking env vars.
|
|
1730
|
+
*/
|
|
1731
|
+
handlesModel(modelId) {
|
|
1732
|
+
const parsed = parseGatewayRouterId(modelId, this);
|
|
1733
|
+
if (!parsed.providerId || !parsed.modelId) return false;
|
|
1734
|
+
if (this.#routeThroughMastraGateway && this.#mastraGatewayApiKey) return true;
|
|
1735
|
+
const customProvider = this.#getCustomProviders().find(
|
|
1736
|
+
(provider) => parsed.providerId === getCustomProviderId(provider.name)
|
|
1737
|
+
);
|
|
1738
|
+
if (customProvider?.apiKey) return true;
|
|
1739
|
+
return hasResolvedAuth(
|
|
1740
|
+
_MastraCodeGateway.resolveProviderAuth({
|
|
1741
|
+
gatewayId: this.id,
|
|
1742
|
+
providerId: parsed.providerId,
|
|
1743
|
+
modelId: parsed.modelId,
|
|
1744
|
+
routerId: modelId
|
|
1745
|
+
})
|
|
1746
|
+
);
|
|
1747
|
+
}
|
|
1671
1748
|
static resolveProviderAuth(request, memoryGatewayApiKey) {
|
|
1672
1749
|
if (request.gatewayId === "mastra" && memoryGatewayApiKey) {
|
|
1673
1750
|
return { apiKey: memoryGatewayApiKey, source: "gateway" };
|
|
@@ -1878,11 +1955,11 @@ var MastraCodeGateway = class _MastraCodeGateway extends MastraModelGateway {
|
|
|
1878
1955
|
};
|
|
1879
1956
|
|
|
1880
1957
|
// src/agents/model.ts
|
|
1881
|
-
function
|
|
1882
|
-
const
|
|
1958
|
+
function getAgentControllerHeaders(requestContext) {
|
|
1959
|
+
const agentControllerContext = requestContext?.get("controller");
|
|
1883
1960
|
const headers = {
|
|
1884
|
-
...
|
|
1885
|
-
...
|
|
1961
|
+
...agentControllerContext?.threadId ? { "x-thread-id": agentControllerContext.threadId } : {},
|
|
1962
|
+
...agentControllerContext?.resourceId ? { "x-resource-id": agentControllerContext.resourceId } : {}
|
|
1886
1963
|
};
|
|
1887
1964
|
return Object.keys(headers).length > 0 ? headers : void 0;
|
|
1888
1965
|
}
|
|
@@ -1891,7 +1968,7 @@ function createMastraCodeGateway(options) {
|
|
|
1891
1968
|
}
|
|
1892
1969
|
function resolveModel(modelId, options) {
|
|
1893
1970
|
reloadAuthStorage();
|
|
1894
|
-
const headers =
|
|
1971
|
+
const headers = getAgentControllerHeaders(options?.requestContext);
|
|
1895
1972
|
const settings = loadSettings();
|
|
1896
1973
|
const isMastraGatewayModel = modelId.startsWith(MASTRA_GATEWAY_PREFIX);
|
|
1897
1974
|
const normalizedModelId = stripMastraGatewayPrefix(modelId);
|
|
@@ -1924,12 +2001,12 @@ function resolveModel(modelId, options) {
|
|
|
1924
2001
|
});
|
|
1925
2002
|
}
|
|
1926
2003
|
function getDynamicModel({ requestContext }) {
|
|
1927
|
-
const
|
|
1928
|
-
const modelId =
|
|
2004
|
+
const agentControllerContext = requestContext.get("controller");
|
|
2005
|
+
const modelId = agentControllerContext?.session?.modelId;
|
|
1929
2006
|
if (!modelId) {
|
|
1930
2007
|
throw new Error("No model selected. Use /models to select a model first.");
|
|
1931
2008
|
}
|
|
1932
|
-
const thinkingLevel =
|
|
2009
|
+
const thinkingLevel = agentControllerContext?.state?.thinkingLevel;
|
|
1933
2010
|
return resolveModel(modelId, { thinkingLevel, requestContext });
|
|
1934
2011
|
}
|
|
1935
2012
|
function getGoalJudgeModel({ requestContext }, settingsPath) {
|
|
@@ -1941,18 +2018,18 @@ function getGoalJudgeModel({ requestContext }, settingsPath) {
|
|
|
1941
2018
|
// src/agents/memory.ts
|
|
1942
2019
|
var cachedMemory = null;
|
|
1943
2020
|
var cachedMemoryKey = null;
|
|
1944
|
-
function
|
|
1945
|
-
const ctx = requestContext.get("
|
|
2021
|
+
function getAgentControllerState(requestContext) {
|
|
2022
|
+
const ctx = requestContext.get("controller");
|
|
1946
2023
|
return ctx?.getState();
|
|
1947
2024
|
}
|
|
1948
2025
|
function getObserverModel({ requestContext }) {
|
|
1949
|
-
const state =
|
|
2026
|
+
const state = getAgentControllerState(requestContext);
|
|
1950
2027
|
return resolveModel(state?.observerModelId ?? DEFAULT_OM_MODEL_ID, {
|
|
1951
2028
|
requestContext
|
|
1952
2029
|
});
|
|
1953
2030
|
}
|
|
1954
2031
|
function getReflectorModel({ requestContext }) {
|
|
1955
|
-
const state =
|
|
2032
|
+
const state = getAgentControllerState(requestContext);
|
|
1956
2033
|
return resolveModel(state?.reflectorModelId ?? DEFAULT_OM_MODEL_ID, {
|
|
1957
2034
|
requestContext
|
|
1958
2035
|
});
|
|
@@ -1982,7 +2059,7 @@ Don't say "Agent did x", say "did x". It will be assumed the agent did what was
|
|
|
1982
2059
|
Drop caveman for: security warnings, irreversible action confirmations, multi-step sequences where fragment order risks misread, user asks to clarify or repeats question, and anything that requires remembering verbatim content. Resume caveman after clear part done`;
|
|
1983
2060
|
function getDynamicMemory(storage, vector) {
|
|
1984
2061
|
return ({ requestContext }) => {
|
|
1985
|
-
const state =
|
|
2062
|
+
const state = getAgentControllerState(requestContext);
|
|
1986
2063
|
const omScope = state?.omScope ?? getOmScope(state?.projectPath);
|
|
1987
2064
|
const obsThreshold = state?.observationThreshold ?? DEFAULT_OBS_THRESHOLD;
|
|
1988
2065
|
const refThreshold = state?.reflectionThreshold ?? DEFAULT_REF_THRESHOLD;
|
|
@@ -2125,7 +2202,7 @@ var planMode = {
|
|
|
2125
2202
|
|
|
2126
2203
|
## Rules
|
|
2127
2204
|
- You have READ-ONLY access to the project. You cannot modify project files or run commands.
|
|
2128
|
-
- The one exception is
|
|
2205
|
+
- The one exception is plan files: you can create and edit markdown files inside \`.mastracode/plans/\` using \`write_file\`, \`view\`, and \`string_replace_lsp\`. You may not write anywhere else.
|
|
2129
2206
|
- First, explore the codebase to understand existing patterns, architecture, and conventions.
|
|
2130
2207
|
- Produce a concrete, actionable plan \u2014 not vague suggestions.
|
|
2131
2208
|
|
|
@@ -2136,11 +2213,13 @@ var planMode = {
|
|
|
2136
2213
|
- **Parallelize**: Make multiple independent tool calls when exploring different areas
|
|
2137
2214
|
|
|
2138
2215
|
## Plan Delivery
|
|
2139
|
-
- Write your plan to \`.mastracode/plans
|
|
2140
|
-
-
|
|
2216
|
+
- Write your plan to a markdown file under \`.mastracode/plans/\` (e.g. \`.mastracode/plans/add-dark-mode.md\`) using \`write_file\`, then call \`submit_plan({ path })\` with the path to that file (never the plan body).
|
|
2217
|
+
- Start the file with a \`# Title\` heading describing the plan.
|
|
2218
|
+
- Reuse the same file while iterating on the same plan; only create a new file for a genuinely different plan so each plan stays available to review.
|
|
2219
|
+
- Do NOT output the plan as text \u2014 it MUST live in the plan file.
|
|
2141
2220
|
- Be concise: reference files by path and line number, don't include raw contents.
|
|
2142
2221
|
- Focus on actionable details, not general observations.
|
|
2143
|
-
-
|
|
2222
|
+
- To revise after "Request changes", edit the same file in place with \`string_replace_lsp\`, and call \`submit_plan\` again with the same path.`,
|
|
2144
2223
|
metadata: {
|
|
2145
2224
|
default: false
|
|
2146
2225
|
},
|
|
@@ -2265,7 +2344,7 @@ function createToolHooks(hookManager) {
|
|
|
2265
2344
|
}
|
|
2266
2345
|
function createDynamicTools(mcpManager, extraTools, disabledTools, storage) {
|
|
2267
2346
|
return function getDynamicTools({ requestContext }) {
|
|
2268
|
-
const ctx = requestContext.get("
|
|
2347
|
+
const ctx = requestContext.get("controller");
|
|
2269
2348
|
const state = ctx?.getState();
|
|
2270
2349
|
const modelId = ctx?.session?.modelId;
|
|
2271
2350
|
const isAnthropicModel = modelId?.startsWith("anthropic/");
|
|
@@ -3148,12 +3227,16 @@ var HookManager = class {
|
|
|
3148
3227
|
function loadMcpConfig(projectDir, configDirName = DEFAULT_CONFIG_DIR) {
|
|
3149
3228
|
const claudeConfig = loadClaudeSettings(projectDir);
|
|
3150
3229
|
const globalConfig = loadSingleConfig2(getGlobalMcpPath(configDirName));
|
|
3230
|
+
const rootConfig = loadSingleConfig2(getRootMcpPath(projectDir));
|
|
3151
3231
|
const projectConfig = loadSingleConfig2(getProjectMcpPath(projectDir, configDirName));
|
|
3152
|
-
return mergeConfigs2(claudeConfig, globalConfig, projectConfig);
|
|
3232
|
+
return mergeConfigs2(claudeConfig, globalConfig, rootConfig, projectConfig);
|
|
3153
3233
|
}
|
|
3154
3234
|
function getProjectMcpPath(projectDir, configDirName = DEFAULT_CONFIG_DIR) {
|
|
3155
3235
|
return path.join(projectDir, configDirName, "mcp.json");
|
|
3156
3236
|
}
|
|
3237
|
+
function getRootMcpPath(projectDir) {
|
|
3238
|
+
return path.join(projectDir, ".mcp.json");
|
|
3239
|
+
}
|
|
3157
3240
|
function getGlobalMcpPath(configDirName = DEFAULT_CONFIG_DIR) {
|
|
3158
3241
|
return path.join(os.homedir(), configDirName, "mcp.json");
|
|
3159
3242
|
}
|
|
@@ -3693,6 +3776,21 @@ function createMcpManager(projectDir, configDirName = DEFAULT_CONFIG_DIR, extraS
|
|
|
3693
3776
|
|
|
3694
3777
|
// src/processors/plan-rejection-abort.ts
|
|
3695
3778
|
var PLAN_REJECTED_PREFIX = "Plan was not approved";
|
|
3779
|
+
function resultText(result) {
|
|
3780
|
+
if (typeof result === "string") return result;
|
|
3781
|
+
if (result && typeof result === "object") {
|
|
3782
|
+
const content = result.content;
|
|
3783
|
+
if (typeof content === "string") return content;
|
|
3784
|
+
}
|
|
3785
|
+
return "";
|
|
3786
|
+
}
|
|
3787
|
+
function isPlanRejection(inv) {
|
|
3788
|
+
if (!inv || inv.state !== "result" || inv.toolName !== "submit_plan") return false;
|
|
3789
|
+
return resultText(inv.result).startsWith(PLAN_REJECTED_PREFIX);
|
|
3790
|
+
}
|
|
3791
|
+
function isPlanRejectionResultPart(part) {
|
|
3792
|
+
return part.type === "tool_result" && part.name === "submit_plan" && resultText(part.result).startsWith(PLAN_REJECTED_PREFIX);
|
|
3793
|
+
}
|
|
3696
3794
|
var PlanRejectionAbortProcessor = class {
|
|
3697
3795
|
id = "plan-rejection-abort";
|
|
3698
3796
|
async processInputStep({ messages, stepNumber, abort }) {
|
|
@@ -3701,18 +3799,24 @@ var PlanRejectionAbortProcessor = class {
|
|
|
3701
3799
|
const msg = messages[i];
|
|
3702
3800
|
if (!msg || msg.role !== "assistant") continue;
|
|
3703
3801
|
const content = msg.content;
|
|
3704
|
-
const parts = content?.parts;
|
|
3705
|
-
if (!Array.isArray(parts)) break;
|
|
3802
|
+
const parts = Array.isArray(content) ? content : Array.isArray(content?.parts) ? content.parts : [];
|
|
3706
3803
|
for (const part of parts) {
|
|
3707
3804
|
if (!part || typeof part !== "object") continue;
|
|
3708
3805
|
const p = part;
|
|
3709
|
-
if (p.type
|
|
3710
|
-
|
|
3711
|
-
|
|
3712
|
-
|
|
3713
|
-
|
|
3714
|
-
|
|
3806
|
+
if (p.type === "tool-invocation" && isPlanRejection(p.toolInvocation)) {
|
|
3807
|
+
abort("Plan rejected by user \u2014 no further response needed");
|
|
3808
|
+
return void 0;
|
|
3809
|
+
}
|
|
3810
|
+
if (isPlanRejectionResultPart(p)) {
|
|
3811
|
+
abort("Plan rejected by user \u2014 no further response needed");
|
|
3812
|
+
return void 0;
|
|
3813
|
+
}
|
|
3814
|
+
}
|
|
3815
|
+
const legacy = !Array.isArray(content) && Array.isArray(content?.toolInvocations) ? content.toolInvocations : [];
|
|
3816
|
+
for (const inv of legacy) {
|
|
3817
|
+
if (isPlanRejection(inv)) {
|
|
3715
3818
|
abort("Plan rejected by user \u2014 no further response needed");
|
|
3819
|
+
return void 0;
|
|
3716
3820
|
}
|
|
3717
3821
|
}
|
|
3718
3822
|
break;
|
|
@@ -3721,10 +3825,10 @@ var PlanRejectionAbortProcessor = class {
|
|
|
3721
3825
|
}
|
|
3722
3826
|
};
|
|
3723
3827
|
var stateSchema = z.object({
|
|
3724
|
-
// Session-scoped selection.
|
|
3828
|
+
// Session-scoped selection.
|
|
3725
3829
|
// validates state against this schema, so they MUST be declared here — Zod
|
|
3726
3830
|
// strips unknown keys on parse, which would otherwise silently discard the
|
|
3727
|
-
// seeded model and leave the
|
|
3831
|
+
// seeded model and leave the controller with no model selected.
|
|
3728
3832
|
currentModelId: z.string().optional(),
|
|
3729
3833
|
modeId: z.string().optional(),
|
|
3730
3834
|
subagentModelId: z.string().optional(),
|
|
@@ -4046,7 +4150,7 @@ function resolveCloudObservabilityConfig(settings, authStorage2, resourceId) {
|
|
|
4046
4150
|
projectId: process.env.MASTRA_PROJECT_ID
|
|
4047
4151
|
};
|
|
4048
4152
|
}
|
|
4049
|
-
async function
|
|
4153
|
+
async function createMastraCodeAgentController(config) {
|
|
4050
4154
|
const cwd = config?.cwd ?? process.cwd();
|
|
4051
4155
|
const homeDir = config?.homeDir ?? config?.initialState?.homeDir;
|
|
4052
4156
|
const configDir = config?.configDir ?? DEFAULT_CONFIG_DIR;
|
|
@@ -4147,11 +4251,11 @@ async function createMastraCodeHarness(config) {
|
|
|
4147
4251
|
default: {
|
|
4148
4252
|
serviceName: "mastracode",
|
|
4149
4253
|
// Only these requestContext keys are stored on spans — prevents leaking
|
|
4150
|
-
// large objects (
|
|
4151
|
-
// Use dot-notation because these are nested inside the '
|
|
4254
|
+
// large objects (controller state, workspace, env vars) into trace data.
|
|
4255
|
+
// Use dot-notation because these are nested inside the 'controller' key.
|
|
4152
4256
|
//
|
|
4153
4257
|
// Session identifiers:
|
|
4154
|
-
// threadId, resourceId, session.modeId,
|
|
4258
|
+
// threadId, resourceId, session.modeId, agentControllerId
|
|
4155
4259
|
// Environment & project:
|
|
4156
4260
|
// state.projectName, state.gitBranch
|
|
4157
4261
|
// Model configuration:
|
|
@@ -4163,26 +4267,26 @@ async function createMastraCodeHarness(config) {
|
|
|
4163
4267
|
// state.observationThreshold, state.reflectionThreshold
|
|
4164
4268
|
requestContextKeys: [
|
|
4165
4269
|
// Session identifiers
|
|
4166
|
-
"
|
|
4167
|
-
"
|
|
4168
|
-
"
|
|
4169
|
-
"
|
|
4270
|
+
"controller.threadId",
|
|
4271
|
+
"controller.resourceId",
|
|
4272
|
+
"controller.session.modeId",
|
|
4273
|
+
"controller.controllerId",
|
|
4170
4274
|
// Environment & project
|
|
4171
|
-
"
|
|
4172
|
-
"
|
|
4275
|
+
"controller.state.projectName",
|
|
4276
|
+
"controller.state.gitBranch",
|
|
4173
4277
|
// Model configuration
|
|
4174
|
-
"
|
|
4175
|
-
"
|
|
4278
|
+
"controller.session.modelId",
|
|
4279
|
+
"controller.state.subagentModelId",
|
|
4176
4280
|
// Agent settings
|
|
4177
|
-
"
|
|
4178
|
-
"
|
|
4179
|
-
"
|
|
4281
|
+
"controller.state.yolo",
|
|
4282
|
+
"controller.state.thinkingLevel",
|
|
4283
|
+
"controller.state.smartEditing",
|
|
4180
4284
|
// Observational memory settings
|
|
4181
|
-
"
|
|
4182
|
-
"
|
|
4183
|
-
"
|
|
4184
|
-
"
|
|
4185
|
-
"
|
|
4285
|
+
"controller.state.omScope",
|
|
4286
|
+
"controller.state.observerModelId",
|
|
4287
|
+
"controller.state.reflectorModelId",
|
|
4288
|
+
"controller.state.observationThreshold",
|
|
4289
|
+
"controller.state.reflectionThreshold"
|
|
4186
4290
|
],
|
|
4187
4291
|
exporters: [
|
|
4188
4292
|
// Only persist traces locally when DuckDB observability is available
|
|
@@ -4206,13 +4310,13 @@ async function createMastraCodeHarness(config) {
|
|
|
4206
4310
|
cwd: project.rootPath,
|
|
4207
4311
|
gitcrawlCommand: process.env.MASTRACODE_GITCRAWL_BIN ?? process.env.GITCRAWL_BIN ?? process.env.MASTRACODE_GITCRAWL_COMMAND ?? process.env.GITCRAWL_COMMAND,
|
|
4208
4312
|
getNotificationStreamOptions: async ({ resourceId, threadId }) => {
|
|
4209
|
-
const session = await
|
|
4313
|
+
const session = await controller.getSessionByResource(resourceId) ?? activeSession;
|
|
4210
4314
|
const modeId = session.mode.get();
|
|
4211
|
-
const defaultModeModelId =
|
|
4315
|
+
const defaultModeModelId = controller.listModes().find((mode) => mode.id === modeId)?.defaultModelId;
|
|
4212
4316
|
const modelId = session.model.get() || activeSession?.model.get() || defaultModeModelId || "";
|
|
4213
4317
|
const requestContext = new RequestContext();
|
|
4214
|
-
const
|
|
4215
|
-
|
|
4318
|
+
const agentControllerContext = {
|
|
4319
|
+
controllerId: controller.id,
|
|
4216
4320
|
state: session.state.get(),
|
|
4217
4321
|
getState: () => session.state.get(),
|
|
4218
4322
|
setState: (updates) => session.state.set(updates),
|
|
@@ -4229,10 +4333,10 @@ async function createMastraCodeHarness(config) {
|
|
|
4229
4333
|
update: (updater) => session.state.update(updater)
|
|
4230
4334
|
}
|
|
4231
4335
|
},
|
|
4232
|
-
workspace:
|
|
4336
|
+
workspace: controller.getWorkspace(),
|
|
4233
4337
|
getSubagentModelId: (params) => session.subagents.model.get(params ?? {})
|
|
4234
4338
|
};
|
|
4235
|
-
requestContext.set("
|
|
4339
|
+
requestContext.set("controller", agentControllerContext);
|
|
4236
4340
|
return {
|
|
4237
4341
|
memory: { thread: threadId, resource: resourceId },
|
|
4238
4342
|
requestContext,
|
|
@@ -4290,8 +4394,8 @@ async function createMastraCodeHarness(config) {
|
|
|
4290
4394
|
new PlanRejectionAbortProcessor(),
|
|
4291
4395
|
new AgentsMDInjector({
|
|
4292
4396
|
getIgnoredInstructionPaths: ({ requestContext }) => {
|
|
4293
|
-
const
|
|
4294
|
-
const state =
|
|
4397
|
+
const agentControllerContext = requestContext?.get("controller");
|
|
4398
|
+
const state = agentControllerContext?.getState();
|
|
4295
4399
|
return getStaticallyLoadedInstructionPaths(state?.projectPath ?? project.rootPath);
|
|
4296
4400
|
}
|
|
4297
4401
|
}),
|
|
@@ -4423,7 +4527,7 @@ async function createMastraCodeHarness(config) {
|
|
|
4423
4527
|
}
|
|
4424
4528
|
}
|
|
4425
4529
|
const typedStateSchema = stateSchema;
|
|
4426
|
-
const
|
|
4530
|
+
const controller = new AgentController({
|
|
4427
4531
|
id: "mastra-code",
|
|
4428
4532
|
resourceId: project.resourceId,
|
|
4429
4533
|
storage,
|
|
@@ -4436,6 +4540,7 @@ async function createMastraCodeHarness(config) {
|
|
|
4436
4540
|
gateways: [mastraCodeGateway],
|
|
4437
4541
|
workspace: config?.workspace ?? ((args) => getDynamicWorkspace(args)),
|
|
4438
4542
|
browser: config?.browser,
|
|
4543
|
+
idGenerator: config?.idGenerator,
|
|
4439
4544
|
toolCategoryResolver: getToolCategory,
|
|
4440
4545
|
initialState: {
|
|
4441
4546
|
projectPath: project.rootPath,
|
|
@@ -4464,10 +4569,9 @@ async function createMastraCodeHarness(config) {
|
|
|
4464
4569
|
acquire: acquireThreadLock,
|
|
4465
4570
|
release: releaseThreadLock
|
|
4466
4571
|
}
|
|
4467
|
-
// , harnessV1
|
|
4468
4572
|
});
|
|
4469
4573
|
return {
|
|
4470
|
-
|
|
4574
|
+
controller,
|
|
4471
4575
|
storage,
|
|
4472
4576
|
observability,
|
|
4473
4577
|
memory,
|
|
@@ -4534,32 +4638,32 @@ async function wireSessionConcerns(base, session) {
|
|
|
4534
4638
|
await restoreOMThreadStateForCurrentThread(omThreadStateSession).catch(() => {
|
|
4535
4639
|
});
|
|
4536
4640
|
}
|
|
4537
|
-
async function
|
|
4538
|
-
const base = await
|
|
4539
|
-
const {
|
|
4540
|
-
await
|
|
4541
|
-
await
|
|
4542
|
-
const session = await
|
|
4641
|
+
async function bootLocalAgentController(config) {
|
|
4642
|
+
const base = await createMastraCodeAgentController(config);
|
|
4643
|
+
const { controller, sessionId, ownerId } = base;
|
|
4644
|
+
await controller.init();
|
|
4645
|
+
await controller.getMastra()?.startWorkers();
|
|
4646
|
+
const session = await controller.createSession({ id: sessionId, ownerId });
|
|
4543
4647
|
await wireSessionConcerns(base, session);
|
|
4544
4648
|
return { ...base, session };
|
|
4545
4649
|
}
|
|
4546
|
-
async function
|
|
4547
|
-
const base = await
|
|
4548
|
-
const {
|
|
4549
|
-
const
|
|
4650
|
+
async function mountAgentControllerOnMastra(config) {
|
|
4651
|
+
const base = await createMastraCodeAgentController(config);
|
|
4652
|
+
const { controller, storage } = base;
|
|
4653
|
+
const controllerId = config?.controllerId ?? controller.id;
|
|
4550
4654
|
let mastra2;
|
|
4551
4655
|
if (config?.mastra) {
|
|
4552
4656
|
mastra2 = config.mastra;
|
|
4553
|
-
|
|
4657
|
+
controller.__registerMastra(mastra2);
|
|
4554
4658
|
} else {
|
|
4555
|
-
mastra2 = new Mastra({
|
|
4659
|
+
mastra2 = new Mastra({ agentControllers: { [controllerId]: controller }, storage });
|
|
4556
4660
|
}
|
|
4557
|
-
await
|
|
4558
|
-
await
|
|
4661
|
+
await controller.init();
|
|
4662
|
+
await controller.getMastra()?.startWorkers();
|
|
4559
4663
|
return { ...base, mastra: mastra2 };
|
|
4560
4664
|
}
|
|
4561
|
-
var createMastraCode =
|
|
4665
|
+
var createMastraCode = bootLocalAgentController;
|
|
4562
4666
|
|
|
4563
|
-
export {
|
|
4564
|
-
//# sourceMappingURL=chunk-
|
|
4565
|
-
//# sourceMappingURL=chunk-
|
|
4667
|
+
export { bootLocalAgentController, createAuthStorage, createMastraCode, createMastraCodeAgentController, mountAgentControllerOnMastra, wireSessionConcerns };
|
|
4668
|
+
//# sourceMappingURL=chunk-GT3A3LAA.js.map
|
|
4669
|
+
//# sourceMappingURL=chunk-GT3A3LAA.js.map
|