mastracode 0.22.3 → 0.23.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 +55 -0
- package/dist/HarnessCompat.d.ts +2 -2
- package/dist/HarnessCompat.d.ts.map +1 -1
- package/dist/agents/mastracode-gateway.d.ts +58 -0
- package/dist/agents/mastracode-gateway.d.ts.map +1 -0
- package/dist/agents/model.d.ts +26 -28
- package/dist/agents/model.d.ts.map +1 -1
- package/dist/agents/{subagents/execute.d.ts → modes/build.d.ts} +3 -3
- package/dist/agents/modes/build.d.ts.map +1 -0
- package/dist/agents/{subagents → modes}/explore.d.ts +2 -2
- package/dist/agents/modes/explore.d.ts.map +1 -0
- package/dist/agents/modes/plan.d.ts +6 -0
- package/dist/agents/modes/plan.d.ts.map +1 -0
- package/dist/{chunk-EATS4KOR.cjs → chunk-3CO7PY6M.cjs} +1094 -239
- package/dist/chunk-3CO7PY6M.cjs.map +1 -0
- package/dist/{chunk-DJEQBK7L.cjs → chunk-CBPEMMRV.cjs} +1659 -2010
- package/dist/chunk-CBPEMMRV.cjs.map +1 -0
- package/dist/{chunk-W7Y7QIJA.js → chunk-FXYM4OEI.js} +14 -805
- package/dist/chunk-FXYM4OEI.js.map +1 -0
- package/dist/{chunk-OXYE6SUY.js → chunk-GKGPZBID.js} +836 -1187
- package/dist/chunk-GKGPZBID.js.map +1 -0
- package/dist/{chunk-FDDVVRPH.js → chunk-RDIIIT54.js} +1076 -221
- package/dist/chunk-RDIIIT54.js.map +1 -0
- package/dist/{chunk-NKTZDFIU.cjs → chunk-XPPJHUAD.cjs} +12 -809
- package/dist/chunk-XPPJHUAD.cjs.map +1 -0
- package/dist/cli.cjs +18 -18
- package/dist/cli.js +3 -3
- package/dist/index.cjs +3 -3
- package/dist/index.d.ts +4 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/mcp/manager.d.ts.map +1 -1
- package/dist/onboarding/onboarding-inline.d.ts +2 -2
- package/dist/onboarding/onboarding-inline.d.ts.map +1 -1
- package/dist/onboarding/settings.d.ts.map +1 -1
- package/dist/providers/claude-max.d.ts.map +1 -1
- package/dist/tui/chat-boundary-reconciliation.d.ts +18 -1
- package/dist/tui/chat-boundary-reconciliation.d.ts.map +1 -1
- package/dist/tui/command-dispatch.d.ts.map +1 -1
- package/dist/tui/commands/browser.d.ts.map +1 -1
- package/dist/tui/commands/goal.d.ts.map +1 -1
- package/dist/tui/commands/mode.d.ts.map +1 -1
- package/dist/tui/commands/new.d.ts.map +1 -1
- package/dist/tui/commands/settings.d.ts.map +1 -1
- package/dist/tui/commands/skills.d.ts.map +1 -1
- package/dist/tui/components/api-key-dialog.d.ts +2 -2
- package/dist/tui/components/api-key-dialog.d.ts.map +1 -1
- package/dist/tui/components/ask-question-dialog.d.ts +2 -2
- package/dist/tui/components/ask-question-dialog.d.ts.map +1 -1
- package/dist/tui/components/ask-question-inline.d.ts +4 -2
- package/dist/tui/components/ask-question-inline.d.ts.map +1 -1
- package/dist/tui/components/assistant-message.d.ts +2 -2
- package/dist/tui/components/assistant-message.d.ts.map +1 -1
- package/dist/tui/components/chat-boundary-spacer.d.ts +9 -9
- package/dist/tui/components/chat-boundary-spacer.d.ts.map +1 -1
- package/dist/tui/components/chat-spacing.d.ts +1 -1
- package/dist/tui/components/chat-spacing.d.ts.map +1 -1
- package/dist/tui/components/collapsible.d.ts +2 -2
- package/dist/tui/components/collapsible.d.ts.map +1 -1
- package/dist/tui/components/custom-editor.d.ts +2 -2
- package/dist/tui/components/custom-editor.d.ts.map +1 -1
- package/dist/tui/components/diff-output.d.ts +3 -1
- package/dist/tui/components/diff-output.d.ts.map +1 -1
- package/dist/tui/components/error-display.d.ts +4 -2
- package/dist/tui/components/error-display.d.ts.map +1 -1
- package/dist/tui/components/goal-cycles-dialog.d.ts +2 -2
- package/dist/tui/components/goal-cycles-dialog.d.ts.map +1 -1
- package/dist/tui/components/idle-counter.d.ts +1 -1
- package/dist/tui/components/idle-counter.d.ts.map +1 -1
- package/dist/tui/components/judge-display.d.ts +14 -2
- package/dist/tui/components/judge-display.d.ts.map +1 -1
- package/dist/tui/components/login-dialog.d.ts +2 -2
- package/dist/tui/components/login-dialog.d.ts.map +1 -1
- package/dist/tui/components/login-mode-selector.d.ts +2 -2
- package/dist/tui/components/login-mode-selector.d.ts.map +1 -1
- package/dist/tui/components/login-selector.d.ts +1 -1
- package/dist/tui/components/login-selector.d.ts.map +1 -1
- package/dist/tui/components/masked-input.d.ts +1 -1
- package/dist/tui/components/masked-input.d.ts.map +1 -1
- package/dist/tui/components/mcp-selector.d.ts +2 -2
- package/dist/tui/components/mcp-selector.d.ts.map +1 -1
- package/dist/tui/components/model-selector.d.ts +2 -2
- package/dist/tui/components/model-selector.d.ts.map +1 -1
- package/dist/tui/components/multi-step-progress.d.ts +3 -1
- package/dist/tui/components/multi-step-progress.d.ts.map +1 -1
- package/dist/tui/components/multiline-input.d.ts +1 -1
- package/dist/tui/components/multiline-input.d.ts.map +1 -1
- package/dist/tui/components/notification-summary.d.ts +1 -1
- package/dist/tui/components/notification-summary.d.ts.map +1 -1
- package/dist/tui/components/notification.d.ts +1 -1
- package/dist/tui/components/notification.d.ts.map +1 -1
- package/dist/tui/components/om-marker.d.ts +3 -1
- package/dist/tui/components/om-marker.d.ts.map +1 -1
- package/dist/tui/components/om-output.d.ts +3 -1
- package/dist/tui/components/om-output.d.ts.map +1 -1
- package/dist/tui/components/om-progress.d.ts +1 -1
- package/dist/tui/components/om-progress.d.ts.map +1 -1
- package/dist/tui/components/om-settings.d.ts +2 -2
- package/dist/tui/components/om-settings.d.ts.map +1 -1
- package/dist/tui/components/plan-approval-inline.d.ts +2 -2
- package/dist/tui/components/plan-approval-inline.d.ts.map +1 -1
- package/dist/tui/components/reactive-signal.d.ts +1 -1
- package/dist/tui/components/reactive-signal.d.ts.map +1 -1
- package/dist/tui/components/settings.d.ts +2 -2
- package/dist/tui/components/settings.d.ts.map +1 -1
- package/dist/tui/components/shell-output.d.ts +3 -1
- package/dist/tui/components/shell-output.d.ts.map +1 -1
- package/dist/tui/components/simple-progress.d.ts +1 -1
- package/dist/tui/components/simple-progress.d.ts.map +1 -1
- package/dist/tui/components/slash-command.d.ts +3 -1
- package/dist/tui/components/slash-command.d.ts.map +1 -1
- package/dist/tui/components/state-signal.d.ts +1 -1
- package/dist/tui/components/state-signal.d.ts.map +1 -1
- package/dist/tui/components/subagent-execution.d.ts +2 -2
- package/dist/tui/components/subagent-execution.d.ts.map +1 -1
- package/dist/tui/components/system-reminder.d.ts +1 -1
- package/dist/tui/components/system-reminder.d.ts.map +1 -1
- package/dist/tui/components/task-progress.d.ts +1 -1
- package/dist/tui/components/task-progress.d.ts.map +1 -1
- package/dist/tui/components/temporal-gap.d.ts +3 -1
- package/dist/tui/components/temporal-gap.d.ts.map +1 -1
- package/dist/tui/components/thinking-settings.d.ts +2 -2
- package/dist/tui/components/thinking-settings.d.ts.map +1 -1
- package/dist/tui/components/thread-selector.d.ts +2 -2
- package/dist/tui/components/thread-selector.d.ts.map +1 -1
- package/dist/tui/components/tool-approval-dialog.d.ts +2 -2
- package/dist/tui/components/tool-approval-dialog.d.ts.map +1 -1
- package/dist/tui/components/tool-execution-enhanced.d.ts +2 -2
- package/dist/tui/components/tool-execution-enhanced.d.ts.map +1 -1
- package/dist/tui/components/tool-validation-error.d.ts +2 -2
- package/dist/tui/components/tool-validation-error.d.ts.map +1 -1
- package/dist/tui/components/user-message.d.ts +2 -2
- package/dist/tui/components/user-message.d.ts.map +1 -1
- package/dist/tui/components/wrapping-autocomplete-list.d.ts +1 -1
- package/dist/tui/components/wrapping-autocomplete-list.d.ts.map +1 -1
- package/dist/tui/components/wrapping-select-list.d.ts +1 -1
- package/dist/tui/components/wrapping-select-list.d.ts.map +1 -1
- package/dist/tui/display.d.ts.map +1 -1
- package/dist/tui/event-dispatch.d.ts.map +1 -1
- package/dist/tui/goal-manager.d.ts +48 -40
- package/dist/tui/goal-manager.d.ts.map +1 -1
- package/dist/tui/handlers/agent-lifecycle.d.ts +13 -0
- package/dist/tui/handlers/agent-lifecycle.d.ts.map +1 -1
- package/dist/tui/handlers/index.d.ts +1 -1
- package/dist/tui/handlers/index.d.ts.map +1 -1
- package/dist/tui/handlers/message.d.ts.map +1 -1
- package/dist/tui/handlers/om.d.ts.map +1 -1
- package/dist/tui/handlers/tool.d.ts.map +1 -1
- package/dist/tui/handlers/types.d.ts +1 -1
- package/dist/tui/handlers/types.d.ts.map +1 -1
- package/dist/tui/mastra-tui.d.ts.map +1 -1
- package/dist/tui/modal-question.d.ts +1 -1
- package/dist/tui/modal-question.d.ts.map +1 -1
- package/dist/tui/overlay.d.ts +1 -1
- package/dist/tui/overlay.d.ts.map +1 -1
- package/dist/tui/prompt-api-key.d.ts +1 -1
- package/dist/tui/prompt-api-key.d.ts.map +1 -1
- package/dist/tui/render-messages.d.ts +1 -1
- package/dist/tui/render-messages.d.ts.map +1 -1
- package/dist/tui/setup.d.ts.map +1 -1
- package/dist/tui/shell.d.ts.map +1 -1
- package/dist/tui/state.d.ts +2 -2
- package/dist/tui/state.d.ts.map +1 -1
- package/dist/tui/status-line.d.ts.map +1 -1
- package/dist/tui/theme.d.ts +1 -1
- package/dist/tui/theme.d.ts.map +1 -1
- package/dist/tui.cjs +19 -19
- package/dist/tui.js +2 -2
- package/package.json +20 -20
- package/dist/agents/coding.d.ts +0 -2
- package/dist/agents/coding.d.ts.map +0 -1
- package/dist/agents/subagents/execute.d.ts.map +0 -1
- package/dist/agents/subagents/explore.d.ts.map +0 -1
- package/dist/agents/subagents/plan.d.ts +0 -10
- package/dist/agents/subagents/plan.d.ts.map +0 -1
- package/dist/chunk-DJEQBK7L.cjs.map +0 -1
- package/dist/chunk-EATS4KOR.cjs.map +0 -1
- package/dist/chunk-FDDVVRPH.js.map +0 -1
- package/dist/chunk-NKTZDFIU.cjs.map +0 -1
- package/dist/chunk-OXYE6SUY.js.map +0 -1
- package/dist/chunk-W7Y7QIJA.js.map +0 -1
|
@@ -1,25 +1,24 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { DEFAULT_OM_MODEL_ID, DEFAULT_CONFIG_DIR,
|
|
3
|
-
import {
|
|
4
|
-
import { createHash } from 'crypto';
|
|
5
|
-
import * as os from 'os';
|
|
6
|
-
import os__default, { hostname, homedir } from 'os';
|
|
1
|
+
import { loadSettings, MEMORY_GATEWAY_PROVIDER, getAvailableModePacks, getAvailableOmPacks, resolveModelDefaults, resolveOmRoleModel, releaseThreadLock, acquireThreadLock, saveSettings, OBSERVABILITY_AUTH_PREFIX, mastra, getCustomProviderId } from './chunk-FXYM4OEI.js';
|
|
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-5FT2NNFO.js';
|
|
3
|
+
import { getToolCategory, MC_TOOLS, TOOL_NAME_OVERRIDES } from './chunk-UOFNLVKF.js';
|
|
7
4
|
import * as path from 'path';
|
|
8
5
|
import path__default, { normalize, join, dirname } from 'path';
|
|
9
6
|
import { Agent } from '@mastra/core/agent';
|
|
10
7
|
import { Harness } from '@mastra/core/harness';
|
|
11
|
-
import {
|
|
8
|
+
import { PROVIDER_REGISTRY, MastraModelGateway, MastraGateway, ModelRouterLanguageModel, GATEWAY_AUTH_HEADER, GatewayRegistry } from '@mastra/core/llm';
|
|
12
9
|
import { StreamErrorRetryProcessor, PrefillErrorHandler, ProviderHistoryCompat, AgentsMDInjector } from '@mastra/core/processors';
|
|
13
10
|
import { RequestContext } from '@mastra/core/request-context';
|
|
14
11
|
import { TaskSignalProvider } from '@mastra/core/signals';
|
|
15
12
|
import { InMemoryHarness, MastraCompositeStore } from '@mastra/core/storage';
|
|
13
|
+
import { createTool, DEFAULT_GOAL_JUDGE_PROMPT } from '@mastra/core/tools';
|
|
16
14
|
import { DuckDBStore } from '@mastra/duckdb';
|
|
17
15
|
import { GithubSignals } from '@mastra/github-signals';
|
|
18
16
|
import { Observability, SensitiveDataFilter, MastraStorageExporter, MastraPlatformExporter } from '@mastra/observability';
|
|
19
17
|
import { spawn, execFile } from 'child_process';
|
|
20
|
-
import { createTool } from '@mastra/core/tools';
|
|
21
18
|
import { createTavilySearchTool, createTavilyExtractTool } from '@mastra/tavily';
|
|
22
19
|
import { estimateTokenCount, sliceByTokens } from 'tokenx';
|
|
20
|
+
import * as os from 'os';
|
|
21
|
+
import os__default, { homedir } from 'os';
|
|
23
22
|
import { LocalFilesystem, Workspace, LocalSandbox } from '@mastra/core/workspace';
|
|
24
23
|
import { z } from 'zod';
|
|
25
24
|
import * as fs from 'fs';
|
|
@@ -29,9 +28,13 @@ import { fastembed } from '@mastra/fastembed';
|
|
|
29
28
|
import { Memory } from '@mastra/memory';
|
|
30
29
|
import { createAnthropic } from '@ai-sdk/anthropic';
|
|
31
30
|
import { createOpenAI } from '@ai-sdk/openai';
|
|
31
|
+
import { createOpenAICompatible } from '@ai-sdk/openai-compatible';
|
|
32
|
+
import { wrapLanguageModel } from 'ai';
|
|
33
|
+
import { GoogleSchemaCompatLayer, applyCompatLayer } from '@mastra/schema-compat';
|
|
32
34
|
import { createNotificationInboxTool, NotificationsStorage } from '@mastra/core/notifications';
|
|
33
35
|
import { createScorer, filterRun } from '@mastra/core/evals';
|
|
34
36
|
import { MCPClient, MCPOAuthClientProvider } from '@mastra/mcp';
|
|
37
|
+
import { createHash } from 'crypto';
|
|
35
38
|
import { mkdir } from 'fs/promises';
|
|
36
39
|
import { PubSub, UnixSocketPubSub } from '@mastra/core/events';
|
|
37
40
|
import { LibSQLStore, LibSQLVector } from '@mastra/libsql';
|
|
@@ -1027,6 +1030,982 @@ async function getDynamicInstructions({ requestContext }) {
|
|
|
1027
1030
|
};
|
|
1028
1031
|
return buildFullPrompt(promptCtx);
|
|
1029
1032
|
}
|
|
1033
|
+
var claudeCodeIdentity = "You are Claude Code, Anthropic's official CLI for Claude.";
|
|
1034
|
+
var OAUTH_REQUIRED_BETAS = [
|
|
1035
|
+
"oauth-2025-04-20",
|
|
1036
|
+
"claude-code-20250219",
|
|
1037
|
+
"interleaved-thinking-2025-05-14",
|
|
1038
|
+
"fine-grained-tool-streaming-2025-05-14"
|
|
1039
|
+
];
|
|
1040
|
+
var authStorageInstance = null;
|
|
1041
|
+
function getAuthStorage() {
|
|
1042
|
+
if (!authStorageInstance) {
|
|
1043
|
+
authStorageInstance = new AuthStorage();
|
|
1044
|
+
}
|
|
1045
|
+
return authStorageInstance;
|
|
1046
|
+
}
|
|
1047
|
+
function setAuthStorage(storage) {
|
|
1048
|
+
authStorageInstance = storage ?? null;
|
|
1049
|
+
}
|
|
1050
|
+
var claudeCodeMiddleware = {
|
|
1051
|
+
specificationVersion: "v3",
|
|
1052
|
+
transformParams: async ({ params }) => {
|
|
1053
|
+
const systemMessage = {
|
|
1054
|
+
role: "system",
|
|
1055
|
+
content: claudeCodeIdentity
|
|
1056
|
+
};
|
|
1057
|
+
if (params.temperature) {
|
|
1058
|
+
delete params.topP;
|
|
1059
|
+
}
|
|
1060
|
+
return {
|
|
1061
|
+
...params,
|
|
1062
|
+
prompt: [systemMessage, ...params.prompt]
|
|
1063
|
+
};
|
|
1064
|
+
}
|
|
1065
|
+
};
|
|
1066
|
+
var promptCacheMiddleware = {
|
|
1067
|
+
specificationVersion: "v3",
|
|
1068
|
+
transformParams: async ({ params }) => {
|
|
1069
|
+
const prompt = [...params.prompt];
|
|
1070
|
+
const cacheControl = { type: "ephemeral", ttl: "5m" };
|
|
1071
|
+
const addCacheToMessage = (msg) => {
|
|
1072
|
+
if (typeof msg.content === "string") {
|
|
1073
|
+
return {
|
|
1074
|
+
...msg,
|
|
1075
|
+
providerOptions: {
|
|
1076
|
+
...msg.providerOptions,
|
|
1077
|
+
anthropic: { ...msg.providerOptions?.anthropic, cacheControl }
|
|
1078
|
+
}
|
|
1079
|
+
};
|
|
1080
|
+
}
|
|
1081
|
+
if (Array.isArray(msg.content) && msg.content.length > 0) {
|
|
1082
|
+
const content = [...msg.content];
|
|
1083
|
+
const lastPart = content[content.length - 1];
|
|
1084
|
+
content[content.length - 1] = {
|
|
1085
|
+
...lastPart,
|
|
1086
|
+
providerOptions: {
|
|
1087
|
+
...lastPart.providerOptions,
|
|
1088
|
+
anthropic: { ...lastPart.providerOptions?.anthropic, cacheControl }
|
|
1089
|
+
}
|
|
1090
|
+
};
|
|
1091
|
+
return { ...msg, content };
|
|
1092
|
+
}
|
|
1093
|
+
return msg;
|
|
1094
|
+
};
|
|
1095
|
+
let lastSystemIdx = -1;
|
|
1096
|
+
for (let i = prompt.length - 1; i >= 0; i--) {
|
|
1097
|
+
if (prompt[i].role === "system") {
|
|
1098
|
+
lastSystemIdx = i;
|
|
1099
|
+
break;
|
|
1100
|
+
}
|
|
1101
|
+
}
|
|
1102
|
+
if (lastSystemIdx >= 0) {
|
|
1103
|
+
prompt[lastSystemIdx] = addCacheToMessage(prompt[lastSystemIdx]);
|
|
1104
|
+
}
|
|
1105
|
+
const lastIdx = prompt.length - 1;
|
|
1106
|
+
if (lastIdx >= 0 && lastIdx !== lastSystemIdx) {
|
|
1107
|
+
prompt[lastIdx] = addCacheToMessage(prompt[lastIdx]);
|
|
1108
|
+
}
|
|
1109
|
+
return { ...params, prompt };
|
|
1110
|
+
}
|
|
1111
|
+
};
|
|
1112
|
+
function buildAnthropicOAuthFetch(opts = {}) {
|
|
1113
|
+
return (async (url, init) => {
|
|
1114
|
+
const storage = opts.authStorage ?? getAuthStorage();
|
|
1115
|
+
storage.reload();
|
|
1116
|
+
const storedCred = storage.get("anthropic");
|
|
1117
|
+
if (storedCred?.type === "api_key") {
|
|
1118
|
+
throw new Error("Anthropic API key credential is configured, but OAuth is required.");
|
|
1119
|
+
}
|
|
1120
|
+
const accessToken = await storage.getApiKey("anthropic");
|
|
1121
|
+
if (!accessToken) {
|
|
1122
|
+
throw new Error("Not logged in to Anthropic. Run /login first.");
|
|
1123
|
+
}
|
|
1124
|
+
const headers = new Headers();
|
|
1125
|
+
if (init?.headers) {
|
|
1126
|
+
const source = init.headers instanceof Headers ? init.headers : Array.isArray(init.headers) ? new Headers(init.headers) : new Headers(init.headers);
|
|
1127
|
+
source.forEach((value, key) => {
|
|
1128
|
+
const lower = key.toLowerCase();
|
|
1129
|
+
if (lower !== "authorization" && lower !== "x-api-key") {
|
|
1130
|
+
headers.set(key, value);
|
|
1131
|
+
}
|
|
1132
|
+
});
|
|
1133
|
+
}
|
|
1134
|
+
headers.set("Authorization", `Bearer ${accessToken}`);
|
|
1135
|
+
const requestBetas = (headers.get("anthropic-beta") ?? "").split(",").map((beta) => beta.trim()).filter(Boolean);
|
|
1136
|
+
headers.set("anthropic-beta", Array.from(/* @__PURE__ */ new Set([...OAUTH_REQUIRED_BETAS, ...requestBetas])).join(","));
|
|
1137
|
+
headers.set("anthropic-version", "2023-06-01");
|
|
1138
|
+
try {
|
|
1139
|
+
return await fetch(url, { ...init, headers });
|
|
1140
|
+
} catch (error) {
|
|
1141
|
+
if (error && typeof error === "object") {
|
|
1142
|
+
Object.assign(error, {
|
|
1143
|
+
requestUrl: url instanceof URL ? url.toString() : typeof url === "string" ? url : url.url
|
|
1144
|
+
});
|
|
1145
|
+
}
|
|
1146
|
+
throw error;
|
|
1147
|
+
}
|
|
1148
|
+
});
|
|
1149
|
+
}
|
|
1150
|
+
function opencodeClaudeMaxProvider(modelId = "claude-sonnet-4-20250514", options) {
|
|
1151
|
+
const headers = options?.headers;
|
|
1152
|
+
if (process.env.NODE_ENV === "test" || process.env.VITEST) {
|
|
1153
|
+
const anthropic2 = createAnthropic({
|
|
1154
|
+
apiKey: "test-api-key",
|
|
1155
|
+
headers
|
|
1156
|
+
});
|
|
1157
|
+
return wrapLanguageModel({
|
|
1158
|
+
model: anthropic2(modelId),
|
|
1159
|
+
middleware: [claudeCodeMiddleware, promptCacheMiddleware]
|
|
1160
|
+
});
|
|
1161
|
+
}
|
|
1162
|
+
const anthropic = createAnthropic({
|
|
1163
|
+
apiKey: "oauth-placeholder",
|
|
1164
|
+
headers,
|
|
1165
|
+
fetch: buildAnthropicOAuthFetch()
|
|
1166
|
+
});
|
|
1167
|
+
return wrapLanguageModel({
|
|
1168
|
+
model: anthropic(modelId),
|
|
1169
|
+
middleware: [claudeCodeMiddleware, promptCacheMiddleware]
|
|
1170
|
+
});
|
|
1171
|
+
}
|
|
1172
|
+
var COPILOT_PROVIDER_ID = "github-copilot";
|
|
1173
|
+
var authStorageInstance2 = null;
|
|
1174
|
+
function getAuthStorage2() {
|
|
1175
|
+
if (!authStorageInstance2) {
|
|
1176
|
+
authStorageInstance2 = new AuthStorage();
|
|
1177
|
+
}
|
|
1178
|
+
return authStorageInstance2;
|
|
1179
|
+
}
|
|
1180
|
+
function setAuthStorage2(storage) {
|
|
1181
|
+
authStorageInstance2 = storage ?? null;
|
|
1182
|
+
}
|
|
1183
|
+
function detectIsAgent(body) {
|
|
1184
|
+
if (!body || typeof body !== "object") return false;
|
|
1185
|
+
const obj = body;
|
|
1186
|
+
const messages = obj.messages;
|
|
1187
|
+
if (Array.isArray(messages) && messages.length > 0) {
|
|
1188
|
+
const last = messages[messages.length - 1];
|
|
1189
|
+
if (last?.role && last.role !== "user") return true;
|
|
1190
|
+
if (Array.isArray(last?.content)) {
|
|
1191
|
+
const hasToolResult = last.content.some(
|
|
1192
|
+
(part) => part && typeof part === "object" && part.type === "tool_result"
|
|
1193
|
+
);
|
|
1194
|
+
if (hasToolResult) return true;
|
|
1195
|
+
}
|
|
1196
|
+
}
|
|
1197
|
+
const input = obj.input;
|
|
1198
|
+
if (Array.isArray(input) && input.length > 0) {
|
|
1199
|
+
const last = input[input.length - 1];
|
|
1200
|
+
if (last?.role && last.role !== "user") return true;
|
|
1201
|
+
}
|
|
1202
|
+
return false;
|
|
1203
|
+
}
|
|
1204
|
+
function detectIsVision(body) {
|
|
1205
|
+
if (!body || typeof body !== "object") return false;
|
|
1206
|
+
const obj = body;
|
|
1207
|
+
const matchPart = (part) => {
|
|
1208
|
+
if (!part || typeof part !== "object") return false;
|
|
1209
|
+
const t = part.type;
|
|
1210
|
+
return t === "image" || t === "image_url" || t === "input_image";
|
|
1211
|
+
};
|
|
1212
|
+
const messages = obj.messages;
|
|
1213
|
+
if (Array.isArray(messages)) {
|
|
1214
|
+
return messages.some(
|
|
1215
|
+
(msg) => msg && typeof msg === "object" && Array.isArray(msg.content) && msg.content.some(matchPart)
|
|
1216
|
+
);
|
|
1217
|
+
}
|
|
1218
|
+
const input = obj.input;
|
|
1219
|
+
if (Array.isArray(input)) {
|
|
1220
|
+
return input.some(
|
|
1221
|
+
(item) => item && typeof item === "object" && Array.isArray(item.content) && item.content.some(matchPart)
|
|
1222
|
+
);
|
|
1223
|
+
}
|
|
1224
|
+
return false;
|
|
1225
|
+
}
|
|
1226
|
+
function buildGitHubCopilotOAuthFetch(opts = {}) {
|
|
1227
|
+
return (async (url, init) => {
|
|
1228
|
+
const storage = opts.authStorage ?? getAuthStorage2();
|
|
1229
|
+
storage.reload();
|
|
1230
|
+
const cred = storage.get(COPILOT_PROVIDER_ID);
|
|
1231
|
+
if (!cred || cred.type !== "oauth") {
|
|
1232
|
+
throw new Error("Not logged in to GitHub Copilot. Run /login first.");
|
|
1233
|
+
}
|
|
1234
|
+
const accessToken = await storage.getApiKey(COPILOT_PROVIDER_ID);
|
|
1235
|
+
if (!accessToken) {
|
|
1236
|
+
throw new Error("Failed to refresh GitHub Copilot token. Please /login again.");
|
|
1237
|
+
}
|
|
1238
|
+
storage.reload();
|
|
1239
|
+
const enterpriseUrl = cred.enterpriseUrl;
|
|
1240
|
+
let parsedBody;
|
|
1241
|
+
if (typeof init?.body === "string") {
|
|
1242
|
+
try {
|
|
1243
|
+
parsedBody = JSON.parse(init.body);
|
|
1244
|
+
} catch {
|
|
1245
|
+
parsedBody = void 0;
|
|
1246
|
+
}
|
|
1247
|
+
}
|
|
1248
|
+
const isAgent = detectIsAgent(parsedBody);
|
|
1249
|
+
const isVision = detectIsVision(parsedBody);
|
|
1250
|
+
const headers = new Headers();
|
|
1251
|
+
if (init?.headers) {
|
|
1252
|
+
const source = init.headers instanceof Headers ? init.headers : Array.isArray(init.headers) ? new Headers(init.headers) : new Headers(init.headers);
|
|
1253
|
+
source.forEach((value, key) => {
|
|
1254
|
+
const lower = key.toLowerCase();
|
|
1255
|
+
if (lower !== "authorization" && lower !== "x-api-key") {
|
|
1256
|
+
headers.set(key, value);
|
|
1257
|
+
}
|
|
1258
|
+
});
|
|
1259
|
+
}
|
|
1260
|
+
headers.set("Authorization", `Bearer ${accessToken}`);
|
|
1261
|
+
headers.set("x-initiator", isAgent ? "agent" : "user");
|
|
1262
|
+
headers.set("Openai-Intent", "conversation-edits");
|
|
1263
|
+
if (isVision) {
|
|
1264
|
+
headers.set("Copilot-Vision-Request", "true");
|
|
1265
|
+
}
|
|
1266
|
+
for (const [key, value] of Object.entries(COPILOT_HEADERS)) {
|
|
1267
|
+
if (!headers.has(key)) {
|
|
1268
|
+
headers.set(key, value);
|
|
1269
|
+
}
|
|
1270
|
+
}
|
|
1271
|
+
const finalUrl = opts.rewriteUrl !== false ? rewriteToCopilotBase(url, accessToken, enterpriseUrl) : url instanceof URL ? url : typeof url === "string" ? new URL(url) : new URL(url.url);
|
|
1272
|
+
try {
|
|
1273
|
+
return await fetch(finalUrl, { ...init, headers });
|
|
1274
|
+
} catch (error) {
|
|
1275
|
+
if (error && typeof error === "object") {
|
|
1276
|
+
Object.assign(error, {
|
|
1277
|
+
requestUrl: finalUrl.toString()
|
|
1278
|
+
});
|
|
1279
|
+
}
|
|
1280
|
+
throw error;
|
|
1281
|
+
}
|
|
1282
|
+
});
|
|
1283
|
+
}
|
|
1284
|
+
function rewriteToCopilotBase(url, token, enterpriseDomain) {
|
|
1285
|
+
const original = url instanceof URL ? url : new URL(typeof url === "string" ? url : url.url);
|
|
1286
|
+
const base = new URL(getGitHubCopilotBaseUrl(token, enterpriseDomain));
|
|
1287
|
+
const pathname = original.pathname.replace(/^\/v1(\/|$)/, "/");
|
|
1288
|
+
return new URL(`${pathname}${original.search}`, base);
|
|
1289
|
+
}
|
|
1290
|
+
function isGeminiModel(modelId) {
|
|
1291
|
+
return modelId.startsWith("gemini-");
|
|
1292
|
+
}
|
|
1293
|
+
function applyGeminiSchemaCompatToTools(modelId, tools) {
|
|
1294
|
+
if (!Array.isArray(tools)) {
|
|
1295
|
+
return tools;
|
|
1296
|
+
}
|
|
1297
|
+
const compatLayer = new GoogleSchemaCompatLayer({
|
|
1298
|
+
provider: COPILOT_PROVIDER_ID,
|
|
1299
|
+
modelId,
|
|
1300
|
+
supportsStructuredOutputs: false
|
|
1301
|
+
});
|
|
1302
|
+
return tools.map((tool) => {
|
|
1303
|
+
if (!tool || typeof tool !== "object" || tool.type !== "function") {
|
|
1304
|
+
return tool;
|
|
1305
|
+
}
|
|
1306
|
+
const functionTool = tool;
|
|
1307
|
+
if (!functionTool.inputSchema) {
|
|
1308
|
+
return tool;
|
|
1309
|
+
}
|
|
1310
|
+
return {
|
|
1311
|
+
...functionTool,
|
|
1312
|
+
inputSchema: applyCompatLayer({
|
|
1313
|
+
schema: functionTool.inputSchema,
|
|
1314
|
+
compatLayers: [compatLayer],
|
|
1315
|
+
mode: "aiSdkSchema"
|
|
1316
|
+
}).jsonSchema
|
|
1317
|
+
};
|
|
1318
|
+
});
|
|
1319
|
+
}
|
|
1320
|
+
function createCopilotMiddleware(modelId) {
|
|
1321
|
+
return {
|
|
1322
|
+
specificationVersion: "v3",
|
|
1323
|
+
transformParams: async ({ params }) => {
|
|
1324
|
+
if (params.temperature !== void 0 && params.temperature !== null) {
|
|
1325
|
+
delete params.topP;
|
|
1326
|
+
}
|
|
1327
|
+
if (isGeminiModel(modelId)) {
|
|
1328
|
+
params.tools = applyGeminiSchemaCompatToTools(
|
|
1329
|
+
modelId,
|
|
1330
|
+
params.tools
|
|
1331
|
+
);
|
|
1332
|
+
}
|
|
1333
|
+
return params;
|
|
1334
|
+
}
|
|
1335
|
+
};
|
|
1336
|
+
}
|
|
1337
|
+
function githubCopilotProvider(modelId = "gpt-4.1", options) {
|
|
1338
|
+
const headers = options?.headers;
|
|
1339
|
+
const copilot = createOpenAICompatible({
|
|
1340
|
+
name: COPILOT_PROVIDER_ID,
|
|
1341
|
+
baseURL: "https://api.githubcopilot.com",
|
|
1342
|
+
apiKey: process.env.NODE_ENV === "test" || process.env.VITEST ? "test-api-key" : "oauth-placeholder",
|
|
1343
|
+
headers,
|
|
1344
|
+
fetch: process.env.NODE_ENV === "test" || process.env.VITEST ? void 0 : buildGitHubCopilotOAuthFetch({ rewriteUrl: false })
|
|
1345
|
+
});
|
|
1346
|
+
return wrapLanguageModel({
|
|
1347
|
+
model: copilot.chatModel(modelId),
|
|
1348
|
+
middleware: [createCopilotMiddleware(modelId)]
|
|
1349
|
+
});
|
|
1350
|
+
}
|
|
1351
|
+
var COPILOT_FALLBACK_MODELS = [
|
|
1352
|
+
{
|
|
1353
|
+
id: "gpt-4.1",
|
|
1354
|
+
name: "GPT-4.1",
|
|
1355
|
+
vendor: "OpenAI",
|
|
1356
|
+
supportedEndpoints: ["/chat/completions"],
|
|
1357
|
+
isAnthropicShaped: false,
|
|
1358
|
+
supportsVision: true,
|
|
1359
|
+
supportsToolCalls: true
|
|
1360
|
+
}
|
|
1361
|
+
];
|
|
1362
|
+
var CATALOG_TTL_MS = 10 * 60 * 1e3;
|
|
1363
|
+
var CATALOG_FAILURE_TTL_MS = 60 * 1e3;
|
|
1364
|
+
var CATALOG_FETCH_TIMEOUT_MS = 5e3;
|
|
1365
|
+
var catalogCache = null;
|
|
1366
|
+
var inflightFetch = null;
|
|
1367
|
+
async function getCopilotModelCatalog(opts = {}) {
|
|
1368
|
+
const storage = opts.authStorage ?? getAuthStorage2();
|
|
1369
|
+
storage.reload();
|
|
1370
|
+
const cred = storage.get(COPILOT_PROVIDER_ID);
|
|
1371
|
+
if (!cred || cred.type !== "oauth") {
|
|
1372
|
+
return [];
|
|
1373
|
+
}
|
|
1374
|
+
const now = Date.now();
|
|
1375
|
+
if (catalogCache && now - catalogCache.fetchedAt < catalogCache.ttl) {
|
|
1376
|
+
return catalogCache.models;
|
|
1377
|
+
}
|
|
1378
|
+
if (inflightFetch) return inflightFetch;
|
|
1379
|
+
inflightFetch = (async () => {
|
|
1380
|
+
try {
|
|
1381
|
+
const accessToken = await storage.getApiKey(COPILOT_PROVIDER_ID);
|
|
1382
|
+
if (!accessToken) throw new Error("No Copilot bearer token");
|
|
1383
|
+
storage.reload();
|
|
1384
|
+
const refreshed = storage.get(COPILOT_PROVIDER_ID);
|
|
1385
|
+
const enterpriseUrl = refreshed?.enterpriseUrl;
|
|
1386
|
+
const baseUrl = getGitHubCopilotBaseUrl(accessToken, enterpriseUrl);
|
|
1387
|
+
const controller = new AbortController();
|
|
1388
|
+
const timer = setTimeout(() => controller.abort(), CATALOG_FETCH_TIMEOUT_MS);
|
|
1389
|
+
try {
|
|
1390
|
+
const models = await fetchCopilotModels({
|
|
1391
|
+
baseUrl,
|
|
1392
|
+
bearerToken: accessToken,
|
|
1393
|
+
signal: controller.signal
|
|
1394
|
+
});
|
|
1395
|
+
catalogCache = { fetchedAt: Date.now(), ttl: CATALOG_TTL_MS, models };
|
|
1396
|
+
return models;
|
|
1397
|
+
} finally {
|
|
1398
|
+
clearTimeout(timer);
|
|
1399
|
+
}
|
|
1400
|
+
} catch (error) {
|
|
1401
|
+
catalogCache = {
|
|
1402
|
+
fetchedAt: Date.now(),
|
|
1403
|
+
ttl: CATALOG_FAILURE_TTL_MS,
|
|
1404
|
+
models: COPILOT_FALLBACK_MODELS
|
|
1405
|
+
};
|
|
1406
|
+
console.warn(
|
|
1407
|
+
"Failed to fetch live GitHub Copilot models, using fallback list:",
|
|
1408
|
+
error instanceof Error ? error.message : error
|
|
1409
|
+
);
|
|
1410
|
+
return COPILOT_FALLBACK_MODELS;
|
|
1411
|
+
} finally {
|
|
1412
|
+
inflightFetch = null;
|
|
1413
|
+
}
|
|
1414
|
+
})();
|
|
1415
|
+
return inflightFetch;
|
|
1416
|
+
}
|
|
1417
|
+
var CODEX_API_ENDPOINT = "https://chatgpt.com/backend-api/codex/responses";
|
|
1418
|
+
var CODEX_ORIGINATOR = "mastracode";
|
|
1419
|
+
var CODEX_USER_AGENT = "mastracode";
|
|
1420
|
+
var authStorageInstance3 = null;
|
|
1421
|
+
function getAuthStorage3() {
|
|
1422
|
+
if (!authStorageInstance3) {
|
|
1423
|
+
authStorageInstance3 = new AuthStorage();
|
|
1424
|
+
}
|
|
1425
|
+
return authStorageInstance3;
|
|
1426
|
+
}
|
|
1427
|
+
function setAuthStorage3(storage) {
|
|
1428
|
+
authStorageInstance3 = storage ?? null;
|
|
1429
|
+
}
|
|
1430
|
+
var CODEX_INSTRUCTIONS = `You are an interactive CLI tool that helps users with software engineering tasks. Use the instructions below and the tools available to you to assist the user.
|
|
1431
|
+
|
|
1432
|
+
IMPORTANT: You should be concise, direct, and helpful. Focus on solving the user's problem efficiently.`;
|
|
1433
|
+
var GPT5_MODEL_RE = /^gpt-5(?:\.|-|$)/;
|
|
1434
|
+
function getEffectiveThinkingLevel(modelId, level) {
|
|
1435
|
+
if (GPT5_MODEL_RE.test(modelId) && level === "off") {
|
|
1436
|
+
return "low";
|
|
1437
|
+
}
|
|
1438
|
+
return level;
|
|
1439
|
+
}
|
|
1440
|
+
var THINKING_LEVEL_TO_REASONING_EFFORT = {
|
|
1441
|
+
off: void 0,
|
|
1442
|
+
low: "low",
|
|
1443
|
+
medium: "medium",
|
|
1444
|
+
high: "high",
|
|
1445
|
+
xhigh: "xhigh"
|
|
1446
|
+
};
|
|
1447
|
+
function createCodexMiddleware(reasoningEffort) {
|
|
1448
|
+
return {
|
|
1449
|
+
specificationVersion: "v3",
|
|
1450
|
+
transformParams: async ({ params }) => {
|
|
1451
|
+
if (params.temperature !== void 0 && params.temperature !== null) {
|
|
1452
|
+
delete params.topP;
|
|
1453
|
+
}
|
|
1454
|
+
params.providerOptions = {
|
|
1455
|
+
...params.providerOptions,
|
|
1456
|
+
openai: {
|
|
1457
|
+
...params.providerOptions?.openai ?? {},
|
|
1458
|
+
instructions: CODEX_INSTRUCTIONS,
|
|
1459
|
+
// Codex API requires store to be false
|
|
1460
|
+
store: false,
|
|
1461
|
+
// Enable reasoning for Codex models — without this, the model
|
|
1462
|
+
// skips the reasoning/action phase and goes straight to final_answer,
|
|
1463
|
+
// resulting in narration instead of tool calls.
|
|
1464
|
+
...reasoningEffort ? { reasoningEffort } : {}
|
|
1465
|
+
}
|
|
1466
|
+
};
|
|
1467
|
+
return params;
|
|
1468
|
+
}
|
|
1469
|
+
};
|
|
1470
|
+
}
|
|
1471
|
+
function buildOpenAICodexOAuthFetch(opts = {}) {
|
|
1472
|
+
return (async (url, init) => {
|
|
1473
|
+
const storage = opts.authStorage ?? getAuthStorage3();
|
|
1474
|
+
storage.reload();
|
|
1475
|
+
const cred = storage.get("openai-codex");
|
|
1476
|
+
if (!cred || cred.type !== "oauth") {
|
|
1477
|
+
throw new Error("Not logged in to OpenAI Codex. Run /login first.");
|
|
1478
|
+
}
|
|
1479
|
+
let accessToken = cred.access;
|
|
1480
|
+
if (Date.now() >= cred.expires) {
|
|
1481
|
+
const refreshedToken = await storage.getApiKey("openai-codex");
|
|
1482
|
+
if (!refreshedToken) {
|
|
1483
|
+
throw new Error("Failed to refresh OpenAI Codex token. Please /login again.");
|
|
1484
|
+
}
|
|
1485
|
+
accessToken = refreshedToken;
|
|
1486
|
+
storage.reload();
|
|
1487
|
+
}
|
|
1488
|
+
const accountId = cred.accountId;
|
|
1489
|
+
const headers = new Headers();
|
|
1490
|
+
if (init?.headers) {
|
|
1491
|
+
if (init.headers instanceof Headers) {
|
|
1492
|
+
init.headers.forEach((value, key) => {
|
|
1493
|
+
if (key.toLowerCase() !== "authorization") {
|
|
1494
|
+
headers.set(key, value);
|
|
1495
|
+
}
|
|
1496
|
+
});
|
|
1497
|
+
} else if (Array.isArray(init.headers)) {
|
|
1498
|
+
for (const [key, value] of init.headers) {
|
|
1499
|
+
if (key.toLowerCase() !== "authorization" && value !== void 0) {
|
|
1500
|
+
headers.set(key, String(value));
|
|
1501
|
+
}
|
|
1502
|
+
}
|
|
1503
|
+
} else {
|
|
1504
|
+
for (const [key, value] of Object.entries(init.headers)) {
|
|
1505
|
+
if (key.toLowerCase() !== "authorization" && value !== void 0) {
|
|
1506
|
+
headers.set(key, String(value));
|
|
1507
|
+
}
|
|
1508
|
+
}
|
|
1509
|
+
}
|
|
1510
|
+
}
|
|
1511
|
+
headers.set("Authorization", `Bearer ${accessToken}`);
|
|
1512
|
+
if (!headers.has("originator")) {
|
|
1513
|
+
headers.set("originator", CODEX_ORIGINATOR);
|
|
1514
|
+
}
|
|
1515
|
+
if (!headers.has("User-Agent")) {
|
|
1516
|
+
headers.set("User-Agent", CODEX_USER_AGENT);
|
|
1517
|
+
}
|
|
1518
|
+
if (accountId) {
|
|
1519
|
+
headers.set("ChatGPT-Account-ID", accountId);
|
|
1520
|
+
}
|
|
1521
|
+
const parsed = url instanceof URL ? url : new URL(typeof url === "string" ? url : url.url);
|
|
1522
|
+
const shouldRewrite = opts.rewriteUrl !== false && (parsed.pathname.includes("/v1/responses") || parsed.pathname.includes("/chat/completions"));
|
|
1523
|
+
const finalUrl = shouldRewrite ? new URL(CODEX_API_ENDPOINT) : parsed;
|
|
1524
|
+
try {
|
|
1525
|
+
return await fetch(finalUrl, { ...init, headers });
|
|
1526
|
+
} catch (error) {
|
|
1527
|
+
if (error && typeof error === "object") {
|
|
1528
|
+
Object.assign(error, {
|
|
1529
|
+
requestUrl: finalUrl.toString()
|
|
1530
|
+
});
|
|
1531
|
+
}
|
|
1532
|
+
throw error;
|
|
1533
|
+
}
|
|
1534
|
+
});
|
|
1535
|
+
}
|
|
1536
|
+
function openaiCodexProvider(modelId = "codex-mini-latest", options) {
|
|
1537
|
+
const requestedLevel = options?.thinkingLevel ?? "medium";
|
|
1538
|
+
const effectiveLevel = getEffectiveThinkingLevel(modelId, requestedLevel);
|
|
1539
|
+
const reasoningEffort = THINKING_LEVEL_TO_REASONING_EFFORT[effectiveLevel];
|
|
1540
|
+
const middleware = createCodexMiddleware(reasoningEffort);
|
|
1541
|
+
const headers = options?.headers;
|
|
1542
|
+
const baseURL = process.env.OPENAI_BASE_URL;
|
|
1543
|
+
if (process.env.NODE_ENV === "test" || process.env.VITEST) {
|
|
1544
|
+
const openai2 = createOpenAI({
|
|
1545
|
+
apiKey: "test-api-key",
|
|
1546
|
+
baseURL,
|
|
1547
|
+
headers
|
|
1548
|
+
});
|
|
1549
|
+
return wrapLanguageModel({
|
|
1550
|
+
model: openai2.responses(modelId),
|
|
1551
|
+
middleware: [middleware]
|
|
1552
|
+
});
|
|
1553
|
+
}
|
|
1554
|
+
const openai = createOpenAI({
|
|
1555
|
+
apiKey: "oauth-dummy-key",
|
|
1556
|
+
baseURL,
|
|
1557
|
+
headers,
|
|
1558
|
+
fetch: buildOpenAICodexOAuthFetch()
|
|
1559
|
+
});
|
|
1560
|
+
return wrapLanguageModel({
|
|
1561
|
+
model: openai.responses(modelId),
|
|
1562
|
+
middleware: [middleware]
|
|
1563
|
+
});
|
|
1564
|
+
}
|
|
1565
|
+
|
|
1566
|
+
// src/agents/mastracode-gateway.ts
|
|
1567
|
+
var OPENAI_PREFIX = "openai/";
|
|
1568
|
+
var MASTRA_GATEWAY_PREFIX = "mastra/";
|
|
1569
|
+
var MASTRACODE_GATEWAY_ID = "mastracode";
|
|
1570
|
+
var CODEX_OPENAI_MODEL_REMAPS = {
|
|
1571
|
+
"gpt-5.3": "gpt-5.3-codex",
|
|
1572
|
+
"gpt-5.2": "gpt-5.2-codex",
|
|
1573
|
+
"gpt-5.1": "gpt-5.1-codex",
|
|
1574
|
+
"gpt-5.1-mini": "gpt-5.1-codex-mini",
|
|
1575
|
+
"gpt-5": "gpt-5-codex"
|
|
1576
|
+
};
|
|
1577
|
+
var authStorage = new AuthStorage();
|
|
1578
|
+
function reloadAuthStorage() {
|
|
1579
|
+
authStorage.reload();
|
|
1580
|
+
}
|
|
1581
|
+
function stripMastraGatewayPrefix(modelId) {
|
|
1582
|
+
return modelId.startsWith(MASTRA_GATEWAY_PREFIX) ? modelId.substring(MASTRA_GATEWAY_PREFIX.length) : modelId;
|
|
1583
|
+
}
|
|
1584
|
+
function normalizeAnthropicModelId(modelId) {
|
|
1585
|
+
return modelId.replace(/\.(?=\d)/g, "-");
|
|
1586
|
+
}
|
|
1587
|
+
function remapOpenAIModelForCodexOAuth(modelId) {
|
|
1588
|
+
const normalizedModelId = stripMastraGatewayPrefix(modelId);
|
|
1589
|
+
if (!normalizedModelId.startsWith(OPENAI_PREFIX)) {
|
|
1590
|
+
return modelId;
|
|
1591
|
+
}
|
|
1592
|
+
const openaiModelId = normalizedModelId.substring(OPENAI_PREFIX.length);
|
|
1593
|
+
if (openaiModelId.includes("-codex")) {
|
|
1594
|
+
return modelId;
|
|
1595
|
+
}
|
|
1596
|
+
const codexModelId = CODEX_OPENAI_MODEL_REMAPS[openaiModelId];
|
|
1597
|
+
if (!codexModelId) {
|
|
1598
|
+
return modelId;
|
|
1599
|
+
}
|
|
1600
|
+
const remappedModelId = `${OPENAI_PREFIX}${codexModelId}`;
|
|
1601
|
+
return modelId.startsWith(MASTRA_GATEWAY_PREFIX) ? `${MASTRA_GATEWAY_PREFIX}${remappedModelId}` : remappedModelId;
|
|
1602
|
+
}
|
|
1603
|
+
function getAnthropicApiKey() {
|
|
1604
|
+
const storedCred = authStorage.get("anthropic");
|
|
1605
|
+
if (storedCred?.type === "api_key" && storedCred.key.trim().length > 0) {
|
|
1606
|
+
return storedCred.key.trim();
|
|
1607
|
+
}
|
|
1608
|
+
const dedicatedKey = authStorage.getStoredApiKey("anthropic")?.trim();
|
|
1609
|
+
if (dedicatedKey) return dedicatedKey;
|
|
1610
|
+
return process.env.ANTHROPIC_API_KEY?.trim() || void 0;
|
|
1611
|
+
}
|
|
1612
|
+
function getOpenAIApiKey() {
|
|
1613
|
+
const storedCred = authStorage.get("openai-codex");
|
|
1614
|
+
if (storedCred?.type === "api_key" && storedCred.key.trim().length > 0) {
|
|
1615
|
+
return storedCred.key.trim();
|
|
1616
|
+
}
|
|
1617
|
+
const dedicatedKey = authStorage.getStoredApiKey("openai-codex")?.trim();
|
|
1618
|
+
if (dedicatedKey) return dedicatedKey;
|
|
1619
|
+
return process.env.OPENAI_API_KEY?.trim() || void 0;
|
|
1620
|
+
}
|
|
1621
|
+
function anthropicApiKeyProvider(modelId, apiKey, headers) {
|
|
1622
|
+
const anthropic = createAnthropic({ apiKey, headers });
|
|
1623
|
+
return wrapLanguageModel({
|
|
1624
|
+
model: anthropic(modelId),
|
|
1625
|
+
middleware: [promptCacheMiddleware]
|
|
1626
|
+
});
|
|
1627
|
+
}
|
|
1628
|
+
function openaiApiKeyProvider(modelId, apiKey, headers) {
|
|
1629
|
+
const openai = createOpenAI({ apiKey, baseURL: process.env.OPENAI_BASE_URL, headers });
|
|
1630
|
+
return wrapLanguageModel({
|
|
1631
|
+
model: openai.responses(modelId),
|
|
1632
|
+
middleware: []
|
|
1633
|
+
});
|
|
1634
|
+
}
|
|
1635
|
+
function getAuthProviderId(providerId) {
|
|
1636
|
+
return providerId === "openai" ? "openai-codex" : providerId;
|
|
1637
|
+
}
|
|
1638
|
+
function getProviderAuthKey(providerId) {
|
|
1639
|
+
const authProviderId = getAuthProviderId(providerId);
|
|
1640
|
+
const storedCred = authStorage.get(authProviderId);
|
|
1641
|
+
if (storedCred?.type === "api_key" && storedCred.key.trim().length > 0) {
|
|
1642
|
+
return storedCred.key.trim();
|
|
1643
|
+
}
|
|
1644
|
+
return authStorage.getStoredApiKey(authProviderId)?.trim() || void 0;
|
|
1645
|
+
}
|
|
1646
|
+
function getGatewayProviderKey(gatewayId, providerId) {
|
|
1647
|
+
if (gatewayId === "models.dev") return providerId;
|
|
1648
|
+
return providerId === gatewayId ? gatewayId : `${gatewayId}/${providerId}`;
|
|
1649
|
+
}
|
|
1650
|
+
function parseGatewayRouterId(routerId, gateway) {
|
|
1651
|
+
const [firstPart = "", secondPart = "", ...restParts] = routerId.split("/");
|
|
1652
|
+
const gatewayId = gateway.id;
|
|
1653
|
+
if (firstPart === gatewayId && secondPart) {
|
|
1654
|
+
return {
|
|
1655
|
+
gatewayId,
|
|
1656
|
+
providerId: secondPart,
|
|
1657
|
+
modelId: restParts.join("/")
|
|
1658
|
+
};
|
|
1659
|
+
}
|
|
1660
|
+
return {
|
|
1661
|
+
gatewayId,
|
|
1662
|
+
providerId: firstPart,
|
|
1663
|
+
modelId: [secondPart, ...restParts].filter(Boolean).join("/")
|
|
1664
|
+
};
|
|
1665
|
+
}
|
|
1666
|
+
function hasResolvedAuth(auth) {
|
|
1667
|
+
if (!auth) return false;
|
|
1668
|
+
if (auth.apiKey || auth.bearerToken) return true;
|
|
1669
|
+
return auth.headers ? Object.keys(auth.headers).length > 0 : false;
|
|
1670
|
+
}
|
|
1671
|
+
async function resolveGatewayProviderAuth(gateway, routerId) {
|
|
1672
|
+
if (!gateway.resolveAuth) return void 0;
|
|
1673
|
+
const parsed = parseGatewayRouterId(routerId, gateway);
|
|
1674
|
+
try {
|
|
1675
|
+
const result = await gateway.resolveAuth({
|
|
1676
|
+
gatewayId: parsed.gatewayId,
|
|
1677
|
+
providerId: parsed.providerId,
|
|
1678
|
+
modelId: parsed.modelId,
|
|
1679
|
+
routerId
|
|
1680
|
+
});
|
|
1681
|
+
return hasResolvedAuth(result) ? result : void 0;
|
|
1682
|
+
} catch {
|
|
1683
|
+
return void 0;
|
|
1684
|
+
}
|
|
1685
|
+
}
|
|
1686
|
+
async function getMastraCodeProviderConfigs(gateway) {
|
|
1687
|
+
const providers = { ...PROVIDER_REGISTRY };
|
|
1688
|
+
try {
|
|
1689
|
+
const gatewayProviders = await gateway.fetchProviders();
|
|
1690
|
+
for (const [providerId, config] of Object.entries(gatewayProviders)) {
|
|
1691
|
+
providers[getGatewayProviderKey(gateway.id, providerId)] = {
|
|
1692
|
+
...config,
|
|
1693
|
+
gateway: gateway.id
|
|
1694
|
+
};
|
|
1695
|
+
}
|
|
1696
|
+
} catch (error) {
|
|
1697
|
+
console.warn(`Failed to load providers from gateway ${gateway.id}:`, error);
|
|
1698
|
+
}
|
|
1699
|
+
return providers;
|
|
1700
|
+
}
|
|
1701
|
+
function getApiKeyEnvVar(providerConfig) {
|
|
1702
|
+
const envVars = providerConfig?.apiKeyEnvVar;
|
|
1703
|
+
return Array.isArray(envVars) ? envVars[0] : envVars;
|
|
1704
|
+
}
|
|
1705
|
+
var MastraCodeGateway = class _MastraCodeGateway extends MastraModelGateway {
|
|
1706
|
+
id = MASTRACODE_GATEWAY_ID;
|
|
1707
|
+
name = "MastraCode Gateway";
|
|
1708
|
+
#mastraGateway;
|
|
1709
|
+
#mastraGatewayBaseUrl;
|
|
1710
|
+
#mastraGatewayApiKey;
|
|
1711
|
+
#routeThroughMastraGateway;
|
|
1712
|
+
#thinkingLevel;
|
|
1713
|
+
#customProviders;
|
|
1714
|
+
#settingsPath;
|
|
1715
|
+
constructor({
|
|
1716
|
+
mastraGatewayBaseUrl,
|
|
1717
|
+
mastraGatewayApiKey,
|
|
1718
|
+
routeThroughMastraGateway,
|
|
1719
|
+
thinkingLevel,
|
|
1720
|
+
customProviders,
|
|
1721
|
+
settingsPath
|
|
1722
|
+
}) {
|
|
1723
|
+
super();
|
|
1724
|
+
this.#mastraGateway = new MastraGateway({ baseUrl: mastraGatewayBaseUrl });
|
|
1725
|
+
this.#mastraGatewayBaseUrl = mastraGatewayBaseUrl;
|
|
1726
|
+
this.#mastraGatewayApiKey = mastraGatewayApiKey;
|
|
1727
|
+
this.#routeThroughMastraGateway = routeThroughMastraGateway;
|
|
1728
|
+
this.#thinkingLevel = thinkingLevel;
|
|
1729
|
+
this.#customProviders = customProviders;
|
|
1730
|
+
this.#settingsPath = settingsPath;
|
|
1731
|
+
}
|
|
1732
|
+
static getMemoryGatewayApiKey() {
|
|
1733
|
+
return authStorage.getStoredApiKey(MEMORY_GATEWAY_PROVIDER) ?? process.env["MASTRA_GATEWAY_API_KEY"];
|
|
1734
|
+
}
|
|
1735
|
+
static resolveProviderAuth(request, memoryGatewayApiKey) {
|
|
1736
|
+
if (request.gatewayId === "mastra" && memoryGatewayApiKey) {
|
|
1737
|
+
return { apiKey: memoryGatewayApiKey, source: "gateway" };
|
|
1738
|
+
}
|
|
1739
|
+
const storedCred = authStorage.get(getAuthProviderId(request.providerId));
|
|
1740
|
+
if (storedCred?.type === "oauth") {
|
|
1741
|
+
return { bearerToken: "oauth", source: "gateway" };
|
|
1742
|
+
}
|
|
1743
|
+
const apiKey = getProviderAuthKey(request.providerId);
|
|
1744
|
+
return apiKey ? { apiKey, source: "gateway" } : void 0;
|
|
1745
|
+
}
|
|
1746
|
+
static createModelCatalogProvider(gateway) {
|
|
1747
|
+
return async () => {
|
|
1748
|
+
const registry = await getMastraCodeProviderConfigs(gateway);
|
|
1749
|
+
const models = [];
|
|
1750
|
+
for (const [provider, providerConfig] of Object.entries(registry)) {
|
|
1751
|
+
const apiKeyEnvVar = getApiKeyEnvVar(providerConfig);
|
|
1752
|
+
const hasEnvKey = apiKeyEnvVar ? Boolean(process.env[apiKeyEnvVar]) : false;
|
|
1753
|
+
const modelNames = providerConfig.models;
|
|
1754
|
+
if (!Array.isArray(modelNames)) continue;
|
|
1755
|
+
const gatewayAuth = modelNames[0] ? await resolveGatewayProviderAuth(gateway, `${provider}/${modelNames[0]}`) : void 0;
|
|
1756
|
+
for (const modelName of modelNames) {
|
|
1757
|
+
const id = `${provider}/${modelName}`;
|
|
1758
|
+
models.push({
|
|
1759
|
+
id,
|
|
1760
|
+
provider,
|
|
1761
|
+
modelName,
|
|
1762
|
+
hasApiKey: hasEnvKey || Boolean(gatewayAuth),
|
|
1763
|
+
apiKeyEnvVar: apiKeyEnvVar || void 0
|
|
1764
|
+
});
|
|
1765
|
+
}
|
|
1766
|
+
}
|
|
1767
|
+
return models;
|
|
1768
|
+
};
|
|
1769
|
+
}
|
|
1770
|
+
createModelCatalogProvider() {
|
|
1771
|
+
return _MastraCodeGateway.createModelCatalogProvider(this);
|
|
1772
|
+
}
|
|
1773
|
+
#getCustomProviders() {
|
|
1774
|
+
return this.#customProviders ?? loadSettings(this.#settingsPath).customProviders;
|
|
1775
|
+
}
|
|
1776
|
+
async fetchProviders() {
|
|
1777
|
+
const providers = {};
|
|
1778
|
+
for (const provider of this.#getCustomProviders()) {
|
|
1779
|
+
const models = provider.models ?? [];
|
|
1780
|
+
if (!models.length) continue;
|
|
1781
|
+
providers[getCustomProviderId(provider.name)] = {
|
|
1782
|
+
name: provider.name,
|
|
1783
|
+
url: provider.url,
|
|
1784
|
+
apiKeyEnvVar: "",
|
|
1785
|
+
apiKeyHeader: "Authorization",
|
|
1786
|
+
gateway: this.id,
|
|
1787
|
+
models
|
|
1788
|
+
};
|
|
1789
|
+
}
|
|
1790
|
+
try {
|
|
1791
|
+
const copilotModels = await getCopilotModelCatalog({ authStorage });
|
|
1792
|
+
providers["github-copilot"] = {
|
|
1793
|
+
name: "GitHub Copilot",
|
|
1794
|
+
apiKeyEnvVar: "",
|
|
1795
|
+
apiKeyHeader: "Authorization",
|
|
1796
|
+
gateway: this.id,
|
|
1797
|
+
models: copilotModels.map((model) => model.id)
|
|
1798
|
+
};
|
|
1799
|
+
} catch (error) {
|
|
1800
|
+
console.warn("Failed to load GitHub Copilot model catalog:", error);
|
|
1801
|
+
}
|
|
1802
|
+
return providers;
|
|
1803
|
+
}
|
|
1804
|
+
buildUrl(modelId) {
|
|
1805
|
+
return this.#routeThroughMastraGateway ? this.#mastraGateway.buildUrl(modelId) : modelId;
|
|
1806
|
+
}
|
|
1807
|
+
async getApiKey(modelId) {
|
|
1808
|
+
const providerId = stripMastraGatewayPrefix(modelId).split("/", 1)[0];
|
|
1809
|
+
if (this.#routeThroughMastraGateway) return this.#mastraGatewayApiKey ?? "";
|
|
1810
|
+
return providerId ? getProviderAuthKey(providerId) ?? "" : "";
|
|
1811
|
+
}
|
|
1812
|
+
resolveAuth(request) {
|
|
1813
|
+
if (this.#routeThroughMastraGateway && this.#mastraGatewayApiKey) {
|
|
1814
|
+
return { apiKey: this.#mastraGatewayApiKey, source: "gateway" };
|
|
1815
|
+
}
|
|
1816
|
+
const customProvider = this.#getCustomProviders().find(
|
|
1817
|
+
(provider) => request.providerId === getCustomProviderId(provider.name)
|
|
1818
|
+
);
|
|
1819
|
+
if (customProvider?.apiKey) {
|
|
1820
|
+
return { apiKey: customProvider.apiKey, source: "gateway" };
|
|
1821
|
+
}
|
|
1822
|
+
return _MastraCodeGateway.resolveProviderAuth(request);
|
|
1823
|
+
}
|
|
1824
|
+
resolveLanguageModel(args) {
|
|
1825
|
+
const customProvider = this.#getCustomProviders().find(
|
|
1826
|
+
(provider) => args.providerId === getCustomProviderId(provider.name)
|
|
1827
|
+
);
|
|
1828
|
+
if (customProvider) {
|
|
1829
|
+
const provider = createOpenAICompatible({
|
|
1830
|
+
name: args.providerId,
|
|
1831
|
+
baseURL: customProvider.url,
|
|
1832
|
+
apiKey: args.apiKey,
|
|
1833
|
+
headers: args.headers
|
|
1834
|
+
});
|
|
1835
|
+
return provider.chatModel(args.modelId);
|
|
1836
|
+
}
|
|
1837
|
+
if (args.providerId === "github-copilot") {
|
|
1838
|
+
return githubCopilotProvider(args.modelId, { headers: args.headers });
|
|
1839
|
+
}
|
|
1840
|
+
if (args.providerId === "moonshotai") {
|
|
1841
|
+
if (!process.env.MOONSHOT_AI_API_KEY) {
|
|
1842
|
+
throw new Error(`Need MOONSHOT_AI_API_KEY`);
|
|
1843
|
+
}
|
|
1844
|
+
return createAnthropic({
|
|
1845
|
+
apiKey: process.env.MOONSHOT_AI_API_KEY,
|
|
1846
|
+
baseURL: "https://api.moonshot.ai/anthropic/v1",
|
|
1847
|
+
name: "moonshotai.anthropicv1",
|
|
1848
|
+
headers: args.headers
|
|
1849
|
+
})(args.modelId);
|
|
1850
|
+
}
|
|
1851
|
+
if (args.providerId === "anthropic") {
|
|
1852
|
+
return this.#resolveAnthropicModel(args);
|
|
1853
|
+
}
|
|
1854
|
+
if (args.providerId === "openai") {
|
|
1855
|
+
const openaiModel = this.#resolveOpenAIModel(args);
|
|
1856
|
+
if (openaiModel) return openaiModel;
|
|
1857
|
+
}
|
|
1858
|
+
if (this.#routeThroughMastraGateway) {
|
|
1859
|
+
return this.#mastraGateway.resolveLanguageModel(args);
|
|
1860
|
+
}
|
|
1861
|
+
return new ModelRouterLanguageModel({
|
|
1862
|
+
id: `${args.providerId}/${args.modelId}`,
|
|
1863
|
+
headers: args.headers
|
|
1864
|
+
});
|
|
1865
|
+
}
|
|
1866
|
+
#resolveAnthropicModel(args) {
|
|
1867
|
+
const bareModelId = normalizeAnthropicModelId(args.modelId);
|
|
1868
|
+
const storedCred = authStorage.get("anthropic");
|
|
1869
|
+
if (this.#routeThroughMastraGateway) {
|
|
1870
|
+
if (storedCred?.type === "oauth") {
|
|
1871
|
+
const anthropic = createAnthropic({
|
|
1872
|
+
apiKey: "oauth-gateway-placeholder",
|
|
1873
|
+
baseURL: `${this.#mastraGatewayBaseUrl}/v1`,
|
|
1874
|
+
headers: {
|
|
1875
|
+
[GATEWAY_AUTH_HEADER]: `Bearer ${args.apiKey}`,
|
|
1876
|
+
...args.headers
|
|
1877
|
+
},
|
|
1878
|
+
fetch: buildAnthropicOAuthFetch({ authStorage })
|
|
1879
|
+
});
|
|
1880
|
+
return wrapLanguageModel({
|
|
1881
|
+
model: anthropic(bareModelId),
|
|
1882
|
+
middleware: [claudeCodeMiddleware, promptCacheMiddleware]
|
|
1883
|
+
});
|
|
1884
|
+
}
|
|
1885
|
+
return this.#mastraGateway.resolveLanguageModel({ ...args, modelId: bareModelId });
|
|
1886
|
+
}
|
|
1887
|
+
if (storedCred?.type === "oauth") {
|
|
1888
|
+
return opencodeClaudeMaxProvider(bareModelId, { headers: args.headers });
|
|
1889
|
+
}
|
|
1890
|
+
if (storedCred?.type === "api_key" && storedCred.key.trim().length > 0) {
|
|
1891
|
+
return anthropicApiKeyProvider(
|
|
1892
|
+
bareModelId,
|
|
1893
|
+
storedCred.key.trim(),
|
|
1894
|
+
args.headers
|
|
1895
|
+
);
|
|
1896
|
+
}
|
|
1897
|
+
const apiKey = getAnthropicApiKey();
|
|
1898
|
+
if (apiKey) {
|
|
1899
|
+
return anthropicApiKeyProvider(bareModelId, apiKey, args.headers);
|
|
1900
|
+
}
|
|
1901
|
+
return opencodeClaudeMaxProvider(bareModelId, { headers: args.headers });
|
|
1902
|
+
}
|
|
1903
|
+
#resolveOpenAIModel(args) {
|
|
1904
|
+
const storedCred = authStorage.get("openai-codex");
|
|
1905
|
+
if (this.#routeThroughMastraGateway) {
|
|
1906
|
+
if (storedCred?.type === "oauth") {
|
|
1907
|
+
const resolvedModelId = remapOpenAIModelForCodexOAuth(`openai/${args.modelId}`);
|
|
1908
|
+
const resolvedBareModelId = resolvedModelId.substring(OPENAI_PREFIX.length);
|
|
1909
|
+
const requestedLevel = this.#thinkingLevel ?? "medium";
|
|
1910
|
+
const effectiveLevel = getEffectiveThinkingLevel(resolvedBareModelId, requestedLevel);
|
|
1911
|
+
const reasoningEffort = THINKING_LEVEL_TO_REASONING_EFFORT[effectiveLevel];
|
|
1912
|
+
const middleware = createCodexMiddleware(reasoningEffort);
|
|
1913
|
+
const openai = createOpenAI({
|
|
1914
|
+
apiKey: "oauth-gateway-placeholder",
|
|
1915
|
+
baseURL: `${this.#mastraGatewayBaseUrl}/v1`,
|
|
1916
|
+
headers: {
|
|
1917
|
+
[GATEWAY_AUTH_HEADER]: `Bearer ${args.apiKey}`,
|
|
1918
|
+
...args.headers
|
|
1919
|
+
},
|
|
1920
|
+
fetch: buildOpenAICodexOAuthFetch({ authStorage, rewriteUrl: false })
|
|
1921
|
+
});
|
|
1922
|
+
return wrapLanguageModel({
|
|
1923
|
+
model: openai.responses(resolvedBareModelId),
|
|
1924
|
+
middleware: [middleware]
|
|
1925
|
+
});
|
|
1926
|
+
}
|
|
1927
|
+
return this.#mastraGateway.resolveLanguageModel(args);
|
|
1928
|
+
}
|
|
1929
|
+
if (storedCred?.type === "oauth") {
|
|
1930
|
+
const resolvedModelId = remapOpenAIModelForCodexOAuth(`openai/${args.modelId}`);
|
|
1931
|
+
return openaiCodexProvider(resolvedModelId.substring(OPENAI_PREFIX.length), {
|
|
1932
|
+
thinkingLevel: this.#thinkingLevel,
|
|
1933
|
+
headers: args.headers
|
|
1934
|
+
});
|
|
1935
|
+
}
|
|
1936
|
+
const apiKey = getOpenAIApiKey();
|
|
1937
|
+
if (apiKey) {
|
|
1938
|
+
return openaiApiKeyProvider(args.modelId, apiKey, args.headers);
|
|
1939
|
+
}
|
|
1940
|
+
return void 0;
|
|
1941
|
+
}
|
|
1942
|
+
};
|
|
1943
|
+
|
|
1944
|
+
// src/agents/model.ts
|
|
1945
|
+
function getHarnessHeaders(requestContext) {
|
|
1946
|
+
const harnessContext = requestContext?.get("harness");
|
|
1947
|
+
const headers = {
|
|
1948
|
+
...harnessContext?.threadId ? { "x-thread-id": harnessContext.threadId } : {},
|
|
1949
|
+
...harnessContext?.resourceId ? { "x-resource-id": harnessContext.resourceId } : {}
|
|
1950
|
+
};
|
|
1951
|
+
return Object.keys(headers).length > 0 ? headers : void 0;
|
|
1952
|
+
}
|
|
1953
|
+
function createMastraCodeGateway(options) {
|
|
1954
|
+
return new MastraCodeGateway(options);
|
|
1955
|
+
}
|
|
1956
|
+
function createMastraCodeModelCatalogProvider(gateway) {
|
|
1957
|
+
return gateway instanceof MastraCodeGateway ? gateway.createModelCatalogProvider() : MastraCodeGateway.createModelCatalogProvider(gateway);
|
|
1958
|
+
}
|
|
1959
|
+
function resolveModel(modelId, options) {
|
|
1960
|
+
reloadAuthStorage();
|
|
1961
|
+
const headers = getHarnessHeaders(options?.requestContext);
|
|
1962
|
+
const settings = loadSettings();
|
|
1963
|
+
const isMastraGatewayModel = modelId.startsWith(MASTRA_GATEWAY_PREFIX);
|
|
1964
|
+
const normalizedModelId = stripMastraGatewayPrefix(modelId);
|
|
1965
|
+
const [providerId, ...modelParts] = normalizedModelId.split("/");
|
|
1966
|
+
const bareModelId = modelParts.join("/");
|
|
1967
|
+
if (!providerId || !bareModelId) {
|
|
1968
|
+
throw new Error(`Invalid model id: ${modelId}`);
|
|
1969
|
+
}
|
|
1970
|
+
const routerId = `${MASTRACODE_GATEWAY_ID}/${normalizedModelId}`;
|
|
1971
|
+
const mgApiKey = MastraCodeGateway.getMemoryGatewayApiKey();
|
|
1972
|
+
const rawGatewayBase = settings.memoryGateway?.baseUrl ?? process.env["MASTRA_GATEWAY_URL"] ?? "https://gateway-api.mastra.ai";
|
|
1973
|
+
const gateway = createMastraCodeGateway({
|
|
1974
|
+
mastraGatewayBaseUrl: rawGatewayBase.replace(/\/+$/, "").replace(/\/v1$/, ""),
|
|
1975
|
+
mastraGatewayApiKey: mgApiKey,
|
|
1976
|
+
routeThroughMastraGateway: Boolean(mgApiKey && isMastraGatewayModel),
|
|
1977
|
+
thinkingLevel: options?.thinkingLevel,
|
|
1978
|
+
customProviders: settings.customProviders
|
|
1979
|
+
});
|
|
1980
|
+
const auth = gateway.resolveAuth({
|
|
1981
|
+
gatewayId: MASTRACODE_GATEWAY_ID,
|
|
1982
|
+
providerId,
|
|
1983
|
+
modelId: bareModelId,
|
|
1984
|
+
routerId
|
|
1985
|
+
});
|
|
1986
|
+
return gateway.resolveLanguageModel({
|
|
1987
|
+
providerId,
|
|
1988
|
+
modelId: bareModelId,
|
|
1989
|
+
apiKey: auth?.apiKey ?? mgApiKey ?? "",
|
|
1990
|
+
headers
|
|
1991
|
+
});
|
|
1992
|
+
}
|
|
1993
|
+
function getDynamicModel({ requestContext }) {
|
|
1994
|
+
const harnessContext = requestContext.get("harness");
|
|
1995
|
+
const modelId = harnessContext?.state?.currentModelId;
|
|
1996
|
+
if (!modelId) {
|
|
1997
|
+
throw new Error("No model selected. Use /models to select a model first.");
|
|
1998
|
+
}
|
|
1999
|
+
const thinkingLevel = harnessContext?.state?.thinkingLevel;
|
|
2000
|
+
return resolveModel(modelId, { thinkingLevel, requestContext });
|
|
2001
|
+
}
|
|
2002
|
+
function getGoalJudgeModel({ requestContext }, settingsPath) {
|
|
2003
|
+
const judgeModelId = loadSettings(settingsPath).models.goalJudgeModel;
|
|
2004
|
+
if (!judgeModelId) return void 0;
|
|
2005
|
+
return resolveModel(judgeModelId, { requestContext });
|
|
2006
|
+
}
|
|
2007
|
+
|
|
2008
|
+
// src/agents/memory.ts
|
|
1030
2009
|
var cachedMemory = null;
|
|
1031
2010
|
var cachedMemoryKey = null;
|
|
1032
2011
|
function getHarnessState(requestContext) {
|
|
@@ -1035,14 +2014,12 @@ function getHarnessState(requestContext) {
|
|
|
1035
2014
|
function getObserverModel({ requestContext }) {
|
|
1036
2015
|
const state = getHarnessState(requestContext);
|
|
1037
2016
|
return resolveModel(state?.observerModelId ?? DEFAULT_OM_MODEL_ID, {
|
|
1038
|
-
remapForCodexOAuth: true,
|
|
1039
2017
|
requestContext
|
|
1040
2018
|
});
|
|
1041
2019
|
}
|
|
1042
2020
|
function getReflectorModel({ requestContext }) {
|
|
1043
2021
|
const state = getHarnessState(requestContext);
|
|
1044
2022
|
return resolveModel(state?.reflectorModelId ?? DEFAULT_OM_MODEL_ID, {
|
|
1045
|
-
remapForCodexOAuth: true,
|
|
1046
2023
|
requestContext
|
|
1047
2024
|
});
|
|
1048
2025
|
}
|
|
@@ -1125,10 +2102,10 @@ ${CAVEMAN_OM_INSTRUCTION}` : DYNAMIC_AGENTS_MD_INSTRUCTION;
|
|
|
1125
2102
|
};
|
|
1126
2103
|
}
|
|
1127
2104
|
|
|
1128
|
-
// src/agents/
|
|
1129
|
-
var
|
|
1130
|
-
id: "
|
|
1131
|
-
name: "
|
|
2105
|
+
// src/agents/modes/build.ts
|
|
2106
|
+
var buildMode = {
|
|
2107
|
+
id: "build",
|
|
2108
|
+
name: "Build",
|
|
1132
2109
|
description: "Task execution with write capabilities. Use for 'implement feature X', 'fix bug Y', 'refactor module Z'.",
|
|
1133
2110
|
instructions: `You are a focused execution agent. Your job is to complete a specific, well-defined task by making the necessary changes to the codebase.
|
|
1134
2111
|
|
|
@@ -1161,14 +2138,19 @@ End with a structured summary:
|
|
|
1161
2138
|
. **Completed**: What you implemented (1-2 sentences)
|
|
1162
2139
|
. **Changes**: Files modified/created
|
|
1163
2140
|
. **Verification**: How you verified it works
|
|
1164
|
-
. **Notes**: Follow-up needed (if any)
|
|
2141
|
+
. **Notes**: Follow-up needed (if any)`,
|
|
2142
|
+
defaultModelId: "openai/gpt-5.5",
|
|
2143
|
+
metadata: {
|
|
2144
|
+
default: true
|
|
2145
|
+
}
|
|
1165
2146
|
};
|
|
1166
2147
|
|
|
1167
|
-
// src/agents/
|
|
1168
|
-
var
|
|
1169
|
-
id: "
|
|
2148
|
+
// src/agents/modes/explore.ts
|
|
2149
|
+
var fastMode = {
|
|
2150
|
+
id: "fast",
|
|
1170
2151
|
name: "Explore",
|
|
1171
2152
|
description: "Read-only codebase exploration. Use for questions like 'find all usages of X', 'how does module Y work'.",
|
|
2153
|
+
defaultModelId: "openai/gpt-5.4-mini",
|
|
1172
2154
|
instructions: `You are an expert code explorer. Your job is to investigate a codebase and answer a specific question or gather specific information.
|
|
1173
2155
|
|
|
1174
2156
|
## Rules
|
|
@@ -1194,14 +2176,15 @@ End with a structured summary:
|
|
|
1194
2176
|
. **Key Files**: Most relevant files with line numbers
|
|
1195
2177
|
. **Details**: Additional context if needed
|
|
1196
2178
|
|
|
1197
|
-
Keep your summary under 300 words
|
|
1198
|
-
allowedWorkspaceTools: [MC_TOOLS.VIEW, MC_TOOLS.SEARCH_CONTENT, MC_TOOLS.FIND_FILES]
|
|
2179
|
+
Keep your summary under 300 words.`
|
|
1199
2180
|
};
|
|
1200
2181
|
|
|
1201
|
-
// src/agents/
|
|
1202
|
-
var
|
|
2182
|
+
// src/agents/modes/plan.ts
|
|
2183
|
+
var planMode = {
|
|
1203
2184
|
id: "plan",
|
|
1204
2185
|
name: "Plan",
|
|
2186
|
+
transitionsTo: "build",
|
|
2187
|
+
defaultModelId: "openai/gpt-5.5",
|
|
1205
2188
|
description: "Read-only analysis and planning. Use for 'create an implementation plan for X', 'analyze the architecture of Y'.",
|
|
1206
2189
|
instructions: `You are an expert software architect and planner. Your job is to analyze a codebase and produce a detailed implementation plan for a given task.
|
|
1207
2190
|
|
|
@@ -1231,7 +2214,9 @@ Structure your plan as:
|
|
|
1231
2214
|
. **Risks**: Potential issues or edge cases (if any)
|
|
1232
2215
|
|
|
1233
2216
|
Be specific about code locations (file paths, function names, line numbers). Keep the plan actionable and under 500 words.`,
|
|
1234
|
-
|
|
2217
|
+
metadata: {
|
|
2218
|
+
default: false
|
|
2219
|
+
}
|
|
1235
2220
|
};
|
|
1236
2221
|
|
|
1237
2222
|
// src/agents/thread-caveman-state.ts
|
|
@@ -1911,17 +2896,6 @@ function createEfficiencyScorer() {
|
|
|
1911
2896
|
return parts.join("\n");
|
|
1912
2897
|
});
|
|
1913
2898
|
}
|
|
1914
|
-
function v1ModeToLegacy(mode, agent) {
|
|
1915
|
-
const meta = mode.metadata ?? {};
|
|
1916
|
-
return {
|
|
1917
|
-
id: mode.id,
|
|
1918
|
-
name: mode.description,
|
|
1919
|
-
default: meta.default === true,
|
|
1920
|
-
defaultModelId: mode.defaultModelId,
|
|
1921
|
-
color: typeof meta.color === "string" ? meta.color : void 0,
|
|
1922
|
-
agent
|
|
1923
|
-
};
|
|
1924
|
-
}
|
|
1925
2899
|
var VALID_EVENTS = [
|
|
1926
2900
|
"PreToolUse",
|
|
1927
2901
|
"PostToolUse",
|
|
@@ -2559,13 +3533,14 @@ function createMcpManager(projectDir, configDirName = DEFAULT_CONFIG_DIR, extraS
|
|
|
2559
3533
|
});
|
|
2560
3534
|
try {
|
|
2561
3535
|
const { toolsets, errors } = await client.listToolsetsWithErrors();
|
|
2562
|
-
|
|
3536
|
+
const typedToolsets = toolsets;
|
|
3537
|
+
for (const [serverName, serverTools] of Object.entries(typedToolsets)) {
|
|
2563
3538
|
for (const [toolName, toolConfig] of Object.entries(serverTools)) {
|
|
2564
3539
|
tools[`${serverName}_${toolName}`] = toolConfig;
|
|
2565
3540
|
}
|
|
2566
3541
|
}
|
|
2567
3542
|
for (const name of serverNames) {
|
|
2568
|
-
const serverTools =
|
|
3543
|
+
const serverTools = typedToolsets[name];
|
|
2569
3544
|
if (serverTools && Object.keys(serverTools).length > 0) {
|
|
2570
3545
|
const toolNames = Object.keys(serverTools).map((t) => `${name}_${t}`);
|
|
2571
3546
|
serverStatuses.set(name, {
|
|
@@ -3042,31 +4017,8 @@ async function createVectorStore(config, effectiveBackend = config.backend) {
|
|
|
3042
4017
|
}
|
|
3043
4018
|
|
|
3044
4019
|
// src/index.ts
|
|
3045
|
-
var PROVIDER_TO_OAUTH_ID = {
|
|
3046
|
-
anthropic: "anthropic",
|
|
3047
|
-
openai: "openai-codex",
|
|
3048
|
-
"github-copilot": "github-copilot"
|
|
3049
|
-
};
|
|
3050
4020
|
var CODE_AGENT_ID = "code-agent";
|
|
3051
|
-
function
|
|
3052
|
-
return createHash("sha256").update(value).digest("hex").slice(0, 32);
|
|
3053
|
-
}
|
|
3054
|
-
function legacyModeToV1(mode, fallbackAgent) {
|
|
3055
|
-
const agent = typeof mode.agent === "function" ? mode.agent({}) : mode.agent;
|
|
3056
|
-
return {
|
|
3057
|
-
id: mode.id,
|
|
3058
|
-
defaultModelId: mode.defaultModelId ?? "openai/gpt-5.5",
|
|
3059
|
-
description: mode.name,
|
|
3060
|
-
...mode.id === "plan" ? { transitionsTo: "build" } : {},
|
|
3061
|
-
metadata: {
|
|
3062
|
-
agentId: (agent ?? fallbackAgent).id,
|
|
3063
|
-
color: mode.color,
|
|
3064
|
-
default: mode.default,
|
|
3065
|
-
name: mode.name
|
|
3066
|
-
}
|
|
3067
|
-
};
|
|
3068
|
-
}
|
|
3069
|
-
function applyEffectiveDefaultsToV1Modes(modes, effectiveDefaults) {
|
|
4021
|
+
function applyEffectiveDefaultsToModes(modes, effectiveDefaults) {
|
|
3070
4022
|
return modes.map((mode) => {
|
|
3071
4023
|
const savedModel = effectiveDefaults[mode.id];
|
|
3072
4024
|
if (!savedModel) {
|
|
@@ -3079,16 +4031,16 @@ function applyEffectiveDefaultsToV1Modes(modes, effectiveDefaults) {
|
|
|
3079
4031
|
});
|
|
3080
4032
|
}
|
|
3081
4033
|
function createAuthStorage() {
|
|
3082
|
-
const
|
|
3083
|
-
setAuthStorage(
|
|
3084
|
-
setAuthStorage3(
|
|
3085
|
-
setAuthStorage2(
|
|
3086
|
-
return
|
|
4034
|
+
const authStorage2 = new AuthStorage();
|
|
4035
|
+
setAuthStorage(authStorage2);
|
|
4036
|
+
setAuthStorage3(authStorage2);
|
|
4037
|
+
setAuthStorage2(authStorage2);
|
|
4038
|
+
return authStorage2;
|
|
3087
4039
|
}
|
|
3088
|
-
function resolveCloudObservabilityConfig(settings,
|
|
4040
|
+
function resolveCloudObservabilityConfig(settings, authStorage2, resourceId) {
|
|
3089
4041
|
const resourceConfig = settings.observability.resources[resourceId];
|
|
3090
4042
|
if (resourceConfig) {
|
|
3091
|
-
const token =
|
|
4043
|
+
const token = authStorage2.getStoredApiKey(`${OBSERVABILITY_AUTH_PREFIX}${resourceId}`);
|
|
3092
4044
|
if (token) {
|
|
3093
4045
|
return { accessToken: token, projectId: resourceConfig.projectId };
|
|
3094
4046
|
}
|
|
@@ -3108,10 +4060,9 @@ async function createMastraCode(config) {
|
|
|
3108
4060
|
process.loadEnvFile(path__default.join(cwd, ".env"));
|
|
3109
4061
|
} catch {
|
|
3110
4062
|
}
|
|
3111
|
-
const
|
|
3112
|
-
const authStorage = createAuthStorage();
|
|
4063
|
+
const authStorage2 = createAuthStorage();
|
|
3113
4064
|
const globalSettings = loadSettings(config?.settingsPath);
|
|
3114
|
-
const storedGatewayKey =
|
|
4065
|
+
const storedGatewayKey = authStorage2.getStoredApiKey(MEMORY_GATEWAY_PROVIDER);
|
|
3115
4066
|
const storedGatewayUrl = globalSettings.memoryGateway?.baseUrl;
|
|
3116
4067
|
if (storedGatewayKey) {
|
|
3117
4068
|
process.env["MASTRA_GATEWAY_API_KEY"] ??= storedGatewayKey;
|
|
@@ -3127,9 +4078,9 @@ async function createMastraCode(config) {
|
|
|
3127
4078
|
providerEnvVars[provider] = Array.isArray(envVars) ? envVars[0] : envVars;
|
|
3128
4079
|
}
|
|
3129
4080
|
providerEnvVars[MEMORY_GATEWAY_PROVIDER] ??= "MASTRA_GATEWAY_API_KEY";
|
|
3130
|
-
|
|
4081
|
+
authStorage2.loadStoredApiKeysIntoEnv(providerEnvVars);
|
|
3131
4082
|
} catch {
|
|
3132
|
-
|
|
4083
|
+
authStorage2.loadStoredApiKeysIntoEnv({
|
|
3133
4084
|
[MEMORY_GATEWAY_PROVIDER]: "MASTRA_GATEWAY_API_KEY",
|
|
3134
4085
|
anthropic: "ANTHROPIC_API_KEY",
|
|
3135
4086
|
openai: "OPENAI_API_KEY",
|
|
@@ -3138,9 +4089,14 @@ async function createMastraCode(config) {
|
|
|
3138
4089
|
deepseek: "DEEPSEEK_API_KEY"
|
|
3139
4090
|
});
|
|
3140
4091
|
}
|
|
3141
|
-
|
|
4092
|
+
const mgApiKey = process.env["MASTRA_GATEWAY_API_KEY"] ?? storedGatewayKey;
|
|
4093
|
+
const mastraGatewayBaseUrl = (process.env["MASTRA_GATEWAY_URL"] ?? storedGatewayUrl ?? "https://gateway-api.mastra.ai").replace(/\/+$/, "").replace(/\/v1$/, "");
|
|
4094
|
+
const mastraCodeGateway = createMastraCodeGateway({
|
|
4095
|
+
mastraGatewayBaseUrl,
|
|
4096
|
+
mastraGatewayApiKey: mgApiKey,
|
|
4097
|
+
routeThroughMastraGateway: false,
|
|
4098
|
+
settingsPath: config?.settingsPath
|
|
3142
4099
|
});
|
|
3143
|
-
const mgApiKey = storedGatewayKey ?? process.env["MASTRA_GATEWAY_API_KEY"];
|
|
3144
4100
|
const project = detectProject(cwd);
|
|
3145
4101
|
const resourceIdOverride = getResourceIdOverride(project.rootPath, configDir);
|
|
3146
4102
|
if (resourceIdOverride) {
|
|
@@ -3229,8 +4185,12 @@ async function createMastraCode(config) {
|
|
|
3229
4185
|
"harness.state.reflectionThreshold"
|
|
3230
4186
|
],
|
|
3231
4187
|
exporters: [
|
|
3232
|
-
|
|
3233
|
-
|
|
4188
|
+
// Only persist traces locally when DuckDB observability is available
|
|
4189
|
+
// (via `/observability local on`). Without this guard the storage
|
|
4190
|
+
// exporter falls through to the default libsql backend and silently
|
|
4191
|
+
// fills the main database with gigabytes of span data.
|
|
4192
|
+
...observabilityDomain ? [new MastraStorageExporter({ strategy: "event-sourced" })] : [],
|
|
4193
|
+
new MastraPlatformExporter(resolveCloudObservabilityConfig(globalSettings, authStorage2, project.resourceId))
|
|
3234
4194
|
],
|
|
3235
4195
|
spanOutputProcessors: [new SensitiveDataFilter()]
|
|
3236
4196
|
}
|
|
@@ -3289,6 +4249,22 @@ async function createMastraCode(config) {
|
|
|
3289
4249
|
// the tools into the toolset and registers the task state-signal processor,
|
|
3290
4250
|
// so the task list persists across turns and survives OM truncation.
|
|
3291
4251
|
signals: [new TaskSignalProvider(), ...githubSignals ? [githubSignals] : []],
|
|
4252
|
+
// Native goal mechanism: the in-loop goal step judges the thread's active
|
|
4253
|
+
// objective each qualifying iteration. The judge model is required for any
|
|
4254
|
+
// gating to occur; when unset the goal step is a complete no-op. A6 auto-wires
|
|
4255
|
+
// the GoalStateProcessor so the `<current-objective>` signal persists across
|
|
4256
|
+
// turns. Per-thread overrides live in the ThreadState `goal` record and win
|
|
4257
|
+
// over these defaults.
|
|
4258
|
+
goal: {
|
|
4259
|
+
// Resolve the judge model through mastracode's gateway (a model-resolver
|
|
4260
|
+
// function) so provider credentials are injected; returns undefined when no
|
|
4261
|
+
// judge model is configured, keeping the goal step a no-op. Bind the same
|
|
4262
|
+
// `settingsPath` used above so the judge model and `maxRuns` come from one
|
|
4263
|
+
// config (a custom settings file would otherwise diverge).
|
|
4264
|
+
judge: (ctx) => getGoalJudgeModel(ctx, config?.settingsPath),
|
|
4265
|
+
maxRuns: globalSettings.models.goalMaxTurns ?? 50,
|
|
4266
|
+
prompt: DEFAULT_GOAL_JUDGE_PROMPT
|
|
4267
|
+
},
|
|
3292
4268
|
inputProcessors: [
|
|
3293
4269
|
new AgentsMDInjector({
|
|
3294
4270
|
getIgnoredInstructionPaths: ({ requestContext }) => {
|
|
@@ -3301,34 +4277,25 @@ async function createMastraCode(config) {
|
|
|
3301
4277
|
],
|
|
3302
4278
|
errorProcessors: [new StreamErrorRetryProcessor(), new PrefillErrorHandler(), new ProviderHistoryCompat()]
|
|
3303
4279
|
});
|
|
3304
|
-
const
|
|
3305
|
-
const defaultModesV1 = [
|
|
4280
|
+
const defaultModes = [
|
|
3306
4281
|
{
|
|
3307
|
-
|
|
3308
|
-
description: "Build",
|
|
3309
|
-
defaultModelId: "anthropic/claude-opus-4-7",
|
|
4282
|
+
...buildMode,
|
|
3310
4283
|
metadata: {
|
|
3311
|
-
|
|
3312
|
-
color: mastra.green
|
|
3313
|
-
default: true
|
|
4284
|
+
...buildMode.metadata,
|
|
4285
|
+
color: mastra.green
|
|
3314
4286
|
}
|
|
3315
4287
|
},
|
|
3316
4288
|
{
|
|
3317
|
-
|
|
3318
|
-
description: "Plan",
|
|
3319
|
-
transitionsTo: "build",
|
|
3320
|
-
defaultModelId: "openai/gpt-5.5",
|
|
4289
|
+
...planMode,
|
|
3321
4290
|
metadata: {
|
|
3322
|
-
|
|
4291
|
+
...planMode.metadata,
|
|
3323
4292
|
color: mastra.purple
|
|
3324
4293
|
}
|
|
3325
4294
|
},
|
|
3326
4295
|
{
|
|
3327
|
-
|
|
3328
|
-
description: "Fast",
|
|
3329
|
-
defaultModelId: "cerebras/zai-glm-4.7",
|
|
4296
|
+
...fastMode,
|
|
3330
4297
|
metadata: {
|
|
3331
|
-
|
|
4298
|
+
...fastMode.metadata,
|
|
3332
4299
|
color: mastra.orange
|
|
3333
4300
|
}
|
|
3334
4301
|
}
|
|
@@ -3337,13 +4304,14 @@ async function createMastraCode(config) {
|
|
|
3337
4304
|
{
|
|
3338
4305
|
id: "gateway-sync",
|
|
3339
4306
|
intervalMs: 5 * 60 * 1e3,
|
|
4307
|
+
immediate: false,
|
|
3340
4308
|
handler: () => syncGateways()
|
|
3341
4309
|
}
|
|
3342
4310
|
];
|
|
3343
4311
|
const heartbeatHandlers = config?.heartbeatHandlers ?? defaultHeartbeatHandlers;
|
|
3344
|
-
const anthropicCred =
|
|
3345
|
-
const openaiCred =
|
|
3346
|
-
const githubCopilotCred =
|
|
4312
|
+
const anthropicCred = authStorage2.get("anthropic");
|
|
4313
|
+
const openaiCred = authStorage2.get("openai-codex");
|
|
4314
|
+
const githubCopilotCred = authStorage2.get("github-copilot");
|
|
3347
4315
|
const startupAccess = {
|
|
3348
4316
|
anthropic: anthropicCred?.type === "oauth" ? "oauth" : anthropicCred?.type === "api_key" && anthropicCred.key.trim().length > 0 ? "apikey" : false,
|
|
3349
4317
|
openai: openaiCred?.type === "oauth" ? "oauth" : openaiCred?.type === "api_key" && openaiCred.key.trim().length > 0 ? "apikey" : false,
|
|
@@ -3378,36 +4346,11 @@ async function createMastraCode(config) {
|
|
|
3378
4346
|
const effectiveReflectionThreshold = globalSettings.models.omReflectionThreshold ?? void 0;
|
|
3379
4347
|
const effectiveCavemanObservations = globalSettings.models.omCavemanObservations ?? void 0;
|
|
3380
4348
|
const effectiveObserveAttachments = globalSettings.models.omObserveAttachments ?? "auto";
|
|
3381
|
-
const
|
|
3382
|
-
|
|
3383
|
-
effectiveDefaults
|
|
3384
|
-
);
|
|
3385
|
-
const defaultModeId = modesV1.find((mode) => mode.metadata?.default === true)?.id ?? modesV1.find((mode) => mode.id === "plan")?.id ?? modesV1[0]?.id;
|
|
4349
|
+
const modes = applyEffectiveDefaultsToModes(config?.modes ? config.modes : defaultModes, effectiveDefaults);
|
|
4350
|
+
const defaultModeId = modes.find((mode) => mode.metadata?.default === true)?.id ?? modes.find((mode) => mode.id === "build")?.id ?? modes[0]?.id;
|
|
3386
4351
|
if (!defaultModeId) {
|
|
3387
4352
|
throw new Error("MastraCode requires at least one mode");
|
|
3388
4353
|
}
|
|
3389
|
-
const modes = modesV1.map((mode) => v1ModeToLegacy(mode, codeAgent));
|
|
3390
|
-
const subagentModeMap = { explore: "fast", plan: "plan", execute: "build" };
|
|
3391
|
-
const subagents = (config?.subagents ?? defaultSubagents).map((sa) => {
|
|
3392
|
-
const modeId = subagentModeMap[sa.id];
|
|
3393
|
-
const model = modeId ? effectiveDefaults[modeId] : void 0;
|
|
3394
|
-
let filtered = sa;
|
|
3395
|
-
if (config?.disabledTools?.length) {
|
|
3396
|
-
if (sa.allowedWorkspaceTools) {
|
|
3397
|
-
filtered = {
|
|
3398
|
-
...filtered,
|
|
3399
|
-
allowedWorkspaceTools: sa.allowedWorkspaceTools.filter((t) => !config.disabledTools.includes(t))
|
|
3400
|
-
};
|
|
3401
|
-
}
|
|
3402
|
-
if (sa.tools) {
|
|
3403
|
-
filtered = {
|
|
3404
|
-
...filtered,
|
|
3405
|
-
tools: Object.fromEntries(Object.entries(sa.tools).filter(([k]) => !config.disabledTools.includes(k)))
|
|
3406
|
-
};
|
|
3407
|
-
}
|
|
3408
|
-
}
|
|
3409
|
-
return model ? { ...filtered, defaultModelId: model } : filtered;
|
|
3410
|
-
});
|
|
3411
4354
|
const globalInitialState = {};
|
|
3412
4355
|
if (effectiveObserverModel) {
|
|
3413
4356
|
globalInitialState.observerModelId = effectiveObserverModel;
|
|
@@ -3441,33 +4384,6 @@ async function createMastraCode(config) {
|
|
|
3441
4384
|
globalInitialState[`subagentModelId_${key}`] = modelId;
|
|
3442
4385
|
}
|
|
3443
4386
|
}
|
|
3444
|
-
const { threads } = await (await storage.getStore("memory"))?.listThreads({
|
|
3445
|
-
perPage: false,
|
|
3446
|
-
filter: {
|
|
3447
|
-
resourceId: project.resourceId
|
|
3448
|
-
}
|
|
3449
|
-
}) ?? { threads: [] };
|
|
3450
|
-
const ownerId = `mastracode-${hash(`${hostname()}\0${project.rootPath}`)}`;
|
|
3451
|
-
await Promise.all(
|
|
3452
|
-
threads.map((thread) => {
|
|
3453
|
-
const sessionHash = hash(`${thread.resourceId}\0${thread.id}`);
|
|
3454
|
-
const meta = thread.metadata;
|
|
3455
|
-
const modeId = typeof meta?.currentModeId === "string" ? meta.currentModeId : defaultModeId;
|
|
3456
|
-
const mode = modesV1.find((mode2) => mode2.id === modeId) ?? modesV1.find((mode2) => mode2.id === defaultModeId);
|
|
3457
|
-
const modelId = typeof meta?.currentModelId === "string" ? meta.currentModelId : mode.defaultModelId;
|
|
3458
|
-
return harnessStorage.saveSession({
|
|
3459
|
-
id: `sess-${sessionHash}`,
|
|
3460
|
-
ownerId,
|
|
3461
|
-
resourceId: thread.resourceId,
|
|
3462
|
-
threadId: thread.id,
|
|
3463
|
-
modeId: mode.id,
|
|
3464
|
-
modelId,
|
|
3465
|
-
origin: "top-level",
|
|
3466
|
-
createdAt: thread.createdAt,
|
|
3467
|
-
lastActivityAt: thread.updatedAt
|
|
3468
|
-
});
|
|
3469
|
-
})
|
|
3470
|
-
);
|
|
3471
4387
|
const typedStateSchema = stateSchema;
|
|
3472
4388
|
const harness = new Harness({
|
|
3473
4389
|
id: "mastra-code",
|
|
@@ -3477,8 +4393,9 @@ async function createMastraCode(config) {
|
|
|
3477
4393
|
memory,
|
|
3478
4394
|
pubsub: signalsPubSub,
|
|
3479
4395
|
stateSchema: typedStateSchema,
|
|
3480
|
-
|
|
3481
|
-
|
|
4396
|
+
agent: codeAgent,
|
|
4397
|
+
subagents: config?.subagents ?? [],
|
|
4398
|
+
gateways: [mastraCodeGateway],
|
|
3482
4399
|
toolCategoryResolver: getToolCategory,
|
|
3483
4400
|
initialState: {
|
|
3484
4401
|
projectPath: project.rootPath,
|
|
@@ -3495,39 +4412,8 @@ async function createMastraCode(config) {
|
|
|
3495
4412
|
browser: config?.browser,
|
|
3496
4413
|
modes,
|
|
3497
4414
|
heartbeatHandlers,
|
|
3498
|
-
|
|
3499
|
-
|
|
3500
|
-
if (gatewayKey) {
|
|
3501
|
-
const providerConfig = gatewayRegistry.getProviders()[provider];
|
|
3502
|
-
if (providerConfig?.gateway === "mastra") return true;
|
|
3503
|
-
}
|
|
3504
|
-
const oauthId = PROVIDER_TO_OAUTH_ID[provider];
|
|
3505
|
-
if (oauthId && authStorage.isLoggedIn(oauthId)) {
|
|
3506
|
-
return true;
|
|
3507
|
-
}
|
|
3508
|
-
if (authStorage.hasStoredApiKey(provider)) {
|
|
3509
|
-
return true;
|
|
3510
|
-
}
|
|
3511
|
-
if (provider === "anthropic") {
|
|
3512
|
-
const cred = authStorage.get("anthropic");
|
|
3513
|
-
if (cred?.type === "api_key" && cred.key.trim().length > 0) {
|
|
3514
|
-
return true;
|
|
3515
|
-
}
|
|
3516
|
-
}
|
|
3517
|
-
if (provider === "openai") {
|
|
3518
|
-
const cred = authStorage.get("openai-codex");
|
|
3519
|
-
if (cred?.type === "api_key" && cred.key.trim().length > 0) {
|
|
3520
|
-
return true;
|
|
3521
|
-
}
|
|
3522
|
-
}
|
|
3523
|
-
const customProvider = loadSettings().customProviders.find((entry) => {
|
|
3524
|
-
return provider === getCustomProviderId(entry.name);
|
|
3525
|
-
});
|
|
3526
|
-
if (customProvider) {
|
|
3527
|
-
return true;
|
|
3528
|
-
}
|
|
3529
|
-
return void 0;
|
|
3530
|
-
},
|
|
4415
|
+
resolveModel,
|
|
4416
|
+
customModelCatalogProvider: createMastraCodeModelCatalogProvider(mastraCodeGateway),
|
|
3531
4417
|
modelUseCountProvider: () => loadSettings().modelUseCounts,
|
|
3532
4418
|
modelUseCountTracker: (modelId) => {
|
|
3533
4419
|
try {
|
|
@@ -3538,37 +4424,6 @@ async function createMastraCode(config) {
|
|
|
3538
4424
|
console.error("Failed to persist model usage count", error);
|
|
3539
4425
|
}
|
|
3540
4426
|
},
|
|
3541
|
-
customModelCatalogProvider: async () => {
|
|
3542
|
-
const settings = loadSettings();
|
|
3543
|
-
const customModels = [];
|
|
3544
|
-
for (const provider of settings.customProviders) {
|
|
3545
|
-
const providerId = getCustomProviderId(provider.name);
|
|
3546
|
-
for (const modelName of provider.models) {
|
|
3547
|
-
customModels.push({
|
|
3548
|
-
id: toCustomProviderModelId(provider.name, modelName),
|
|
3549
|
-
provider: providerId,
|
|
3550
|
-
modelName,
|
|
3551
|
-
hasApiKey: true,
|
|
3552
|
-
apiKeyEnvVar: void 0
|
|
3553
|
-
});
|
|
3554
|
-
}
|
|
3555
|
-
}
|
|
3556
|
-
try {
|
|
3557
|
-
const copilotModels = await getCopilotModelCatalog({ authStorage });
|
|
3558
|
-
for (const m of copilotModels) {
|
|
3559
|
-
customModels.push({
|
|
3560
|
-
id: `github-copilot/${m.id}`,
|
|
3561
|
-
provider: "github-copilot",
|
|
3562
|
-
modelName: m.id,
|
|
3563
|
-
hasApiKey: true,
|
|
3564
|
-
apiKeyEnvVar: void 0
|
|
3565
|
-
});
|
|
3566
|
-
}
|
|
3567
|
-
} catch (error) {
|
|
3568
|
-
console.warn("Failed to load GitHub Copilot model catalog:", error);
|
|
3569
|
-
}
|
|
3570
|
-
return customModels;
|
|
3571
|
-
},
|
|
3572
4427
|
threadLock: crossProcessPubSub ? void 0 : {
|
|
3573
4428
|
acquire: acquireThreadLock,
|
|
3574
4429
|
release: releaseThreadLock
|
|
@@ -3589,8 +4444,8 @@ async function createMastraCode(config) {
|
|
|
3589
4444
|
if (!threadId) return;
|
|
3590
4445
|
githubSignals.stopAllPolling();
|
|
3591
4446
|
try {
|
|
3592
|
-
const
|
|
3593
|
-
const thread =
|
|
4447
|
+
const threads = await harness.listThreads({ allResources: true });
|
|
4448
|
+
const thread = threads.find((item) => item.id === threadId);
|
|
3594
4449
|
await githubSignals.startPollingForThread(
|
|
3595
4450
|
{
|
|
3596
4451
|
threadId,
|
|
@@ -3617,7 +4472,7 @@ async function createMastraCode(config) {
|
|
|
3617
4472
|
mcpManager,
|
|
3618
4473
|
hookManager,
|
|
3619
4474
|
signalsPubSub,
|
|
3620
|
-
authStorage,
|
|
4475
|
+
authStorage: authStorage2,
|
|
3621
4476
|
resolveModel,
|
|
3622
4477
|
storageWarning,
|
|
3623
4478
|
observabilityWarning,
|
|
@@ -3629,5 +4484,5 @@ async function createMastraCode(config) {
|
|
|
3629
4484
|
}
|
|
3630
4485
|
|
|
3631
4486
|
export { createAuthStorage, createMastraCode };
|
|
3632
|
-
//# sourceMappingURL=chunk-
|
|
3633
|
-
//# sourceMappingURL=chunk-
|
|
4487
|
+
//# sourceMappingURL=chunk-RDIIIT54.js.map
|
|
4488
|
+
//# sourceMappingURL=chunk-RDIIIT54.js.map
|