create-agentmark 0.10.1 → 0.10.2
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
|
@@ -34,7 +34,7 @@ var createAdapterConfig = (provider) => {
|
|
|
34
34
|
}
|
|
35
35
|
},
|
|
36
36
|
"claude-agent-sdk": {
|
|
37
|
-
package: "@agentmark-ai/claude-agent-sdk-adapter",
|
|
37
|
+
package: "@agentmark-ai/claude-agent-sdk-v0-adapter",
|
|
38
38
|
dependencies: ["@anthropic-ai/claude-agent-sdk@^0.1.0"],
|
|
39
39
|
classes: {
|
|
40
40
|
modelRegistry: "ClaudeAgentModelRegistry",
|
|
@@ -84,7 +84,7 @@ sdk.initTracing({ disableBatch: true });
|
|
|
84
84
|
if (adapter === "claude-agent-sdk") {
|
|
85
85
|
return `import "dotenv/config";
|
|
86
86
|
import { query } from "@anthropic-ai/claude-agent-sdk";
|
|
87
|
-
import { withTracing } from "@agentmark-ai/claude-agent-sdk-adapter";
|
|
87
|
+
import { withTracing } from "@agentmark-ai/claude-agent-sdk-v0-adapter";
|
|
88
88
|
${tracingImport}import { client } from "./agentmark.client";
|
|
89
89
|
${tracingInit}
|
|
90
90
|
const telemetry = {
|
|
@@ -641,7 +641,7 @@ object_config:
|
|
|
641
641
|
- names
|
|
642
642
|
test_settings:
|
|
643
643
|
dataset: party.jsonl
|
|
644
|
-
|
|
644
|
+
scores:
|
|
645
645
|
- exact_match_json
|
|
646
646
|
props:
|
|
647
647
|
party_text: "We're having a party with Alice, Bob, and Carol."
|
|
@@ -815,7 +815,7 @@ import type { ToolsInput } from '@mastra/core/agent';
|
|
|
815
815
|
import { z } from 'zod';` : `import { tool } from 'ai';
|
|
816
816
|
import type { Tool } from 'ai';
|
|
817
817
|
import { z } from 'zod';`;
|
|
818
|
-
const createClientCall = isClaudeAgentSdk ? `return createAgentMarkClient<AgentMarkTypes>({ loader, modelRegistry,
|
|
818
|
+
const createClientCall = isClaudeAgentSdk ? `return createAgentMarkClient<AgentMarkTypes>({ loader, modelRegistry, scores, adapterOptions, mcpServers: { 'customer-support': customerSupportTools } });` : `return createAgentMarkClient<AgentMarkTypes>({ loader, modelRegistry, tools, scores });`;
|
|
819
819
|
const toolSchemaField = isMastra ? `parameters: z.object({ query: z.string().describe('The search query') })` : `inputSchema: z.object({ query: z.string().describe('The search query') })`;
|
|
820
820
|
const toolsReturnType = isMastra ? "ToolsInput" : "Record<string, Tool>";
|
|
821
821
|
const toolsSetup = isClaudeAgentSdk ? `
|
|
@@ -868,7 +868,7 @@ import path from 'node:path';
|
|
|
868
868
|
import dotenv from 'dotenv';
|
|
869
869
|
dotenv.config({ path: path.resolve(__dirname, '.env') });
|
|
870
870
|
import { createAgentMarkClient, ${modelRegistry} } from "${adapterConfig.package}";
|
|
871
|
-
import type {
|
|
871
|
+
import type { ScoreRegistry } from "@agentmark-ai/prompt-core";
|
|
872
872
|
${loaderImport}
|
|
873
873
|
import AgentMarkTypes from './agentmark.types';
|
|
874
874
|
${providerImport}
|
|
@@ -878,22 +878,26 @@ ${adapterOptionsImport}
|
|
|
878
878
|
${modelRegistrySetup}
|
|
879
879
|
${toolsSetup}
|
|
880
880
|
|
|
881
|
-
const
|
|
882
|
-
exact_match_json:
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
}
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
881
|
+
const scores: ScoreRegistry = {
|
|
882
|
+
exact_match_json: {
|
|
883
|
+
schema: { type: 'boolean' },
|
|
884
|
+
description: 'Whether output matches expected JSON exactly',
|
|
885
|
+
eval: ({ output, expectedOutput }) => {
|
|
886
|
+
if (!expectedOutput) {
|
|
887
|
+
return { score: 0, label: 'error', reason: 'No expected output provided', passed: false };
|
|
888
|
+
}
|
|
889
|
+
try {
|
|
890
|
+
const ok = JSON.stringify(output) === JSON.stringify(JSON.parse(expectedOutput));
|
|
891
|
+
return {
|
|
892
|
+
score: ok ? 1 : 0,
|
|
893
|
+
label: ok ? 'correct' : 'incorrect',
|
|
894
|
+
reason: ok ? 'Exact match' : 'Mismatch',
|
|
895
|
+
passed: ok
|
|
896
|
+
};
|
|
897
|
+
} catch (e) {
|
|
898
|
+
return { score: 0, label: 'error', reason: 'Failed to parse expected output as JSON', passed: false };
|
|
899
|
+
}
|
|
900
|
+
},
|
|
897
901
|
},
|
|
898
902
|
};
|
|
899
903
|
|
|
@@ -1476,7 +1480,7 @@ description = "An AgentMark application using Claude Agent SDK"
|
|
|
1476
1480
|
requires-python = ">=3.12"
|
|
1477
1481
|
dependencies = [
|
|
1478
1482
|
"agentmark-sdk>=0.1.0",
|
|
1479
|
-
"agentmark-claude-agent-sdk>=0.1.0",
|
|
1483
|
+
"agentmark-claude-agent-sdk-v0>=0.1.0",
|
|
1480
1484
|
"agentmark-prompt-core>=0.1.0",
|
|
1481
1485
|
"python-dotenv>=1.0.0",
|
|
1482
1486
|
"claude-agent-sdk>=0.1.0",
|
|
@@ -1507,7 +1511,7 @@ description = "An AgentMark application using Pydantic AI"
|
|
|
1507
1511
|
requires-python = ">=3.12"
|
|
1508
1512
|
dependencies = [
|
|
1509
1513
|
"agentmark-sdk>=0.1.0",
|
|
1510
|
-
"agentmark-pydantic-ai>=0.1.0",
|
|
1514
|
+
"agentmark-pydantic-ai-v0>=0.1.0",
|
|
1511
1515
|
"agentmark-prompt-core>=0.1.0",
|
|
1512
1516
|
"python-dotenv>=1.0.0",
|
|
1513
1517
|
"pydantic-ai[openai]>=0.1.0",
|
|
@@ -1533,40 +1537,122 @@ asyncio_mode = "auto"
|
|
|
1533
1537
|
strict = true
|
|
1534
1538
|
`;
|
|
1535
1539
|
};
|
|
1536
|
-
var
|
|
1540
|
+
var getHandlerPyContent = (adapter) => {
|
|
1541
|
+
const webhookClass = adapter === "claude-agent-sdk" ? "ClaudeAgentSDKWebhookHandler" : "PydanticAIWebhookHandler";
|
|
1542
|
+
const webhookImport = adapter === "claude-agent-sdk" ? "from agentmark_claude_agent_sdk import ClaudeAgentSDKWebhookHandler" : "from agentmark_pydantic_ai_v0 import PydanticAIWebhookHandler";
|
|
1543
|
+
return `"""AgentMark handler for managed cloud deployments.
|
|
1544
|
+
|
|
1545
|
+
This file is used by the AgentMark platform to execute prompts and experiments
|
|
1546
|
+
on deployed infrastructure. It mirrors the TypeScript handler.ts pattern.
|
|
1547
|
+
"""
|
|
1548
|
+
|
|
1549
|
+
import os
|
|
1550
|
+
|
|
1551
|
+
from agentmark_sdk import AgentMarkSDK
|
|
1552
|
+
${webhookImport}
|
|
1553
|
+
from agentmark_client import client
|
|
1554
|
+
|
|
1555
|
+
# Initialize tracing
|
|
1556
|
+
sdk = AgentMarkSDK(
|
|
1557
|
+
api_key=os.environ.get("AGENTMARK_API_KEY", ""),
|
|
1558
|
+
app_id=os.environ.get("AGENTMARK_APP_ID", ""),
|
|
1559
|
+
base_url=os.environ.get("AGENTMARK_BASE_URL"),
|
|
1560
|
+
)
|
|
1561
|
+
sdk.init_tracing(disable_batch=True)
|
|
1562
|
+
|
|
1563
|
+
adapter = ${webhookClass}(client)
|
|
1564
|
+
|
|
1565
|
+
|
|
1566
|
+
async def handler(request: dict):
|
|
1567
|
+
"""Handle prompt-run and dataset-run requests from the platform."""
|
|
1568
|
+
req_type = request.get("type")
|
|
1569
|
+
data = request.get("data", {})
|
|
1570
|
+
|
|
1571
|
+
if req_type == "prompt-run":
|
|
1572
|
+
return await adapter.run_prompt(data["ast"], {
|
|
1573
|
+
"shouldStream": data.get("options", {}).get("shouldStream", True),
|
|
1574
|
+
"customProps": data.get("customProps"),
|
|
1575
|
+
})
|
|
1576
|
+
|
|
1577
|
+
if req_type == "dataset-run":
|
|
1578
|
+
return await adapter.run_experiment(
|
|
1579
|
+
data["ast"],
|
|
1580
|
+
data.get("experimentId", ""),
|
|
1581
|
+
data.get("datasetPath"),
|
|
1582
|
+
)
|
|
1583
|
+
|
|
1584
|
+
raise ValueError(f"Unknown request type: {req_type}")
|
|
1585
|
+
`;
|
|
1586
|
+
};
|
|
1587
|
+
var getAgentmarkClientContent = (deploymentMode, adapter) => {
|
|
1588
|
+
const isCloud = deploymentMode === "cloud";
|
|
1589
|
+
const loaderImport = isCloud ? `from agentmark.prompt_core import ApiLoader` : `from agentmark.prompt_core import FileLoader`;
|
|
1590
|
+
const loaderSetup = isCloud ? `# API loader for cloud deployment \u2014 fetches datasets from the AgentMark gateway
|
|
1591
|
+
loader = ApiLoader.cloud()` : `# File loader for local development
|
|
1592
|
+
project_root = Path(__file__).parent.resolve()
|
|
1593
|
+
loader = FileLoader(base_dir=str(project_root))`;
|
|
1537
1594
|
if (adapter === "claude-agent-sdk") {
|
|
1538
1595
|
return `"""AgentMark client configuration.
|
|
1539
1596
|
|
|
1540
1597
|
This file configures the AgentMark client with Claude Agent SDK adapter.
|
|
1541
|
-
Customize the model registry as needed.
|
|
1598
|
+
Customize the model registry and eval registry as needed.
|
|
1542
1599
|
"""
|
|
1543
1600
|
|
|
1601
|
+
import json
|
|
1544
1602
|
import os
|
|
1545
1603
|
from pathlib import Path
|
|
1546
1604
|
from dotenv import load_dotenv
|
|
1547
1605
|
|
|
1548
|
-
|
|
1606
|
+
${loaderImport}
|
|
1549
1607
|
from agentmark_claude_agent_sdk import (
|
|
1550
1608
|
create_claude_agent_client,
|
|
1551
|
-
|
|
1609
|
+
ClaudeAgentModelRegistry,
|
|
1552
1610
|
)
|
|
1553
1611
|
|
|
1554
1612
|
# Load environment variables
|
|
1555
1613
|
load_dotenv()
|
|
1556
1614
|
|
|
1557
|
-
#
|
|
1558
|
-
#
|
|
1559
|
-
model_registry =
|
|
1615
|
+
# Register the model providers your prompts use.
|
|
1616
|
+
# This maps "anthropic/claude-sonnet-4-20250514" in prompt files to the Claude Agent SDK.
|
|
1617
|
+
model_registry = ClaudeAgentModelRegistry()
|
|
1618
|
+
model_registry.register_providers({
|
|
1619
|
+
"anthropic": "anthropic",
|
|
1620
|
+
})
|
|
1621
|
+
|
|
1622
|
+
|
|
1623
|
+
# Eval registry \u2014 define evaluation functions for experiments
|
|
1624
|
+
# TODO: Update to use scores (ScoreRegistry) once the Python SDK supports it.
|
|
1625
|
+
# The TypeScript SDK already uses scores with schema definitions.
|
|
1626
|
+
def exact_match_json(params):
|
|
1627
|
+
"""Check if output matches expected output exactly."""
|
|
1628
|
+
output = params.get("output")
|
|
1629
|
+
expected_output = params.get("expectedOutput")
|
|
1630
|
+
if not expected_output:
|
|
1631
|
+
return {"score": 0, "label": "error", "reason": "No expected output provided", "passed": False}
|
|
1632
|
+
try:
|
|
1633
|
+
actual = json.loads(output) if isinstance(output, str) else output
|
|
1634
|
+
expected = json.loads(expected_output) if isinstance(expected_output, str) else expected_output
|
|
1635
|
+
ok = actual == expected
|
|
1636
|
+
return {
|
|
1637
|
+
"score": 1 if ok else 0,
|
|
1638
|
+
"label": "correct" if ok else "incorrect",
|
|
1639
|
+
"reason": "Exact match" if ok else "Mismatch",
|
|
1640
|
+
"passed": ok,
|
|
1641
|
+
}
|
|
1642
|
+
except (json.JSONDecodeError, TypeError):
|
|
1643
|
+
return {"score": 0, "label": "error", "reason": "Failed to parse JSON", "passed": False}
|
|
1560
1644
|
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1645
|
+
eval_registry = {
|
|
1646
|
+
"exact_match_json": exact_match_json,
|
|
1647
|
+
}
|
|
1648
|
+
|
|
1649
|
+
${loaderSetup}
|
|
1565
1650
|
|
|
1566
1651
|
# Create the client
|
|
1567
1652
|
# Claude Agent SDK handles tools natively through the SDK
|
|
1568
1653
|
client = create_claude_agent_client(
|
|
1569
1654
|
model_registry=model_registry,
|
|
1655
|
+
eval_registry=eval_registry,
|
|
1570
1656
|
loader=loader,
|
|
1571
1657
|
)
|
|
1572
1658
|
|
|
@@ -1576,25 +1662,30 @@ __all__ = ["client"]
|
|
|
1576
1662
|
return `"""AgentMark client configuration.
|
|
1577
1663
|
|
|
1578
1664
|
This file configures the AgentMark client with Pydantic AI adapter.
|
|
1579
|
-
Customize the model registry and
|
|
1665
|
+
Customize the model registry, tools, and eval registry as needed.
|
|
1580
1666
|
"""
|
|
1581
1667
|
|
|
1668
|
+
import json
|
|
1582
1669
|
import os
|
|
1583
1670
|
from pathlib import Path
|
|
1584
1671
|
from dotenv import load_dotenv
|
|
1585
1672
|
|
|
1586
|
-
|
|
1673
|
+
${loaderImport}
|
|
1587
1674
|
from agentmark_pydantic_ai_v0 import (
|
|
1588
1675
|
create_pydantic_ai_client,
|
|
1589
|
-
|
|
1676
|
+
PydanticAIModelRegistry,
|
|
1590
1677
|
)
|
|
1591
1678
|
|
|
1592
1679
|
# Load environment variables
|
|
1593
1680
|
load_dotenv()
|
|
1594
1681
|
|
|
1595
|
-
#
|
|
1596
|
-
#
|
|
1597
|
-
model_registry =
|
|
1682
|
+
# Register the model providers your prompts use.
|
|
1683
|
+
# This maps "openai/gpt-4o" in prompt files to "openai:gpt-4o" for Pydantic AI.
|
|
1684
|
+
model_registry = PydanticAIModelRegistry()
|
|
1685
|
+
model_registry.register_providers({
|
|
1686
|
+
"openai": "openai",
|
|
1687
|
+
"anthropic": "anthropic",
|
|
1688
|
+
})
|
|
1598
1689
|
|
|
1599
1690
|
# Define tools as native pydantic-ai Tool objects or callables
|
|
1600
1691
|
# Example:
|
|
@@ -1603,15 +1694,40 @@ model_registry = create_default_model_registry()
|
|
|
1603
1694
|
# tools = [search]
|
|
1604
1695
|
tools = []
|
|
1605
1696
|
|
|
1606
|
-
|
|
1607
|
-
#
|
|
1608
|
-
|
|
1609
|
-
|
|
1697
|
+
|
|
1698
|
+
# Eval registry \u2014 define evaluation functions for experiments
|
|
1699
|
+
# TODO: Update to use scores (ScoreRegistry) once the Python SDK supports it.
|
|
1700
|
+
# The TypeScript SDK already uses scores with schema definitions.
|
|
1701
|
+
def exact_match_json(params):
|
|
1702
|
+
"""Check if output matches expected output exactly."""
|
|
1703
|
+
output = params.get("output")
|
|
1704
|
+
expected_output = params.get("expectedOutput")
|
|
1705
|
+
if not expected_output:
|
|
1706
|
+
return {"score": 0, "label": "error", "reason": "No expected output provided", "passed": False}
|
|
1707
|
+
try:
|
|
1708
|
+
actual = json.loads(output) if isinstance(output, str) else output
|
|
1709
|
+
expected = json.loads(expected_output) if isinstance(expected_output, str) else expected_output
|
|
1710
|
+
ok = actual == expected
|
|
1711
|
+
return {
|
|
1712
|
+
"score": 1 if ok else 0,
|
|
1713
|
+
"label": "correct" if ok else "incorrect",
|
|
1714
|
+
"reason": "Exact match" if ok else "Mismatch",
|
|
1715
|
+
"passed": ok,
|
|
1716
|
+
}
|
|
1717
|
+
except (json.JSONDecodeError, TypeError):
|
|
1718
|
+
return {"score": 0, "label": "error", "reason": "Failed to parse JSON", "passed": False}
|
|
1719
|
+
|
|
1720
|
+
eval_registry = {
|
|
1721
|
+
"exact_match_json": exact_match_json,
|
|
1722
|
+
}
|
|
1723
|
+
|
|
1724
|
+
${loaderSetup}
|
|
1610
1725
|
|
|
1611
1726
|
# Create the client
|
|
1612
1727
|
client = create_pydantic_ai_client(
|
|
1613
1728
|
model_registry=model_registry,
|
|
1614
1729
|
tools=tools,
|
|
1730
|
+
eval_registry=eval_registry,
|
|
1615
1731
|
loader=loader,
|
|
1616
1732
|
)
|
|
1617
1733
|
|
|
@@ -1839,6 +1955,15 @@ var createPythonApp = async (client, targetPath = ".", apiKey = "", deploymentMo
|
|
|
1839
1955
|
console.log("\u23ED\uFE0F Skipped pyproject.toml (existing project)");
|
|
1840
1956
|
}
|
|
1841
1957
|
fs5.writeFileSync(`${targetPath}/agentmark_client.py`, getAgentmarkClientContent(deploymentMode, adapter));
|
|
1958
|
+
if (deploymentMode === "cloud") {
|
|
1959
|
+
const handlerPath = path3.join(targetPath, "handler.py");
|
|
1960
|
+
if (fs5.existsSync(handlerPath)) {
|
|
1961
|
+
console.log("\u23ED\uFE0F Skipped handler.py (already exists - preserving customizations)");
|
|
1962
|
+
} else {
|
|
1963
|
+
fs5.writeFileSync(handlerPath, getHandlerPyContent(adapter));
|
|
1964
|
+
console.log(`\u2705 Created handler.py for cloud deployment`);
|
|
1965
|
+
}
|
|
1966
|
+
}
|
|
1842
1967
|
if (!isExistingProject) {
|
|
1843
1968
|
fs5.writeFileSync(`${targetPath}/main.py`, getMainPyContent(adapter, deploymentMode));
|
|
1844
1969
|
} else {
|
|
@@ -1927,7 +2052,7 @@ var createPythonApp = async (client, targetPath = ".", apiKey = "", deploymentMo
|
|
|
1927
2052
|
if (pythonVenv) {
|
|
1928
2053
|
const activateCmd = process.platform === "win32" ? `${pythonVenv.name}\\Scripts\\activate` : `source ${pythonVenv.name}/bin/activate`;
|
|
1929
2054
|
console.log(` $ ${activateCmd}`);
|
|
1930
|
-
console.log(' $ pip install agentmark-pydantic-ai agentmark-prompt-core python-dotenv "pydantic-ai[openai]"');
|
|
2055
|
+
console.log(' $ pip install agentmark-pydantic-ai-v0 agentmark-prompt-core python-dotenv "pydantic-ai[openai]"');
|
|
1931
2056
|
} else {
|
|
1932
2057
|
console.log(" $ python -m venv .venv");
|
|
1933
2058
|
console.log(" $ source .venv/bin/activate # On Windows: .venv\\Scripts\\activate");
|
|
@@ -2089,22 +2214,45 @@ function initGitRepo(targetPath) {
|
|
|
2089
2214
|
}
|
|
2090
2215
|
|
|
2091
2216
|
// src/index.ts
|
|
2217
|
+
var VALID_ADAPTERS_TS = ["ai-sdk", "claude-agent-sdk", "mastra"];
|
|
2218
|
+
var VALID_ADAPTERS_PY = ["pydantic-ai", "claude-agent-sdk"];
|
|
2219
|
+
var VALID_CLIENTS = ["claude-code", "cursor", "vscode", "zed", "skip"];
|
|
2092
2220
|
var parseArgs = () => {
|
|
2093
2221
|
const args = process.argv.slice(2);
|
|
2094
|
-
|
|
2095
|
-
let
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2222
|
+
const result = {};
|
|
2223
|
+
for (let i = 0; i < args.length; i++) {
|
|
2224
|
+
const arg = args[i];
|
|
2225
|
+
switch (arg) {
|
|
2226
|
+
case "--cloud":
|
|
2227
|
+
result.deploymentMode = "cloud";
|
|
2228
|
+
break;
|
|
2229
|
+
case "--self-host":
|
|
2230
|
+
result.deploymentMode = "static";
|
|
2231
|
+
break;
|
|
2232
|
+
case "--python":
|
|
2233
|
+
result.language = "python";
|
|
2234
|
+
break;
|
|
2235
|
+
case "--typescript":
|
|
2236
|
+
result.language = "typescript";
|
|
2237
|
+
break;
|
|
2238
|
+
case "--overwrite":
|
|
2239
|
+
result.overwrite = true;
|
|
2240
|
+
break;
|
|
2241
|
+
case "--path":
|
|
2242
|
+
result.path = args[++i];
|
|
2243
|
+
break;
|
|
2244
|
+
case "--adapter":
|
|
2245
|
+
result.adapter = args[++i];
|
|
2246
|
+
break;
|
|
2247
|
+
case "--api-key":
|
|
2248
|
+
result.apiKey = args[++i];
|
|
2249
|
+
break;
|
|
2250
|
+
case "--client":
|
|
2251
|
+
result.client = args[++i];
|
|
2252
|
+
break;
|
|
2105
2253
|
}
|
|
2106
2254
|
}
|
|
2107
|
-
return
|
|
2255
|
+
return result;
|
|
2108
2256
|
};
|
|
2109
2257
|
var main = async () => {
|
|
2110
2258
|
const cliArgs = parseArgs();
|
|
@@ -2115,12 +2263,16 @@ var main = async () => {
|
|
|
2115
2263
|
agentmarkPath: "."
|
|
2116
2264
|
};
|
|
2117
2265
|
console.log("Initializing project.");
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2266
|
+
let folderName = cliArgs.path;
|
|
2267
|
+
if (!folderName) {
|
|
2268
|
+
const response = await prompts2({
|
|
2269
|
+
name: "folderName",
|
|
2270
|
+
type: "text",
|
|
2271
|
+
message: "Where would you like to create your AgentMark app?",
|
|
2272
|
+
initial: "my-agentmark-app"
|
|
2273
|
+
});
|
|
2274
|
+
folderName = response.folderName;
|
|
2275
|
+
}
|
|
2124
2276
|
const isCurrentDir = isCurrentDirectory(folderName);
|
|
2125
2277
|
const targetPath = isCurrentDir ? process.cwd() : path6.resolve(folderName);
|
|
2126
2278
|
if (!isCurrentDir) {
|
|
@@ -2130,7 +2282,15 @@ var main = async () => {
|
|
|
2130
2282
|
if (projectInfo.isExistingProject) {
|
|
2131
2283
|
displayProjectDetectionSummary(projectInfo);
|
|
2132
2284
|
}
|
|
2133
|
-
|
|
2285
|
+
let resolutions;
|
|
2286
|
+
if (cliArgs.overwrite) {
|
|
2287
|
+
resolutions = projectInfo.conflictingFiles.map((f) => ({
|
|
2288
|
+
path: f.path,
|
|
2289
|
+
action: "overwrite"
|
|
2290
|
+
}));
|
|
2291
|
+
} else {
|
|
2292
|
+
resolutions = await promptForResolutions(projectInfo.conflictingFiles);
|
|
2293
|
+
}
|
|
2134
2294
|
let language = cliArgs.language;
|
|
2135
2295
|
if (!language) {
|
|
2136
2296
|
const response = await prompts2({
|
|
@@ -2144,40 +2304,49 @@ var main = async () => {
|
|
|
2144
2304
|
});
|
|
2145
2305
|
language = response.language;
|
|
2146
2306
|
}
|
|
2147
|
-
let adapter;
|
|
2148
|
-
if (
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2307
|
+
let adapter = cliArgs.adapter;
|
|
2308
|
+
if (!adapter) {
|
|
2309
|
+
if (language === "python") {
|
|
2310
|
+
const response = await prompts2({
|
|
2311
|
+
name: "adapter",
|
|
2312
|
+
type: "select",
|
|
2313
|
+
message: "Which adapter would you like to use?",
|
|
2314
|
+
choices: [
|
|
2315
|
+
{ title: "Pydantic AI", value: "pydantic-ai" },
|
|
2316
|
+
{ title: "Claude Agent SDK", value: "claude-agent-sdk" }
|
|
2317
|
+
]
|
|
2318
|
+
});
|
|
2319
|
+
adapter = response.adapter;
|
|
2320
|
+
} else {
|
|
2321
|
+
const response = await prompts2({
|
|
2322
|
+
name: "adapter",
|
|
2323
|
+
type: "select",
|
|
2324
|
+
message: "Which adapter would you like to use?",
|
|
2325
|
+
choices: [
|
|
2326
|
+
{ title: "AI SDK (Vercel)", value: "ai-sdk" },
|
|
2327
|
+
{ title: "Claude Agent SDK", value: "claude-agent-sdk" },
|
|
2328
|
+
{ title: "Mastra", value: "mastra" }
|
|
2329
|
+
]
|
|
2330
|
+
});
|
|
2331
|
+
adapter = response.adapter;
|
|
2332
|
+
}
|
|
2333
|
+
}
|
|
2334
|
+
const validAdapters = language === "python" ? VALID_ADAPTERS_PY : VALID_ADAPTERS_TS;
|
|
2335
|
+
if (!validAdapters.includes(adapter)) {
|
|
2336
|
+
console.error(`Invalid adapter "${adapter}" for ${language}. Valid: ${validAdapters.join(", ")}`);
|
|
2337
|
+
process.exit(1);
|
|
2338
|
+
}
|
|
2339
|
+
let apiKey = cliArgs.apiKey ?? "";
|
|
2340
|
+
if (!cliArgs.apiKey && cliArgs.apiKey !== "") {
|
|
2341
|
+
const apiKeyName = adapter === "claude-agent-sdk" ? "Anthropic" : "OpenAI";
|
|
2342
|
+
const { providedApiKey } = await prompts2({
|
|
2343
|
+
name: "providedApiKey",
|
|
2344
|
+
type: "password",
|
|
2345
|
+
message: `Enter your ${apiKeyName} API key (or press Enter to skip):`,
|
|
2346
|
+
initial: ""
|
|
2169
2347
|
});
|
|
2170
|
-
|
|
2171
|
-
}
|
|
2172
|
-
const apiKeyName = adapter === "claude-agent-sdk" ? "Anthropic" : "OpenAI";
|
|
2173
|
-
let apiKey = "";
|
|
2174
|
-
const { providedApiKey } = await prompts2({
|
|
2175
|
-
name: "providedApiKey",
|
|
2176
|
-
type: "password",
|
|
2177
|
-
message: `Enter your ${apiKeyName} API key (or press Enter to skip):`,
|
|
2178
|
-
initial: ""
|
|
2179
|
-
});
|
|
2180
|
-
apiKey = providedApiKey || "";
|
|
2348
|
+
apiKey = providedApiKey || "";
|
|
2349
|
+
}
|
|
2181
2350
|
let deploymentMode = cliArgs.deploymentMode;
|
|
2182
2351
|
if (!deploymentMode) {
|
|
2183
2352
|
const response = await prompts2({
|
|
@@ -2199,18 +2368,26 @@ var main = async () => {
|
|
|
2199
2368
|
});
|
|
2200
2369
|
deploymentMode = response.deploymentMode;
|
|
2201
2370
|
}
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2371
|
+
let client = cliArgs.client;
|
|
2372
|
+
if (!client) {
|
|
2373
|
+
const response = await prompts2({
|
|
2374
|
+
name: "client",
|
|
2375
|
+
type: "select",
|
|
2376
|
+
message: "Make your IDE an AgentMark expert",
|
|
2377
|
+
choices: [
|
|
2378
|
+
{ title: "Claude Code", value: "claude-code" },
|
|
2379
|
+
{ title: "Cursor", value: "cursor" },
|
|
2380
|
+
{ title: "VS Code", value: "vscode" },
|
|
2381
|
+
{ title: "Zed", value: "zed" },
|
|
2382
|
+
{ title: "Skip", value: "skip" }
|
|
2383
|
+
]
|
|
2384
|
+
});
|
|
2385
|
+
client = response.client;
|
|
2386
|
+
}
|
|
2387
|
+
if (!VALID_CLIENTS.includes(client)) {
|
|
2388
|
+
console.error(`Invalid client "${client}". Valid: ${VALID_CLIENTS.join(", ")}`);
|
|
2389
|
+
process.exit(1);
|
|
2390
|
+
}
|
|
2214
2391
|
let usedModels;
|
|
2215
2392
|
if (language === "python") {
|
|
2216
2393
|
usedModels = await createPythonApp(client, targetPath, apiKey, deploymentMode, adapter, projectInfo, resolutions);
|
|
@@ -2219,7 +2396,7 @@ var main = async () => {
|
|
|
2219
2396
|
}
|
|
2220
2397
|
config.builtInModels = usedModels;
|
|
2221
2398
|
if (deploymentMode === "cloud") {
|
|
2222
|
-
config.handler = "handler.ts";
|
|
2399
|
+
config.handler = language === "python" ? "handler.py" : "handler.ts";
|
|
2223
2400
|
}
|
|
2224
2401
|
const agentmarkJsonPath = path6.join(targetPath, "agentmark.json");
|
|
2225
2402
|
const agentmarkJsonResolution = resolutions.find((r) => r.path === "agentmark.json");
|