create-agentmark 0.6.0 → 0.8.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.
@@ -22,6 +22,15 @@ var createAdapterConfig = (provider) => {
22
22
  toolRegistry: "MastraToolRegistry",
23
23
  webhookHandler: "MastraAdapterWebhookHandler"
24
24
  }
25
+ },
26
+ "claude-agent-sdk": {
27
+ package: "@agentmark-ai/claude-agent-sdk-adapter",
28
+ dependencies: ["@anthropic-ai/claude-agent-sdk@^0.1.0"],
29
+ classes: {
30
+ modelRegistry: "ClaudeAgentModelRegistry",
31
+ toolRegistry: "ClaudeAgentToolRegistry",
32
+ webhookHandler: "ClaudeAgentWebhookHandler"
33
+ }
25
34
  }
26
35
  };
27
36
  };
@@ -39,7 +48,61 @@ function getAdapterConfig(adapter, provider) {
39
48
 
40
49
  // src/utils/examples/templates/app-index.ts
41
50
  var getIndexFileContent = (adapter = "ai-sdk") => {
42
- if (adapter === "mastra") {
51
+ if (adapter === "claude-agent-sdk") {
52
+ return `import "dotenv/config";
53
+ import { query } from "@anthropic-ai/claude-agent-sdk";
54
+ import { withTracing } from "@agentmark-ai/claude-agent-sdk-adapter";
55
+ import { client } from "./agentmark.client";
56
+
57
+ const telemetry = {
58
+ isEnabled: true,
59
+ metadata: {
60
+ trace_name: "customer-support",
61
+ user_id: "user-123",
62
+ session_id: "session-123",
63
+ session_name: "my-first-session",
64
+ },
65
+ };
66
+
67
+ const runCustomerSupport = async (customer_message: string) => {
68
+ const prompt = await client.loadTextPrompt("customer-support-agent");
69
+ const adapted = await prompt.format({
70
+ props: {
71
+ customer_question: customer_message,
72
+ },
73
+ telemetry,
74
+ });
75
+
76
+ // Execute with Claude Agent SDK using withTracing for telemetry
77
+ // The adapted object contains { query, telemetry } ready for withTracing()
78
+ const tracedResult = await withTracing(query, adapted);
79
+
80
+ // traceId is available immediately
81
+ console.log("Trace ID:", tracedResult.traceId);
82
+
83
+ let result = "";
84
+ for await (const message of tracedResult) {
85
+ if (message.type === "result" && message.subtype === "success") {
86
+ result = message.result || "";
87
+ }
88
+ }
89
+
90
+ return result;
91
+ };
92
+
93
+ const main = async () => {
94
+ try {
95
+ const user_message = "How long does shipping take?";
96
+ const assistant = await runCustomerSupport(user_message);
97
+ console.log("Customer support response:", assistant);
98
+ } catch (error) {
99
+ console.error(error);
100
+ }
101
+ };
102
+
103
+ main();
104
+ `;
105
+ } else if (adapter === "mastra") {
43
106
  return `import "dotenv/config";
44
107
  import { Agent } from "@mastra/core/agent";
45
108
  import { client } from "./agentmark.client";
@@ -131,70 +194,207 @@ main();
131
194
  };
132
195
 
133
196
  // src/utils/examples/templates/env.ts
134
- var getEnvFileContent = (_modelProvider, apiKey = "") => {
197
+ var getEnvFileContent = (_modelProvider, apiKey = "", adapter = "ai-sdk") => {
135
198
  const apiKeyValue = apiKey || "your_api_key_here";
199
+ const apiKeyName = adapter === "claude-agent-sdk" ? "ANTHROPIC_API_KEY" : "OPENAI_API_KEY";
136
200
  return `# Cloud deployment: Set these environment variables
137
201
  # AGENTMARK_BASE_URL=https://api.agentmark.co
138
202
  # AGENTMARK_API_KEY=your_agentmark_api_key
139
203
  # AGENTMARK_APP_ID=your_agentmark_app_id
140
204
  # Learn more: https://docs.agentmark.co/platform/getting_started/quickstart
141
205
 
142
- OPENAI_API_KEY=${apiKeyValue}
206
+ ${apiKeyName}=${apiKeyValue}
143
207
  `;
144
208
  };
145
209
 
146
210
  // src/utils/examples/templates/package-setup.ts
211
+ import fs2 from "fs-extra";
212
+ import { execSync } from "child_process";
213
+
214
+ // src/utils/file-merge.ts
147
215
  import fs from "fs-extra";
148
- import { execSync, execFileSync } from "child_process";
149
- var setupPackageJson = (targetPath = ".", deploymentMode = "cloud") => {
216
+ import path from "path";
217
+ function mergePackageJson(targetPath, agentmarkDeps, agentmarkDevDeps, agentmarkScripts) {
218
+ const packageJsonPath = path.join(targetPath, "package.json");
219
+ const result = {
220
+ success: false,
221
+ warnings: [],
222
+ added: [],
223
+ skipped: []
224
+ };
225
+ try {
226
+ if (!fs.existsSync(packageJsonPath)) {
227
+ result.warnings.push("No existing package.json found");
228
+ return result;
229
+ }
230
+ const existing = fs.readJsonSync(packageJsonPath);
231
+ if (!existing.dependencies) {
232
+ existing.dependencies = {};
233
+ }
234
+ if (!existing.devDependencies) {
235
+ existing.devDependencies = {};
236
+ }
237
+ if (!existing.scripts) {
238
+ existing.scripts = {};
239
+ }
240
+ const deps = existing.dependencies;
241
+ const devDeps = existing.devDependencies;
242
+ const scripts = existing.scripts;
243
+ for (const [pkg, version] of Object.entries(agentmarkDeps)) {
244
+ if (deps[pkg]) {
245
+ result.skipped.push(`dependency: ${pkg} (already exists)`);
246
+ } else {
247
+ deps[pkg] = version;
248
+ result.added.push(`dependency: ${pkg}@${version}`);
249
+ }
250
+ }
251
+ for (const [pkg, version] of Object.entries(agentmarkDevDeps)) {
252
+ if (devDeps[pkg]) {
253
+ result.skipped.push(`devDependency: ${pkg} (already exists)`);
254
+ } else {
255
+ devDeps[pkg] = version;
256
+ result.added.push(`devDependency: ${pkg}@${version}`);
257
+ }
258
+ }
259
+ for (const [scriptName, scriptCmd] of Object.entries(agentmarkScripts)) {
260
+ if (scripts[scriptName]) {
261
+ const namespacedName = `agentmark:${scriptName}`;
262
+ if (scripts[namespacedName]) {
263
+ result.skipped.push(`script: ${scriptName}`);
264
+ result.warnings.push(
265
+ `Script "${scriptName}" and "${namespacedName}" both already exist. Skipping.`
266
+ );
267
+ } else {
268
+ scripts[namespacedName] = scriptCmd;
269
+ result.added.push(`script: ${namespacedName} (namespaced due to conflict)`);
270
+ result.warnings.push(
271
+ `Script "${scriptName}" already exists. Added as "${namespacedName}" instead.`
272
+ );
273
+ }
274
+ } else {
275
+ scripts[scriptName] = scriptCmd;
276
+ result.added.push(`script: ${scriptName}`);
277
+ }
278
+ }
279
+ fs.writeJsonSync(packageJsonPath, existing, { spaces: 2 });
280
+ result.success = true;
281
+ result.content = JSON.stringify(existing, null, 2);
282
+ return result;
283
+ } catch (error) {
284
+ result.warnings.push(`Error merging package.json: ${error}`);
285
+ return result;
286
+ }
287
+ }
288
+
289
+ // src/utils/types.ts
290
+ var PACKAGE_MANAGERS = {
291
+ "yarn.lock": {
292
+ name: "yarn",
293
+ lockFile: "yarn.lock",
294
+ installCmd: "yarn install",
295
+ addCmd: "yarn add",
296
+ addDevCmd: "yarn add --dev",
297
+ runCmd: "yarn"
298
+ },
299
+ "pnpm-lock.yaml": {
300
+ name: "pnpm",
301
+ lockFile: "pnpm-lock.yaml",
302
+ installCmd: "pnpm install",
303
+ addCmd: "pnpm add",
304
+ addDevCmd: "pnpm add --save-dev",
305
+ runCmd: "pnpm"
306
+ },
307
+ "bun.lockb": {
308
+ name: "bun",
309
+ lockFile: "bun.lockb",
310
+ installCmd: "bun install",
311
+ addCmd: "bun add",
312
+ addDevCmd: "bun add --dev",
313
+ runCmd: "bun run"
314
+ },
315
+ "package-lock.json": {
316
+ name: "npm",
317
+ lockFile: "package-lock.json",
318
+ installCmd: "npm install",
319
+ addCmd: "npm install",
320
+ addDevCmd: "npm install --save-dev",
321
+ runCmd: "npm run"
322
+ }
323
+ };
324
+ var DEFAULT_PACKAGE_MANAGER = PACKAGE_MANAGERS["package-lock.json"];
325
+
326
+ // src/utils/examples/templates/package-setup.ts
327
+ var setupPackageJson = (targetPath = ".", deploymentMode = "cloud", projectInfo = null) => {
150
328
  const packageJsonPath = `${targetPath}/package.json`;
151
- if (!fs.existsSync(packageJsonPath)) {
329
+ const isExistingProject = projectInfo?.isExistingProject ?? false;
330
+ if (!fs2.existsSync(packageJsonPath)) {
152
331
  console.log("Creating package.json...");
153
332
  execSync("npm init -y", { cwd: targetPath });
154
333
  }
155
- const pkgJson = fs.readJsonSync(packageJsonPath);
156
- pkgJson.name = pkgJson.name === "test" || !pkgJson.name ? "agentmark-example-app" : pkgJson.name;
157
- pkgJson.description = pkgJson.description || "A simple Node.js app using the Agentmark SDK";
158
- const devScript = "agentmark dev";
159
- const scripts = {
160
- ...pkgJson.scripts,
161
- "demo": "npx tsx index.ts",
162
- "dev": devScript,
163
- "prompt": "agentmark run-prompt",
164
- "experiment": "agentmark run-experiment"
165
- };
166
- if (deploymentMode === "static") {
167
- scripts["build"] = "agentmark build --out dist/agentmark";
334
+ if (isExistingProject && fs2.existsSync(packageJsonPath)) {
335
+ const scriptsToAdd = {
336
+ "demo": "npx tsx index.ts",
337
+ "dev": "agentmark dev",
338
+ "prompt": "agentmark run-prompt",
339
+ "experiment": "agentmark run-experiment"
340
+ };
341
+ if (deploymentMode === "static") {
342
+ scriptsToAdd["build"] = "agentmark build --out dist/agentmark";
343
+ }
344
+ const result = mergePackageJson(targetPath, {}, {}, scriptsToAdd);
345
+ if (result.added.length > 0) {
346
+ console.log(`\u2705 Added to package.json: ${result.added.join(", ")}`);
347
+ }
348
+ if (result.skipped.length > 0) {
349
+ console.log(`\u23ED\uFE0F Skipped existing in package.json: ${result.skipped.join(", ")}`);
350
+ }
351
+ if (result.warnings.length > 0) {
352
+ result.warnings.forEach((w) => console.log(`\u26A0\uFE0F ${w}`));
353
+ }
354
+ } else {
355
+ const pkgJson = fs2.readJsonSync(packageJsonPath);
356
+ pkgJson.name = pkgJson.name === "test" || !pkgJson.name ? "agentmark-example-app" : pkgJson.name;
357
+ pkgJson.description = pkgJson.description || "A simple Node.js app using the Agentmark SDK";
358
+ const devScript = "agentmark dev";
359
+ const scripts = {
360
+ ...pkgJson.scripts,
361
+ "demo": "npx tsx index.ts",
362
+ "dev": devScript,
363
+ "prompt": "agentmark run-prompt",
364
+ "experiment": "agentmark run-experiment"
365
+ };
366
+ if (deploymentMode === "static") {
367
+ scripts["build"] = "agentmark build --out dist/agentmark";
368
+ }
369
+ pkgJson.scripts = scripts;
370
+ fs2.writeJsonSync(packageJsonPath, pkgJson, { spaces: 2 });
168
371
  }
169
- pkgJson.scripts = scripts;
170
- pkgJson.overrides = {
171
- ...pkgJson.overrides,
172
- "axios": "^1.7.9"
173
- };
174
- fs.writeJsonSync(packageJsonPath, pkgJson, { spaces: 2 });
175
372
  };
176
- var installDependencies = (modelProvider, targetPath = ".", adapter = "ai-sdk", deploymentMode = "cloud") => {
373
+ var installDependencies = (modelProvider, targetPath = ".", adapter = "ai-sdk", deploymentMode = "cloud", packageManager = null) => {
177
374
  console.log("Installing required packages...");
178
375
  console.log("This might take a moment...");
179
376
  const adapterConfig = getAdapterConfig(adapter, modelProvider);
377
+ const pm = packageManager || DEFAULT_PACKAGE_MANAGER;
378
+ const npmSuffix = pm.name === "npm" ? " --legacy-peer-deps" : "";
180
379
  try {
181
- const devDepsCmd = "npm install --save-dev typescript ts-node @types/node @agentmark-ai/cli --legacy-peer-deps";
380
+ const devDeps = ["typescript", "ts-node", "@types/node", "@agentmark-ai/cli"];
381
+ const devDepsCmd = `${pm.addDevCmd} ${devDeps.join(" ")}${npmSuffix}`;
382
+ console.log(`Using ${pm.name} to install dependencies...`);
182
383
  execSync(devDepsCmd, {
183
384
  stdio: "inherit",
184
385
  cwd: targetPath
185
386
  });
186
387
  const loaderPackages = deploymentMode === "static" ? ["@agentmark-ai/loader-api", "@agentmark-ai/loader-file"] : ["@agentmark-ai/loader-api"];
187
- const installArgs = [
188
- "install",
388
+ const deps = [
189
389
  "dotenv",
190
390
  "@agentmark-ai/prompt-core",
191
391
  "@agentmark-ai/sdk",
192
392
  adapterConfig.package,
193
393
  ...loaderPackages,
194
- ...adapterConfig.dependencies,
195
- "--legacy-peer-deps"
394
+ ...adapterConfig.dependencies
196
395
  ];
197
- execFileSync("npm", installArgs, { stdio: "inherit", cwd: targetPath });
396
+ const depsCmd = `${pm.addCmd} ${deps.join(" ")}${npmSuffix}`;
397
+ execSync(depsCmd, { stdio: "inherit", cwd: targetPath });
198
398
  console.log("Packages installed successfully!");
199
399
  } catch (error) {
200
400
  console.error("Error installing packages:", error);
@@ -368,28 +568,32 @@ var getStoryDataset = () => {
368
568
  };
369
569
 
370
570
  // src/utils/examples/templates/example-prompts.ts
371
- import fs2 from "fs-extra";
571
+ import fs3 from "fs-extra";
372
572
  var createExamplePrompts = (model, targetPath = ".", adapter = "ai-sdk") => {
373
- fs2.ensureDirSync(`${targetPath}/agentmark`);
374
- if (adapter !== "mastra") {
573
+ fs3.ensureDirSync(`${targetPath}/agentmark`);
574
+ const noImageSupport = ["mastra", "claude-agent-sdk"];
575
+ const noSpeechSupport = ["mastra", "claude-agent-sdk"];
576
+ const skipImagePrompts = noImageSupport.includes(adapter);
577
+ const skipSpeechPrompts = noSpeechSupport.includes(adapter);
578
+ if (!skipImagePrompts) {
375
579
  const animalDrawingPrompt = getAnimalDrawingPrompt();
376
- fs2.writeFileSync(`${targetPath}/agentmark/animal-drawing.prompt.mdx`, animalDrawingPrompt);
580
+ fs3.writeFileSync(`${targetPath}/agentmark/animal-drawing.prompt.mdx`, animalDrawingPrompt);
377
581
  const animalDataset = getAnimalDataset();
378
- fs2.writeFileSync(`${targetPath}/agentmark/animal.jsonl`, animalDataset);
582
+ fs3.writeFileSync(`${targetPath}/agentmark/animal.jsonl`, animalDataset);
379
583
  }
380
584
  const customerSupportPrompt = getCustomerSupportPrompt(model);
381
- fs2.writeFileSync(`${targetPath}/agentmark/customer-support-agent.prompt.mdx`, customerSupportPrompt);
585
+ fs3.writeFileSync(`${targetPath}/agentmark/customer-support-agent.prompt.mdx`, customerSupportPrompt);
382
586
  const customerQueryDataset = getCustomerQueryDataset();
383
- fs2.writeFileSync(`${targetPath}/agentmark/customer-query.jsonl`, customerQueryDataset);
587
+ fs3.writeFileSync(`${targetPath}/agentmark/customer-query.jsonl`, customerQueryDataset);
384
588
  const partyPlannerPrompt = getPartyPlannerPrompt(model);
385
- fs2.writeFileSync(`${targetPath}/agentmark/party-planner.prompt.mdx`, partyPlannerPrompt);
589
+ fs3.writeFileSync(`${targetPath}/agentmark/party-planner.prompt.mdx`, partyPlannerPrompt);
386
590
  const partyDataset = getPartyDataset();
387
- fs2.writeFileSync(`${targetPath}/agentmark/party.jsonl`, partyDataset);
388
- if (adapter !== "mastra") {
591
+ fs3.writeFileSync(`${targetPath}/agentmark/party.jsonl`, partyDataset);
592
+ if (!skipSpeechPrompts) {
389
593
  const storyTellerPrompt = getStoryTellerPrompt();
390
- fs2.writeFileSync(`${targetPath}/agentmark/story-teller.prompt.mdx`, storyTellerPrompt);
594
+ fs3.writeFileSync(`${targetPath}/agentmark/story-teller.prompt.mdx`, storyTellerPrompt);
391
595
  const storyDataset = getStoryDataset();
392
- fs2.writeFileSync(`${targetPath}/agentmark/story.jsonl`, storyDataset);
596
+ fs3.writeFileSync(`${targetPath}/agentmark/story.jsonl`, storyDataset);
393
597
  }
394
598
  };
395
599
 
@@ -398,8 +602,9 @@ var getClientConfigContent = (options) => {
398
602
  const { provider, languageModels, adapter, deploymentMode = "cloud" } = options;
399
603
  const adapterConfig = getAdapterConfig(adapter, provider);
400
604
  const { modelRegistry, toolRegistry } = adapterConfig.classes;
401
- const providerImport = `import { ${provider} } from '@ai-sdk/${provider}';`;
402
- const extraModelRegs = provider === "openai" ? `.registerModels(["dall-e-3"], (name: string) => ${provider}.image(name))
605
+ const isClaudeAgentSdk = adapter === "claude-agent-sdk";
606
+ const providerImport = isClaudeAgentSdk ? "" : `import { ${provider} } from '@ai-sdk/${provider}';`;
607
+ const extraModelRegs = provider === "openai" && !isClaudeAgentSdk ? `.registerModels(["dall-e-3"], (name: string) => ${provider}.image(name))
403
608
  .registerModels(["tts-1-hd"], (name: string) => ${provider}.speech(name))` : "";
404
609
  const loaderImport = deploymentMode === "cloud" ? `import { ApiLoader } from "@agentmark-ai/loader-api";` : `import { ApiLoader } from "@agentmark-ai/loader-api";
405
610
  import { FileLoader } from "@agentmark-ai/loader-file";`;
@@ -414,6 +619,51 @@ import { FileLoader } from "@agentmark-ai/loader-file";`;
414
619
  });` : ` const loader = process.env.NODE_ENV === 'development'
415
620
  ? ApiLoader.local({ baseUrl: process.env.AGENTMARK_BASE_URL || 'http://localhost:9418' })
416
621
  : new FileLoader('./dist/agentmark');`;
622
+ const modelRegistrySetup = isClaudeAgentSdk ? `function createModelRegistry() {
623
+ // Claude Agent SDK accepts model names directly.
624
+ // Use createDefault() for simple pass-through of model names.
625
+ const modelRegistry = ${modelRegistry}.createDefault();
626
+
627
+ // To configure specific models (e.g., extended thinking), use:
628
+ // const modelRegistry = new ${modelRegistry}()
629
+ // .registerModels(/claude-.*-thinking/, (name) => ({
630
+ // model: name,
631
+ // maxThinkingTokens: 10000, // Enable extended thinking
632
+ // }))
633
+ // .registerModels("claude-sonnet-4-20250514", (name) => ({ model: name }));
634
+
635
+ return modelRegistry;
636
+ }` : `function createModelRegistry() {
637
+ const modelRegistry = new ${modelRegistry}()
638
+ .registerModels(${JSON.stringify(languageModels)}, (name: string) => ${provider}(name))
639
+ ${extraModelRegs};
640
+ return modelRegistry;
641
+ }`;
642
+ const adapterOptionsImport = isClaudeAgentSdk ? `
643
+ // Claude Agent SDK adapter options
644
+ // See: https://github.com/anthropics/claude-agent-sdk
645
+ const adapterOptions = {
646
+ // Permission mode controls tool access:
647
+ // - 'default': Requires user approval for each tool use
648
+ // - 'acceptEdits': Auto-approve file edits only
649
+ // - 'bypassPermissions': Auto-approve all tools (use for automated pipelines)
650
+ // - 'plan': Planning mode only, no tool execution
651
+ permissionMode: 'bypassPermissions' as const,
652
+
653
+ // Maximum conversation turns before stopping
654
+ maxTurns: 20,
655
+
656
+ // Optional: Set working directory for file operations
657
+ // cwd: process.cwd(),
658
+
659
+ // Optional: Budget limit in USD
660
+ // maxBudgetUsd: 10.00,
661
+
662
+ // Optional: Restrict which tools the agent can use
663
+ // allowedTools: ['Read', 'Write', 'Glob'],
664
+ // disallowedTools: ['Bash'],
665
+ };` : "";
666
+ const createClientCall = isClaudeAgentSdk ? `return createAgentMarkClient<AgentMarkTypes, typeof toolRegistry>({ loader, modelRegistry, toolRegistry, evalRegistry, adapterOptions });` : `return createAgentMarkClient<AgentMarkTypes, typeof toolRegistry>({ loader, modelRegistry, toolRegistry, evalRegistry });`;
417
667
  return `// agentmark.client.ts
418
668
  import path from 'node:path';
419
669
  import dotenv from 'dotenv';
@@ -422,13 +672,9 @@ import { createAgentMarkClient, ${modelRegistry}, ${toolRegistry}, EvalRegistry
422
672
  ${loaderImport}
423
673
  import AgentMarkTypes, { Tools } from './agentmark.types';
424
674
  ${providerImport}
675
+ ${adapterOptionsImport}
425
676
 
426
- function createModelRegistry() {
427
- const modelRegistry = new ${modelRegistry}()
428
- .registerModels(${JSON.stringify(languageModels)}, (name: string) => ${provider}(name))
429
- ${extraModelRegs};
430
- return modelRegistry;
431
- }
677
+ ${modelRegistrySetup}
432
678
 
433
679
  function createToolRegistry() {
434
680
  const toolRegistry = new ${toolRegistry}<Tools>()
@@ -475,7 +721,7 @@ ${loaderSetup}
475
721
  const modelRegistry = createModelRegistry();
476
722
  const toolRegistry = createToolRegistry();
477
723
  const evalRegistry = createEvalRegistry();
478
- return createAgentMarkClient<AgentMarkTypes, typeof toolRegistry>({ loader, modelRegistry, toolRegistry, evalRegistry });
724
+ ${createClientCall}
479
725
  }
480
726
 
481
727
  export const client = createClient();