create-agentmark 0.9.0 → 0.10.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/dist/index.js
CHANGED
|
@@ -17,7 +17,6 @@ var createAdapterConfig = (provider) => {
|
|
|
17
17
|
dependencies: ["ai@^5", `@ai-sdk/${provider}@^2`],
|
|
18
18
|
classes: {
|
|
19
19
|
modelRegistry: "VercelAIModelRegistry",
|
|
20
|
-
toolRegistry: "VercelAIToolRegistry",
|
|
21
20
|
webhookHandler: "VercelAdapterWebhookHandler"
|
|
22
21
|
}
|
|
23
22
|
},
|
|
@@ -26,11 +25,11 @@ var createAdapterConfig = (provider) => {
|
|
|
26
25
|
dependencies: [
|
|
27
26
|
"@mastra/core@<0.20.0",
|
|
28
27
|
"@mastra/mcp@<0.13.4",
|
|
29
|
-
`@ai-sdk/${provider}@<2
|
|
28
|
+
`@ai-sdk/${provider}@<2`,
|
|
29
|
+
"ai@^4"
|
|
30
30
|
],
|
|
31
31
|
classes: {
|
|
32
32
|
modelRegistry: "MastraModelRegistry",
|
|
33
|
-
toolRegistry: "MastraToolRegistry",
|
|
34
33
|
webhookHandler: "MastraAdapterWebhookHandler"
|
|
35
34
|
}
|
|
36
35
|
},
|
|
@@ -39,7 +38,6 @@ var createAdapterConfig = (provider) => {
|
|
|
39
38
|
dependencies: ["@anthropic-ai/claude-agent-sdk@^0.1.0"],
|
|
40
39
|
classes: {
|
|
41
40
|
modelRegistry: "ClaudeAgentModelRegistry",
|
|
42
|
-
toolRegistry: "ClaudeAgentToolRegistry",
|
|
43
41
|
webhookHandler: "ClaudeAgentWebhookHandler"
|
|
44
42
|
}
|
|
45
43
|
}
|
|
@@ -229,16 +227,22 @@ main();
|
|
|
229
227
|
};
|
|
230
228
|
|
|
231
229
|
// src/utils/examples/templates/env.ts
|
|
232
|
-
var getEnvFileContent = (_modelProvider, apiKey = "", adapter = "ai-sdk") => {
|
|
230
|
+
var getEnvFileContent = (_modelProvider, apiKey = "", adapter = "ai-sdk", deploymentMode = "cloud") => {
|
|
233
231
|
const apiKeyValue = apiKey || "your_api_key_here";
|
|
234
232
|
const apiKeyName = adapter === "claude-agent-sdk" ? "ANTHROPIC_API_KEY" : "OPENAI_API_KEY";
|
|
235
|
-
|
|
233
|
+
const cloudEnvVars = deploymentMode === "cloud" ? `
|
|
234
|
+
# AgentMark Cloud \u2014 required for managed deployments
|
|
235
|
+
AGENTMARK_API_KEY=your_agentmark_api_key
|
|
236
|
+
AGENTMARK_APP_ID=your_agentmark_app_id
|
|
237
|
+
` : `
|
|
238
|
+
# Cloud deployment: Set these environment variables
|
|
236
239
|
# AGENTMARK_BASE_URL=https://api.agentmark.co
|
|
237
240
|
# AGENTMARK_API_KEY=your_agentmark_api_key
|
|
238
241
|
# AGENTMARK_APP_ID=your_agentmark_app_id
|
|
242
|
+
`;
|
|
243
|
+
return `${apiKeyName}=${apiKeyValue}
|
|
244
|
+
${cloudEnvVars}
|
|
239
245
|
# Learn more: https://docs.agentmark.co/platform/getting_started/quickstart
|
|
240
|
-
|
|
241
|
-
${apiKeyName}=${apiKeyValue}
|
|
242
246
|
`;
|
|
243
247
|
};
|
|
244
248
|
|
|
@@ -752,8 +756,9 @@ var createExamplePrompts = (model, targetPath = ".", adapter = "ai-sdk") => {
|
|
|
752
756
|
// src/utils/examples/templates/user-client-config.ts
|
|
753
757
|
var getClientConfigContent = (options) => {
|
|
754
758
|
const { provider, adapter, deploymentMode = "cloud" } = options;
|
|
759
|
+
const isMastra = adapter === "mastra";
|
|
755
760
|
const adapterConfig = getAdapterConfig(adapter, provider);
|
|
756
|
-
const { modelRegistry
|
|
761
|
+
const { modelRegistry } = adapterConfig.classes;
|
|
757
762
|
const isClaudeAgentSdk = adapter === "claude-agent-sdk";
|
|
758
763
|
const providerImport = isClaudeAgentSdk ? "" : `import { ${provider} } from '@ai-sdk/${provider}';`;
|
|
759
764
|
const loaderImport = deploymentMode === "cloud" ? `import { ApiLoader } from "@agentmark-ai/loader-api";` : `import { ApiLoader } from "@agentmark-ai/loader-api";
|
|
@@ -812,64 +817,98 @@ const adapterOptions = {
|
|
|
812
817
|
// allowedTools: ['Read', 'Write', 'Glob'],
|
|
813
818
|
// disallowedTools: ['Bash'],
|
|
814
819
|
};` : "";
|
|
815
|
-
const
|
|
820
|
+
const toolImport = isClaudeAgentSdk ? `import { tool, createSdkMcpServer } from "@anthropic-ai/claude-agent-sdk";
|
|
821
|
+
import { z } from 'zod';` : isMastra ? `import { tool } from 'ai';
|
|
822
|
+
import type { ToolsInput } from '@mastra/core/agent';
|
|
823
|
+
import { z } from 'zod';` : `import { tool } from 'ai';
|
|
824
|
+
import type { Tool } from 'ai';
|
|
825
|
+
import { z } from 'zod';`;
|
|
826
|
+
const createClientCall = isClaudeAgentSdk ? `return createAgentMarkClient<AgentMarkTypes>({ loader, modelRegistry, evalRegistry, adapterOptions, mcpServers: { 'customer-support': customerSupportTools } });` : `return createAgentMarkClient<AgentMarkTypes>({ loader, modelRegistry, tools, evalRegistry });`;
|
|
827
|
+
const toolSchemaField = isMastra ? `parameters: z.object({ query: z.string().describe('The search query') })` : `inputSchema: z.object({ query: z.string().describe('The search query') })`;
|
|
828
|
+
const toolsReturnType = isMastra ? "ToolsInput" : "Record<string, Tool>";
|
|
829
|
+
const toolsSetup = isClaudeAgentSdk ? `
|
|
830
|
+
// Custom tools exposed as an MCP server \u2014 the SDK's native tool mechanism.
|
|
831
|
+
// The server name is used in mcpServers config; tool names are used in prompt files.
|
|
832
|
+
const knowledgeBase = tool(
|
|
833
|
+
'search_knowledgebase',
|
|
834
|
+
'Search the knowledge base for relevant articles',
|
|
835
|
+
{ query: z.string().describe('The search query') },
|
|
836
|
+
async ({ query }) => ({
|
|
837
|
+
content: [{ type: 'text' as const, text: JSON.stringify({
|
|
838
|
+
articles: [
|
|
839
|
+
{ topic: 'shipping', content: 'Standard shipping takes 3\u20135 business days.' },
|
|
840
|
+
{ topic: 'warranty', content: 'All products include a 1-year limited warranty.' },
|
|
841
|
+
{ topic: 'returns', content: 'You can return items within 30 days of delivery.' },
|
|
842
|
+
],
|
|
843
|
+
}) }],
|
|
844
|
+
})
|
|
845
|
+
);
|
|
846
|
+
|
|
847
|
+
const customerSupportTools = createSdkMcpServer({
|
|
848
|
+
name: 'customer-support',
|
|
849
|
+
tools: [knowledgeBase],
|
|
850
|
+
});` : `
|
|
851
|
+
function createTools(): ${toolsReturnType} {
|
|
852
|
+
return {
|
|
853
|
+
search_knowledgebase: tool({
|
|
854
|
+
description: 'Search the knowledge base for relevant articles',
|
|
855
|
+
${toolSchemaField},
|
|
856
|
+
execute: async ({ query }) => {
|
|
857
|
+
// Simulate search delay
|
|
858
|
+
await new Promise(resolve => setTimeout(resolve, 500));
|
|
859
|
+
|
|
860
|
+
// Return all three knowledge base articles
|
|
861
|
+
// The LLM will select the relevant one based on the query
|
|
862
|
+
return {
|
|
863
|
+
articles: [
|
|
864
|
+
{ topic: 'shipping', content: 'Standard shipping takes 3\u20135 business days.' },
|
|
865
|
+
{ topic: 'warranty', content: 'All products include a 1-year limited warranty.' },
|
|
866
|
+
{ topic: 'returns', content: 'You can return items within 30 days of delivery.' }
|
|
867
|
+
]
|
|
868
|
+
};
|
|
869
|
+
},
|
|
870
|
+
}),
|
|
871
|
+
};
|
|
872
|
+
}`;
|
|
873
|
+
const toolsVariable = isClaudeAgentSdk ? "" : ` const tools = createTools();`;
|
|
816
874
|
return `// agentmark.client.ts
|
|
817
875
|
import path from 'node:path';
|
|
818
876
|
import dotenv from 'dotenv';
|
|
819
877
|
dotenv.config({ path: path.resolve(__dirname, '.env') });
|
|
820
|
-
import { createAgentMarkClient, ${modelRegistry}
|
|
878
|
+
import { createAgentMarkClient, ${modelRegistry} } from "${adapterConfig.package}";
|
|
879
|
+
import type { EvalRegistry } from "${adapterConfig.package}";
|
|
821
880
|
${loaderImport}
|
|
822
|
-
import AgentMarkTypes
|
|
881
|
+
import AgentMarkTypes from './agentmark.types';
|
|
823
882
|
${providerImport}
|
|
883
|
+
${toolImport}
|
|
824
884
|
${adapterOptionsImport}
|
|
825
885
|
|
|
826
886
|
${modelRegistrySetup}
|
|
887
|
+
${toolsSetup}
|
|
827
888
|
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
// The LLM will select the relevant one based on the query
|
|
889
|
+
const evalRegistry: EvalRegistry = {
|
|
890
|
+
exact_match_json: ({ output, expectedOutput }) => {
|
|
891
|
+
if (!expectedOutput) {
|
|
892
|
+
return { score: 0, label: 'error', reason: 'No expected output provided', passed: false };
|
|
893
|
+
}
|
|
894
|
+
try {
|
|
895
|
+
const ok = JSON.stringify(output) === JSON.stringify(JSON.parse(expectedOutput));
|
|
836
896
|
return {
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
]
|
|
897
|
+
score: ok ? 1 : 0,
|
|
898
|
+
label: ok ? 'correct' : 'incorrect',
|
|
899
|
+
reason: ok ? 'Exact match' : 'Mismatch',
|
|
900
|
+
passed: ok
|
|
842
901
|
};
|
|
843
|
-
})
|
|
844
|
-
|
|
845
|
-
}
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
const evalRegistry = new EvalRegistry()
|
|
849
|
-
.register('exact_match_json', ({ output, expectedOutput }) => {
|
|
850
|
-
if (!expectedOutput) {
|
|
851
|
-
return { score: 0, label: 'error', reason: 'No expected output provided', passed: false };
|
|
852
|
-
}
|
|
853
|
-
try {
|
|
854
|
-
const ok = JSON.stringify(output) === JSON.stringify(JSON.parse(expectedOutput));
|
|
855
|
-
return {
|
|
856
|
-
score: ok ? 1 : 0,
|
|
857
|
-
label: ok ? 'correct' : 'incorrect',
|
|
858
|
-
reason: ok ? 'Exact match' : 'Mismatch',
|
|
859
|
-
passed: ok
|
|
860
|
-
};
|
|
861
|
-
} catch (e) {
|
|
862
|
-
return { score: 0, label: 'error', reason: 'Failed to parse expected output as JSON', passed: false };
|
|
863
|
-
}
|
|
864
|
-
});
|
|
865
|
-
return evalRegistry;
|
|
866
|
-
}
|
|
902
|
+
} catch (e) {
|
|
903
|
+
return { score: 0, label: 'error', reason: 'Failed to parse expected output as JSON', passed: false };
|
|
904
|
+
}
|
|
905
|
+
},
|
|
906
|
+
};
|
|
867
907
|
|
|
868
908
|
function createClient() {
|
|
869
909
|
${loaderSetup}
|
|
870
910
|
const modelRegistry = createModelRegistry();
|
|
871
|
-
|
|
872
|
-
const evalRegistry = createEvalRegistry();
|
|
911
|
+
${toolsVariable}
|
|
873
912
|
${createClientCall}
|
|
874
913
|
}
|
|
875
914
|
|
|
@@ -1113,6 +1152,10 @@ var createExampleApp = async (client, targetPath = ".", apiKey = "", adapter = "
|
|
|
1113
1152
|
} else {
|
|
1114
1153
|
envVars[apiKeyEnvVar] = adapter === "claude-agent-sdk" ? "your-anthropic-api-key" : "your-openai-api-key";
|
|
1115
1154
|
}
|
|
1155
|
+
if (deploymentMode === "cloud") {
|
|
1156
|
+
envVars["AGENTMARK_API_KEY"] = "your_agentmark_api_key";
|
|
1157
|
+
envVars["AGENTMARK_APP_ID"] = "your_agentmark_app_id";
|
|
1158
|
+
}
|
|
1116
1159
|
const result = appendEnv(targetPath, envVars);
|
|
1117
1160
|
if (result.added.length > 0) {
|
|
1118
1161
|
console.log(`\u2705 Added to .env: ${result.added.join(", ")}`);
|
|
@@ -1121,7 +1164,7 @@ var createExampleApp = async (client, targetPath = ".", apiKey = "", adapter = "
|
|
|
1121
1164
|
console.log(`\u23ED\uFE0F Skipped existing .env vars: ${result.skipped.join(", ")}`);
|
|
1122
1165
|
}
|
|
1123
1166
|
} else {
|
|
1124
|
-
fs4.writeFileSync(`${targetPath}/.env`, getEnvFileContent(modelProvider, apiKey, adapter));
|
|
1167
|
+
fs4.writeFileSync(`${targetPath}/.env`, getEnvFileContent(modelProvider, apiKey, adapter, deploymentMode));
|
|
1125
1168
|
}
|
|
1126
1169
|
const gitignoreEntries = ["node_modules/", ".env", "*.agentmark-outputs/", "dist/"];
|
|
1127
1170
|
if (shouldMergeFile(".gitignore", projectInfo, resolutions)) {
|
|
@@ -1166,6 +1209,59 @@ var createExampleApp = async (client, targetPath = ".", apiKey = "", adapter = "
|
|
|
1166
1209
|
export default interface AgentmarkTypes {}
|
|
1167
1210
|
`);
|
|
1168
1211
|
}
|
|
1212
|
+
if (deploymentMode === "cloud") {
|
|
1213
|
+
const handlerAdapterConfig = getAdapterConfig(adapter, modelProvider);
|
|
1214
|
+
const { webhookHandler: handlerClass } = handlerAdapterConfig.classes;
|
|
1215
|
+
const handlerContent = `import { ${handlerClass} } from '${handlerAdapterConfig.package}/runner';
|
|
1216
|
+
import { AgentMarkSDK } from '@agentmark-ai/sdk';
|
|
1217
|
+
import { client } from './agentmark.client';
|
|
1218
|
+
|
|
1219
|
+
// Initialize tracing \u2014 sends traces to AgentMark Cloud
|
|
1220
|
+
const sdk = new AgentMarkSDK({
|
|
1221
|
+
apiKey: process.env.AGENTMARK_API_KEY ?? '',
|
|
1222
|
+
appId: process.env.AGENTMARK_APP_ID ?? '',
|
|
1223
|
+
baseUrl: process.env.AGENTMARK_BASE_URL,
|
|
1224
|
+
});
|
|
1225
|
+
sdk.initTracing({ disableBatch: true });
|
|
1226
|
+
|
|
1227
|
+
const adapter = new ${handlerClass}(client as any);
|
|
1228
|
+
|
|
1229
|
+
export default async function handler(request: {
|
|
1230
|
+
type: 'prompt-run' | 'dataset-run';
|
|
1231
|
+
data: {
|
|
1232
|
+
ast: unknown;
|
|
1233
|
+
customProps?: Record<string, unknown>;
|
|
1234
|
+
options?: { shouldStream?: boolean };
|
|
1235
|
+
experimentId?: string;
|
|
1236
|
+
datasetPath?: string;
|
|
1237
|
+
};
|
|
1238
|
+
}) {
|
|
1239
|
+
if (request.type === 'prompt-run') {
|
|
1240
|
+
return adapter.runPrompt(request.data.ast, {
|
|
1241
|
+
shouldStream: request.data.options?.shouldStream,
|
|
1242
|
+
customProps: request.data.customProps,
|
|
1243
|
+
});
|
|
1244
|
+
}
|
|
1245
|
+
|
|
1246
|
+
if (request.type === 'dataset-run') {
|
|
1247
|
+
return adapter.runExperiment(
|
|
1248
|
+
request.data.ast,
|
|
1249
|
+
request.data.experimentId ?? '',
|
|
1250
|
+
request.data.datasetPath,
|
|
1251
|
+
);
|
|
1252
|
+
}
|
|
1253
|
+
|
|
1254
|
+
throw new Error(\`Unknown request type: \${request.type}\`);
|
|
1255
|
+
}
|
|
1256
|
+
`;
|
|
1257
|
+
const handlerPath = path2.join(targetPath, "handler.ts");
|
|
1258
|
+
if (fs4.existsSync(handlerPath)) {
|
|
1259
|
+
console.log("\u23ED\uFE0F Skipped handler.ts (already exists - preserving customizations)");
|
|
1260
|
+
} else {
|
|
1261
|
+
fs4.writeFileSync(handlerPath, handlerContent);
|
|
1262
|
+
console.log(`\u2705 Created handler.ts for cloud deployment`);
|
|
1263
|
+
}
|
|
1264
|
+
}
|
|
1169
1265
|
console.log("Creating development server entry point...");
|
|
1170
1266
|
const adapterConfig = getAdapterConfig(adapter, modelProvider);
|
|
1171
1267
|
const { webhookHandler } = adapterConfig.classes;
|
|
@@ -1450,7 +1546,7 @@ var getAgentmarkClientContent = (_deploymentMode, adapter) => {
|
|
|
1450
1546
|
return `"""AgentMark client configuration.
|
|
1451
1547
|
|
|
1452
1548
|
This file configures the AgentMark client with Claude Agent SDK adapter.
|
|
1453
|
-
Customize the model registry
|
|
1549
|
+
Customize the model registry as needed.
|
|
1454
1550
|
"""
|
|
1455
1551
|
|
|
1456
1552
|
import os
|
|
@@ -1461,7 +1557,6 @@ from agentmark.prompt_core import FileLoader
|
|
|
1461
1557
|
from agentmark_claude_agent_sdk import (
|
|
1462
1558
|
create_claude_agent_client,
|
|
1463
1559
|
create_default_model_registry,
|
|
1464
|
-
ClaudeAgentToolRegistry,
|
|
1465
1560
|
)
|
|
1466
1561
|
|
|
1467
1562
|
# Load environment variables
|
|
@@ -1471,26 +1566,15 @@ load_dotenv()
|
|
|
1471
1566
|
# Supports: claude-* models
|
|
1472
1567
|
model_registry = create_default_model_registry()
|
|
1473
1568
|
|
|
1474
|
-
# Configure tool registry for custom tools
|
|
1475
|
-
tool_registry = ClaudeAgentToolRegistry()
|
|
1476
|
-
|
|
1477
|
-
# Example tool registration:
|
|
1478
|
-
# tool_registry.register(
|
|
1479
|
-
# "search",
|
|
1480
|
-
# lambda args, ctx: f"Search results for: {args['query']}",
|
|
1481
|
-
# description="Search the web",
|
|
1482
|
-
# parameters={"type": "object", "properties": {"query": {"type": "string"}}, "required": ["query"]},
|
|
1483
|
-
# )
|
|
1484
|
-
|
|
1485
1569
|
# Create file loader for local development
|
|
1486
1570
|
# Uses the project root as base directory for resolving relative paths
|
|
1487
1571
|
project_root = Path(__file__).parent.resolve()
|
|
1488
1572
|
loader = FileLoader(base_dir=str(project_root))
|
|
1489
1573
|
|
|
1490
1574
|
# Create the client
|
|
1575
|
+
# Claude Agent SDK handles tools natively through the SDK
|
|
1491
1576
|
client = create_claude_agent_client(
|
|
1492
1577
|
model_registry=model_registry,
|
|
1493
|
-
tool_registry=tool_registry,
|
|
1494
1578
|
loader=loader,
|
|
1495
1579
|
)
|
|
1496
1580
|
|
|
@@ -1500,7 +1584,7 @@ __all__ = ["client"]
|
|
|
1500
1584
|
return `"""AgentMark client configuration.
|
|
1501
1585
|
|
|
1502
1586
|
This file configures the AgentMark client with Pydantic AI adapter.
|
|
1503
|
-
Customize the model registry and
|
|
1587
|
+
Customize the model registry and tools as needed.
|
|
1504
1588
|
"""
|
|
1505
1589
|
|
|
1506
1590
|
import os
|
|
@@ -1511,7 +1595,6 @@ from agentmark.prompt_core import FileLoader
|
|
|
1511
1595
|
from agentmark_pydantic_ai_v0 import (
|
|
1512
1596
|
create_pydantic_ai_client,
|
|
1513
1597
|
create_default_model_registry,
|
|
1514
|
-
PydanticAIToolRegistry,
|
|
1515
1598
|
)
|
|
1516
1599
|
|
|
1517
1600
|
# Load environment variables
|
|
@@ -1521,14 +1604,12 @@ load_dotenv()
|
|
|
1521
1604
|
# Supports: gpt-*, claude-*, gemini-*, etc.
|
|
1522
1605
|
model_registry = create_default_model_registry()
|
|
1523
1606
|
|
|
1524
|
-
#
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
# Example tool registration:
|
|
1528
|
-
# @tool_registry.register("search")
|
|
1529
|
-
# async def search_web(args: dict, ctx: dict | None) -> str:
|
|
1530
|
-
# query = args["query"]
|
|
1607
|
+
# Define tools as native pydantic-ai Tool objects or callables
|
|
1608
|
+
# Example:
|
|
1609
|
+
# def search(query: str) -> str:
|
|
1531
1610
|
# return f"Search results for: {query}"
|
|
1611
|
+
# tools = [search]
|
|
1612
|
+
tools = []
|
|
1532
1613
|
|
|
1533
1614
|
# Create file loader for local development
|
|
1534
1615
|
# Uses the project root as base directory for resolving relative paths
|
|
@@ -1538,7 +1619,7 @@ loader = FileLoader(base_dir=str(project_root))
|
|
|
1538
1619
|
# Create the client
|
|
1539
1620
|
client = create_pydantic_ai_client(
|
|
1540
1621
|
model_registry=model_registry,
|
|
1541
|
-
|
|
1622
|
+
tools=tools,
|
|
1542
1623
|
loader=loader,
|
|
1543
1624
|
)
|
|
1544
1625
|
|
|
@@ -2145,6 +2226,9 @@ var main = async () => {
|
|
|
2145
2226
|
usedModels = await createExampleApp(client, targetPath, apiKey, adapter, deploymentMode, projectInfo, resolutions);
|
|
2146
2227
|
}
|
|
2147
2228
|
config.builtInModels = usedModels;
|
|
2229
|
+
if (deploymentMode === "cloud") {
|
|
2230
|
+
config.handler = "handler.ts";
|
|
2231
|
+
}
|
|
2148
2232
|
const agentmarkJsonPath = path6.join(targetPath, "agentmark.json");
|
|
2149
2233
|
const agentmarkJsonResolution = resolutions.find((r) => r.path === "agentmark.json");
|
|
2150
2234
|
if (!fs8.existsSync(agentmarkJsonPath) || agentmarkJsonResolution?.action === "overwrite") {
|