@mastra/code-sdk 1.2.0-alpha.10 → 1.2.0-alpha.13
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 +48 -0
- package/dist/agents/model.d.ts.map +1 -1
- package/dist/agents/model.js +4 -1
- package/dist/agents/model.js.map +1 -1
- package/dist/agents/tools.js +1 -1
- package/dist/headless/cli.d.ts.map +1 -1
- package/dist/headless/cli.js +3 -0
- package/dist/headless/cli.js.map +1 -1
- package/dist/index.d.ts +68 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +173 -61
- package/dist/index.js.map +1 -1
- package/dist/plugin.d.ts +64 -1
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +3 -1
- package/dist/plugin.js.map +1 -1
- package/dist/plugins/loader.d.ts +7 -3
- package/dist/plugins/loader.d.ts.map +1 -1
- package/dist/plugins/loader.js +53 -1
- package/dist/plugins/loader.js.map +1 -1
- package/dist/plugins/manager.d.ts +36 -2
- package/dist/plugins/manager.d.ts.map +1 -1
- package/dist/plugins/manager.js +74 -2
- package/dist/plugins/manager.js.map +1 -1
- package/dist/plugins/signal-lane.d.ts +58 -0
- package/dist/plugins/signal-lane.d.ts.map +1 -0
- package/dist/plugins/signal-lane.js +166 -0
- package/dist/plugins/signal-lane.js.map +1 -0
- package/dist/plugins/types.d.ts +36 -0
- package/dist/plugins/types.d.ts.map +1 -1
- package/package.json +13 -13
package/dist/index.js
CHANGED
|
@@ -29,6 +29,7 @@ import { hasExplicitOMConfiguration } from "./onboarding/om-settings.js";
|
|
|
29
29
|
import { getAvailableModePacks, getAvailableOmPacks, selectPreferredOMPack } from "./onboarding/packs.js";
|
|
30
30
|
import { getToolCategory } from "./permissions.js";
|
|
31
31
|
import { PluginManager } from "./plugins/manager.js";
|
|
32
|
+
import { PluginSignalLane } from "./plugins/signal-lane.js";
|
|
32
33
|
import { PlanRejectionAbortProcessor } from "./processors/plan-rejection-abort.js";
|
|
33
34
|
import { stateSchema } from "./schema.js";
|
|
34
35
|
import { mastraBrand } from "./theme-palette.js";
|
|
@@ -50,6 +51,7 @@ import { AgentController } from "@mastra/core/agent-controller";
|
|
|
50
51
|
import { createCodingAgent } from "@mastra/core/coding-agent";
|
|
51
52
|
import { PROVIDER_REGISTRY } from "@mastra/core/llm";
|
|
52
53
|
import { Mastra } from "@mastra/core/mastra";
|
|
54
|
+
import { defaultNotificationDeliveryDecision } from "@mastra/core/notifications";
|
|
53
55
|
import { AgentsMDInjector, PrefillErrorHandler, ProviderHistoryCompat, StreamErrorRetryProcessor, isBadRequestError } from "@mastra/core/processors";
|
|
54
56
|
import { RequestContext } from "@mastra/core/request-context";
|
|
55
57
|
import { InMemoryHarness, MastraCompositeStore } from "@mastra/core/storage";
|
|
@@ -201,6 +203,7 @@ async function createMastraCodeAgentController(config) {
|
|
|
201
203
|
const homeDir = config?.homeDir ?? config?.initialState?.homeDir;
|
|
202
204
|
const configDir = config?.configDir ?? ".mastracode";
|
|
203
205
|
let activeSession;
|
|
206
|
+
let pluginRuntimeController;
|
|
204
207
|
if (configDir !== ".mastracode") validateConfigDirName(configDir);
|
|
205
208
|
try {
|
|
206
209
|
process.loadEnvFile(path.join(cwd, ".env"));
|
|
@@ -324,60 +327,126 @@ async function createMastraCodeAgentController(config) {
|
|
|
324
327
|
configDir,
|
|
325
328
|
homeDir
|
|
326
329
|
});
|
|
330
|
+
pluginManager?.setRuntime({
|
|
331
|
+
getController: () => pluginRuntimeController,
|
|
332
|
+
getActiveSession: () => activeSession
|
|
333
|
+
});
|
|
327
334
|
const loadedPlugins = pluginManager ? await pluginManager.reload() : [];
|
|
328
335
|
const pluginTools = pluginManager?.getPluginTools() ?? {};
|
|
329
336
|
const outcomeScorer = createOutcomeScorer();
|
|
330
337
|
const efficiencyScorer = createEfficiencyScorer();
|
|
338
|
+
const getNotificationStreamOptions = async ({ resourceId, threadId }) => {
|
|
339
|
+
const session = await controller.getSessionByResource(resourceId) ?? activeSession;
|
|
340
|
+
if (!session) return void 0;
|
|
341
|
+
const modeId = session.mode.get();
|
|
342
|
+
const defaultModeModelId = controller.listModes().find((mode) => mode.id === modeId)?.defaultModelId;
|
|
343
|
+
const modelId = session.model.get() || activeSession?.model.get() || defaultModeModelId || "";
|
|
344
|
+
const requestContext = new RequestContext();
|
|
345
|
+
const agentControllerContext = {
|
|
346
|
+
controllerId: controller.id,
|
|
347
|
+
state: session.state.get(),
|
|
348
|
+
getState: () => session.state.get(),
|
|
349
|
+
setState: (updates) => session.state.set(updates),
|
|
350
|
+
threadId,
|
|
351
|
+
resourceId,
|
|
352
|
+
session: {
|
|
353
|
+
id: session.identity.getId(),
|
|
354
|
+
ownerId: session.identity.getOwnerId(),
|
|
355
|
+
modeId,
|
|
356
|
+
modelId,
|
|
357
|
+
state: {
|
|
358
|
+
get: () => session.state.get(),
|
|
359
|
+
set: (updates) => session.state.set(updates),
|
|
360
|
+
update: (updater) => session.state.update(updater)
|
|
361
|
+
}
|
|
362
|
+
},
|
|
363
|
+
workspace: session.getWorkspace(),
|
|
364
|
+
getSubagentModelId: (params) => session.subagents.model.get(params ?? {})
|
|
365
|
+
};
|
|
366
|
+
requestContext.set("controller", agentControllerContext);
|
|
367
|
+
return {
|
|
368
|
+
memory: {
|
|
369
|
+
thread: threadId,
|
|
370
|
+
resource: resourceId
|
|
371
|
+
},
|
|
372
|
+
requestContext,
|
|
373
|
+
maxSteps: 1e3,
|
|
374
|
+
savePerStep: false,
|
|
375
|
+
requireToolApproval: session.state.get().yolo !== true,
|
|
376
|
+
modelSettings: { temperature: 1 }
|
|
377
|
+
};
|
|
378
|
+
};
|
|
331
379
|
const githubSignals = globalSettings.signals?.experimentalGithubSignals && !config?.disableGithubSignals ? new GithubSignals({
|
|
332
380
|
cwd: project.rootPath,
|
|
333
381
|
gitcrawlCommand: process.env.MASTRACODE_GITCRAWL_BIN ?? process.env.GITCRAWL_BIN ?? process.env.MASTRACODE_GITCRAWL_COMMAND ?? process.env.GITCRAWL_COMMAND,
|
|
334
|
-
getNotificationStreamOptions
|
|
335
|
-
const session = await controller.getSessionByResource(resourceId) ?? activeSession;
|
|
336
|
-
const modeId = session.mode.get();
|
|
337
|
-
const defaultModeModelId = controller.listModes().find((mode) => mode.id === modeId)?.defaultModelId;
|
|
338
|
-
const modelId = session.model.get() || activeSession?.model.get() || defaultModeModelId || "";
|
|
339
|
-
const requestContext = new RequestContext();
|
|
340
|
-
const agentControllerContext = {
|
|
341
|
-
controllerId: controller.id,
|
|
342
|
-
state: session.state.get(),
|
|
343
|
-
getState: () => session.state.get(),
|
|
344
|
-
setState: (updates) => session.state.set(updates),
|
|
345
|
-
threadId,
|
|
346
|
-
resourceId,
|
|
347
|
-
session: {
|
|
348
|
-
id: session.identity.getId(),
|
|
349
|
-
ownerId: session.identity.getOwnerId(),
|
|
350
|
-
modeId,
|
|
351
|
-
modelId,
|
|
352
|
-
state: {
|
|
353
|
-
get: () => session.state.get(),
|
|
354
|
-
set: (updates) => session.state.set(updates),
|
|
355
|
-
update: (updater) => session.state.update(updater)
|
|
356
|
-
}
|
|
357
|
-
},
|
|
358
|
-
workspace: controller.getWorkspace(),
|
|
359
|
-
getSubagentModelId: (params) => session.subagents.model.get(params ?? {})
|
|
360
|
-
};
|
|
361
|
-
requestContext.set("controller", agentControllerContext);
|
|
362
|
-
return {
|
|
363
|
-
memory: {
|
|
364
|
-
thread: threadId,
|
|
365
|
-
resource: resourceId
|
|
366
|
-
},
|
|
367
|
-
requestContext,
|
|
368
|
-
maxSteps: 1e3,
|
|
369
|
-
savePerStep: false,
|
|
370
|
-
requireToolApproval: session.state.get().yolo !== true,
|
|
371
|
-
modelSettings: { temperature: 1 }
|
|
372
|
-
};
|
|
373
|
-
}
|
|
382
|
+
getNotificationStreamOptions
|
|
374
383
|
}) : void 0;
|
|
384
|
+
const mastraCodeInputProcessors = [
|
|
385
|
+
...config?.inputProcessors ?? [],
|
|
386
|
+
new PlanRejectionAbortProcessor(),
|
|
387
|
+
new AgentsMDInjector({
|
|
388
|
+
isEnabled: ({ requestContext }) => {
|
|
389
|
+
const state = getInjectorSessionState(requestContext);
|
|
390
|
+
return state?.untrustedCheckout !== true || typeof state?.baseRef === "string";
|
|
391
|
+
},
|
|
392
|
+
getReader: ({ requestContext }) => {
|
|
393
|
+
const state = getInjectorSessionState(requestContext);
|
|
394
|
+
if (state?.untrustedCheckout !== true || typeof state?.baseRef !== "string") return void 0;
|
|
395
|
+
return createGitRefReminderReader(state?.projectPath ?? project.rootPath, state.baseRef);
|
|
396
|
+
},
|
|
397
|
+
getIgnoredInstructionPaths: ({ requestContext }) => {
|
|
398
|
+
const state = getInjectorSessionState(requestContext);
|
|
399
|
+
const projectPath = state?.projectPath ?? project.rootPath;
|
|
400
|
+
return getStaticallyLoadedInstructionPaths(projectPath, void 0, state?.untrustedCheckout === true && typeof state?.baseRef === "string" ? createGitRefInstructionReader(projectPath, state.baseRef) : void 0);
|
|
401
|
+
}
|
|
402
|
+
}),
|
|
403
|
+
new ProviderHistoryCompat()
|
|
404
|
+
];
|
|
405
|
+
const taskSignalProvider = new TaskSignalProvider();
|
|
406
|
+
const NO_PLUGIN_PROCESSORS = {
|
|
407
|
+
input: [],
|
|
408
|
+
output: []
|
|
409
|
+
};
|
|
410
|
+
let pluginProcessorReadWarned = false;
|
|
411
|
+
const pluginSignalLane = pluginManager ? new PluginSignalLane({ reservedProviderIds: [taskSignalProvider.id, ...githubSignals ? [githubSignals.id] : []] }) : void 0;
|
|
412
|
+
let unsubscribePluginReload;
|
|
413
|
+
/**
|
|
414
|
+
* Plugin processors are read through a function so that enabling, disabling or
|
|
415
|
+
* updating a plugin takes effect on the next request rather than requiring a
|
|
416
|
+
* new agent. This runs before every LLM call, and also outside the request
|
|
417
|
+
* path when the Agent catalogues its configured processors — where a throw is
|
|
418
|
+
* swallowed into a debug log. So it only reads already-resolved state: no
|
|
419
|
+
* filesystem, no network, no construction, and it never throws.
|
|
420
|
+
*/
|
|
421
|
+
const readPluginProcessors = () => {
|
|
422
|
+
try {
|
|
423
|
+
return pluginManager?.getPluginProcessors() ?? NO_PLUGIN_PROCESSORS;
|
|
424
|
+
} catch (error) {
|
|
425
|
+
if (!pluginProcessorReadWarned) {
|
|
426
|
+
pluginProcessorReadWarned = true;
|
|
427
|
+
console.warn("Failed to read plugin processors:", error);
|
|
428
|
+
}
|
|
429
|
+
return NO_PLUGIN_PROCESSORS;
|
|
430
|
+
}
|
|
431
|
+
};
|
|
375
432
|
const codeAgent = createCodingAgent({
|
|
376
433
|
id: CODE_AGENT_ID,
|
|
377
434
|
name: "Code Agent",
|
|
378
435
|
workspace: void 0,
|
|
379
436
|
instructions: getDynamicInstructions,
|
|
380
437
|
model: (ctx) => getDynamicModel(ctx, config?.settingsPath),
|
|
438
|
+
notifications: { deliveryPolicy: { decide: async (input) => {
|
|
439
|
+
const decision = defaultNotificationDeliveryDecision(input);
|
|
440
|
+
if (!input.record.resourceId) return decision;
|
|
441
|
+
const streamOptions = await getNotificationStreamOptions({
|
|
442
|
+
resourceId: input.record.resourceId,
|
|
443
|
+
threadId: input.record.threadId
|
|
444
|
+
});
|
|
445
|
+
return streamOptions ? {
|
|
446
|
+
...decision,
|
|
447
|
+
streamOptions
|
|
448
|
+
} : decision;
|
|
449
|
+
} } },
|
|
381
450
|
tools: createDynamicTools(mcpManager, config?.extraTools, config?.disabledTools, storage, pluginTools),
|
|
382
451
|
hooks: createToolHooks(hookManager, config?.postToolObserver),
|
|
383
452
|
scorers: {
|
|
@@ -393,7 +462,7 @@ async function createMastraCodeAgentController(config) {
|
|
|
393
462
|
}
|
|
394
463
|
}
|
|
395
464
|
},
|
|
396
|
-
signals: [
|
|
465
|
+
signals: [taskSignalProvider, ...githubSignals ? [githubSignals] : []],
|
|
397
466
|
goal: {
|
|
398
467
|
judge: (ctx) => getGoalJudgeModel(ctx, config?.settingsPath),
|
|
399
468
|
maxRuns: globalSettings.models.goalMaxTurns ?? 50,
|
|
@@ -401,27 +470,12 @@ async function createMastraCodeAgentController(config) {
|
|
|
401
470
|
prompt: DEFAULT_GOAL_JUDGE_PROMPT,
|
|
402
471
|
tools: getGoalJudgeTools
|
|
403
472
|
},
|
|
404
|
-
inputProcessors: [
|
|
405
|
-
...
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
isEnabled: ({ requestContext }) => {
|
|
409
|
-
const state = getInjectorSessionState(requestContext);
|
|
410
|
-
return state?.untrustedCheckout !== true || typeof state?.baseRef === "string";
|
|
411
|
-
},
|
|
412
|
-
getReader: ({ requestContext }) => {
|
|
413
|
-
const state = getInjectorSessionState(requestContext);
|
|
414
|
-
if (state?.untrustedCheckout !== true || typeof state?.baseRef !== "string") return void 0;
|
|
415
|
-
return createGitRefReminderReader(state?.projectPath ?? project.rootPath, state.baseRef);
|
|
416
|
-
},
|
|
417
|
-
getIgnoredInstructionPaths: ({ requestContext }) => {
|
|
418
|
-
const state = getInjectorSessionState(requestContext);
|
|
419
|
-
const projectPath = state?.projectPath ?? project.rootPath;
|
|
420
|
-
return getStaticallyLoadedInstructionPaths(projectPath, void 0, state?.untrustedCheckout === true && typeof state?.baseRef === "string" ? createGitRefInstructionReader(projectPath, state.baseRef) : void 0);
|
|
421
|
-
}
|
|
422
|
-
}),
|
|
423
|
-
new ProviderHistoryCompat()
|
|
473
|
+
inputProcessors: () => [
|
|
474
|
+
...mastraCodeInputProcessors,
|
|
475
|
+
...readPluginProcessors().input.map((entry) => entry.value),
|
|
476
|
+
...pluginSignalLane?.getInputProcessors() ?? []
|
|
424
477
|
],
|
|
478
|
+
outputProcessors: () => [...readPluginProcessors().output.map((entry) => entry.value), ...pluginSignalLane?.getOutputProcessors() ?? []],
|
|
425
479
|
errorProcessors: [
|
|
426
480
|
new ProviderHistoryCompat(),
|
|
427
481
|
new StreamErrorRetryProcessor({ matchers: [
|
|
@@ -570,6 +624,11 @@ async function createMastraCodeAgentController(config) {
|
|
|
570
624
|
release: releaseThreadLock
|
|
571
625
|
}
|
|
572
626
|
});
|
|
627
|
+
pluginRuntimeController = controller;
|
|
628
|
+
if (pluginSignalLane && pluginManager) {
|
|
629
|
+
pluginSignalLane.sync(pluginManager.getPluginSignalProviders());
|
|
630
|
+
unsubscribePluginReload = pluginManager.onReload(() => pluginSignalLane.sync(pluginManager.getPluginSignalProviders()));
|
|
631
|
+
}
|
|
573
632
|
return {
|
|
574
633
|
controller,
|
|
575
634
|
storage,
|
|
@@ -594,6 +653,55 @@ async function createMastraCodeAgentController(config) {
|
|
|
594
653
|
ownerId,
|
|
595
654
|
setActiveSession: (session) => {
|
|
596
655
|
activeSession = session;
|
|
656
|
+
},
|
|
657
|
+
/**
|
|
658
|
+
* Starts the signal providers contributed by plugins. Called by the
|
|
659
|
+
* composition layer once the controller is inited, because that is when a
|
|
660
|
+
* Mastra instance exists — a provider without one has no storage, and
|
|
661
|
+
* nothing else will hand it one: the Agent propagates Mastra only to the
|
|
662
|
+
* providers in its own `signals` array, which these deliberately are not in.
|
|
663
|
+
*/
|
|
664
|
+
startPluginSignalProviders: () => {
|
|
665
|
+
const mastra = controller.getMastra();
|
|
666
|
+
if (!pluginSignalLane || !mastra) return;
|
|
667
|
+
pluginSignalLane.setMastra(mastra, codeAgent);
|
|
668
|
+
},
|
|
669
|
+
/**
|
|
670
|
+
* Stops every plugin-contributed signal provider and stops listening for
|
|
671
|
+
* plugin reloads. The inverse of `startPluginSignalProviders`, for an
|
|
672
|
+
* embedder that is done with this controller: a `pluginManager` shared
|
|
673
|
+
* across controllers (`MastraCodeConfig.pluginManager`) outlives any one of
|
|
674
|
+
* them, so without this its providers keep polling and its reload listener
|
|
675
|
+
* keeps firing for a controller that is gone.
|
|
676
|
+
*/
|
|
677
|
+
stopPluginSignalProviders: () => {
|
|
678
|
+
unsubscribePluginReload?.();
|
|
679
|
+
unsubscribePluginReload = void 0;
|
|
680
|
+
pluginSignalLane?.stopAll();
|
|
681
|
+
},
|
|
682
|
+
/**
|
|
683
|
+
* Hands Mastra to the statically configured input processors.
|
|
684
|
+
*
|
|
685
|
+
* The Agent does this itself, but only for processors configured as a
|
|
686
|
+
* plain array (`Array.isArray` in `__registerMastra`). This lane is a
|
|
687
|
+
* function so plugins can contribute to it, which takes those processors
|
|
688
|
+
* out of that branch — including any an embedder passed as
|
|
689
|
+
* `config.inputProcessors`, some of which need Mastra to work at all
|
|
690
|
+
* (`CostGuardProcessor` reads observability storage there). Doing it here
|
|
691
|
+
* keeps that unchanged.
|
|
692
|
+
*
|
|
693
|
+
* Plugin processors are deliberately not included: they come and go with
|
|
694
|
+
* their plugin, and the registry keeps the first instance registered under
|
|
695
|
+
* an id forever, which would leave a retired instance behind. Plugins
|
|
696
|
+
* reach Mastra through `getController()` on the plugin context instead.
|
|
697
|
+
*/
|
|
698
|
+
registerConfiguredProcessorsWithMastra: () => {
|
|
699
|
+
const mastra = controller.getMastra();
|
|
700
|
+
if (!mastra) return;
|
|
701
|
+
for (const processor of mastraCodeInputProcessors) {
|
|
702
|
+
mastra.addProcessor(processor);
|
|
703
|
+
mastra.addProcessorConfiguration(processor, CODE_AGENT_ID, "input");
|
|
704
|
+
}
|
|
597
705
|
}
|
|
598
706
|
};
|
|
599
707
|
}
|
|
@@ -646,6 +754,8 @@ async function bootLocalAgentController(config) {
|
|
|
646
754
|
const { controller, sessionId, ownerId } = base;
|
|
647
755
|
await controller.init();
|
|
648
756
|
await controller.getMastra()?.startWorkers();
|
|
757
|
+
base.registerConfiguredProcessorsWithMastra();
|
|
758
|
+
base.startPluginSignalProviders();
|
|
649
759
|
const session = await controller.createSession({
|
|
650
760
|
id: sessionId,
|
|
651
761
|
ownerId
|
|
@@ -723,6 +833,8 @@ async function prepareAgentControllerMount(config) {
|
|
|
723
833
|
const finalize = async () => {
|
|
724
834
|
await controller.init();
|
|
725
835
|
await controller.getMastra()?.startWorkers();
|
|
836
|
+
base.registerConfiguredProcessorsWithMastra();
|
|
837
|
+
base.startPluginSignalProviders();
|
|
726
838
|
};
|
|
727
839
|
return {
|
|
728
840
|
base,
|