mastracode 0.4.0 → 0.5.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 +328 -0
- package/LICENSE.md +15 -0
- package/README.md +68 -29
- package/dist/agents/memory.d.ts.map +1 -1
- package/dist/agents/model.d.ts +17 -6
- package/dist/agents/model.d.ts.map +1 -1
- package/dist/agents/prompts/index.d.ts.map +1 -1
- package/dist/agents/prompts/tool-guidance.d.ts +2 -0
- package/dist/agents/prompts/tool-guidance.d.ts.map +1 -1
- package/dist/agents/subagents/audit-tests.d.ts +0 -7
- package/dist/agents/subagents/audit-tests.d.ts.map +1 -1
- package/dist/agents/subagents/execute.d.ts +0 -7
- package/dist/agents/subagents/execute.d.ts.map +1 -1
- package/dist/agents/subagents/explore.d.ts +0 -7
- package/dist/agents/subagents/explore.d.ts.map +1 -1
- package/dist/agents/subagents/index.d.ts.map +1 -1
- package/dist/agents/subagents/plan.d.ts +0 -7
- package/dist/agents/subagents/plan.d.ts.map +1 -1
- package/dist/agents/tools.d.ts +3 -1
- package/dist/agents/tools.d.ts.map +1 -1
- package/dist/agents/workspace.d.ts +4 -1
- package/dist/agents/workspace.d.ts.map +1 -1
- package/dist/{chunk-K4WJUBEC.cjs → chunk-AJEYT7X3.cjs} +763 -429
- package/dist/chunk-AJEYT7X3.cjs.map +1 -0
- package/dist/{chunk-U5A7TFNT.js → chunk-CC2724NI.js} +46 -10
- package/dist/chunk-CC2724NI.js.map +1 -0
- package/dist/{chunk-REVOTI2T.js → chunk-JI4M5525.js} +740 -412
- package/dist/chunk-JI4M5525.js.map +1 -0
- package/dist/{chunk-Z4QRXVST.cjs → chunk-MBPGUMYQ.cjs} +325 -251
- package/dist/chunk-MBPGUMYQ.cjs.map +1 -0
- package/dist/{chunk-MT3YCFCC.cjs → chunk-OEDRHUU5.cjs} +47 -9
- package/dist/chunk-OEDRHUU5.cjs.map +1 -0
- package/dist/{chunk-M5LKPQB4.js → chunk-WKPHD54B.js} +283 -209
- package/dist/chunk-WKPHD54B.js.map +1 -0
- package/dist/{chunk-C4X3C2DL.cjs → chunk-XVYUS2EA.cjs} +2213 -1035
- package/dist/chunk-XVYUS2EA.cjs.map +1 -0
- package/dist/{chunk-X3BGE7CL.js → chunk-YQNZ7DHQ.js} +1788 -613
- package/dist/chunk-YQNZ7DHQ.js.map +1 -0
- package/dist/cli.cjs +79 -31
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +71 -23
- package/dist/cli.js.map +1 -1
- package/dist/clipboard/index.d.ts +5 -0
- package/dist/clipboard/index.d.ts.map +1 -1
- package/dist/error-classification.d.ts +10 -0
- package/dist/error-classification.d.ts.map +1 -0
- package/dist/index.cjs +2 -2
- package/dist/index.d.ts +10 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/mcp/config.d.ts +8 -0
- package/dist/mcp/config.d.ts.map +1 -1
- package/dist/mcp/index.d.ts +1 -1
- package/dist/mcp/index.d.ts.map +1 -1
- package/dist/mcp/manager.d.ts +4 -2
- package/dist/mcp/manager.d.ts.map +1 -1
- package/dist/mcp/types.d.ts +30 -3
- package/dist/mcp/types.d.ts.map +1 -1
- package/dist/onboarding/onboarding-inline.d.ts +2 -0
- package/dist/onboarding/onboarding-inline.d.ts.map +1 -1
- package/dist/onboarding/packs.d.ts +1 -0
- package/dist/onboarding/packs.d.ts.map +1 -1
- package/dist/onboarding/settings.d.ts +37 -2
- package/dist/onboarding/settings.d.ts.map +1 -1
- package/dist/permissions-S3LGXIDB.js +3 -0
- package/dist/{permissions-CVXKYIWR.js.map → permissions-S3LGXIDB.js.map} +1 -1
- package/dist/permissions-VGABAVGD.cjs +40 -0
- package/dist/{permissions-2HIUSRQN.cjs.map → permissions-VGABAVGD.cjs.map} +1 -1
- package/dist/permissions.d.ts.map +1 -1
- package/dist/providers/claude-max.d.ts +13 -0
- package/dist/providers/claude-max.d.ts.map +1 -1
- package/dist/providers/openai-codex.d.ts +1 -0
- package/dist/providers/openai-codex.d.ts.map +1 -1
- package/dist/tool-names.d.ts +68 -0
- package/dist/tool-names.d.ts.map +1 -0
- package/dist/tools/ast-smart-edit.d.ts +77 -5
- package/dist/tools/ast-smart-edit.d.ts.map +1 -1
- package/dist/tools/index.d.ts +2 -2
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/string-replace-lsp.d.ts +15 -0
- package/dist/tools/string-replace-lsp.d.ts.map +1 -1
- package/dist/tools/subagent.d.ts.map +1 -1
- package/dist/tools/utils.d.ts +4 -2
- package/dist/tools/utils.d.ts.map +1 -1
- package/dist/tui/command-dispatch.d.ts.map +1 -1
- package/dist/tui/commands/clone.d.ts +29 -0
- package/dist/tui/commands/clone.d.ts.map +1 -0
- package/dist/tui/commands/custom-providers.d.ts +8 -0
- package/dist/tui/commands/custom-providers.d.ts.map +1 -0
- package/dist/tui/commands/index.d.ts +3 -1
- package/dist/tui/commands/index.d.ts.map +1 -1
- package/dist/tui/commands/mcp.d.ts.map +1 -1
- package/dist/tui/commands/models-pack.d.ts +4 -0
- package/dist/tui/commands/models-pack.d.ts.map +1 -1
- package/dist/tui/commands/om.d.ts.map +1 -1
- package/dist/tui/commands/report-issue.d.ts +3 -0
- package/dist/tui/commands/report-issue.d.ts.map +1 -0
- package/dist/tui/commands/resource.d.ts.map +1 -1
- package/dist/tui/commands/settings.d.ts.map +1 -1
- package/dist/tui/commands/threads.d.ts +1 -0
- package/dist/tui/commands/threads.d.ts.map +1 -1
- package/dist/tui/components/ask-question-inline.d.ts +3 -0
- package/dist/tui/components/ask-question-inline.d.ts.map +1 -1
- package/dist/tui/components/custom-editor.d.ts +1 -1
- package/dist/tui/components/custom-editor.d.ts.map +1 -1
- package/dist/tui/components/help-overlay.d.ts.map +1 -1
- package/dist/tui/components/plan-approval-inline.d.ts.map +1 -1
- package/dist/tui/components/settings.d.ts +2 -0
- package/dist/tui/components/settings.d.ts.map +1 -1
- package/dist/tui/components/subagent-execution.d.ts +6 -1
- package/dist/tui/components/subagent-execution.d.ts.map +1 -1
- package/dist/tui/components/thread-selector.d.ts +6 -0
- package/dist/tui/components/thread-selector.d.ts.map +1 -1
- package/dist/tui/components/tool-execution-enhanced.d.ts +1 -0
- package/dist/tui/components/tool-execution-enhanced.d.ts.map +1 -1
- package/dist/tui/components/tool-validation-error.d.ts.map +1 -1
- package/dist/tui/handlers/message.d.ts.map +1 -1
- package/dist/tui/handlers/prompts.d.ts +6 -0
- package/dist/tui/handlers/prompts.d.ts.map +1 -1
- package/dist/tui/handlers/subagent.d.ts.map +1 -1
- package/dist/tui/mastra-tui.d.ts +14 -5
- package/dist/tui/mastra-tui.d.ts.map +1 -1
- package/dist/tui/render-messages.d.ts.map +1 -1
- package/dist/tui/setup.d.ts.map +1 -1
- package/dist/tui/state.d.ts +4 -5
- package/dist/tui/state.d.ts.map +1 -1
- package/dist/tui.cjs +19 -19
- package/dist/tui.js +2 -2
- package/dist/utils/debug-log.d.ts +12 -0
- package/dist/utils/debug-log.d.ts.map +1 -0
- package/dist/utils/plans.d.ts +7 -0
- package/dist/utils/plans.d.ts.map +1 -0
- package/dist/utils/update-check.d.ts +40 -0
- package/dist/utils/update-check.d.ts.map +1 -0
- package/package.json +8 -8
- package/dist/chunk-C4X3C2DL.cjs.map +0 -1
- package/dist/chunk-K4WJUBEC.cjs.map +0 -1
- package/dist/chunk-M5LKPQB4.js.map +0 -1
- package/dist/chunk-MT3YCFCC.cjs.map +0 -1
- package/dist/chunk-REVOTI2T.js.map +0 -1
- package/dist/chunk-U5A7TFNT.js.map +0 -1
- package/dist/chunk-X3BGE7CL.js.map +0 -1
- package/dist/chunk-Z4QRXVST.cjs.map +0 -1
- package/dist/docs/SKILL.md +0 -30
- package/dist/docs/assets/SOURCE_MAP.json +0 -11
- package/dist/docs/references/docs-mastra-code-configuration.md +0 -299
- package/dist/docs/references/docs-mastra-code-customization.md +0 -228
- package/dist/docs/references/docs-mastra-code-modes.md +0 -104
- package/dist/docs/references/docs-mastra-code-overview.md +0 -135
- package/dist/docs/references/docs-mastra-code-tools.md +0 -229
- package/dist/docs/references/reference-mastra-code-createMastraCode.md +0 -108
- package/dist/permissions-2HIUSRQN.cjs +0 -40
- package/dist/permissions-CVXKYIWR.js +0 -3
- package/dist/tui/commands/models.d.ts +0 -3
- package/dist/tui/commands/models.d.ts.map +0 -1
|
@@ -1,23 +1,21 @@
|
|
|
1
|
-
import { setAuthStorage, setAuthStorage2, loadSettings, getDynamicModel, createViewTool, createGrepTool, createGlobTool, createExecuteCommandTool, createWriteFileTool, getAvailableModePacks, getAvailableOmPacks, resolveModelDefaults, resolveOmModel, mastra, exploreSubagent, planSubagent,
|
|
1
|
+
import { setAuthStorage, setAuthStorage2, loadSettings, getDynamicModel, createViewTool, createGrepTool, createGlobTool, createExecuteCommandTool, createWriteFileTool, createStringReplaceLspTool, getAvailableModePacks, getAvailableOmPacks, resolveModelDefaults, resolveOmModel, mastra, exploreSubagent, planSubagent, executeSubagent, releaseThreadLock, acquireThreadLock, getDynamicWorkspace, resolveModel, getCustomProviderId, toCustomProviderModelId, saveSettings, hasTavilyKey, createWebSearchTool, createWebExtractTool, requestSandboxAccessTool } from './chunk-JI4M5525.js';
|
|
2
2
|
import { AuthStorage, detectProject, getResourceIdOverride, getStorageConfig, getCurrentGitBranch, getOmScope, getDatabasePath } from './chunk-SM3QCOA7.js';
|
|
3
|
-
import { getToolCategory } from './chunk-
|
|
4
|
-
import { Mastra } from '@mastra/core';
|
|
3
|
+
import { getToolCategory, MC_TOOLS } from './chunk-CC2724NI.js';
|
|
5
4
|
import { Agent } from '@mastra/core/agent';
|
|
6
5
|
import { taskCheckTool, taskWriteTool, Harness } from '@mastra/core/harness';
|
|
7
|
-
import {
|
|
8
|
-
import * as
|
|
9
|
-
import
|
|
6
|
+
import { PROVIDER_REGISTRY, ModelsDevGateway, NetlifyGateway } from '@mastra/core/llm';
|
|
7
|
+
import * as fs3 from 'fs';
|
|
8
|
+
import fs3__default, { readFileSync, existsSync } from 'fs';
|
|
10
9
|
import * as os from 'os';
|
|
11
10
|
import os__default, { homedir } from 'os';
|
|
12
|
-
import * as
|
|
13
|
-
import
|
|
11
|
+
import * as path3 from 'path';
|
|
12
|
+
import path3__default, { join } from 'path';
|
|
14
13
|
import { Memory } from '@mastra/memory';
|
|
15
14
|
import { createAnthropic } from '@ai-sdk/anthropic';
|
|
16
|
-
import {
|
|
15
|
+
import { createOpenAI } from '@ai-sdk/openai';
|
|
17
16
|
import { spawn } from 'child_process';
|
|
18
17
|
import { MCPClient } from '@mastra/mcp';
|
|
19
18
|
import { z } from 'zod';
|
|
20
|
-
import { ModelsDevGateway, NetlifyGateway } from '@mastra/core/llm';
|
|
21
19
|
import { LibSQLStore } from '@mastra/libsql';
|
|
22
20
|
import { PostgresStore } from '@mastra/pg';
|
|
23
21
|
|
|
@@ -326,80 +324,117 @@ ${sections.join("\n\n")}
|
|
|
326
324
|
|
|
327
325
|
// src/agents/prompts/tool-guidance.ts
|
|
328
326
|
function buildToolGuidance(modeId, options = {}) {
|
|
327
|
+
const denied = options.deniedTools ?? /* @__PURE__ */ new Set();
|
|
329
328
|
const sections = [];
|
|
330
329
|
sections.push(`# Tool Usage Rules
|
|
331
330
|
|
|
332
331
|
IMPORTANT: You can ONLY call tools by their exact registered names listed below. Shell commands like \`git\`, \`npm\`, \`ls\`, etc. are NOT tools \u2014 they must be run via the \`execute_command\` tool.
|
|
333
332
|
|
|
334
333
|
You have access to the following tools. Use the RIGHT tool for the job:`);
|
|
335
|
-
|
|
336
|
-
|
|
334
|
+
const readTools = [];
|
|
335
|
+
if (!denied.has(MC_TOOLS.VIEW)) {
|
|
336
|
+
readTools.push(`
|
|
337
|
+
**${MC_TOOLS.VIEW}** \u2014 Read file contents
|
|
337
338
|
- Use this to read files before editing them. NEVER propose changes to code you haven't read.
|
|
338
|
-
- Use \`
|
|
339
|
-
-
|
|
340
|
-
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
-
|
|
346
|
-
-
|
|
347
|
-
- Example: Find
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
-
|
|
355
|
-
|
|
356
|
-
|
|
339
|
+
- Use \`offset\` (1-indexed start line) and \`limit\` (number of lines) for large files.
|
|
340
|
+
- Example: Read lines 50-100: \`{ path: "src/big-file.ts", offset: 50, limit: 51 }\`
|
|
341
|
+
- To list directories, use \`${MC_TOOLS.FIND_FILES}\` instead.`);
|
|
342
|
+
}
|
|
343
|
+
if (!denied.has(MC_TOOLS.SEARCH_CONTENT)) {
|
|
344
|
+
readTools.push(`
|
|
345
|
+
**${MC_TOOLS.SEARCH_CONTENT}** \u2014 Search file contents using regex
|
|
346
|
+
- Preferred for content search (finding functions, variables, error messages, imports, etc.)
|
|
347
|
+
- Use \`path\` to filter by directory or glob pattern. Supports \`contextLines\`, \`caseSensitive\`, and \`maxCount\`.
|
|
348
|
+
- Example: Find a function: \`{ pattern: "function handleSubmit", path: "**/*.ts" }\`
|
|
349
|
+
- Example: Find imports: \`{ pattern: "from ['\\"\\]express['\\"\\]", path: "**/*.ts" }\`
|
|
350
|
+
- Respects .gitignore by default.`);
|
|
351
|
+
}
|
|
352
|
+
if (!denied.has(MC_TOOLS.FIND_FILES)) {
|
|
353
|
+
readTools.push(`
|
|
354
|
+
**${MC_TOOLS.FIND_FILES}** \u2014 List files and directories as a tree
|
|
355
|
+
- Preferred for exploring project structure and finding files by pattern.
|
|
356
|
+
- Returns tree-style output. Respects .gitignore by default.
|
|
357
|
+
- Example: List project root: \`{ path: "./" }\`
|
|
358
|
+
- Example: Find test files: \`{ path: "./src", pattern: "**/*.test.ts" }\`
|
|
359
|
+
- Example: Find config files: \`{ pattern: "*.config.{js,ts,json}" }\``);
|
|
360
|
+
}
|
|
361
|
+
if (!denied.has(MC_TOOLS.EXECUTE_COMMAND)) {
|
|
362
|
+
readTools.push(`
|
|
363
|
+
**${MC_TOOLS.EXECUTE_COMMAND}** \u2014 Run shell commands
|
|
357
364
|
- Use for: git, npm/pnpm, docker, build tools, test runners, and other terminal operations.
|
|
358
|
-
-
|
|
359
|
-
- Commands have a 30-second default timeout. Use
|
|
360
|
-
-
|
|
365
|
+
- Prefer dedicated tools for: file reading (${MC_TOOLS.VIEW}), file search (${MC_TOOLS.SEARCH_CONTENT}/${MC_TOOLS.FIND_FILES}), file editing (${MC_TOOLS.STRING_REPLACE_LSP}/${MC_TOOLS.WRITE_FILE}).
|
|
366
|
+
- Commands have a 30-second default timeout. Use \`timeout\` for longer commands, \`cwd\` for working directory.
|
|
367
|
+
- Use the \`tail\` parameter or pipe to \`| tail -N\` to limit output \u2014 the full output streams to the user, only the tail is returned to you. If you're building any kind of package you should be tailing.
|
|
361
368
|
- Good: Run independent commands in parallel when possible.
|
|
362
|
-
- Bad: Running \`cat file.txt\` \u2014 use the
|
|
369
|
+
- Bad: Running \`cat file.txt\` \u2014 use the ${MC_TOOLS.VIEW} tool instead.`);
|
|
370
|
+
}
|
|
371
|
+
if (readTools.length > 0) {
|
|
372
|
+
sections.push(readTools.join("\n"));
|
|
373
|
+
}
|
|
363
374
|
if (modeId !== "plan") {
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
-
|
|
369
|
-
-
|
|
375
|
+
const writeTools = [];
|
|
376
|
+
if (!denied.has(MC_TOOLS.STRING_REPLACE_LSP)) {
|
|
377
|
+
writeTools.push(`
|
|
378
|
+
**${MC_TOOLS.STRING_REPLACE_LSP}** \u2014 Edit files by replacing exact text
|
|
379
|
+
- You MUST read a file with \`${MC_TOOLS.VIEW}\` before editing it.
|
|
380
|
+
- \`old_string\` must be an exact match of existing text in the file.
|
|
381
|
+
- Provide enough surrounding context in \`old_string\` to make it unique.
|
|
382
|
+
- Use \`replace_all: true\` to replace all occurrences (default: false, requires unique match).
|
|
383
|
+
- For creating new files, use \`${MC_TOOLS.WRITE_FILE}\` instead.
|
|
370
384
|
- Good: Include 2-3 lines of surrounding context to ensure uniqueness.
|
|
371
|
-
- Bad: Using just \`return true;\` \u2014 too common, will match multiple places
|
|
372
|
-
|
|
373
|
-
|
|
385
|
+
- Bad: Using just \`return true;\` \u2014 too common, will match multiple places.`);
|
|
386
|
+
}
|
|
387
|
+
if (!denied.has(MC_TOOLS.WRITE_FILE)) {
|
|
388
|
+
writeTools.push(`
|
|
389
|
+
**${MC_TOOLS.WRITE_FILE}** \u2014 Create new files or overwrite existing ones
|
|
374
390
|
- Use this to create new files.
|
|
375
|
-
- If overwriting an existing file, you MUST have read it first with
|
|
376
|
-
-
|
|
391
|
+
- If overwriting an existing file, you MUST have read it first with \`${MC_TOOLS.VIEW}\`.
|
|
392
|
+
- Prefer editing existing files over creating new ones.`);
|
|
393
|
+
}
|
|
394
|
+
if (writeTools.length > 0) {
|
|
395
|
+
sections.push(writeTools.join("\n"));
|
|
396
|
+
}
|
|
377
397
|
}
|
|
378
398
|
if (options.hasWebSearch) {
|
|
379
|
-
|
|
380
|
-
|
|
399
|
+
const webTools = [];
|
|
400
|
+
if (!denied.has("web_search")) webTools.push("**web_search**");
|
|
401
|
+
if (!denied.has("web_extract")) webTools.push("**web_extract**");
|
|
402
|
+
if (webTools.length > 0) {
|
|
403
|
+
sections.push(`
|
|
404
|
+
${webTools.join(" / ")} \u2014 Search the web / extract page content
|
|
381
405
|
- Use for looking up documentation, error messages, package APIs.`);
|
|
406
|
+
}
|
|
382
407
|
}
|
|
383
|
-
|
|
408
|
+
const taskTools = [];
|
|
409
|
+
if (!denied.has("task_write")) {
|
|
410
|
+
taskTools.push(`
|
|
384
411
|
**task_write** \u2014 Track tasks for complex multi-step work
|
|
385
412
|
- Use when a task requires 3 or more distinct steps or actions.
|
|
386
413
|
- Pass the FULL task list each time (replaces previous list).
|
|
387
414
|
- Mark tasks \`in_progress\` BEFORE starting work. Only ONE task should be \`in_progress\` at a time.
|
|
388
415
|
- Mark tasks \`completed\` IMMEDIATELY after finishing each task. Do not batch completions.
|
|
389
|
-
- Each task has: content (imperative form), status (pending|in_progress|completed), activeForm (present continuous form shown during execution)
|
|
390
|
-
|
|
416
|
+
- Each task has: content (imperative form), status (pending|in_progress|completed), activeForm (present continuous form shown during execution).`);
|
|
417
|
+
}
|
|
418
|
+
if (!denied.has("task_check")) {
|
|
419
|
+
taskTools.push(`
|
|
391
420
|
**task_check** \u2014 Check completion status of tasks
|
|
392
421
|
- Use this BEFORE deciding you're done with a task to verify all tasks are completed.
|
|
393
422
|
- Returns the number of completed, in progress, and pending tasks.
|
|
394
423
|
- If any tasks remain incomplete, continue working on them.
|
|
395
|
-
- IMPORTANT: Always check task completion before ending work on a complex task
|
|
396
|
-
|
|
424
|
+
- IMPORTANT: Always check task completion before ending work on a complex task.`);
|
|
425
|
+
}
|
|
426
|
+
if (!denied.has("ask_user")) {
|
|
427
|
+
taskTools.push(`
|
|
397
428
|
**ask_user** \u2014 Ask the user a structured question
|
|
398
429
|
- Use when you need clarification, want to validate assumptions, or need the user to make a decision.
|
|
399
430
|
- Provide clear, specific questions. End with a question mark.
|
|
400
431
|
- Include options (2-4 choices) for structured decisions. Omit options for open-ended questions.
|
|
401
432
|
- Don't use this for simple yes/no \u2014 just ask in your text response.`);
|
|
402
|
-
|
|
433
|
+
}
|
|
434
|
+
if (taskTools.length > 0) {
|
|
435
|
+
sections.push(taskTools.join("\n"));
|
|
436
|
+
}
|
|
437
|
+
if (modeId === "plan" && !denied.has("submit_plan")) {
|
|
403
438
|
sections.push(`
|
|
404
439
|
**submit_plan** \u2014 Submit a completed implementation plan for user review
|
|
405
440
|
- Call this tool when your plan is complete. Do NOT just describe your plan in text \u2014 you MUST call this tool.
|
|
@@ -407,10 +442,12 @@ You have access to the following tools. Use the RIGHT tool for the job:`);
|
|
|
407
442
|
- On approval, the system automatically switches to the default mode so you can implement.
|
|
408
443
|
- Takes two arguments: \`title\` (short descriptive title) and \`plan\` (full plan in markdown).`);
|
|
409
444
|
}
|
|
410
|
-
|
|
445
|
+
if (!denied.has("subagent")) {
|
|
446
|
+
sections.push(`
|
|
411
447
|
**subagent** \u2014 Delegate a focused task to a specialized subagent
|
|
412
448
|
- Only use subagents when you will spawn **multiple subagents in parallel**. If you only need one task done, do it yourself.
|
|
413
449
|
- Subagent outputs are **untrusted**. Always review and verify the results.`);
|
|
450
|
+
}
|
|
414
451
|
return sections.join("\n");
|
|
415
452
|
}
|
|
416
453
|
|
|
@@ -423,7 +460,14 @@ var modePrompts = {
|
|
|
423
460
|
function buildFullPrompt(ctx) {
|
|
424
461
|
const modelId = ctx.state?.currentModelId;
|
|
425
462
|
const hasWebSearch = hasTavilyKey() || !!modelId && modelId.startsWith("anthropic/");
|
|
426
|
-
const
|
|
463
|
+
const deniedTools = /* @__PURE__ */ new Set();
|
|
464
|
+
const permRules = ctx.state?.permissionRules;
|
|
465
|
+
if (permRules?.tools) {
|
|
466
|
+
for (const [name, policy] of Object.entries(permRules.tools)) {
|
|
467
|
+
if (policy === "deny") deniedTools.add(name);
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
const toolGuidance = buildToolGuidance(ctx.modeId, { hasWebSearch, deniedTools });
|
|
427
471
|
const baseCtx = {
|
|
428
472
|
projectPath: ctx.workingDir,
|
|
429
473
|
projectName: ctx.projectName || "unknown",
|
|
@@ -491,11 +535,11 @@ function getHarnessState(requestContext) {
|
|
|
491
535
|
}
|
|
492
536
|
function getObserverModel({ requestContext }) {
|
|
493
537
|
const state = getHarnessState(requestContext);
|
|
494
|
-
return resolveModel(state?.observerModelId ?? DEFAULT_OM_MODEL_ID);
|
|
538
|
+
return resolveModel(state?.observerModelId ?? DEFAULT_OM_MODEL_ID, { remapForCodexOAuth: true });
|
|
495
539
|
}
|
|
496
540
|
function getReflectorModel({ requestContext }) {
|
|
497
541
|
const state = getHarnessState(requestContext);
|
|
498
|
-
return resolveModel(state?.reflectorModelId ?? DEFAULT_OM_MODEL_ID);
|
|
542
|
+
return resolveModel(state?.reflectorModelId ?? DEFAULT_OM_MODEL_ID, { remapForCodexOAuth: true });
|
|
499
543
|
}
|
|
500
544
|
function getDynamicMemory(storage) {
|
|
501
545
|
return ({ requestContext }) => {
|
|
@@ -518,19 +562,13 @@ function getDynamicMemory(storage) {
|
|
|
518
562
|
bufferActivation: 2e3,
|
|
519
563
|
model: getObserverModel,
|
|
520
564
|
messageTokens: obsThreshold,
|
|
521
|
-
blockAfter: 2
|
|
522
|
-
modelSettings: {
|
|
523
|
-
maxOutputTokens: 6e4
|
|
524
|
-
}
|
|
565
|
+
blockAfter: 2
|
|
525
566
|
},
|
|
526
567
|
reflection: {
|
|
527
568
|
bufferActivation: 1 / 2,
|
|
528
569
|
blockAfter: 1.1,
|
|
529
570
|
model: getReflectorModel,
|
|
530
|
-
observationTokens: refThreshold
|
|
531
|
-
modelSettings: {
|
|
532
|
-
maxOutputTokens: 6e4
|
|
533
|
-
}
|
|
571
|
+
observationTokens: refThreshold
|
|
534
572
|
}
|
|
535
573
|
}
|
|
536
574
|
}
|
|
@@ -539,120 +577,48 @@ function getDynamicMemory(storage) {
|
|
|
539
577
|
return cachedMemory;
|
|
540
578
|
};
|
|
541
579
|
}
|
|
542
|
-
function createDynamicTools(mcpManager) {
|
|
580
|
+
function createDynamicTools(mcpManager, extraTools) {
|
|
543
581
|
return function getDynamicTools({ requestContext }) {
|
|
544
582
|
const ctx = requestContext.get("harness");
|
|
545
583
|
const state = ctx?.getState?.();
|
|
546
|
-
const modeId = ctx?.modeId ?? "build";
|
|
547
584
|
const modelId = state?.currentModelId;
|
|
548
585
|
const isAnthropicModel = modelId?.startsWith("anthropic/");
|
|
549
|
-
const
|
|
550
|
-
const viewTool = createViewTool(projectPath);
|
|
551
|
-
const grepTool = createGrepTool(projectPath);
|
|
552
|
-
const globTool = createGlobTool(projectPath);
|
|
553
|
-
const executeCommandTool = createExecuteCommandTool(projectPath);
|
|
554
|
-
const writeFileTool = createWriteFileTool(projectPath);
|
|
586
|
+
const isOpenAIModel = modelId?.startsWith("openai/");
|
|
555
587
|
const tools = {
|
|
556
|
-
view: viewTool,
|
|
557
|
-
search_content: grepTool,
|
|
558
|
-
find_files: globTool,
|
|
559
|
-
execute_command: executeCommandTool,
|
|
560
588
|
request_sandbox_access: requestSandboxAccessTool
|
|
561
589
|
};
|
|
562
|
-
if (modeId !== "plan") {
|
|
563
|
-
tools.string_replace_lsp = stringReplaceLspTool;
|
|
564
|
-
tools.ast_smart_edit = astSmartEditTool;
|
|
565
|
-
tools.write_file = writeFileTool;
|
|
566
|
-
}
|
|
567
590
|
if (hasTavilyKey()) {
|
|
568
591
|
tools.web_search = createWebSearchTool();
|
|
569
592
|
tools.web_extract = createWebExtractTool();
|
|
570
593
|
} else if (isAnthropicModel) {
|
|
571
594
|
const anthropic = createAnthropic({});
|
|
572
595
|
tools.web_search = anthropic.tools.webSearch_20250305();
|
|
596
|
+
} else if (isOpenAIModel) {
|
|
597
|
+
const openai = createOpenAI({});
|
|
598
|
+
tools.web_search = openai.tools.webSearch();
|
|
573
599
|
}
|
|
574
600
|
if (mcpManager) {
|
|
575
601
|
const mcpTools = mcpManager.getTools();
|
|
576
602
|
Object.assign(tools, mcpTools);
|
|
577
603
|
}
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
function collectSkillPaths(skillsDirs) {
|
|
586
|
-
const paths = [];
|
|
587
|
-
const seen = /* @__PURE__ */ new Set();
|
|
588
|
-
for (const skillsDir of skillsDirs) {
|
|
589
|
-
if (!fs4__default.existsSync(skillsDir)) continue;
|
|
590
|
-
const resolved = fs4__default.realpathSync(skillsDir);
|
|
591
|
-
if (!seen.has(resolved)) {
|
|
592
|
-
seen.add(resolved);
|
|
593
|
-
paths.push(skillsDir);
|
|
604
|
+
if (extraTools) {
|
|
605
|
+
const resolved = typeof extraTools === "function" ? extraTools({ requestContext }) : extraTools;
|
|
606
|
+
for (const [name, tool] of Object.entries(resolved)) {
|
|
607
|
+
if (!(name in tools)) {
|
|
608
|
+
tools[name] = tool;
|
|
609
|
+
}
|
|
610
|
+
}
|
|
594
611
|
}
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
for (const
|
|
598
|
-
if (
|
|
599
|
-
|
|
600
|
-
const realPath = fs4__default.realpathSync(linkPath);
|
|
601
|
-
const stat = fs4__default.statSync(realPath);
|
|
602
|
-
if (stat.isDirectory()) {
|
|
603
|
-
const realParent = path__default.dirname(realPath);
|
|
604
|
-
if (!seen.has(realParent)) {
|
|
605
|
-
seen.add(realParent);
|
|
606
|
-
paths.push(realParent);
|
|
607
|
-
}
|
|
608
|
-
}
|
|
612
|
+
const permissionRules = state?.permissionRules;
|
|
613
|
+
if (permissionRules?.tools) {
|
|
614
|
+
for (const [name, policy] of Object.entries(permissionRules.tools)) {
|
|
615
|
+
if (policy === "deny") {
|
|
616
|
+
delete tools[name];
|
|
609
617
|
}
|
|
610
618
|
}
|
|
611
|
-
} catch {
|
|
612
619
|
}
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
}
|
|
616
|
-
var skillPaths = collectSkillPaths([
|
|
617
|
-
mastraCodeLocalSkillsPath,
|
|
618
|
-
claudeLocalSkillsPath,
|
|
619
|
-
mastraCodeGlobalSkillsPath,
|
|
620
|
-
claudeGlobalSkillsPath
|
|
621
|
-
]);
|
|
622
|
-
function getDynamicWorkspace({ requestContext }) {
|
|
623
|
-
const ctx = requestContext.get("harness");
|
|
624
|
-
const state = ctx?.getState?.();
|
|
625
|
-
const projectPath = state?.projectPath;
|
|
626
|
-
if (!projectPath) {
|
|
627
|
-
throw new Error("Project path is required");
|
|
628
|
-
}
|
|
629
|
-
const sandboxPaths = state?.sandboxAllowedPaths ?? [];
|
|
630
|
-
const workspace = new Workspace({
|
|
631
|
-
id: "mastra-code-workspace",
|
|
632
|
-
name: "Mastra Code Workspace",
|
|
633
|
-
filesystem: new LocalFilesystem({
|
|
634
|
-
basePath: projectPath,
|
|
635
|
-
allowedPaths: skillPaths
|
|
636
|
-
}),
|
|
637
|
-
sandbox: new LocalSandbox({
|
|
638
|
-
workingDirectory: projectPath,
|
|
639
|
-
env: process.env
|
|
640
|
-
}),
|
|
641
|
-
// Disable workspace tools — built-in tools are used instead.
|
|
642
|
-
// Workspace tools use different output formats (e.g. → separator, offset/limit params)
|
|
643
|
-
// that the TUI renderers don't fully support yet.
|
|
644
|
-
// We will update to use workspace tools very soon - just disabling until then
|
|
645
|
-
tools: { enabled: false },
|
|
646
|
-
...skillPaths.length > 0 ? { skills: skillPaths } : {}
|
|
647
|
-
});
|
|
648
|
-
workspace.filesystem.setAllowedPaths([...skillPaths, ...sandboxPaths.map((p) => path__default.resolve(p))]);
|
|
649
|
-
return workspace;
|
|
650
|
-
}
|
|
651
|
-
if (skillPaths.length > 0) {
|
|
652
|
-
console.info(`Skills loaded from:`);
|
|
653
|
-
for (const p of skillPaths) {
|
|
654
|
-
console.info(` - ${p}`);
|
|
655
|
-
}
|
|
620
|
+
return tools;
|
|
621
|
+
};
|
|
656
622
|
}
|
|
657
623
|
var VALID_EVENTS = [
|
|
658
624
|
"PreToolUse",
|
|
@@ -670,15 +636,15 @@ function loadHooksConfig(projectDir) {
|
|
|
670
636
|
return mergeConfigs(globalConfig, projectConfig);
|
|
671
637
|
}
|
|
672
638
|
function getProjectHooksPath(projectDir) {
|
|
673
|
-
return
|
|
639
|
+
return path3.join(projectDir, ".mastracode", "hooks.json");
|
|
674
640
|
}
|
|
675
641
|
function getGlobalHooksPath() {
|
|
676
|
-
return
|
|
642
|
+
return path3.join(os.homedir(), ".mastracode", "hooks.json");
|
|
677
643
|
}
|
|
678
644
|
function loadSingleConfig(filePath) {
|
|
679
645
|
try {
|
|
680
|
-
if (!
|
|
681
|
-
const raw =
|
|
646
|
+
if (!fs3.existsSync(filePath)) return {};
|
|
647
|
+
const raw = fs3.readFileSync(filePath, "utf-8");
|
|
682
648
|
return validateConfig(JSON.parse(raw));
|
|
683
649
|
} catch {
|
|
684
650
|
return {};
|
|
@@ -975,18 +941,18 @@ function loadMcpConfig(projectDir) {
|
|
|
975
941
|
return mergeConfigs2(claudeConfig, globalConfig, projectConfig);
|
|
976
942
|
}
|
|
977
943
|
function getProjectMcpPath(projectDir) {
|
|
978
|
-
return
|
|
944
|
+
return path3.join(projectDir, ".mastracode", "mcp.json");
|
|
979
945
|
}
|
|
980
946
|
function getGlobalMcpPath() {
|
|
981
|
-
return
|
|
947
|
+
return path3.join(os.homedir(), ".mastracode", "mcp.json");
|
|
982
948
|
}
|
|
983
949
|
function getClaudeSettingsPath(projectDir) {
|
|
984
|
-
return
|
|
950
|
+
return path3.join(projectDir, ".claude", "settings.local.json");
|
|
985
951
|
}
|
|
986
952
|
function loadSingleConfig2(filePath) {
|
|
987
953
|
try {
|
|
988
|
-
if (!
|
|
989
|
-
const raw =
|
|
954
|
+
if (!fs3.existsSync(filePath)) return {};
|
|
955
|
+
const raw = fs3.readFileSync(filePath, "utf-8");
|
|
990
956
|
return validateConfig2(JSON.parse(raw));
|
|
991
957
|
} catch {
|
|
992
958
|
return {};
|
|
@@ -995,8 +961,8 @@ function loadSingleConfig2(filePath) {
|
|
|
995
961
|
function loadClaudeSettings(projectDir) {
|
|
996
962
|
try {
|
|
997
963
|
const filePath = getClaudeSettingsPath(projectDir);
|
|
998
|
-
if (!
|
|
999
|
-
const raw =
|
|
964
|
+
if (!fs3.existsSync(filePath)) return {};
|
|
965
|
+
const raw = fs3.readFileSync(filePath, "utf-8");
|
|
1000
966
|
const parsed = JSON.parse(raw);
|
|
1001
967
|
if (parsed?.mcpServers && typeof parsed.mcpServers === "object") {
|
|
1002
968
|
return validateConfig2({ mcpServers: parsed.mcpServers });
|
|
@@ -1006,43 +972,97 @@ function loadClaudeSettings(projectDir) {
|
|
|
1006
972
|
return {};
|
|
1007
973
|
}
|
|
1008
974
|
}
|
|
975
|
+
function classifyServerEntry(raw) {
|
|
976
|
+
if (!raw || typeof raw !== "object") {
|
|
977
|
+
return { kind: "skip", reason: "Invalid entry: expected an object" };
|
|
978
|
+
}
|
|
979
|
+
const obj = raw;
|
|
980
|
+
const hasCommand = typeof obj.command === "string";
|
|
981
|
+
const hasUrl = typeof obj.url === "string";
|
|
982
|
+
if (hasCommand && hasUrl) {
|
|
983
|
+
return { kind: "skip", reason: 'Cannot specify both "command" and "url"' };
|
|
984
|
+
}
|
|
985
|
+
if (hasCommand) {
|
|
986
|
+
return { kind: "stdio" };
|
|
987
|
+
}
|
|
988
|
+
if (hasUrl) {
|
|
989
|
+
try {
|
|
990
|
+
new URL(obj.url);
|
|
991
|
+
} catch {
|
|
992
|
+
return { kind: "skip", reason: `Invalid URL: "${obj.url}"` };
|
|
993
|
+
}
|
|
994
|
+
return { kind: "http" };
|
|
995
|
+
}
|
|
996
|
+
return { kind: "skip", reason: 'Missing required field: "command" (stdio) or "url" (http)' };
|
|
997
|
+
}
|
|
1009
998
|
function validateConfig2(raw) {
|
|
1010
999
|
if (!raw || typeof raw !== "object") return {};
|
|
1011
1000
|
const obj = raw;
|
|
1012
1001
|
if (!obj.mcpServers || typeof obj.mcpServers !== "object") return {};
|
|
1013
1002
|
const servers = {};
|
|
1003
|
+
const skippedServers = [];
|
|
1014
1004
|
const rawServers = obj.mcpServers;
|
|
1015
1005
|
for (const [name, entry] of Object.entries(rawServers)) {
|
|
1016
|
-
|
|
1006
|
+
const classification = classifyServerEntry(entry);
|
|
1007
|
+
if (classification.kind === "stdio") {
|
|
1008
|
+
const e = entry;
|
|
1009
|
+
servers[name] = {
|
|
1010
|
+
command: e.command,
|
|
1011
|
+
args: Array.isArray(e.args) ? e.args : void 0,
|
|
1012
|
+
env: typeof e.env === "object" && e.env !== null ? e.env : void 0
|
|
1013
|
+
};
|
|
1014
|
+
} else if (classification.kind === "http") {
|
|
1015
|
+
const e = entry;
|
|
1017
1016
|
servers[name] = {
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
env: typeof entry.env === "object" && entry.env !== null ? entry.env : void 0
|
|
1017
|
+
url: e.url,
|
|
1018
|
+
headers: typeof e.headers === "object" && e.headers !== null ? e.headers : void 0
|
|
1021
1019
|
};
|
|
1020
|
+
} else {
|
|
1021
|
+
skippedServers.push({ name, reason: classification.reason });
|
|
1022
1022
|
}
|
|
1023
1023
|
}
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
if (
|
|
1029
|
-
|
|
1030
|
-
|
|
1024
|
+
const result = {};
|
|
1025
|
+
if (Object.keys(servers).length > 0) {
|
|
1026
|
+
result.mcpServers = servers;
|
|
1027
|
+
}
|
|
1028
|
+
if (skippedServers.length > 0) {
|
|
1029
|
+
result.skippedServers = skippedServers;
|
|
1030
|
+
}
|
|
1031
|
+
return result;
|
|
1031
1032
|
}
|
|
1032
1033
|
function mergeConfigs2(...configs) {
|
|
1033
1034
|
const merged = {};
|
|
1035
|
+
const allSkipped = [];
|
|
1034
1036
|
for (const config of configs) {
|
|
1035
1037
|
if (config.mcpServers) {
|
|
1036
1038
|
for (const [name, server] of Object.entries(config.mcpServers)) {
|
|
1037
1039
|
merged[name] = server;
|
|
1038
1040
|
}
|
|
1039
1041
|
}
|
|
1042
|
+
if (config.skippedServers) {
|
|
1043
|
+
allSkipped.push(...config.skippedServers);
|
|
1044
|
+
}
|
|
1045
|
+
}
|
|
1046
|
+
const validNames = new Set(Object.keys(merged));
|
|
1047
|
+
const filteredSkipped = allSkipped.filter((s) => !validNames.has(s.name));
|
|
1048
|
+
const skippedMap = /* @__PURE__ */ new Map();
|
|
1049
|
+
for (const s of filteredSkipped) {
|
|
1050
|
+
skippedMap.set(s.name, s);
|
|
1051
|
+
}
|
|
1052
|
+
const result = {};
|
|
1053
|
+
if (Object.keys(merged).length > 0) {
|
|
1054
|
+
result.mcpServers = merged;
|
|
1040
1055
|
}
|
|
1041
|
-
if (
|
|
1042
|
-
|
|
1056
|
+
if (skippedMap.size > 0) {
|
|
1057
|
+
result.skippedServers = Array.from(skippedMap.values());
|
|
1058
|
+
}
|
|
1059
|
+
return result;
|
|
1043
1060
|
}
|
|
1044
1061
|
|
|
1045
1062
|
// src/mcp/manager.ts
|
|
1063
|
+
function getTransport(cfg) {
|
|
1064
|
+
return "url" in cfg ? "http" : "stdio";
|
|
1065
|
+
}
|
|
1046
1066
|
function createMcpManager(projectDir) {
|
|
1047
1067
|
let config = loadMcpConfig(projectDir);
|
|
1048
1068
|
let client = null;
|
|
@@ -1052,7 +1072,15 @@ function createMcpManager(projectDir) {
|
|
|
1052
1072
|
function buildServerDefs(servers) {
|
|
1053
1073
|
const defs = {};
|
|
1054
1074
|
for (const [name, cfg] of Object.entries(servers)) {
|
|
1055
|
-
|
|
1075
|
+
if ("url" in cfg) {
|
|
1076
|
+
const httpCfg = cfg;
|
|
1077
|
+
defs[name] = {
|
|
1078
|
+
url: new URL(httpCfg.url),
|
|
1079
|
+
requestInit: httpCfg.headers ? { headers: httpCfg.headers } : void 0
|
|
1080
|
+
};
|
|
1081
|
+
} else {
|
|
1082
|
+
defs[name] = { command: cfg.command, args: cfg.args, env: cfg.env };
|
|
1083
|
+
}
|
|
1056
1084
|
}
|
|
1057
1085
|
return defs;
|
|
1058
1086
|
}
|
|
@@ -1075,7 +1103,8 @@ function createMcpManager(projectDir) {
|
|
|
1075
1103
|
name,
|
|
1076
1104
|
connected: true,
|
|
1077
1105
|
toolCount: serverToolNames.length,
|
|
1078
|
-
toolNames: serverToolNames
|
|
1106
|
+
toolNames: serverToolNames,
|
|
1107
|
+
transport: getTransport(servers[name])
|
|
1079
1108
|
});
|
|
1080
1109
|
}
|
|
1081
1110
|
} catch (error) {
|
|
@@ -1086,6 +1115,7 @@ function createMcpManager(projectDir) {
|
|
|
1086
1115
|
connected: false,
|
|
1087
1116
|
toolCount: 0,
|
|
1088
1117
|
toolNames: [],
|
|
1118
|
+
transport: getTransport(servers[name]),
|
|
1089
1119
|
error: errMsg
|
|
1090
1120
|
});
|
|
1091
1121
|
}
|
|
@@ -1120,11 +1150,16 @@ function createMcpManager(projectDir) {
|
|
|
1120
1150
|
return { ...tools };
|
|
1121
1151
|
},
|
|
1122
1152
|
hasServers() {
|
|
1123
|
-
|
|
1153
|
+
const hasConfigured = config.mcpServers !== void 0 && Object.keys(config.mcpServers).length > 0;
|
|
1154
|
+
const hasSkipped = config.skippedServers !== void 0 && config.skippedServers.length > 0;
|
|
1155
|
+
return hasConfigured || hasSkipped;
|
|
1124
1156
|
},
|
|
1125
1157
|
getServerStatuses() {
|
|
1126
1158
|
return Array.from(serverStatuses.values());
|
|
1127
1159
|
},
|
|
1160
|
+
getSkippedServers() {
|
|
1161
|
+
return [...config.skippedServers ?? []];
|
|
1162
|
+
},
|
|
1128
1163
|
getConfigPaths() {
|
|
1129
1164
|
return {
|
|
1130
1165
|
project: getProjectMcpPath(projectDir),
|
|
@@ -1182,21 +1217,21 @@ var stateSchema = z.object({
|
|
|
1182
1217
|
approvedAt: z.string()
|
|
1183
1218
|
}).nullable().default(null)
|
|
1184
1219
|
});
|
|
1185
|
-
var CACHE_DIR =
|
|
1186
|
-
var CACHE_FILE =
|
|
1187
|
-
var GLOBAL_PROVIDER_REGISTRY_JSON =
|
|
1188
|
-
var GLOBAL_PROVIDER_TYPES_DTS =
|
|
1220
|
+
var CACHE_DIR = path3__default.join(os__default.homedir(), ".cache", "mastra");
|
|
1221
|
+
var CACHE_FILE = path3__default.join(CACHE_DIR, "gateway-refresh-time");
|
|
1222
|
+
var GLOBAL_PROVIDER_REGISTRY_JSON = path3__default.join(CACHE_DIR, "provider-registry.json");
|
|
1223
|
+
var GLOBAL_PROVIDER_TYPES_DTS = path3__default.join(CACHE_DIR, "provider-types.generated.d.ts");
|
|
1189
1224
|
var DEFAULT_SYNC_INTERVAL_MS = 5 * 60 * 1e3;
|
|
1190
1225
|
var isSyncing = false;
|
|
1191
1226
|
async function atomicWriteFile(filePath, content) {
|
|
1192
1227
|
const randomSuffix = Math.random().toString(36).substring(2, 15);
|
|
1193
1228
|
const tempPath = `${filePath}.${process.pid}.${Date.now()}.${randomSuffix}.tmp`;
|
|
1194
1229
|
try {
|
|
1195
|
-
await
|
|
1196
|
-
await
|
|
1230
|
+
await fs3__default.promises.writeFile(tempPath, content, "utf-8");
|
|
1231
|
+
await fs3__default.promises.rename(tempPath, filePath);
|
|
1197
1232
|
} catch (error) {
|
|
1198
1233
|
try {
|
|
1199
|
-
await
|
|
1234
|
+
await fs3__default.promises.unlink(tempPath);
|
|
1200
1235
|
} catch {
|
|
1201
1236
|
}
|
|
1202
1237
|
throw error;
|
|
@@ -1261,10 +1296,10 @@ export type ModelForProvider<P extends Provider> = ProviderModelsMap[P][number];
|
|
|
1261
1296
|
}
|
|
1262
1297
|
function getLastSyncTime() {
|
|
1263
1298
|
try {
|
|
1264
|
-
if (!
|
|
1299
|
+
if (!fs3__default.existsSync(CACHE_FILE)) {
|
|
1265
1300
|
return null;
|
|
1266
1301
|
}
|
|
1267
|
-
const timestamp =
|
|
1302
|
+
const timestamp = fs3__default.readFileSync(CACHE_FILE, "utf-8").trim();
|
|
1268
1303
|
return new Date(parseInt(timestamp, 10));
|
|
1269
1304
|
} catch {
|
|
1270
1305
|
return null;
|
|
@@ -1272,10 +1307,10 @@ function getLastSyncTime() {
|
|
|
1272
1307
|
}
|
|
1273
1308
|
function saveLastSyncTime(date) {
|
|
1274
1309
|
try {
|
|
1275
|
-
if (!
|
|
1276
|
-
|
|
1310
|
+
if (!fs3__default.existsSync(CACHE_DIR)) {
|
|
1311
|
+
fs3__default.mkdirSync(CACHE_DIR, { recursive: true });
|
|
1277
1312
|
}
|
|
1278
|
-
|
|
1313
|
+
fs3__default.writeFileSync(CACHE_FILE, date.getTime().toString(), "utf-8");
|
|
1279
1314
|
} catch (error) {
|
|
1280
1315
|
console.warn("[GatewaySync] Failed to save sync time:", error);
|
|
1281
1316
|
}
|
|
@@ -1296,7 +1331,7 @@ async function syncGateways(force = false) {
|
|
|
1296
1331
|
isSyncing = true;
|
|
1297
1332
|
try {
|
|
1298
1333
|
const { providers, models } = await fetchProvidersFromGateways();
|
|
1299
|
-
await
|
|
1334
|
+
await fs3__default.promises.mkdir(CACHE_DIR, { recursive: true });
|
|
1300
1335
|
const registryData = {
|
|
1301
1336
|
providers,
|
|
1302
1337
|
models,
|
|
@@ -1393,19 +1428,13 @@ async function createMastraCode(config) {
|
|
|
1393
1428
|
const storageWarning = storageResult.warning;
|
|
1394
1429
|
const memory = getDynamicMemory(storage);
|
|
1395
1430
|
const mcpManager = config?.disableMcp ? void 0 : createMcpManager(project.rootPath);
|
|
1396
|
-
const
|
|
1431
|
+
const codeAgent = new Agent({
|
|
1397
1432
|
id: "code-agent",
|
|
1398
1433
|
name: "Code Agent",
|
|
1399
1434
|
instructions: getDynamicInstructions,
|
|
1400
1435
|
model: getDynamicModel,
|
|
1401
|
-
tools: createDynamicTools(mcpManager)
|
|
1402
|
-
});
|
|
1403
|
-
const mastraInstance = new Mastra({
|
|
1404
|
-
agents: { codeAgentInstance },
|
|
1405
|
-
logger: noopLogger,
|
|
1406
|
-
storage
|
|
1436
|
+
tools: createDynamicTools(mcpManager, config?.extraTools)
|
|
1407
1437
|
});
|
|
1408
|
-
const codeAgent = mastraInstance.getAgent("codeAgentInstance");
|
|
1409
1438
|
const hookManager = config?.disableHooks ? void 0 : new HookManager(project.rootPath, "session-init");
|
|
1410
1439
|
if (hookManager?.hasHooks()) {
|
|
1411
1440
|
const hookConfig = hookManager.getConfig();
|
|
@@ -1417,6 +1446,7 @@ async function createMastraCode(config) {
|
|
|
1417
1446
|
const globTool = createGlobTool(project.rootPath);
|
|
1418
1447
|
const executeCommandTool = createExecuteCommandTool(project.rootPath);
|
|
1419
1448
|
const writeFileTool = createWriteFileTool(project.rootPath);
|
|
1449
|
+
const stringReplaceLspTool = createStringReplaceLspTool(project.rootPath);
|
|
1420
1450
|
const readOnlyTools = {
|
|
1421
1451
|
view: viewTool,
|
|
1422
1452
|
search_content: grepTool,
|
|
@@ -1490,6 +1520,18 @@ async function createMastraCode(config) {
|
|
|
1490
1520
|
google: process.env.GOOGLE_GENERATIVE_AI_API_KEY ? "apikey" : false,
|
|
1491
1521
|
deepseek: process.env.DEEPSEEK_API_KEY ? "apikey" : false
|
|
1492
1522
|
};
|
|
1523
|
+
try {
|
|
1524
|
+
const registry = PROVIDER_REGISTRY;
|
|
1525
|
+
for (const [provider, config2] of Object.entries(registry)) {
|
|
1526
|
+
if (startupAccess[provider] && startupAccess[provider] !== false) continue;
|
|
1527
|
+
const envVars = config2?.apiKeyEnvVar;
|
|
1528
|
+
const envVarList = Array.isArray(envVars) ? envVars : envVars ? [envVars] : [];
|
|
1529
|
+
if (envVarList.some((envVar) => process.env[envVar])) {
|
|
1530
|
+
startupAccess[provider] = "apikey";
|
|
1531
|
+
}
|
|
1532
|
+
}
|
|
1533
|
+
} catch {
|
|
1534
|
+
}
|
|
1493
1535
|
const builtinPacks = getAvailableModePacks(startupAccess);
|
|
1494
1536
|
const builtinOmPacks = getAvailableOmPacks(startupAccess);
|
|
1495
1537
|
const effectiveDefaults = resolveModelDefaults(globalSettings, builtinPacks);
|
|
@@ -1536,7 +1578,7 @@ async function createMastraCode(config) {
|
|
|
1536
1578
|
...globalInitialState,
|
|
1537
1579
|
...config?.initialState
|
|
1538
1580
|
},
|
|
1539
|
-
workspace: getDynamicWorkspace,
|
|
1581
|
+
workspace: config?.workspace ?? getDynamicWorkspace,
|
|
1540
1582
|
modes,
|
|
1541
1583
|
heartbeatHandlers: config?.heartbeatHandlers ?? defaultHeartbeatHandlers,
|
|
1542
1584
|
modelAuthChecker: (provider) => {
|
|
@@ -1544,9 +1586,41 @@ async function createMastraCode(config) {
|
|
|
1544
1586
|
if (oauthId && authStorage.isLoggedIn(oauthId)) {
|
|
1545
1587
|
return true;
|
|
1546
1588
|
}
|
|
1589
|
+
const customProvider = loadSettings().customProviders.find((entry) => {
|
|
1590
|
+
return provider === getCustomProviderId(entry.name);
|
|
1591
|
+
});
|
|
1592
|
+
if (customProvider) {
|
|
1593
|
+
return true;
|
|
1594
|
+
}
|
|
1547
1595
|
return void 0;
|
|
1548
1596
|
},
|
|
1549
1597
|
modelUseCountProvider: () => loadSettings().modelUseCounts,
|
|
1598
|
+
modelUseCountTracker: (modelId) => {
|
|
1599
|
+
try {
|
|
1600
|
+
const settings = loadSettings();
|
|
1601
|
+
settings.modelUseCounts[modelId] = (settings.modelUseCounts[modelId] ?? 0) + 1;
|
|
1602
|
+
saveSettings(settings);
|
|
1603
|
+
} catch (error) {
|
|
1604
|
+
console.error("Failed to persist model usage count", error);
|
|
1605
|
+
}
|
|
1606
|
+
},
|
|
1607
|
+
customModelCatalogProvider: () => {
|
|
1608
|
+
const settings = loadSettings();
|
|
1609
|
+
const customModels = [];
|
|
1610
|
+
for (const provider of settings.customProviders) {
|
|
1611
|
+
const providerId = getCustomProviderId(provider.name);
|
|
1612
|
+
for (const modelName of provider.models) {
|
|
1613
|
+
customModels.push({
|
|
1614
|
+
id: toCustomProviderModelId(provider.name, modelName),
|
|
1615
|
+
provider: providerId,
|
|
1616
|
+
modelName,
|
|
1617
|
+
hasApiKey: true,
|
|
1618
|
+
apiKeyEnvVar: void 0
|
|
1619
|
+
});
|
|
1620
|
+
}
|
|
1621
|
+
}
|
|
1622
|
+
return customModels;
|
|
1623
|
+
},
|
|
1550
1624
|
threadLock: {
|
|
1551
1625
|
acquire: acquireThreadLock,
|
|
1552
1626
|
release: releaseThreadLock
|
|
@@ -1561,9 +1635,9 @@ async function createMastraCode(config) {
|
|
|
1561
1635
|
}
|
|
1562
1636
|
});
|
|
1563
1637
|
}
|
|
1564
|
-
return { harness, mcpManager, hookManager, authStorage, storageWarning };
|
|
1638
|
+
return { harness, mcpManager, hookManager, authStorage, resolveModel, storageWarning };
|
|
1565
1639
|
}
|
|
1566
1640
|
|
|
1567
1641
|
export { createMastraCode };
|
|
1568
|
-
//# sourceMappingURL=chunk-
|
|
1569
|
-
//# sourceMappingURL=chunk-
|
|
1642
|
+
//# sourceMappingURL=chunk-WKPHD54B.js.map
|
|
1643
|
+
//# sourceMappingURL=chunk-WKPHD54B.js.map
|