@inspectr/mcplab 1.28.1 → 1.28.3
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/dist/app/assets/index-Bug5M-yX.js +258 -0
- package/dist/app/index.html +1 -1
- package/dist/app-server/assistant-events.d.ts +8 -28
- package/dist/app-server/mastra-scenario-assistant.d.ts +63 -0
- package/dist/app-server/mastra-scenario-assistant.d.ts.map +1 -0
- package/dist/app-server/mastra-scenario-assistant.js +113 -0
- package/dist/app-server/mastra-scenario-assistant.js.map +1 -0
- package/dist/app-server/mastra-scenario-tools.d.ts +97 -0
- package/dist/app-server/mastra-scenario-tools.d.ts.map +1 -0
- package/dist/app-server/mastra-scenario-tools.js +81 -0
- package/dist/app-server/mastra-scenario-tools.js.map +1 -0
- package/dist/app-server/scenario-assistant-domain.d.ts +130 -156
- package/dist/app-server/scenario-assistant-observability.d.ts +25 -0
- package/dist/app-server/scenario-assistant-observability.d.ts.map +1 -0
- package/dist/app-server/scenario-assistant-observability.js +47 -0
- package/dist/app-server/scenario-assistant-observability.js.map +1 -0
- package/dist/app-server/scenario-assistant-runtime.d.ts +5 -0
- package/dist/app-server/scenario-assistant-runtime.d.ts.map +1 -0
- package/dist/app-server/scenario-assistant-runtime.js +7 -0
- package/dist/app-server/scenario-assistant-runtime.js.map +1 -0
- package/dist/app-server/types.d.ts +25 -25
- package/package.json +4 -4
- package/dist/app/assets/index-C73rVN95.js +0 -258
package/dist/app/index.html
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
<meta name="twitter:card" content="summary_large_image" />
|
|
17
17
|
<meta name="twitter:site" content="@Inspectr" />
|
|
18
18
|
<meta name="twitter:image" content="" />
|
|
19
|
-
<script type="module" crossorigin src="/assets/index-
|
|
19
|
+
<script type="module" crossorigin src="/assets/index-Bug5M-yX.js"></script>
|
|
20
20
|
<link rel="stylesheet" crossorigin href="/assets/index-CVe_v-Bh.css">
|
|
21
21
|
</head>
|
|
22
22
|
|
|
@@ -1,35 +1,15 @@
|
|
|
1
1
|
import type { IncomingMessage, ServerResponse } from 'node:http';
|
|
2
2
|
import { type SseEvent } from './jobs.js';
|
|
3
|
-
export type AssistantSseEventType =
|
|
4
|
-
| 'session_started'
|
|
5
|
-
| 'turn_started'
|
|
6
|
-
| 'tool_call_requested'
|
|
7
|
-
| 'tool_call_approved'
|
|
8
|
-
| 'tool_call_denied'
|
|
9
|
-
| 'tool_call_resolved'
|
|
10
|
-
| 'assistant_message_completed'
|
|
11
|
-
| 'session_warning'
|
|
12
|
-
| 'session_error'
|
|
13
|
-
| 'session_finished';
|
|
3
|
+
export type AssistantSseEventType = 'session_started' | 'turn_started' | 'tool_call_requested' | 'tool_call_approved' | 'tool_call_denied' | 'tool_call_resolved' | 'assistant_message_completed' | 'session_warning' | 'session_error' | 'session_finished';
|
|
14
4
|
export type AssistantSseEvent = SseEvent & {
|
|
15
|
-
|
|
5
|
+
type: AssistantSseEventType;
|
|
16
6
|
};
|
|
17
7
|
export interface AssistantSseSessionState {
|
|
18
|
-
|
|
19
|
-
|
|
8
|
+
events: AssistantSseEvent[];
|
|
9
|
+
clients: Set<ServerResponse>;
|
|
20
10
|
}
|
|
21
|
-
export declare function createAssistantSseEvent(
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
): AssistantSseEvent;
|
|
25
|
-
export declare function broadcastAssistantSseEvent(
|
|
26
|
-
session: AssistantSseSessionState,
|
|
27
|
-
event: AssistantSseEvent
|
|
28
|
-
): void;
|
|
29
|
-
export declare function serveAssistantSseStream(
|
|
30
|
-
req: IncomingMessage,
|
|
31
|
-
res: ServerResponse,
|
|
32
|
-
session: AssistantSseSessionState
|
|
33
|
-
): void;
|
|
11
|
+
export declare function createAssistantSseEvent(type: AssistantSseEventType, payload: Record<string, unknown>): AssistantSseEvent;
|
|
12
|
+
export declare function broadcastAssistantSseEvent(session: AssistantSseSessionState, event: AssistantSseEvent): void;
|
|
13
|
+
export declare function serveAssistantSseStream(req: IncomingMessage, res: ServerResponse, session: AssistantSseSessionState): void;
|
|
34
14
|
export declare function endAssistantSseClients(session: AssistantSseSessionState): void;
|
|
35
|
-
//# sourceMappingURL=assistant-events.d.ts.map
|
|
15
|
+
//# sourceMappingURL=assistant-events.d.ts.map
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { Agent } from '@mastra/core/agent';
|
|
2
|
+
import { Mastra } from '@mastra/core/mastra';
|
|
3
|
+
import { Memory } from '@mastra/memory';
|
|
4
|
+
import { LibSQLStore } from '@mastra/libsql';
|
|
5
|
+
import type { AgentConfig, McpClientManager, ToolDef } from '@inspectr/mcplab-core';
|
|
6
|
+
import { type ScenarioAssistantProposal } from './mastra-scenario-tools.js';
|
|
7
|
+
export interface MastraScenarioContext {
|
|
8
|
+
scenario: {
|
|
9
|
+
id: string;
|
|
10
|
+
name?: string;
|
|
11
|
+
prompt: string;
|
|
12
|
+
serverNames: string[];
|
|
13
|
+
evalRules: unknown[];
|
|
14
|
+
extractRules: unknown[];
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
export declare function scenarioAssistantScopeKey(params: {
|
|
18
|
+
scenarioId: string;
|
|
19
|
+
configPath?: string;
|
|
20
|
+
}): string;
|
|
21
|
+
export interface MastraScenarioAssistantOptions {
|
|
22
|
+
storagePath: string;
|
|
23
|
+
scopeKey?: string;
|
|
24
|
+
agentConfig: AgentConfig;
|
|
25
|
+
tools: ToolDef[];
|
|
26
|
+
toolMappings: Map<
|
|
27
|
+
string,
|
|
28
|
+
{
|
|
29
|
+
server: string;
|
|
30
|
+
tool: string;
|
|
31
|
+
}
|
|
32
|
+
>;
|
|
33
|
+
mcp: McpClientManager;
|
|
34
|
+
context: MastraScenarioContext;
|
|
35
|
+
onProposal?: (proposal: ScenarioAssistantProposal) => void;
|
|
36
|
+
}
|
|
37
|
+
export declare class MastraScenarioAssistant {
|
|
38
|
+
readonly threadId: string;
|
|
39
|
+
readonly resourceId: string;
|
|
40
|
+
readonly storage: LibSQLStore;
|
|
41
|
+
readonly mastra: Mastra;
|
|
42
|
+
readonly memory: Memory;
|
|
43
|
+
readonly agent: Agent;
|
|
44
|
+
readonly provider: string;
|
|
45
|
+
readonly modelName: string;
|
|
46
|
+
constructor(options: MastraScenarioAssistantOptions);
|
|
47
|
+
init(): Promise<void>;
|
|
48
|
+
listSuspendedRuns(): Promise<import('@mastra/core/agent').AgentListSuspendedRunsResult>;
|
|
49
|
+
stream(
|
|
50
|
+
message: string,
|
|
51
|
+
context: MastraScenarioContext,
|
|
52
|
+
signal?: AbortSignal
|
|
53
|
+
): Promise<import('@mastra/core/stream').MastraModelOutput<undefined>>;
|
|
54
|
+
resumeStream(
|
|
55
|
+
runId: string,
|
|
56
|
+
approved: boolean,
|
|
57
|
+
signal?: AbortSignal,
|
|
58
|
+
toolCallId?: string
|
|
59
|
+
): Promise<import('@mastra/core/stream').MastraModelOutput<undefined>>;
|
|
60
|
+
close(): Promise<void>;
|
|
61
|
+
}
|
|
62
|
+
export declare function buildScenarioAssistantInstructions(context: MastraScenarioContext): string;
|
|
63
|
+
//# sourceMappingURL=mastra-scenario-assistant.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mastra-scenario-assistant.d.ts","sourceRoot":"","sources":["../../src/app-server/mastra-scenario-assistant.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AACpF,OAAO,EAIL,KAAK,yBAAyB,EAC/B,MAAM,4BAA4B,CAAC;AAOpC,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE;QACR,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;QACf,WAAW,EAAE,MAAM,EAAE,CAAC;QACtB,SAAS,EAAE,OAAO,EAAE,CAAC;QACrB,YAAY,EAAE,OAAO,EAAE,CAAC;KACzB,CAAC;CACH;AAED,wBAAgB,yBAAyB,CAAC,MAAM,EAAE;IAChD,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,GAAG,MAAM,CAIT;AAED,MAAM,WAAW,8BAA8B;IAC7C,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,WAAW,CAAC;IACzB,KAAK,EAAE,OAAO,EAAE,CAAC;IACjB,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC5D,GAAG,EAAE,gBAAgB,CAAC;IACtB,OAAO,EAAE,qBAAqB,CAAC;IAC/B,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,yBAAyB,KAAK,IAAI,CAAC;CAC5D;AAED,qBAAa,uBAAuB;IAClC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC;IAC9B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;gBAEf,OAAO,EAAE,8BAA8B;IAqC7C,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAIrB,iBAAiB;IAIvB,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,qBAAqB,EAAE,MAAM,CAAC,EAAE,WAAW;IA6B5E,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,WAAW,EAAE,UAAU,CAAC,EAAE,MAAM;IAWlF,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAG7B;AAED,wBAAgB,kCAAkC,CAAC,OAAO,EAAE,qBAAqB,GAAG,MAAM,CAUzF"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { Agent } from '@mastra/core/agent';
|
|
2
|
+
import { Mastra } from '@mastra/core/mastra';
|
|
3
|
+
import { Memory } from '@mastra/memory';
|
|
4
|
+
import { LibSQLStore } from '@mastra/libsql';
|
|
5
|
+
import { createMastraScenarioTools, createScenarioAssistantProposalTool, resolveMastraScenarioModel } from './mastra-scenario-tools.js';
|
|
6
|
+
import { logScenarioAssistantRequest, startScenarioAssistantLangSmithRun } from './scenario-assistant-observability.js';
|
|
7
|
+
export function scenarioAssistantScopeKey(params) {
|
|
8
|
+
return params.configPath
|
|
9
|
+
? `config:${params.configPath}:${params.scenarioId}`
|
|
10
|
+
: `library:${params.scenarioId}`;
|
|
11
|
+
}
|
|
12
|
+
export class MastraScenarioAssistant {
|
|
13
|
+
threadId;
|
|
14
|
+
resourceId;
|
|
15
|
+
storage;
|
|
16
|
+
mastra;
|
|
17
|
+
memory;
|
|
18
|
+
agent;
|
|
19
|
+
provider;
|
|
20
|
+
modelName;
|
|
21
|
+
constructor(options) {
|
|
22
|
+
this.provider = options.agentConfig.provider;
|
|
23
|
+
this.modelName = options.agentConfig.model;
|
|
24
|
+
const scope = options.scopeKey ?? `scenario:${options.context.scenario.id}`;
|
|
25
|
+
this.threadId = scope;
|
|
26
|
+
this.resourceId = scope;
|
|
27
|
+
this.storage = new LibSQLStore({
|
|
28
|
+
id: 'mcplab-scenario-assistant',
|
|
29
|
+
url: `file:${options.storagePath}`
|
|
30
|
+
});
|
|
31
|
+
this.mastra = new Mastra({ storage: this.storage });
|
|
32
|
+
this.memory = new Memory({ storage: this.storage, options: { lastMessages: 50 } });
|
|
33
|
+
const mcpTools = createMastraScenarioTools({
|
|
34
|
+
tools: options.tools,
|
|
35
|
+
mappings: options.toolMappings,
|
|
36
|
+
callTool: (server, tool, args, callOptions) => options.mcp.callTool(server, tool, args, callOptions)
|
|
37
|
+
});
|
|
38
|
+
const proposalTool = createScenarioAssistantProposalTool(options.onProposal ?? (() => undefined));
|
|
39
|
+
this.agent = new Agent({
|
|
40
|
+
id: 'mcplab-scenario-assistant',
|
|
41
|
+
name: 'MCPLab Scenario Assistant',
|
|
42
|
+
description: 'Authors MCP evaluation test cases.',
|
|
43
|
+
instructions: buildScenarioAssistantInstructions(options.context),
|
|
44
|
+
model: resolveMastraScenarioModel(options.agentConfig, {
|
|
45
|
+
endpoint: process.env.AZURE_OPENAI_ENDPOINT,
|
|
46
|
+
apiKey: process.env.AZURE_OPENAI_API_KEY,
|
|
47
|
+
apiVersion: process.env.AZURE_OPENAI_API_VERSION
|
|
48
|
+
}),
|
|
49
|
+
tools: { ...mcpTools, propose_test_case_patch: proposalTool },
|
|
50
|
+
memory: this.memory,
|
|
51
|
+
mastra: this.mastra
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
async init() {
|
|
55
|
+
await this.storage.init();
|
|
56
|
+
}
|
|
57
|
+
async listSuspendedRuns() {
|
|
58
|
+
return this.agent.listSuspendedRuns({ threadId: this.threadId, resourceId: this.resourceId });
|
|
59
|
+
}
|
|
60
|
+
stream(message, context, signal) {
|
|
61
|
+
const request = {
|
|
62
|
+
sessionId: this.threadId,
|
|
63
|
+
provider: this.provider,
|
|
64
|
+
model: this.modelName,
|
|
65
|
+
message
|
|
66
|
+
};
|
|
67
|
+
logScenarioAssistantRequest(request);
|
|
68
|
+
const trace = startScenarioAssistantLangSmithRun(request);
|
|
69
|
+
return this.agent
|
|
70
|
+
.stream(message, {
|
|
71
|
+
memory: { thread: this.threadId, resource: this.resourceId },
|
|
72
|
+
instructions: buildScenarioAssistantInstructions(context),
|
|
73
|
+
abortSignal: signal,
|
|
74
|
+
maxSteps: 25
|
|
75
|
+
})
|
|
76
|
+
.then((result) => {
|
|
77
|
+
void trace?.end({ outputs: { runId: result.runId } }).then(() => trace?.postRun());
|
|
78
|
+
return result;
|
|
79
|
+
})
|
|
80
|
+
.catch(async (error) => {
|
|
81
|
+
if (trace) {
|
|
82
|
+
await trace.end(undefined, error instanceof Error ? error.message : String(error));
|
|
83
|
+
await trace.postRun();
|
|
84
|
+
}
|
|
85
|
+
throw error;
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
resumeStream(runId, approved, signal, toolCallId) {
|
|
89
|
+
const options = {
|
|
90
|
+
runId,
|
|
91
|
+
memory: { thread: this.threadId, resource: this.resourceId },
|
|
92
|
+
abortSignal: signal
|
|
93
|
+
};
|
|
94
|
+
return approved
|
|
95
|
+
? this.agent.approveToolCall({ ...options, toolCallId })
|
|
96
|
+
: this.agent.declineToolCall({ ...options, toolCallId, reason: 'User denied tool call' });
|
|
97
|
+
}
|
|
98
|
+
async close() {
|
|
99
|
+
await this.storage.close();
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
export function buildScenarioAssistantInstructions(context) {
|
|
103
|
+
return [
|
|
104
|
+
'You are a Scenario Authoring Assistant for MCP evaluation test cases.',
|
|
105
|
+
'Help the user author a deterministic prompt, Checks, and Value Capture Rules.',
|
|
106
|
+
'Use MCP tools when live server information is needed. Read-only tools may run automatically; all other tools require user approval.',
|
|
107
|
+
'Use user-facing terminology: Checks and Value Capture Rules.',
|
|
108
|
+
'When proposing edits, call propose_test_case_patch with the structured replacement payload. Never mutate the test case directly.',
|
|
109
|
+
'Ask clarifying questions when the test-case intent is unclear.',
|
|
110
|
+
`Current test-case context: ${JSON.stringify(context.scenario)}`
|
|
111
|
+
].join('\n');
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=mastra-scenario-assistant.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mastra-scenario-assistant.js","sourceRoot":"","sources":["../../src/app-server/mastra-scenario-assistant.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import type { AgentConfig, ToolDef } from '@inspectr/mcplab-core';
|
|
2
|
+
export interface MastraScenarioToolMapping {
|
|
3
|
+
server: string;
|
|
4
|
+
tool: string;
|
|
5
|
+
}
|
|
6
|
+
export interface MastraScenarioToolSource {
|
|
7
|
+
tools: ToolDef[];
|
|
8
|
+
mappings: Map<string, MastraScenarioToolMapping>;
|
|
9
|
+
callTool: (
|
|
10
|
+
server: string,
|
|
11
|
+
tool: string,
|
|
12
|
+
args: unknown,
|
|
13
|
+
options?: {
|
|
14
|
+
signal?: AbortSignal;
|
|
15
|
+
}
|
|
16
|
+
) => Promise<unknown>;
|
|
17
|
+
}
|
|
18
|
+
export interface ScenarioAssistantProposal {
|
|
19
|
+
prompt?: {
|
|
20
|
+
replacement: string;
|
|
21
|
+
rationale?: string;
|
|
22
|
+
};
|
|
23
|
+
evalRules?: {
|
|
24
|
+
replacement: Array<Record<string, unknown>>;
|
|
25
|
+
rationale?: string;
|
|
26
|
+
};
|
|
27
|
+
extractRules?: {
|
|
28
|
+
replacement: Array<{
|
|
29
|
+
name: string;
|
|
30
|
+
pattern: string;
|
|
31
|
+
}>;
|
|
32
|
+
rationale?: string;
|
|
33
|
+
};
|
|
34
|
+
notes?: string[];
|
|
35
|
+
}
|
|
36
|
+
export declare function resolveMastraScenarioModel(
|
|
37
|
+
agent: AgentConfig,
|
|
38
|
+
azure?: {
|
|
39
|
+
endpoint?: string;
|
|
40
|
+
apiKey?: string;
|
|
41
|
+
apiVersion?: string;
|
|
42
|
+
},
|
|
43
|
+
credentials?: {
|
|
44
|
+
openaiApiKey?: string;
|
|
45
|
+
anthropicApiKey?: string;
|
|
46
|
+
}
|
|
47
|
+
): import('@ai-sdk/provider').LanguageModelV4;
|
|
48
|
+
/** Adapt MCPLab's already-authenticated MCP tools to Mastra's tool contract. */
|
|
49
|
+
export declare function createMastraScenarioTools(
|
|
50
|
+
source: MastraScenarioToolSource
|
|
51
|
+
): Record<
|
|
52
|
+
string,
|
|
53
|
+
import('@mastra/core/tools').Tool<
|
|
54
|
+
any,
|
|
55
|
+
any,
|
|
56
|
+
any,
|
|
57
|
+
any,
|
|
58
|
+
import('@mastra/core/tools').ToolExecutionContext<any, any, unknown>,
|
|
59
|
+
string,
|
|
60
|
+
unknown
|
|
61
|
+
>
|
|
62
|
+
>;
|
|
63
|
+
export declare function createScenarioAssistantProposalTool(
|
|
64
|
+
onProposal: (proposal: ScenarioAssistantProposal) => void
|
|
65
|
+
): import('@mastra/core/tools').Tool<
|
|
66
|
+
{
|
|
67
|
+
prompt?:
|
|
68
|
+
| {
|
|
69
|
+
replacement: string;
|
|
70
|
+
rationale?: string | undefined;
|
|
71
|
+
}
|
|
72
|
+
| undefined;
|
|
73
|
+
evalRules?:
|
|
74
|
+
| {
|
|
75
|
+
replacement: Record<string, unknown>[];
|
|
76
|
+
rationale?: string | undefined;
|
|
77
|
+
}
|
|
78
|
+
| undefined;
|
|
79
|
+
extractRules?:
|
|
80
|
+
| {
|
|
81
|
+
replacement: {
|
|
82
|
+
name: string;
|
|
83
|
+
pattern: string;
|
|
84
|
+
}[];
|
|
85
|
+
rationale?: string | undefined;
|
|
86
|
+
}
|
|
87
|
+
| undefined;
|
|
88
|
+
notes?: string[] | undefined;
|
|
89
|
+
},
|
|
90
|
+
unknown,
|
|
91
|
+
unknown,
|
|
92
|
+
unknown,
|
|
93
|
+
import('@mastra/core/tools').ToolExecutionContext<unknown, unknown, unknown>,
|
|
94
|
+
'propose_test_case_patch',
|
|
95
|
+
unknown
|
|
96
|
+
>;
|
|
97
|
+
//# sourceMappingURL=mastra-scenario-tools.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mastra-scenario-tools.d.ts","sourceRoot":"","sources":["../../src/app-server/mastra-scenario-tools.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAElE,MAAM,WAAW,yBAAyB;IACxC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,wBAAwB;IACvC,KAAK,EAAE,OAAO,EAAE,CAAC;IACjB,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,yBAAyB,CAAC,CAAC;IACjD,QAAQ,EAAE,CACR,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,OAAO,EACb,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,WAAW,CAAA;KAAE,KAC/B,OAAO,CAAC,OAAO,CAAC,CAAC;CACvB;AAED,MAAM,WAAW,yBAAyB;IACxC,MAAM,CAAC,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACrD,SAAS,CAAC,EAAE;QAAE,WAAW,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAChF,YAAY,CAAC,EAAE;QAAE,WAAW,EAAE,KAAK,CAAC;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,OAAO,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC7F,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,WAAW,EAClB,KAAK,CAAC,EAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,EACnE,WAAW,CAAC,EAAE;IAAE,YAAY,CAAC,EAAE,MAAM,CAAC;IAAC,eAAe,CAAC,EAAE,MAAM,CAAA;CAAE,8CAwBlE;AAED,gFAAgF;AAChF,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,wBAAwB,gKA2BzE;AAED,wBAAgB,mCAAmC,CACjD,UAAU,EAAE,CAAC,QAAQ,EAAE,yBAAyB,KAAK,IAAI;;;;;;;;;;;;;;;;;gJAwB1D"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { createTool } from '@mastra/core/tools';
|
|
2
|
+
import { jsonSchemaToZod } from '@mastra/core/workflows';
|
|
3
|
+
import { createAnthropic } from '@ai-sdk/anthropic';
|
|
4
|
+
import { createOpenAI } from '@ai-sdk/openai';
|
|
5
|
+
import { createAzure } from '@ai-sdk/azure';
|
|
6
|
+
import { z } from 'zod';
|
|
7
|
+
export function resolveMastraScenarioModel(agent, azure, credentials) {
|
|
8
|
+
if (agent.provider === 'openai') {
|
|
9
|
+
return createOpenAI({ apiKey: credentials?.openaiApiKey ?? process.env.OPENAI_API_KEY }).chat(agent.model);
|
|
10
|
+
}
|
|
11
|
+
if (agent.provider === 'anthropic') {
|
|
12
|
+
return createAnthropic({
|
|
13
|
+
apiKey: credentials?.anthropicApiKey ?? process.env.ANTHROPIC_API_KEY
|
|
14
|
+
}).chat(agent.model);
|
|
15
|
+
}
|
|
16
|
+
const endpoint = azure?.endpoint?.replace(/\/$/, '');
|
|
17
|
+
const provider = createAzure({
|
|
18
|
+
baseURL: endpoint
|
|
19
|
+
? endpoint.endsWith('/openai')
|
|
20
|
+
? endpoint
|
|
21
|
+
: `${endpoint}/openai`
|
|
22
|
+
: undefined,
|
|
23
|
+
apiKey: azure?.apiKey,
|
|
24
|
+
apiVersion: azure?.apiVersion,
|
|
25
|
+
useDeploymentBasedUrls: true
|
|
26
|
+
});
|
|
27
|
+
return provider.chat(agent.model);
|
|
28
|
+
}
|
|
29
|
+
/** Adapt MCPLab's already-authenticated MCP tools to Mastra's tool contract. */
|
|
30
|
+
export function createMastraScenarioTools(source) {
|
|
31
|
+
const result = {};
|
|
32
|
+
for (const definition of source.tools) {
|
|
33
|
+
const mapping = source.mappings.get(definition.name);
|
|
34
|
+
if (!mapping)
|
|
35
|
+
continue;
|
|
36
|
+
let inputSchema = z.record(z.string(), z.unknown());
|
|
37
|
+
if (definition.inputSchema && typeof definition.inputSchema === 'object') {
|
|
38
|
+
try {
|
|
39
|
+
inputSchema = jsonSchemaToZod(definition.inputSchema);
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
// Keep a permissive schema for non-standard MCP schemas.
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
result[definition.name] = createTool({
|
|
46
|
+
id: definition.name,
|
|
47
|
+
description: definition.description ?? definition.name,
|
|
48
|
+
inputSchema,
|
|
49
|
+
requireApproval: definition.annotations?.readOnlyHint !== true,
|
|
50
|
+
execute: async (args, context) => source.callTool(mapping.server, mapping.tool, args, {
|
|
51
|
+
signal: context?.abortSignal
|
|
52
|
+
})
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
return result;
|
|
56
|
+
}
|
|
57
|
+
export function createScenarioAssistantProposalTool(onProposal) {
|
|
58
|
+
const rule = z.record(z.string(), z.unknown());
|
|
59
|
+
return createTool({
|
|
60
|
+
id: 'propose_test_case_patch',
|
|
61
|
+
description: 'Propose apply-ready changes to the current MCP evaluation test case.',
|
|
62
|
+
inputSchema: z.object({
|
|
63
|
+
prompt: z.object({ replacement: z.string(), rationale: z.string().optional() }).optional(),
|
|
64
|
+
evalRules: z
|
|
65
|
+
.object({ replacement: z.array(rule), rationale: z.string().optional() })
|
|
66
|
+
.optional(),
|
|
67
|
+
extractRules: z
|
|
68
|
+
.object({
|
|
69
|
+
replacement: z.array(z.object({ name: z.string(), pattern: z.string() })),
|
|
70
|
+
rationale: z.string().optional()
|
|
71
|
+
})
|
|
72
|
+
.optional(),
|
|
73
|
+
notes: z.array(z.string()).optional()
|
|
74
|
+
}),
|
|
75
|
+
execute: async (proposal) => {
|
|
76
|
+
onProposal(proposal);
|
|
77
|
+
return { recorded: true };
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=mastra-scenario-tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mastra-scenario-tools.js","sourceRoot":"","sources":["../../src/app-server/mastra-scenario-tools.ts"],"names":[],"mappings":"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"}
|