create-agentmark 0.10.5 → 0.10.7
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
|
@@ -71,7 +71,7 @@ sdk.initTracing({ disableBatch: true });
|
|
|
71
71
|
`;
|
|
72
72
|
const staticTracingInit = `
|
|
73
73
|
// Initialize tracing - traces will be sent to local dev server
|
|
74
|
-
// Make sure to run "
|
|
74
|
+
// Make sure to run "npx agentmark dev" in another terminal first
|
|
75
75
|
// To disable tracing, comment out sdk.initTracing() below
|
|
76
76
|
const sdk = new AgentMarkSDK({
|
|
77
77
|
apiKey: "",
|
|
@@ -242,7 +242,7 @@ AGENTMARK_APP_ID=your_agentmark_app_id
|
|
|
242
242
|
`;
|
|
243
243
|
return `${apiKeyName}=${apiKeyValue}
|
|
244
244
|
${cloudEnvVars}
|
|
245
|
-
# Learn more: https://docs.agentmark.co/
|
|
245
|
+
# Learn more: https://docs.agentmark.co/getting-started/quickstart
|
|
246
246
|
`;
|
|
247
247
|
};
|
|
248
248
|
|
|
@@ -487,9 +487,10 @@ var setupPackageJson = (targetPath = ".", deploymentMode = "cloud", projectInfo
|
|
|
487
487
|
console.log("Creating package.json...");
|
|
488
488
|
execSync("npm init -y", { cwd: targetPath });
|
|
489
489
|
}
|
|
490
|
+
const demoScript = deploymentMode === "static" ? "npx agentmark build --out dist/agentmark && npx tsx index.ts" : "npx tsx index.ts";
|
|
490
491
|
if (isExistingProject && fs2.existsSync(packageJsonPath)) {
|
|
491
492
|
const scriptsToAdd = {
|
|
492
|
-
"demo":
|
|
493
|
+
"demo": demoScript,
|
|
493
494
|
"agentmark": "agentmark"
|
|
494
495
|
};
|
|
495
496
|
if (deploymentMode === "static") {
|
|
@@ -509,9 +510,12 @@ var setupPackageJson = (targetPath = ".", deploymentMode = "cloud", projectInfo
|
|
|
509
510
|
const pkgJson = fs2.readJsonSync(packageJsonPath);
|
|
510
511
|
pkgJson.name = pkgJson.name === "test" || !pkgJson.name ? "agentmark-example-app" : pkgJson.name;
|
|
511
512
|
pkgJson.description = pkgJson.description || "A simple Node.js app using the Agentmark SDK";
|
|
513
|
+
if (pkgJson.type === "commonjs") {
|
|
514
|
+
delete pkgJson.type;
|
|
515
|
+
}
|
|
512
516
|
const scripts = {
|
|
513
517
|
...pkgJson.scripts,
|
|
514
|
-
"demo":
|
|
518
|
+
"demo": demoScript,
|
|
515
519
|
"agentmark": "agentmark"
|
|
516
520
|
};
|
|
517
521
|
if (deploymentMode === "static") {
|
|
@@ -641,7 +645,7 @@ object_config:
|
|
|
641
645
|
- names
|
|
642
646
|
test_settings:
|
|
643
647
|
dataset: party.jsonl
|
|
644
|
-
|
|
648
|
+
evals:
|
|
645
649
|
- exact_match_json
|
|
646
650
|
props:
|
|
647
651
|
party_text: "We're having a party with Alice, Bob, and Carol."
|
|
@@ -757,12 +761,16 @@ var getClientConfigContent = (options) => {
|
|
|
757
761
|
import { FileLoader } from "@agentmark-ai/loader-file";`;
|
|
758
762
|
const loaderSetup = deploymentMode === "cloud" ? ` // ApiLoader works for both development and production
|
|
759
763
|
// - Development: 'agentmark dev' sets AGENTMARK_BASE_URL to localhost
|
|
760
|
-
// - Production: Set AGENTMARK_API_KEY and AGENTMARK_APP_ID for cloud
|
|
764
|
+
// - Production: Set AGENTMARK_API_KEY and AGENTMARK_APP_ID for cloud.
|
|
765
|
+
// AGENTMARK_BASE_URL overrides the default https://api.agentmark.co
|
|
766
|
+
// target \u2014 managed deployments use this to point back at the gateway
|
|
767
|
+
// that dispatched the job.
|
|
761
768
|
const loader = process.env.NODE_ENV === 'development'
|
|
762
769
|
? ApiLoader.local({ baseUrl: process.env.AGENTMARK_BASE_URL || 'http://localhost:9418' })
|
|
763
770
|
: ApiLoader.cloud({
|
|
764
771
|
apiKey: process.env.AGENTMARK_API_KEY!,
|
|
765
772
|
appId: process.env.AGENTMARK_APP_ID!,
|
|
773
|
+
baseUrl: process.env.AGENTMARK_BASE_URL,
|
|
766
774
|
});` : ` const loader = process.env.NODE_ENV === 'development'
|
|
767
775
|
? ApiLoader.local({ baseUrl: process.env.AGENTMARK_BASE_URL || 'http://localhost:9418' })
|
|
768
776
|
: new FileLoader('./dist/agentmark');`;
|
|
@@ -1136,6 +1144,19 @@ var createExampleApp = async (client, targetPath = ".", apiKey = "", adapter = "
|
|
|
1136
1144
|
`${targetPath}/agentmark.client.ts`,
|
|
1137
1145
|
getClientConfigContent({ provider: modelProvider, adapter, deploymentMode })
|
|
1138
1146
|
);
|
|
1147
|
+
const gitignoreEntries = ["node_modules/", ".env", "*.agentmark-outputs/", "dist/"];
|
|
1148
|
+
if (shouldMergeFile(".gitignore", projectInfo, resolutions)) {
|
|
1149
|
+
const result = appendGitignore(targetPath, gitignoreEntries);
|
|
1150
|
+
if (result.added.length > 0) {
|
|
1151
|
+
console.log(`\u2705 Added to .gitignore: ${result.added.join(", ")}`);
|
|
1152
|
+
}
|
|
1153
|
+
if (result.skipped.length > 0) {
|
|
1154
|
+
console.log(`\u23ED\uFE0F Already in .gitignore: ${result.skipped.join(", ")}`);
|
|
1155
|
+
}
|
|
1156
|
+
} else {
|
|
1157
|
+
const gitignore = gitignoreEntries.join("\n");
|
|
1158
|
+
fs4.writeFileSync(`${targetPath}/.gitignore`, gitignore);
|
|
1159
|
+
}
|
|
1139
1160
|
if (shouldMergeFile(".env", projectInfo, resolutions)) {
|
|
1140
1161
|
const envVars = {};
|
|
1141
1162
|
const apiKeyEnvVar = adapter === "claude-agent-sdk" ? "ANTHROPIC_API_KEY" : "OPENAI_API_KEY";
|
|
@@ -1158,19 +1179,6 @@ var createExampleApp = async (client, targetPath = ".", apiKey = "", adapter = "
|
|
|
1158
1179
|
} else {
|
|
1159
1180
|
fs4.writeFileSync(`${targetPath}/.env`, getEnvFileContent(modelProvider, apiKey, adapter, deploymentMode));
|
|
1160
1181
|
}
|
|
1161
|
-
const gitignoreEntries = ["node_modules/", ".env", "*.agentmark-outputs/", "dist/"];
|
|
1162
|
-
if (shouldMergeFile(".gitignore", projectInfo, resolutions)) {
|
|
1163
|
-
const result = appendGitignore(targetPath, gitignoreEntries);
|
|
1164
|
-
if (result.added.length > 0) {
|
|
1165
|
-
console.log(`\u2705 Added to .gitignore: ${result.added.join(", ")}`);
|
|
1166
|
-
}
|
|
1167
|
-
if (result.skipped.length > 0) {
|
|
1168
|
-
console.log(`\u23ED\uFE0F Already in .gitignore: ${result.skipped.join(", ")}`);
|
|
1169
|
-
}
|
|
1170
|
-
} else {
|
|
1171
|
-
const gitignore = gitignoreEntries.join("\n");
|
|
1172
|
-
fs4.writeFileSync(`${targetPath}/.gitignore`, gitignore);
|
|
1173
|
-
}
|
|
1174
1182
|
if (!isExistingProject) {
|
|
1175
1183
|
fs4.writeFileSync(
|
|
1176
1184
|
`${targetPath}/index.ts`,
|
|
@@ -1219,15 +1227,23 @@ sdk.initTracing({ disableBatch: true });
|
|
|
1219
1227
|
const adapter = new ${handlerClass}(client as any);
|
|
1220
1228
|
|
|
1221
1229
|
export default async function handler(request: {
|
|
1222
|
-
type: 'prompt-run' | 'dataset-run';
|
|
1230
|
+
type: 'prompt-run' | 'dataset-run' | 'get-evals';
|
|
1223
1231
|
data: {
|
|
1224
|
-
ast
|
|
1232
|
+
ast?: any;
|
|
1225
1233
|
customProps?: Record<string, unknown>;
|
|
1226
1234
|
options?: { shouldStream?: boolean };
|
|
1227
1235
|
experimentId?: string;
|
|
1228
1236
|
datasetPath?: string;
|
|
1229
1237
|
};
|
|
1230
1238
|
}) {
|
|
1239
|
+
if (request.type === 'get-evals') {
|
|
1240
|
+
return {
|
|
1241
|
+
type: 'evals',
|
|
1242
|
+
result: JSON.stringify(Object.keys(client.getEvalRegistry())),
|
|
1243
|
+
traceId: '',
|
|
1244
|
+
};
|
|
1245
|
+
}
|
|
1246
|
+
|
|
1231
1247
|
if (request.type === 'prompt-run') {
|
|
1232
1248
|
return adapter.runPrompt(request.data.ast, {
|
|
1233
1249
|
shouldStream: request.data.options?.shouldStream,
|
|
@@ -1327,20 +1343,11 @@ main().catch((err) => {
|
|
|
1327
1343
|
console.log("\n" + "\u2550".repeat(70));
|
|
1328
1344
|
console.log("Next Steps");
|
|
1329
1345
|
console.log("\u2550".repeat(70));
|
|
1330
|
-
const runCmd = packageManager?.runCmd ?? "npm run";
|
|
1331
|
-
const pkgJsonPath = path2.join(targetPath, "package.json");
|
|
1332
|
-
let agentmarkScriptName = "agentmark";
|
|
1333
|
-
if (fs4.existsSync(pkgJsonPath)) {
|
|
1334
|
-
const pkgJson = fs4.readJsonSync(pkgJsonPath);
|
|
1335
|
-
if (pkgJson.scripts?.["agentmark:agentmark"]) {
|
|
1336
|
-
agentmarkScriptName = "agentmark:agentmark";
|
|
1337
|
-
}
|
|
1338
|
-
}
|
|
1339
1346
|
console.log("\n Get Started:");
|
|
1340
1347
|
if (folderName !== "." && folderName !== "./" && !isExistingProject) {
|
|
1341
1348
|
console.log(` $ cd ${folderName}`);
|
|
1342
1349
|
}
|
|
1343
|
-
console.log(` $
|
|
1350
|
+
console.log(` $ npx agentmark dev
|
|
1344
1351
|
`);
|
|
1345
1352
|
console.log("\u2500".repeat(70));
|
|
1346
1353
|
console.log("Resources");
|
|
@@ -1467,7 +1474,8 @@ var setupMCPServer2 = (client, targetPath) => {
|
|
|
1467
1474
|
return;
|
|
1468
1475
|
}
|
|
1469
1476
|
};
|
|
1470
|
-
var getPyprojectContent = (projectName, adapter) => {
|
|
1477
|
+
var getPyprojectContent = (projectName, adapter, deploymentMode) => {
|
|
1478
|
+
const pyModules = deploymentMode === "cloud" ? `["agentmark_client", "main", "handler"]` : `["agentmark_client", "main"]`;
|
|
1471
1479
|
if (adapter === "claude-agent-sdk") {
|
|
1472
1480
|
return `[project]
|
|
1473
1481
|
name = "${projectName}"
|
|
@@ -1475,9 +1483,9 @@ version = "0.1.0"
|
|
|
1475
1483
|
description = "An AgentMark application using Claude Agent SDK"
|
|
1476
1484
|
requires-python = ">=3.12"
|
|
1477
1485
|
dependencies = [
|
|
1478
|
-
"agentmark-sdk>=0.
|
|
1479
|
-
"agentmark-claude-agent-sdk-v0>=0.1.
|
|
1480
|
-
"agentmark-prompt-core>=0.1.
|
|
1486
|
+
"agentmark-sdk>=0.2.0",
|
|
1487
|
+
"agentmark-claude-agent-sdk-v0>=0.1.4",
|
|
1488
|
+
"agentmark-prompt-core>=0.1.2",
|
|
1481
1489
|
"python-dotenv>=1.0.0",
|
|
1482
1490
|
"claude-agent-sdk>=0.1.0",
|
|
1483
1491
|
]
|
|
@@ -1490,8 +1498,11 @@ dev = [
|
|
|
1490
1498
|
]
|
|
1491
1499
|
|
|
1492
1500
|
[build-system]
|
|
1493
|
-
requires = ["
|
|
1494
|
-
build-backend = "
|
|
1501
|
+
requires = ["setuptools>=61", "wheel"]
|
|
1502
|
+
build-backend = "setuptools.build_meta"
|
|
1503
|
+
|
|
1504
|
+
[tool.setuptools]
|
|
1505
|
+
py-modules = ${pyModules}
|
|
1495
1506
|
|
|
1496
1507
|
[tool.pytest.ini_options]
|
|
1497
1508
|
asyncio_mode = "auto"
|
|
@@ -1506,11 +1517,11 @@ version = "0.1.0"
|
|
|
1506
1517
|
description = "An AgentMark application using Pydantic AI"
|
|
1507
1518
|
requires-python = ">=3.12"
|
|
1508
1519
|
dependencies = [
|
|
1509
|
-
"agentmark-sdk>=0.
|
|
1510
|
-
"agentmark-pydantic-ai-v0>=0.1.
|
|
1511
|
-
"agentmark-prompt-core>=0.1.
|
|
1520
|
+
"agentmark-sdk>=0.2.0",
|
|
1521
|
+
"agentmark-pydantic-ai-v0>=0.1.4",
|
|
1522
|
+
"agentmark-prompt-core>=0.1.2",
|
|
1512
1523
|
"python-dotenv>=1.0.0",
|
|
1513
|
-
"pydantic-ai[openai]>=
|
|
1524
|
+
"pydantic-ai-slim[openai]>=1.0,<2.0",
|
|
1514
1525
|
]
|
|
1515
1526
|
|
|
1516
1527
|
[project.optional-dependencies]
|
|
@@ -1519,12 +1530,13 @@ dev = [
|
|
|
1519
1530
|
"pytest-asyncio>=0.21",
|
|
1520
1531
|
"mypy>=1.0",
|
|
1521
1532
|
]
|
|
1522
|
-
anthropic = ["pydantic-ai[anthropic]"]
|
|
1523
|
-
gemini = ["pydantic-ai[gemini]"]
|
|
1524
1533
|
|
|
1525
1534
|
[build-system]
|
|
1526
|
-
requires = ["
|
|
1527
|
-
build-backend = "
|
|
1535
|
+
requires = ["setuptools>=61", "wheel"]
|
|
1536
|
+
build-backend = "setuptools.build_meta"
|
|
1537
|
+
|
|
1538
|
+
[tool.setuptools]
|
|
1539
|
+
py-modules = ${pyModules}
|
|
1528
1540
|
|
|
1529
1541
|
[tool.pytest.ini_options]
|
|
1530
1542
|
asyncio_mode = "auto"
|
|
@@ -1534,8 +1546,8 @@ strict = true
|
|
|
1534
1546
|
`;
|
|
1535
1547
|
};
|
|
1536
1548
|
var getHandlerPyContent = (adapter) => {
|
|
1537
|
-
const webhookClass = adapter === "claude-agent-sdk" ? "
|
|
1538
|
-
const webhookImport = adapter === "claude-agent-sdk" ? "from
|
|
1549
|
+
const webhookClass = adapter === "claude-agent-sdk" ? "ClaudeAgentWebhookHandler" : "PydanticAIWebhookHandler";
|
|
1550
|
+
const webhookImport = adapter === "claude-agent-sdk" ? "from agentmark_claude_agent_sdk_v0 import ClaudeAgentWebhookHandler" : "from agentmark_pydantic_ai_v0 import PydanticAIWebhookHandler";
|
|
1539
1551
|
return `"""AgentMark handler for managed cloud deployments.
|
|
1540
1552
|
|
|
1541
1553
|
This file is used by the AgentMark platform to execute prompts and experiments
|
|
@@ -1560,10 +1572,18 @@ adapter = ${webhookClass}(client)
|
|
|
1560
1572
|
|
|
1561
1573
|
|
|
1562
1574
|
async def handler(request: dict):
|
|
1563
|
-
"""Handle prompt-run
|
|
1575
|
+
"""Handle prompt-run, dataset-run, and get-evals requests from the platform."""
|
|
1564
1576
|
req_type = request.get("type")
|
|
1565
1577
|
data = request.get("data", {})
|
|
1566
1578
|
|
|
1579
|
+
if req_type == "get-evals":
|
|
1580
|
+
import json
|
|
1581
|
+
return {
|
|
1582
|
+
"type": "evals",
|
|
1583
|
+
"result": json.dumps(list(client.get_eval_registry().keys())),
|
|
1584
|
+
"traceId": "",
|
|
1585
|
+
}
|
|
1586
|
+
|
|
1567
1587
|
if req_type == "prompt-run":
|
|
1568
1588
|
return await adapter.run_prompt(data["ast"], {
|
|
1569
1589
|
"shouldStream": data.get("options", {}).get("shouldStream", True),
|
|
@@ -1584,9 +1604,8 @@ var getAgentmarkClientContent = (deploymentMode, adapter) => {
|
|
|
1584
1604
|
const isCloud = deploymentMode === "cloud";
|
|
1585
1605
|
const loaderImport = isCloud ? `from agentmark.prompt_core import ApiLoader` : `from agentmark.prompt_core import FileLoader`;
|
|
1586
1606
|
const loaderSetup = isCloud ? `# API loader for cloud deployment \u2014 fetches datasets from the AgentMark gateway
|
|
1587
|
-
loader = ApiLoader.cloud()` : `# File loader for local development
|
|
1588
|
-
|
|
1589
|
-
loader = FileLoader(base_dir=str(project_root))`;
|
|
1607
|
+
loader = ApiLoader.cloud()` : `# File loader for local development \u2014 reads pre-built prompts from the build output directory
|
|
1608
|
+
loader = FileLoader("./dist/agentmark")`;
|
|
1590
1609
|
if (adapter === "claude-agent-sdk") {
|
|
1591
1610
|
return `"""AgentMark client configuration.
|
|
1592
1611
|
|
|
@@ -1596,12 +1615,11 @@ Customize the model registry and eval registry as needed.
|
|
|
1596
1615
|
|
|
1597
1616
|
import json
|
|
1598
1617
|
import os
|
|
1599
|
-
from pathlib import Path
|
|
1600
1618
|
from dotenv import load_dotenv
|
|
1601
1619
|
|
|
1602
1620
|
${loaderImport}
|
|
1603
1621
|
from agentmark.prompt_core import EvalRegistry
|
|
1604
|
-
from
|
|
1622
|
+
from agentmark_claude_agent_sdk_v0 import (
|
|
1605
1623
|
create_claude_agent_client,
|
|
1606
1624
|
ClaudeAgentModelRegistry,
|
|
1607
1625
|
)
|
|
@@ -1662,7 +1680,6 @@ Customize the model registry, tools, and eval registry as needed.
|
|
|
1662
1680
|
|
|
1663
1681
|
import json
|
|
1664
1682
|
import os
|
|
1665
|
-
from pathlib import Path
|
|
1666
1683
|
from dotenv import load_dotenv
|
|
1667
1684
|
|
|
1668
1685
|
${loaderImport}
|
|
@@ -1741,7 +1758,7 @@ sdk.init_tracing(disable_batch=True)
|
|
|
1741
1758
|
`;
|
|
1742
1759
|
const staticTracingInit = `
|
|
1743
1760
|
# Initialize tracing - traces will be sent to local dev server
|
|
1744
|
-
# Make sure to run "
|
|
1761
|
+
# Make sure to run "npx agentmark dev" in another terminal first
|
|
1745
1762
|
# To disable tracing, comment out sdk.init_tracing() below
|
|
1746
1763
|
sdk = AgentMarkSDK(
|
|
1747
1764
|
api_key="",
|
|
@@ -1754,49 +1771,40 @@ sdk.init_tracing(disable_batch=True)
|
|
|
1754
1771
|
if (adapter === "claude-agent-sdk") {
|
|
1755
1772
|
return `"""Example usage of AgentMark with Claude Agent SDK.
|
|
1756
1773
|
|
|
1757
|
-
Run with:
|
|
1774
|
+
Run with:
|
|
1775
|
+
npx agentmark build # compile party-planner.prompt.mdx -> dist/agentmark/*.json
|
|
1776
|
+
python main.py
|
|
1758
1777
|
"""
|
|
1759
1778
|
|
|
1760
1779
|
import asyncio
|
|
1761
|
-
import json
|
|
1762
1780
|
import os
|
|
1763
|
-
from pathlib import Path
|
|
1764
1781
|
|
|
1765
1782
|
from agentmark_sdk import AgentMarkSDK
|
|
1766
|
-
from
|
|
1783
|
+
from agentmark_claude_agent_sdk_v0 import traced_query
|
|
1767
1784
|
from agentmark_client import client
|
|
1768
1785
|
${tracingInit}
|
|
1769
1786
|
|
|
1770
1787
|
async def main():
|
|
1771
|
-
"""Run the party planner prompt."""
|
|
1772
|
-
#
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1788
|
+
"""Run the party planner prompt (object_config: extracts attendee names)."""
|
|
1789
|
+
# \`agentmark build\` writes pre-compiled prompts to dist/agentmark/.
|
|
1790
|
+
# The FileLoader reads them by name \u2014 extension is optional.
|
|
1791
|
+
try:
|
|
1792
|
+
prompt = await client.load_object_prompt("party-planner.prompt.mdx")
|
|
1793
|
+
except FileNotFoundError:
|
|
1794
|
+
print("Pre-built prompt not found. Run 'npx agentmark build' first.")
|
|
1777
1795
|
return
|
|
1778
1796
|
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
# Load and format the prompt
|
|
1783
|
-
prompt = await client.load_text_prompt(ast)
|
|
1784
|
-
params = await prompt.format(props={
|
|
1785
|
-
"numberOfGuests": 10,
|
|
1786
|
-
"theme": "80s disco",
|
|
1787
|
-
"dietaryRestrictions": ["vegetarian", "gluten-free"],
|
|
1797
|
+
adapted = await prompt.format(props={
|
|
1798
|
+
"party_text": "We're having a party with Alice, Bob, and Carol.",
|
|
1788
1799
|
})
|
|
1789
1800
|
|
|
1790
|
-
# Execute
|
|
1801
|
+
# Execute via Claude Agent SDK (streamed) with automatic OTEL tracing.
|
|
1802
|
+
# adapted.query.options.output_format is set to the object schema.
|
|
1791
1803
|
print("Running party planner prompt...")
|
|
1792
|
-
result = await run_text_prompt(params)
|
|
1793
|
-
|
|
1794
|
-
print("\\n" + "=" * 50)
|
|
1795
|
-
print("Party Plan:")
|
|
1796
1804
|
print("=" * 50)
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
print(
|
|
1805
|
+
async for message in traced_query(adapted):
|
|
1806
|
+
print(message)
|
|
1807
|
+
print("=" * 50)
|
|
1800
1808
|
|
|
1801
1809
|
|
|
1802
1810
|
if __name__ == "__main__":
|
|
@@ -1805,47 +1813,44 @@ if __name__ == "__main__":
|
|
|
1805
1813
|
}
|
|
1806
1814
|
return `"""Example usage of AgentMark with Pydantic AI.
|
|
1807
1815
|
|
|
1808
|
-
Run with:
|
|
1816
|
+
Run with:
|
|
1817
|
+
npx agentmark build # compile party-planner.prompt.mdx -> dist/agentmark/*.json
|
|
1818
|
+
python main.py
|
|
1809
1819
|
"""
|
|
1820
|
+
# To use a different LLM provider, install: pip install "pydantic-ai-slim[anthropic]" (or [google], [bedrock], etc.)
|
|
1810
1821
|
|
|
1811
1822
|
import asyncio
|
|
1812
|
-
import json
|
|
1813
1823
|
import os
|
|
1814
|
-
from pathlib import Path
|
|
1815
1824
|
|
|
1816
1825
|
from agentmark_sdk import AgentMarkSDK
|
|
1817
|
-
from agentmark_pydantic_ai_v0 import
|
|
1826
|
+
from agentmark_pydantic_ai_v0 import run_object_prompt
|
|
1818
1827
|
from agentmark_client import client
|
|
1819
1828
|
${tracingInit}
|
|
1820
1829
|
|
|
1821
1830
|
async def main():
|
|
1822
|
-
"""Run the party planner prompt."""
|
|
1823
|
-
#
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1831
|
+
"""Run the party planner prompt (object_config: extracts attendee names)."""
|
|
1832
|
+
# \`agentmark build\` writes pre-compiled prompts to dist/agentmark/.
|
|
1833
|
+
# The FileLoader reads them by name \u2014 extension is optional, and it
|
|
1834
|
+
# extracts the inner AST from the { ast, metadata } wrapper for you.
|
|
1835
|
+
try:
|
|
1836
|
+
prompt = await client.load_object_prompt("party-planner.prompt.mdx")
|
|
1837
|
+
except FileNotFoundError:
|
|
1838
|
+
print("Pre-built prompt not found. Run 'npx agentmark build' first.")
|
|
1828
1839
|
return
|
|
1829
1840
|
|
|
1830
|
-
with open(prompt_path) as f:
|
|
1831
|
-
ast = json.load(f)
|
|
1832
|
-
|
|
1833
|
-
# Load and format the prompt
|
|
1834
|
-
prompt = await client.load_text_prompt(ast)
|
|
1835
1841
|
params = await prompt.format(props={
|
|
1836
|
-
"
|
|
1837
|
-
"theme": "80s disco",
|
|
1838
|
-
"dietaryRestrictions": ["vegetarian", "gluten-free"],
|
|
1842
|
+
"party_text": "We're having a party with Alice, Bob, and Carol.",
|
|
1839
1843
|
})
|
|
1840
1844
|
|
|
1841
1845
|
# Execute the prompt
|
|
1842
1846
|
print("Running party planner prompt...")
|
|
1843
|
-
result = await
|
|
1847
|
+
result = await run_object_prompt(params)
|
|
1844
1848
|
|
|
1845
1849
|
print("\\n" + "=" * 50)
|
|
1846
|
-
print("
|
|
1850
|
+
print("Extracted attendees:")
|
|
1847
1851
|
print("=" * 50)
|
|
1848
|
-
|
|
1852
|
+
# result.output is a Pydantic model instance with the schema's fields
|
|
1853
|
+
print(result.output.names)
|
|
1849
1854
|
print("\\n" + "-" * 50)
|
|
1850
1855
|
print(f"Tokens used: {result.usage.total_tokens}")
|
|
1851
1856
|
|
|
@@ -1855,10 +1860,10 @@ if __name__ == "__main__":
|
|
|
1855
1860
|
`;
|
|
1856
1861
|
};
|
|
1857
1862
|
var getDevServerContent = (adapter) => {
|
|
1858
|
-
const adapterPackage = adapter === "claude-agent-sdk" ? "
|
|
1863
|
+
const adapterPackage = adapter === "claude-agent-sdk" ? "agentmark_claude_agent_sdk_v0" : "agentmark_pydantic_ai_v0";
|
|
1859
1864
|
return `"""Auto-generated webhook server for AgentMark development.
|
|
1860
1865
|
|
|
1861
|
-
This server is started by '
|
|
1866
|
+
This server is started by 'npx agentmark dev' (agentmark dev) and handles
|
|
1862
1867
|
prompt execution requests from the CLI.
|
|
1863
1868
|
"""
|
|
1864
1869
|
|
|
@@ -1898,6 +1903,62 @@ OPENAI_API_KEY=${apiKey}
|
|
|
1898
1903
|
# GOOGLE_API_KEY=your-key-here
|
|
1899
1904
|
`;
|
|
1900
1905
|
};
|
|
1906
|
+
var getReadmeContent = (projectName, adapter) => {
|
|
1907
|
+
const adapterName = adapter === "claude-agent-sdk" ? "Claude Agent SDK" : "Pydantic AI";
|
|
1908
|
+
const apiKeyEnvVar = adapter === "claude-agent-sdk" ? "ANTHROPIC_API_KEY" : "OPENAI_API_KEY";
|
|
1909
|
+
const directInstallCmd = adapter === "claude-agent-sdk" ? "pip install agentmark-sdk agentmark-claude-agent-sdk-v0 agentmark-prompt-core python-dotenv claude-agent-sdk" : 'pip install agentmark-sdk agentmark-pydantic-ai-v0 agentmark-prompt-core python-dotenv "pydantic-ai-slim[openai]>=1.0,<2.0"';
|
|
1910
|
+
return `# ${projectName}
|
|
1911
|
+
|
|
1912
|
+
An AgentMark application using ${adapterName}.
|
|
1913
|
+
|
|
1914
|
+
## Prerequisites
|
|
1915
|
+
|
|
1916
|
+
- Python 3.12+
|
|
1917
|
+
- **pip 26.1+** (older pip versions fail to resolve the dependency graph \u2014 see "Why pip 26.1?" below)
|
|
1918
|
+
|
|
1919
|
+
## Setup
|
|
1920
|
+
|
|
1921
|
+
\`\`\`bash
|
|
1922
|
+
# 1. Create and activate a virtual environment
|
|
1923
|
+
python -m venv .venv
|
|
1924
|
+
source .venv/bin/activate # On Windows: .venv\\Scripts\\activate
|
|
1925
|
+
|
|
1926
|
+
# 2. Upgrade pip (REQUIRED \u2014 older pip cannot resolve pydantic-ai's transitive graph)
|
|
1927
|
+
python -m pip install --upgrade "pip>=26.1"
|
|
1928
|
+
|
|
1929
|
+
# 3. Install dependencies
|
|
1930
|
+
${directInstallCmd}
|
|
1931
|
+
|
|
1932
|
+
# 4. Set your API key
|
|
1933
|
+
echo "${apiKeyEnvVar}=your-key-here" > .env
|
|
1934
|
+
\`\`\`
|
|
1935
|
+
|
|
1936
|
+
## Run
|
|
1937
|
+
|
|
1938
|
+
\`\`\`bash
|
|
1939
|
+
# Start the AgentMark dev server (in another terminal)
|
|
1940
|
+
npx agentmark dev
|
|
1941
|
+
|
|
1942
|
+
# Run the example prompt
|
|
1943
|
+
python main.py
|
|
1944
|
+
\`\`\`
|
|
1945
|
+
|
|
1946
|
+
Then open [http://localhost:9418](http://localhost:9418) to view your traces.
|
|
1947
|
+
|
|
1948
|
+
## Why pip 26.1?
|
|
1949
|
+
|
|
1950
|
+
The \`pydantic-ai-slim\` package transitively depends on \`mcp\`, \`fastmcp\`, and
|
|
1951
|
+
\`logfire\`, which together produce a deep dependency graph. Pip versions before
|
|
1952
|
+
26.1 fall into long backtracking loops and abort with \`resolution-too-deep\`.
|
|
1953
|
+
Pip 26.1's resolver handles this graph efficiently. If you skip the upgrade and
|
|
1954
|
+
hit the error, run \`python -m pip install --upgrade pip\` and retry.
|
|
1955
|
+
|
|
1956
|
+
## Resources
|
|
1957
|
+
|
|
1958
|
+
- [Documentation](https://docs.agentmark.co)
|
|
1959
|
+
- [GitHub](https://github.com/agentmark-ai/agentmark)
|
|
1960
|
+
`;
|
|
1961
|
+
};
|
|
1901
1962
|
var getGitignoreContent = () => {
|
|
1902
1963
|
return `# Python
|
|
1903
1964
|
__pycache__/
|
|
@@ -1944,7 +2005,7 @@ var createPythonApp = async (client, targetPath = ".", apiKey = "", deploymentMo
|
|
|
1944
2005
|
console.log(`Example prompts and datasets created in ${folderName}/agentmark/`);
|
|
1945
2006
|
if (!isExistingProject) {
|
|
1946
2007
|
const projectName = path3.basename(targetPath).replace(/[^a-zA-Z0-9_-]/g, "-");
|
|
1947
|
-
fs5.writeFileSync(`${targetPath}/pyproject.toml`, getPyprojectContent(projectName, adapter));
|
|
2008
|
+
fs5.writeFileSync(`${targetPath}/pyproject.toml`, getPyprojectContent(projectName, adapter, deploymentMode));
|
|
1948
2009
|
} else {
|
|
1949
2010
|
console.log("\u23ED\uFE0F Skipped pyproject.toml (existing project)");
|
|
1950
2011
|
}
|
|
@@ -2011,6 +2072,14 @@ var createPythonApp = async (client, targetPath = ".", apiKey = "", deploymentMo
|
|
|
2011
2072
|
} else {
|
|
2012
2073
|
fs5.writeFileSync(`${targetPath}/.gitignore`, getGitignoreContent());
|
|
2013
2074
|
}
|
|
2075
|
+
if (!isExistingProject) {
|
|
2076
|
+
const readmePath = path3.join(targetPath, "README.md");
|
|
2077
|
+
if (!fs5.existsSync(readmePath)) {
|
|
2078
|
+
const projectName = path3.basename(targetPath).replace(/[^a-zA-Z0-9_-]/g, "-");
|
|
2079
|
+
fs5.writeFileSync(readmePath, getReadmeContent(projectName, adapter));
|
|
2080
|
+
console.log(`\u2705 Created README.md`);
|
|
2081
|
+
}
|
|
2082
|
+
}
|
|
2014
2083
|
const agentmarkInternalDir = path3.join(targetPath, ".agentmark");
|
|
2015
2084
|
fs5.ensureDirSync(agentmarkInternalDir);
|
|
2016
2085
|
fs5.writeFileSync(path3.join(agentmarkInternalDir, "dev_server.py"), getDevServerContent(adapter));
|
|
@@ -2043,16 +2112,20 @@ var createPythonApp = async (client, targetPath = ".", apiKey = "", deploymentMo
|
|
|
2043
2112
|
if (folderName !== "." && folderName !== "./" && !isExistingProject) {
|
|
2044
2113
|
console.log(` $ cd ${folderName}`);
|
|
2045
2114
|
}
|
|
2115
|
+
const pipInstallCmd = adapter === "claude-agent-sdk" ? " $ pip install agentmark-sdk agentmark-claude-agent-sdk-v0 agentmark-prompt-core python-dotenv claude-agent-sdk" : ' $ pip install agentmark-sdk agentmark-pydantic-ai-v0 agentmark-prompt-core python-dotenv "pydantic-ai-slim[openai]>=1.0,<2.0"';
|
|
2116
|
+
const pipUpgradeCmd = ' $ python -m pip install --upgrade "pip>=26.1"';
|
|
2046
2117
|
if (pythonVenv) {
|
|
2047
2118
|
const activateCmd = process.platform === "win32" ? `${pythonVenv.name}\\Scripts\\activate` : `source ${pythonVenv.name}/bin/activate`;
|
|
2048
2119
|
console.log(` $ ${activateCmd}`);
|
|
2049
|
-
console.log(
|
|
2120
|
+
console.log(pipUpgradeCmd);
|
|
2121
|
+
console.log(pipInstallCmd);
|
|
2050
2122
|
} else {
|
|
2051
2123
|
console.log(" $ python -m venv .venv");
|
|
2052
2124
|
console.log(" $ source .venv/bin/activate # On Windows: .venv\\Scripts\\activate");
|
|
2053
|
-
console.log(
|
|
2125
|
+
console.log(pipUpgradeCmd);
|
|
2126
|
+
console.log(pipInstallCmd);
|
|
2054
2127
|
}
|
|
2055
|
-
console.log(" $
|
|
2128
|
+
console.log(" $ npx agentmark dev\n");
|
|
2056
2129
|
console.log("\u2500".repeat(70));
|
|
2057
2130
|
console.log("Resources");
|
|
2058
2131
|
console.log("\u2500".repeat(70));
|