create-agentmark 0.10.5 → 0.10.6
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),
|
|
@@ -1601,7 +1621,7 @@ from dotenv import load_dotenv
|
|
|
1601
1621
|
|
|
1602
1622
|
${loaderImport}
|
|
1603
1623
|
from agentmark.prompt_core import EvalRegistry
|
|
1604
|
-
from
|
|
1624
|
+
from agentmark_claude_agent_sdk_v0 import (
|
|
1605
1625
|
create_claude_agent_client,
|
|
1606
1626
|
ClaudeAgentModelRegistry,
|
|
1607
1627
|
)
|
|
@@ -1741,7 +1761,7 @@ sdk.init_tracing(disable_batch=True)
|
|
|
1741
1761
|
`;
|
|
1742
1762
|
const staticTracingInit = `
|
|
1743
1763
|
# Initialize tracing - traces will be sent to local dev server
|
|
1744
|
-
# Make sure to run "
|
|
1764
|
+
# Make sure to run "npx agentmark dev" in another terminal first
|
|
1745
1765
|
# To disable tracing, comment out sdk.init_tracing() below
|
|
1746
1766
|
sdk = AgentMarkSDK(
|
|
1747
1767
|
api_key="",
|
|
@@ -1754,49 +1774,40 @@ sdk.init_tracing(disable_batch=True)
|
|
|
1754
1774
|
if (adapter === "claude-agent-sdk") {
|
|
1755
1775
|
return `"""Example usage of AgentMark with Claude Agent SDK.
|
|
1756
1776
|
|
|
1757
|
-
Run with:
|
|
1777
|
+
Run with:
|
|
1778
|
+
npx agentmark build # compile party-planner.prompt.mdx -> dist/agentmark/*.json
|
|
1779
|
+
python main.py
|
|
1758
1780
|
"""
|
|
1759
1781
|
|
|
1760
1782
|
import asyncio
|
|
1761
|
-
import json
|
|
1762
1783
|
import os
|
|
1763
|
-
from pathlib import Path
|
|
1764
1784
|
|
|
1765
1785
|
from agentmark_sdk import AgentMarkSDK
|
|
1766
|
-
from
|
|
1786
|
+
from agentmark_claude_agent_sdk_v0 import traced_query
|
|
1767
1787
|
from agentmark_client import client
|
|
1768
1788
|
${tracingInit}
|
|
1769
1789
|
|
|
1770
1790
|
async def main():
|
|
1771
|
-
"""Run the party planner prompt."""
|
|
1772
|
-
#
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1791
|
+
"""Run the party planner prompt (object_config: extracts attendee names)."""
|
|
1792
|
+
# \`agentmark build\` writes pre-compiled prompts to dist/agentmark/.
|
|
1793
|
+
# The FileLoader reads them by name \u2014 extension is optional.
|
|
1794
|
+
try:
|
|
1795
|
+
prompt = await client.load_object_prompt("party-planner.prompt.mdx")
|
|
1796
|
+
except FileNotFoundError:
|
|
1797
|
+
print("Pre-built prompt not found. Run 'npx agentmark build' first.")
|
|
1777
1798
|
return
|
|
1778
1799
|
|
|
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"],
|
|
1800
|
+
adapted = await prompt.format(props={
|
|
1801
|
+
"party_text": "We're having a party with Alice, Bob, and Carol.",
|
|
1788
1802
|
})
|
|
1789
1803
|
|
|
1790
|
-
# Execute
|
|
1804
|
+
# Execute via Claude Agent SDK (streamed) with automatic OTEL tracing.
|
|
1805
|
+
# adapted.query.options.output_format is set to the object schema.
|
|
1791
1806
|
print("Running party planner prompt...")
|
|
1792
|
-
result = await run_text_prompt(params)
|
|
1793
|
-
|
|
1794
|
-
print("\\n" + "=" * 50)
|
|
1795
|
-
print("Party Plan:")
|
|
1796
1807
|
print("=" * 50)
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
print(
|
|
1808
|
+
async for message in traced_query(adapted):
|
|
1809
|
+
print(message)
|
|
1810
|
+
print("=" * 50)
|
|
1800
1811
|
|
|
1801
1812
|
|
|
1802
1813
|
if __name__ == "__main__":
|
|
@@ -1805,47 +1816,44 @@ if __name__ == "__main__":
|
|
|
1805
1816
|
}
|
|
1806
1817
|
return `"""Example usage of AgentMark with Pydantic AI.
|
|
1807
1818
|
|
|
1808
|
-
Run with:
|
|
1819
|
+
Run with:
|
|
1820
|
+
npx agentmark build # compile party-planner.prompt.mdx -> dist/agentmark/*.json
|
|
1821
|
+
python main.py
|
|
1809
1822
|
"""
|
|
1823
|
+
# To use a different LLM provider, install: pip install "pydantic-ai-slim[anthropic]" (or [google], [bedrock], etc.)
|
|
1810
1824
|
|
|
1811
1825
|
import asyncio
|
|
1812
|
-
import json
|
|
1813
1826
|
import os
|
|
1814
|
-
from pathlib import Path
|
|
1815
1827
|
|
|
1816
1828
|
from agentmark_sdk import AgentMarkSDK
|
|
1817
|
-
from agentmark_pydantic_ai_v0 import
|
|
1829
|
+
from agentmark_pydantic_ai_v0 import run_object_prompt
|
|
1818
1830
|
from agentmark_client import client
|
|
1819
1831
|
${tracingInit}
|
|
1820
1832
|
|
|
1821
1833
|
async def main():
|
|
1822
|
-
"""Run the party planner prompt."""
|
|
1823
|
-
#
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1834
|
+
"""Run the party planner prompt (object_config: extracts attendee names)."""
|
|
1835
|
+
# \`agentmark build\` writes pre-compiled prompts to dist/agentmark/.
|
|
1836
|
+
# The FileLoader reads them by name \u2014 extension is optional, and it
|
|
1837
|
+
# extracts the inner AST from the { ast, metadata } wrapper for you.
|
|
1838
|
+
try:
|
|
1839
|
+
prompt = await client.load_object_prompt("party-planner.prompt.mdx")
|
|
1840
|
+
except FileNotFoundError:
|
|
1841
|
+
print("Pre-built prompt not found. Run 'npx agentmark build' first.")
|
|
1828
1842
|
return
|
|
1829
1843
|
|
|
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
1844
|
params = await prompt.format(props={
|
|
1836
|
-
"
|
|
1837
|
-
"theme": "80s disco",
|
|
1838
|
-
"dietaryRestrictions": ["vegetarian", "gluten-free"],
|
|
1845
|
+
"party_text": "We're having a party with Alice, Bob, and Carol.",
|
|
1839
1846
|
})
|
|
1840
1847
|
|
|
1841
1848
|
# Execute the prompt
|
|
1842
1849
|
print("Running party planner prompt...")
|
|
1843
|
-
result = await
|
|
1850
|
+
result = await run_object_prompt(params)
|
|
1844
1851
|
|
|
1845
1852
|
print("\\n" + "=" * 50)
|
|
1846
|
-
print("
|
|
1853
|
+
print("Extracted attendees:")
|
|
1847
1854
|
print("=" * 50)
|
|
1848
|
-
|
|
1855
|
+
# result.output is a Pydantic model instance with the schema's fields
|
|
1856
|
+
print(result.output.names)
|
|
1849
1857
|
print("\\n" + "-" * 50)
|
|
1850
1858
|
print(f"Tokens used: {result.usage.total_tokens}")
|
|
1851
1859
|
|
|
@@ -1855,10 +1863,10 @@ if __name__ == "__main__":
|
|
|
1855
1863
|
`;
|
|
1856
1864
|
};
|
|
1857
1865
|
var getDevServerContent = (adapter) => {
|
|
1858
|
-
const adapterPackage = adapter === "claude-agent-sdk" ? "
|
|
1866
|
+
const adapterPackage = adapter === "claude-agent-sdk" ? "agentmark_claude_agent_sdk_v0" : "agentmark_pydantic_ai_v0";
|
|
1859
1867
|
return `"""Auto-generated webhook server for AgentMark development.
|
|
1860
1868
|
|
|
1861
|
-
This server is started by '
|
|
1869
|
+
This server is started by 'npx agentmark dev' (agentmark dev) and handles
|
|
1862
1870
|
prompt execution requests from the CLI.
|
|
1863
1871
|
"""
|
|
1864
1872
|
|
|
@@ -1898,6 +1906,62 @@ OPENAI_API_KEY=${apiKey}
|
|
|
1898
1906
|
# GOOGLE_API_KEY=your-key-here
|
|
1899
1907
|
`;
|
|
1900
1908
|
};
|
|
1909
|
+
var getReadmeContent = (projectName, adapter) => {
|
|
1910
|
+
const adapterName = adapter === "claude-agent-sdk" ? "Claude Agent SDK" : "Pydantic AI";
|
|
1911
|
+
const apiKeyEnvVar = adapter === "claude-agent-sdk" ? "ANTHROPIC_API_KEY" : "OPENAI_API_KEY";
|
|
1912
|
+
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"';
|
|
1913
|
+
return `# ${projectName}
|
|
1914
|
+
|
|
1915
|
+
An AgentMark application using ${adapterName}.
|
|
1916
|
+
|
|
1917
|
+
## Prerequisites
|
|
1918
|
+
|
|
1919
|
+
- Python 3.12+
|
|
1920
|
+
- **pip 26.1+** (older pip versions fail to resolve the dependency graph \u2014 see "Why pip 26.1?" below)
|
|
1921
|
+
|
|
1922
|
+
## Setup
|
|
1923
|
+
|
|
1924
|
+
\`\`\`bash
|
|
1925
|
+
# 1. Create and activate a virtual environment
|
|
1926
|
+
python -m venv .venv
|
|
1927
|
+
source .venv/bin/activate # On Windows: .venv\\Scripts\\activate
|
|
1928
|
+
|
|
1929
|
+
# 2. Upgrade pip (REQUIRED \u2014 older pip cannot resolve pydantic-ai's transitive graph)
|
|
1930
|
+
python -m pip install --upgrade "pip>=26.1"
|
|
1931
|
+
|
|
1932
|
+
# 3. Install dependencies
|
|
1933
|
+
${directInstallCmd}
|
|
1934
|
+
|
|
1935
|
+
# 4. Set your API key
|
|
1936
|
+
echo "${apiKeyEnvVar}=your-key-here" > .env
|
|
1937
|
+
\`\`\`
|
|
1938
|
+
|
|
1939
|
+
## Run
|
|
1940
|
+
|
|
1941
|
+
\`\`\`bash
|
|
1942
|
+
# Start the AgentMark dev server (in another terminal)
|
|
1943
|
+
npx agentmark dev
|
|
1944
|
+
|
|
1945
|
+
# Run the example prompt
|
|
1946
|
+
python main.py
|
|
1947
|
+
\`\`\`
|
|
1948
|
+
|
|
1949
|
+
Then open [http://localhost:9418](http://localhost:9418) to view your traces.
|
|
1950
|
+
|
|
1951
|
+
## Why pip 26.1?
|
|
1952
|
+
|
|
1953
|
+
The \`pydantic-ai-slim\` package transitively depends on \`mcp\`, \`fastmcp\`, and
|
|
1954
|
+
\`logfire\`, which together produce a deep dependency graph. Pip versions before
|
|
1955
|
+
26.1 fall into long backtracking loops and abort with \`resolution-too-deep\`.
|
|
1956
|
+
Pip 26.1's resolver handles this graph efficiently. If you skip the upgrade and
|
|
1957
|
+
hit the error, run \`python -m pip install --upgrade pip\` and retry.
|
|
1958
|
+
|
|
1959
|
+
## Resources
|
|
1960
|
+
|
|
1961
|
+
- [Documentation](https://docs.agentmark.co)
|
|
1962
|
+
- [GitHub](https://github.com/agentmark-ai/agentmark)
|
|
1963
|
+
`;
|
|
1964
|
+
};
|
|
1901
1965
|
var getGitignoreContent = () => {
|
|
1902
1966
|
return `# Python
|
|
1903
1967
|
__pycache__/
|
|
@@ -1944,7 +2008,7 @@ var createPythonApp = async (client, targetPath = ".", apiKey = "", deploymentMo
|
|
|
1944
2008
|
console.log(`Example prompts and datasets created in ${folderName}/agentmark/`);
|
|
1945
2009
|
if (!isExistingProject) {
|
|
1946
2010
|
const projectName = path3.basename(targetPath).replace(/[^a-zA-Z0-9_-]/g, "-");
|
|
1947
|
-
fs5.writeFileSync(`${targetPath}/pyproject.toml`, getPyprojectContent(projectName, adapter));
|
|
2011
|
+
fs5.writeFileSync(`${targetPath}/pyproject.toml`, getPyprojectContent(projectName, adapter, deploymentMode));
|
|
1948
2012
|
} else {
|
|
1949
2013
|
console.log("\u23ED\uFE0F Skipped pyproject.toml (existing project)");
|
|
1950
2014
|
}
|
|
@@ -2011,6 +2075,14 @@ var createPythonApp = async (client, targetPath = ".", apiKey = "", deploymentMo
|
|
|
2011
2075
|
} else {
|
|
2012
2076
|
fs5.writeFileSync(`${targetPath}/.gitignore`, getGitignoreContent());
|
|
2013
2077
|
}
|
|
2078
|
+
if (!isExistingProject) {
|
|
2079
|
+
const readmePath = path3.join(targetPath, "README.md");
|
|
2080
|
+
if (!fs5.existsSync(readmePath)) {
|
|
2081
|
+
const projectName = path3.basename(targetPath).replace(/[^a-zA-Z0-9_-]/g, "-");
|
|
2082
|
+
fs5.writeFileSync(readmePath, getReadmeContent(projectName, adapter));
|
|
2083
|
+
console.log(`\u2705 Created README.md`);
|
|
2084
|
+
}
|
|
2085
|
+
}
|
|
2014
2086
|
const agentmarkInternalDir = path3.join(targetPath, ".agentmark");
|
|
2015
2087
|
fs5.ensureDirSync(agentmarkInternalDir);
|
|
2016
2088
|
fs5.writeFileSync(path3.join(agentmarkInternalDir, "dev_server.py"), getDevServerContent(adapter));
|
|
@@ -2043,16 +2115,20 @@ var createPythonApp = async (client, targetPath = ".", apiKey = "", deploymentMo
|
|
|
2043
2115
|
if (folderName !== "." && folderName !== "./" && !isExistingProject) {
|
|
2044
2116
|
console.log(` $ cd ${folderName}`);
|
|
2045
2117
|
}
|
|
2118
|
+
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"';
|
|
2119
|
+
const pipUpgradeCmd = ' $ python -m pip install --upgrade "pip>=26.1"';
|
|
2046
2120
|
if (pythonVenv) {
|
|
2047
2121
|
const activateCmd = process.platform === "win32" ? `${pythonVenv.name}\\Scripts\\activate` : `source ${pythonVenv.name}/bin/activate`;
|
|
2048
2122
|
console.log(` $ ${activateCmd}`);
|
|
2049
|
-
console.log(
|
|
2123
|
+
console.log(pipUpgradeCmd);
|
|
2124
|
+
console.log(pipInstallCmd);
|
|
2050
2125
|
} else {
|
|
2051
2126
|
console.log(" $ python -m venv .venv");
|
|
2052
2127
|
console.log(" $ source .venv/bin/activate # On Windows: .venv\\Scripts\\activate");
|
|
2053
|
-
console.log(
|
|
2128
|
+
console.log(pipUpgradeCmd);
|
|
2129
|
+
console.log(pipInstallCmd);
|
|
2054
2130
|
}
|
|
2055
|
-
console.log(" $
|
|
2131
|
+
console.log(" $ npx agentmark dev\n");
|
|
2056
2132
|
console.log("\u2500".repeat(70));
|
|
2057
2133
|
console.log("Resources");
|
|
2058
2134
|
console.log("\u2500".repeat(70));
|