@botbotgo/agent-harness 0.0.14 → 0.0.16

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.
@@ -73,6 +73,9 @@ export type LangChainAgentParams = {
73
73
  model: CompiledModel;
74
74
  tools: CompiledTool[];
75
75
  systemPrompt?: string;
76
+ responseFormat?: unknown;
77
+ contextSchema?: unknown;
78
+ middleware?: Array<Record<string, unknown>>;
76
79
  description: string;
77
80
  };
78
81
  export type CompiledSubAgent = {
@@ -84,11 +87,17 @@ export type CompiledSubAgent = {
84
87
  interruptOn?: Record<string, boolean | object>;
85
88
  skills?: string[];
86
89
  memory?: string[];
90
+ responseFormat?: unknown;
91
+ contextSchema?: unknown;
92
+ middleware?: Array<Record<string, unknown>>;
87
93
  };
88
94
  export type DeepAgentParams = {
89
95
  model: CompiledModel;
90
96
  tools: CompiledTool[];
91
97
  systemPrompt?: string;
98
+ responseFormat?: unknown;
99
+ contextSchema?: unknown;
100
+ middleware?: Array<Record<string, unknown>>;
92
101
  description: string;
93
102
  subagents: CompiledSubAgent[];
94
103
  interruptOn?: Record<string, boolean | object>;
@@ -218,7 +218,7 @@ export async function listResourceToolsForSource(source, workspaceRoot = process
218
218
  }
219
219
  export function createResourceBackendResolver(workspace) {
220
220
  const localResolver = createProviderBackendResolver(localResource, workspace);
221
- return (binding) => localResolver?.(binding) ?? [];
221
+ return (binding) => localResolver?.(binding);
222
222
  }
223
223
  export function createResourceToolResolver(workspace, options = {}) {
224
224
  const functionResolver = createFunctionToolResolver(workspace);
@@ -15,6 +15,8 @@ export declare class AgentRuntimeAdapter {
15
15
  private synthesizeDeepAgentAnswer;
16
16
  private resolveModel;
17
17
  private buildToolNameMapping;
18
+ private buildAgentMessages;
19
+ private buildRawModelMessages;
18
20
  private resolveTools;
19
21
  private normalizeInterruptPolicy;
20
22
  private compileInterruptOn;
@@ -23,7 +25,6 @@ export declare class AgentRuntimeAdapter {
23
25
  private resolveCheckpointer;
24
26
  private buildRouteSystemPrompt;
25
27
  private resolveSubagents;
26
- private buildConversation;
27
28
  create(binding: CompiledAgentBinding): Promise<RunnableLike>;
28
29
  route(input: string, primaryBinding: CompiledAgentBinding, secondaryBinding: CompiledAgentBinding, options?: {
29
30
  systemPrompt?: string;
@@ -8,6 +8,7 @@ import { createAgent, humanInTheLoopMiddleware, initChatModel } from "langchain"
8
8
  import { extractEmptyAssistantMessageFailure, extractReasoningText, extractToolFallbackContext, extractVisibleOutput, isLikelyToolArgsObject, isToolCallParseFailure, STRICT_TOOL_JSON_INSTRUCTION, sanitizeVisibleText, tryParseJson, wrapResolvedModel, } from "./parsing/output-parsing.js";
9
9
  import { extractAgentStep, extractInterruptPayload, extractReasoningStreamOutput, extractTerminalStreamOutput, extractToolResult, normalizeTerminalOutputKey, readStreamDelta, } from "./parsing/stream-event-parsing.js";
10
10
  import { wrapToolForExecution } from "./tool-hitl.js";
11
+ import { resolveDeclaredMiddleware } from "./declared-middleware.js";
11
12
  const AGENT_INTERRUPT_SENTINEL_PREFIX = "__agent_harness_interrupt__:";
12
13
  const MODEL_SAFE_TOOL_NAME_PATTERN = /^[a-zA-Z0-9_-]+$/;
13
14
  function asObject(value) {
@@ -76,6 +77,9 @@ function wrapResolvedToolWithModelFacingName(resolvedTool, modelFacingName) {
76
77
  },
77
78
  });
78
79
  }
80
+ function countConfiguredTools(binding) {
81
+ return binding.langchainAgentParams?.tools.length ?? binding.deepAgentParams?.tools.length ?? 0;
82
+ }
79
83
  export class AgentRuntimeAdapter {
80
84
  options;
81
85
  constructor(options = {}) {
@@ -197,6 +201,20 @@ export class AgentRuntimeAdapter {
197
201
  buildToolNameMapping(tools) {
198
202
  return buildToolNameMapping(tools);
199
203
  }
204
+ buildAgentMessages(history, input) {
205
+ return [
206
+ ...history.map((item) => ({ role: item.role, content: item.content })),
207
+ { role: "user", content: input },
208
+ ];
209
+ }
210
+ buildRawModelMessages(systemPrompt, history, input) {
211
+ const messages = [];
212
+ if (systemPrompt) {
213
+ messages.push({ role: "system", content: systemPrompt });
214
+ }
215
+ messages.push(...this.buildAgentMessages(history, input));
216
+ return messages;
217
+ }
200
218
  resolveTools(tools, binding) {
201
219
  const resolved = this.options.toolResolver ? this.options.toolResolver(tools.map((tool) => tool.id), binding) : [];
202
220
  const toolNameMapping = this.buildToolNameMapping(tools);
@@ -249,8 +267,15 @@ export class AgentRuntimeAdapter {
249
267
  }
250
268
  return this.compileInterruptOn(binding.langchainAgentParams?.tools ?? [], binding.agent.langchainAgentConfig?.interruptOn);
251
269
  }
252
- resolveMiddleware(binding, interruptOn) {
253
- const middleware = this.options.middlewareResolver ? this.options.middlewareResolver(binding) : [];
270
+ async resolveMiddleware(binding, interruptOn) {
271
+ const declarativeMiddleware = await resolveDeclaredMiddleware(binding.langchainAgentParams?.middleware ??
272
+ binding.deepAgentParams?.middleware, {
273
+ resolveModel: (model) => this.resolveModel(model),
274
+ });
275
+ const middleware = [
276
+ ...declarativeMiddleware,
277
+ ...(this.options.middlewareResolver ? this.options.middlewareResolver(binding) : []),
278
+ ];
254
279
  if (interruptOn && Object.keys(interruptOn).length > 0) {
255
280
  middleware.push(humanInTheLoopMiddleware({ interruptOn }));
256
281
  }
@@ -285,32 +310,28 @@ export class AgentRuntimeAdapter {
285
310
  model: subagent.model ? (await this.resolveModel(subagent.model)) : undefined,
286
311
  tools: subagent.tools ? this.resolveTools(subagent.tools) : undefined,
287
312
  interruptOn: this.compileInterruptOn(subagent.tools ?? [], subagent.interruptOn),
313
+ responseFormat: subagent.responseFormat,
314
+ contextSchema: subagent.contextSchema,
315
+ middleware: (await resolveDeclaredMiddleware(subagent.middleware, {
316
+ resolveModel: (model) => this.resolveModel(model),
317
+ })),
288
318
  })));
289
319
  }
290
- buildConversation(systemPrompt, history, input) {
291
- const messages = [];
292
- if (systemPrompt) {
293
- messages.push({ role: "system", content: systemPrompt });
294
- }
295
- for (const item of history) {
296
- messages.push({ role: item.role, content: item.content });
297
- }
298
- messages.push({ role: "user", content: input });
299
- return messages;
300
- }
301
320
  async create(binding) {
302
321
  if (binding.langchainAgentParams) {
303
322
  const interruptOn = this.resolveInterruptOn(binding);
304
323
  const model = (await this.resolveModel(binding.langchainAgentParams.model));
305
324
  const tools = this.resolveTools(binding.langchainAgentParams.tools, binding);
306
325
  if (tools.length > 0 && typeof model.bindTools !== "function") {
307
- return this.createModelFallbackRunnable(model);
326
+ throw new Error(`Agent ${binding.agent.id} configures ${tools.length} tool(s), but resolved model ${binding.langchainAgentParams.model.id} does not support tool binding.`);
308
327
  }
309
328
  return createAgent({
310
329
  model: model,
311
330
  tools: tools,
312
331
  systemPrompt: binding.langchainAgentParams.systemPrompt,
313
- middleware: this.resolveMiddleware(binding, interruptOn),
332
+ responseFormat: binding.langchainAgentParams.responseFormat,
333
+ contextSchema: binding.langchainAgentParams.contextSchema,
334
+ middleware: (await this.resolveMiddleware(binding, interruptOn)),
314
335
  checkpointer: this.resolveCheckpointer(binding),
315
336
  });
316
337
  }
@@ -322,7 +343,9 @@ export class AgentRuntimeAdapter {
322
343
  model: (await this.resolveModel(params.model)),
323
344
  tools: this.resolveTools(params.tools, binding),
324
345
  systemPrompt: params.systemPrompt,
325
- middleware: this.resolveMiddleware(binding),
346
+ responseFormat: params.responseFormat,
347
+ contextSchema: params.contextSchema,
348
+ middleware: (await this.resolveMiddleware(binding)),
326
349
  subagents: (await this.resolveSubagents(params.subagents)),
327
350
  checkpointer: this.resolveCheckpointer(binding),
328
351
  store: this.options.storeResolver?.(binding),
@@ -365,7 +388,7 @@ export class AgentRuntimeAdapter {
365
388
  }
366
389
  async invoke(binding, input, threadId, runId, resumePayload, history = []) {
367
390
  const request = resumePayload === undefined
368
- ? { messages: this.buildConversation(binding.langchainAgentParams?.systemPrompt ?? binding.deepAgentParams?.systemPrompt, history, input) }
391
+ ? { messages: this.buildAgentMessages(history, input) }
369
392
  : new Command({ resume: resumePayload });
370
393
  let result;
371
394
  try {
@@ -378,7 +401,7 @@ export class AgentRuntimeAdapter {
378
401
  }
379
402
  const retriedBinding = this.applyStrictToolJsonInstruction(binding);
380
403
  const runnable = await this.create(retriedBinding);
381
- result = (await runnable.invoke({ messages: this.buildConversation(retriedBinding.langchainAgentParams?.systemPrompt ?? retriedBinding.deepAgentParams?.systemPrompt, history, input) }, { configurable: { thread_id: threadId } }));
404
+ result = (await runnable.invoke({ messages: this.buildAgentMessages(history, input) }, { configurable: { thread_id: threadId } }));
382
405
  }
383
406
  const interruptContent = Array.isArray(result.__interrupt__) && result.__interrupt__.length > 0 ? JSON.stringify(result.__interrupt__) : undefined;
384
407
  const extractedOutput = extractVisibleOutput(result);
@@ -414,7 +437,7 @@ export class AgentRuntimeAdapter {
414
437
  // agent loop and only adds an extra model round-trip before the runnable path.
415
438
  if (canUseDirectModelStream && typeof model.stream === "function") {
416
439
  let emitted = false;
417
- const stream = await model.stream(this.buildConversation(binding.langchainAgentParams.systemPrompt, history, input));
440
+ const stream = await model.stream(this.buildRawModelMessages(binding.langchainAgentParams.systemPrompt, history, input));
418
441
  for await (const chunk of stream) {
419
442
  const delta = readStreamDelta(chunk);
420
443
  if (delta) {
@@ -433,7 +456,7 @@ export class AgentRuntimeAdapter {
433
456
  }
434
457
  }
435
458
  const runnable = await this.create(binding);
436
- const request = { messages: this.buildConversation(binding.deepAgentParams?.systemPrompt, history, input) };
459
+ const request = { messages: this.buildAgentMessages(history, input) };
437
460
  if (typeof runnable.streamEvents === "function") {
438
461
  const events = await runnable.streamEvents(request, { configurable: { thread_id: threadId }, version: "v2" });
439
462
  let terminalOutput = "";
@@ -500,6 +523,11 @@ export class AgentRuntimeAdapter {
500
523
  }
501
524
  }
502
525
  catch (error) {
526
+ if (countConfiguredTools(binding) > 0 &&
527
+ error instanceof Error &&
528
+ error.message.includes("does not support tool binding")) {
529
+ throw error;
530
+ }
503
531
  if (!isToolCallParseFailure(error)) {
504
532
  throw error;
505
533
  }
@@ -0,0 +1,4 @@
1
+ import type { CompiledModel } from "../contracts/types.js";
2
+ export declare function resolveDeclaredMiddleware(middlewareConfigs: unknown[] | undefined, options: {
3
+ resolveModel: (model: CompiledModel) => Promise<unknown>;
4
+ }): Promise<unknown[]>;
@@ -0,0 +1,56 @@
1
+ import { modelCallLimitMiddleware, modelRetryMiddleware, summarizationMiddleware, todoListMiddleware, toolCallLimitMiddleware, toolRetryMiddleware, } from "langchain";
2
+ function asMiddlewareConfig(value) {
3
+ return typeof value === "object" && value !== null && !Array.isArray(value) ? { ...value } : null;
4
+ }
5
+ function requireKind(config) {
6
+ const kind = typeof config.kind === "string" ? config.kind.trim() : "";
7
+ if (!kind) {
8
+ throw new Error("Declarative middleware entries must include a non-empty kind");
9
+ }
10
+ return kind;
11
+ }
12
+ function omitKind(config) {
13
+ const { kind: _kind, ...rest } = config;
14
+ return rest;
15
+ }
16
+ export async function resolveDeclaredMiddleware(middlewareConfigs, options) {
17
+ const resolved = [];
18
+ for (const rawConfig of middlewareConfigs ?? []) {
19
+ const config = asMiddlewareConfig(rawConfig);
20
+ if (!config) {
21
+ continue;
22
+ }
23
+ const kind = requireKind(config);
24
+ const runtimeConfig = omitKind(config);
25
+ switch (kind) {
26
+ case "summarization": {
27
+ if (runtimeConfig.model && typeof runtimeConfig.model === "object" && runtimeConfig.model !== null && "id" in runtimeConfig.model) {
28
+ runtimeConfig.model = await options.resolveModel(runtimeConfig.model);
29
+ }
30
+ if (runtimeConfig.model === undefined) {
31
+ throw new Error("summarization middleware requires model or modelRef");
32
+ }
33
+ resolved.push(summarizationMiddleware(runtimeConfig));
34
+ break;
35
+ }
36
+ case "modelRetry":
37
+ resolved.push(modelRetryMiddleware(runtimeConfig));
38
+ break;
39
+ case "toolRetry":
40
+ resolved.push(toolRetryMiddleware(runtimeConfig));
41
+ break;
42
+ case "toolCallLimit":
43
+ resolved.push(toolCallLimitMiddleware(runtimeConfig));
44
+ break;
45
+ case "modelCallLimit":
46
+ resolved.push(modelCallLimitMiddleware(runtimeConfig));
47
+ break;
48
+ case "todoList":
49
+ resolved.push(todoListMiddleware(runtimeConfig));
50
+ break;
51
+ default:
52
+ throw new Error(`Unsupported declarative middleware kind ${kind}`);
53
+ }
54
+ }
55
+ return resolved;
56
+ }
@@ -30,6 +30,19 @@ function requireModel(models, ref, ownerId) {
30
30
  }
31
31
  return compileModel(model);
32
32
  }
33
+ function compileMiddlewareConfigs(middleware, models, ownerId) {
34
+ if (!middleware || middleware.length === 0) {
35
+ return undefined;
36
+ }
37
+ return middleware.map((config) => {
38
+ const compiled = { ...config };
39
+ if (compiled.kind === "summarization" && typeof compiled.modelRef === "string") {
40
+ compiled.model = requireModel(models, compiled.modelRef, ownerId);
41
+ delete compiled.modelRef;
42
+ }
43
+ return compiled;
44
+ });
45
+ }
33
46
  function resolveAgentRuntimeName(agent) {
34
47
  const baseName = agent.id;
35
48
  if (baseName.includes(".")) {
@@ -72,6 +85,9 @@ function buildSubagent(agent, workspaceRoot, models, tools, parentSkills, parent
72
85
  interruptOn: agent.deepAgentConfig?.interruptOn,
73
86
  skills: compileAgentSkills(workspaceRoot, agent, parentSkills),
74
87
  memory: ownMemory.length > 0 ? ownMemory : parentMemory,
88
+ responseFormat: agent.deepAgentConfig?.responseFormat,
89
+ contextSchema: agent.deepAgentConfig?.contextSchema,
90
+ middleware: compileMiddlewareConfigs(agent.deepAgentConfig?.middleware, models, agent.id),
75
91
  };
76
92
  }
77
93
  function resolveDirectPrompt(agent) {
@@ -148,6 +164,9 @@ export function compileBinding(workspaceRoot, agent, agents, referencedSubagentI
148
164
  model: compiledAgentModel,
149
165
  tools: requireTools(tools, agent.toolRefs, agent.id),
150
166
  systemPrompt: resolveSystemPrompt(agent),
167
+ responseFormat: agent.langchainAgentConfig?.responseFormat,
168
+ contextSchema: agent.langchainAgentConfig?.contextSchema,
169
+ middleware: compileMiddlewareConfigs(agent.langchainAgentConfig?.middleware, models, agent.id),
151
170
  description: agent.description,
152
171
  };
153
172
  return {
@@ -162,6 +181,9 @@ export function compileBinding(workspaceRoot, agent, agents, referencedSubagentI
162
181
  model: compiledAgentModel,
163
182
  tools: requireTools(tools, agent.toolRefs, agent.id),
164
183
  systemPrompt: resolveSystemPrompt(agent),
184
+ responseFormat: agent.deepAgentConfig?.responseFormat,
185
+ contextSchema: agent.deepAgentConfig?.contextSchema,
186
+ middleware: compileMiddlewareConfigs(agent.deepAgentConfig?.middleware, models, agent.id),
165
187
  description: agent.description,
166
188
  subagents: agent.subagentRefs.map((ref) => {
167
189
  const subagent = agents.get(resolveRefId(ref));
@@ -174,6 +174,12 @@ function readSingleRef(value) {
174
174
  }
175
175
  return undefined;
176
176
  }
177
+ function readMiddlewareArray(items) {
178
+ const middleware = toArray(items)
179
+ .filter((item) => typeof item === "object" && item !== null && !Array.isArray(item))
180
+ .map((item) => ({ ...item }));
181
+ return middleware.length > 0 ? middleware : undefined;
182
+ }
177
183
  export function parseAgentItem(item, sourcePath) {
178
184
  const subagentRefs = readRefArray(item.subagents);
179
185
  const subagentPathRefs = readPathArray(item.subagents);
@@ -193,11 +199,19 @@ export function parseAgentItem(item, sourcePath) {
193
199
  subagentRefs,
194
200
  subagentPathRefs,
195
201
  langchainAgentConfig: {
196
- ...(typeof item.systemPrompt === "string" || typeof item.interruptOn === "object" || typeof item.checkpointer === "object"
202
+ ...(typeof item.systemPrompt === "string" ||
203
+ typeof item.interruptOn === "object" ||
204
+ typeof item.checkpointer === "object" ||
205
+ item.responseFormat !== undefined ||
206
+ item.contextSchema !== undefined ||
207
+ item.middleware !== undefined
197
208
  ? {
198
209
  ...(typeof item.systemPrompt === "string" ? { systemPrompt: item.systemPrompt } : {}),
199
210
  ...(typeof item.interruptOn === "object" && item.interruptOn ? { interruptOn: item.interruptOn } : {}),
200
211
  ...(typeof item.checkpointer === "object" && item.checkpointer ? { checkpointer: item.checkpointer } : {}),
212
+ ...(item.responseFormat !== undefined ? { responseFormat: item.responseFormat } : {}),
213
+ ...(item.contextSchema !== undefined ? { contextSchema: item.contextSchema } : {}),
214
+ ...(readMiddlewareArray(item.middleware) ? { middleware: readMiddlewareArray(item.middleware) } : {}),
201
215
  }
202
216
  : {}),
203
217
  },
@@ -206,13 +220,19 @@ export function parseAgentItem(item, sourcePath) {
206
220
  typeof item.backend === "object" ||
207
221
  typeof item.store === "object" ||
208
222
  typeof item.checkpointer === "object" ||
209
- typeof item.interruptOn === "object"
223
+ typeof item.interruptOn === "object" ||
224
+ item.responseFormat !== undefined ||
225
+ item.contextSchema !== undefined ||
226
+ item.middleware !== undefined
210
227
  ? {
211
228
  ...(typeof item.systemPrompt === "string" ? { systemPrompt: item.systemPrompt } : {}),
212
229
  ...(typeof item.backend === "object" && item.backend ? { backend: item.backend } : {}),
213
230
  ...(typeof item.store === "object" && item.store ? { store: item.store } : {}),
214
231
  ...(typeof item.checkpointer === "object" && item.checkpointer ? { checkpointer: item.checkpointer } : {}),
215
232
  ...(typeof item.interruptOn === "object" && item.interruptOn ? { interruptOn: item.interruptOn } : {}),
233
+ ...(item.responseFormat !== undefined ? { responseFormat: item.responseFormat } : {}),
234
+ ...(item.contextSchema !== undefined ? { contextSchema: item.contextSchema } : {}),
235
+ ...(readMiddlewareArray(item.middleware) ? { middleware: readMiddlewareArray(item.middleware) } : {}),
216
236
  }
217
237
  : {}),
218
238
  },
@@ -1,4 +1,12 @@
1
1
  const allowedExecutionModes = new Set(["deepagent", "langchain-v1"]);
2
+ const allowedMiddlewareKinds = new Set([
3
+ "summarization",
4
+ "modelRetry",
5
+ "toolRetry",
6
+ "toolCallLimit",
7
+ "modelCallLimit",
8
+ "todoList",
9
+ ]);
2
10
  function hasPromptContent(value) {
3
11
  return typeof value === "string" && value.trim().length > 0;
4
12
  }
@@ -15,6 +23,25 @@ function validateCheckpointerConfig(agent) {
15
23
  throw new Error(`Agent ${agent.id} checkpointer.path is not supported for kind MemorySaver`);
16
24
  }
17
25
  }
26
+ function validateMiddlewareConfig(agent) {
27
+ const middlewareConfigs = [
28
+ ...(agent.langchainAgentConfig?.middleware ?? []),
29
+ ...(agent.deepAgentConfig?.middleware ?? []),
30
+ ];
31
+ for (const config of middlewareConfigs) {
32
+ if (typeof config !== "object" || config === null || Array.isArray(config)) {
33
+ throw new Error(`Agent ${agent.id} middleware entries must be objects`);
34
+ }
35
+ const typed = config;
36
+ const kind = typeof typed.kind === "string" ? typed.kind : "";
37
+ if (!allowedMiddlewareKinds.has(kind)) {
38
+ throw new Error(`Agent ${agent.id} middleware kind ${kind || "(missing)"} is not supported`);
39
+ }
40
+ if (kind === "summarization" && typed.model === undefined && typeof typed.modelRef !== "string") {
41
+ throw new Error(`Agent ${agent.id} summarization middleware requires model or modelRef`);
42
+ }
43
+ }
44
+ }
18
45
  export function validateAgent(agent) {
19
46
  if (!agent.id) {
20
47
  throw new Error(`Agent id is required in ${agent.sourcePath}`);
@@ -35,6 +62,7 @@ export function validateAgent(agent) {
35
62
  throw new Error(`Agent ${agent.id} must use deepagent execution when subagents are defined`);
36
63
  }
37
64
  validateCheckpointerConfig(agent);
65
+ validateMiddlewareConfig(agent);
38
66
  }
39
67
  export function validateTopology(agents) {
40
68
  const ids = new Set();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@botbotgo/agent-harness",
3
- "version": "0.0.14",
3
+ "version": "0.0.16",
4
4
  "description": "Agent Harness framework package",
5
5
  "type": "module",
6
6
  "packageManager": "npm@10.9.2",
@@ -43,7 +43,7 @@
43
43
  "scripts": {
44
44
  "build": "rm -rf dist tsconfig.tsbuildinfo && tsc -p tsconfig.json && cp -R config dist/",
45
45
  "check": "tsc -p tsconfig.json --noEmit",
46
- "test": "vitest run test/public-api.test.ts test/resource-optional-provider.test.ts test/stock-research-app-load-harness.test.ts test/release-workflow.test.ts test/release-version.test.ts test/gitignore.test.ts test/package-lock.test.ts test/readme.test.ts",
46
+ "test": "vitest run test/public-api.test.ts test/resource-optional-provider.test.ts test/stock-research-app-load-harness.test.ts test/release-workflow.test.ts test/release-version.test.ts test/gitignore.test.ts test/package-lock.test.ts test/readme.test.ts test/runtime-adapter-regressions.test.ts",
47
47
  "release:prepare": "npm version patch --no-git-tag-version && node ./scripts/sync-example-version.mjs",
48
48
  "release:pack": "npm pack --dry-run",
49
49
  "release:publish": "npm publish --access public --registry https://registry.npmjs.org/"