@perstack/runtime 0.0.38 → 0.0.40

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/src/index.js CHANGED
@@ -1,24 +1,25 @@
1
- import { setup, assign, createActor } from 'xstate';
2
1
  import { createAmazonBedrock } from '@ai-sdk/amazon-bedrock';
3
2
  import { createAnthropic } from '@ai-sdk/anthropic';
4
3
  import { createAzure } from '@ai-sdk/azure';
5
4
  import { createGoogleGenerativeAI } from '@ai-sdk/google';
6
5
  import { createOpenAI } from '@ai-sdk/openai';
7
- import { knownModels, stopRunByDelegate, stopRunByInteractiveTool, resolveThought, attemptCompletion, resolvePdfFile, resolveImageFile, resolveToolResult, stopRunByExceededMaxSteps, continueToNextStep, retry, completeRun, callDelegate, callInteractiveTool, callTool, startRun, startGeneration, finishToolCall, runParamsSchema, checkpointSchema } from '@perstack/core';
6
+ import { knownModels, stopRunByDelegate, stopRunByInteractiveTool, resolveThought, attemptCompletion, resolvePdfFile, resolveImageFile, resolveToolResult, stopRunByExceededMaxSteps, continueToNextStep, retry, completeRun, callDelegate, callInteractiveTool, callTool, startRun, startGeneration, finishToolCall, runParamsSchema, createRuntimeEvent, checkpointSchema } from '@perstack/core';
8
7
  import { createOllama } from 'ollama-ai-provider-v2';
8
+ import { existsSync } from 'fs';
9
+ import { readFile, writeFile, mkdir, readdir } from 'fs/promises';
10
+ import path from 'path';
11
+ import { createId } from '@paralleldrive/cuid2';
12
+ import { setup, assign, createActor } from 'xstate';
13
+ import { ApiV1Client } from '@perstack/api-client/v1';
9
14
  import { Client } from '@modelcontextprotocol/sdk/client/index.js';
10
15
  import { SSEClientTransport } from '@modelcontextprotocol/sdk/client/sse.js';
11
16
  import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
12
17
  import { McpError } from '@modelcontextprotocol/sdk/types.js';
13
- import { createId } from '@paralleldrive/cuid2';
14
18
  import { generateText, tool, jsonSchema } from 'ai';
15
19
  import { dedent } from 'ts-dedent';
16
- import { readFile, writeFile, mkdir, readdir } from 'fs/promises';
17
- import { existsSync } from 'fs';
18
- import path from 'path';
19
- import { ApiV1Client } from '@perstack/api-client/v1';
20
+ import { createRequire } from 'module';
20
21
 
21
- // src/runtime-state-machine.ts
22
+ // src/model.ts
22
23
  function getModel(modelId, providerConfig) {
23
24
  switch (providerConfig.name) {
24
25
  case "anthropic": {
@@ -76,6 +77,78 @@ function getContextWindow(providerName, modelId) {
76
77
  function calculateContextWindowUsage(usage, contextWindow) {
77
78
  return (usage.inputTokens + usage.cachedInputTokens + usage.outputTokens) / contextWindow;
78
79
  }
80
+ async function defaultRetrieveCheckpoint(runId, checkpointId) {
81
+ const runDir = getRunDir(runId);
82
+ const checkpointFiles = await readdir(runDir, { withFileTypes: true }).then(
83
+ (files) => files.filter((file) => file.isFile() && file.name.startsWith("checkpoint-"))
84
+ );
85
+ const checkpointFile = checkpointFiles.find((file) => file.name.endsWith(`-${checkpointId}.json`));
86
+ if (!checkpointFile) {
87
+ throw new Error(`checkpoint not found: ${runId} ${checkpointId}`);
88
+ }
89
+ const checkpointPath = `${runDir}/${checkpointFile.name}`;
90
+ const checkpoint = await readFile(checkpointPath, "utf8");
91
+ return checkpointSchema.parse(JSON.parse(checkpoint));
92
+ }
93
+ async function defaultStoreCheckpoint(checkpoint, timestamp) {
94
+ const { id, runId, stepNumber } = checkpoint;
95
+ const runDir = getRunDir(runId);
96
+ const checkpointPath = `${runDir}/checkpoint-${timestamp}-${stepNumber}-${id}.json`;
97
+ await mkdir(runDir, { recursive: true });
98
+ await writeFile(checkpointPath, JSON.stringify(checkpoint));
99
+ }
100
+ async function defaultStoreEvent(event) {
101
+ const { timestamp, runId, stepNumber, type } = event;
102
+ const runDir = getRunDir(runId);
103
+ const eventPath = `${runDir}/event-${timestamp}-${stepNumber}-${type}.json`;
104
+ await mkdir(runDir, { recursive: true });
105
+ await writeFile(eventPath, JSON.stringify(event));
106
+ }
107
+ var RunEventEmitter = class {
108
+ listeners = [];
109
+ subscribe(listener) {
110
+ this.listeners.push(listener);
111
+ }
112
+ async emit(event) {
113
+ for (const listener of this.listeners) {
114
+ await listener({
115
+ ...event,
116
+ id: createId(),
117
+ timestamp: Date.now()
118
+ });
119
+ }
120
+ }
121
+ };
122
+ async function resolveExpertToRun(expertKey, experts, clientOptions) {
123
+ if (experts[expertKey]) {
124
+ return experts[expertKey];
125
+ }
126
+ const client = new ApiV1Client({
127
+ baseUrl: clientOptions.perstackApiBaseUrl,
128
+ apiKey: clientOptions.perstackApiKey
129
+ });
130
+ const { expert } = await client.registry.experts.get({ expertKey });
131
+ experts[expertKey] = toRuntimeExpert(expert);
132
+ return experts[expertKey];
133
+ }
134
+ function toRuntimeExpert(expert) {
135
+ const skills = Object.fromEntries(
136
+ Object.entries(expert.skills).map(([name, skill]) => {
137
+ switch (skill.type) {
138
+ case "mcpStdioSkill":
139
+ return [name, { ...skill, name }];
140
+ case "mcpSseSkill":
141
+ return [name, { ...skill, name }];
142
+ case "interactiveSkill":
143
+ return [name, { ...skill, name }];
144
+ default: {
145
+ throw new Error(`Unknown skill type: ${skill.type}`);
146
+ }
147
+ }
148
+ })
149
+ );
150
+ return { ...expert, skills };
151
+ }
79
152
  var SkillManager = class {
80
153
  _toolDefinitions = [];
81
154
  _initialized = false;
@@ -89,8 +162,12 @@ var SkillManager = class {
89
162
  _mcpClient;
90
163
  _params;
91
164
  _env;
92
- constructor(params) {
165
+ _runId;
166
+ _eventListener;
167
+ constructor(params, runId, eventListener) {
93
168
  this._params = params;
169
+ this._runId = runId;
170
+ this._eventListener = eventListener;
94
171
  this.type = params.type;
95
172
  switch (params.type) {
96
173
  case "mcp":
@@ -175,8 +252,16 @@ var SkillManager = class {
175
252
  env[envName] = this._env[envName];
176
253
  }
177
254
  const { command, args } = this._getCommandArgs(params.skill);
178
- const transport = new StdioClientTransport({ command, args, env });
255
+ const transport = new StdioClientTransport({ command, args, env, stderr: "ignore" });
179
256
  await this._mcpClient.connect(transport);
257
+ if (this._eventListener) {
258
+ const serverInfo = this._mcpClient.getServerVersion();
259
+ const event = createRuntimeEvent("skillConnected", this._runId, {
260
+ skillName: params.skill.name,
261
+ serverInfo: serverInfo ? { name: serverInfo.name, version: serverInfo.version } : void 0
262
+ });
263
+ this._eventListener(event);
264
+ }
180
265
  break;
181
266
  }
182
267
  case "mcpSseSkill": {
@@ -246,6 +331,12 @@ var SkillManager = class {
246
331
  async close() {
247
332
  if (this._mcpClient) {
248
333
  await this._mcpClient.close();
334
+ if (this._eventListener && this.skill) {
335
+ const event = createRuntimeEvent("skillDisconnected", this._runId, {
336
+ skillName: this.skill.name
337
+ });
338
+ this._eventListener(event);
339
+ }
249
340
  }
250
341
  }
251
342
  async getToolDefinitions() {
@@ -352,8 +443,8 @@ var SkillManager = class {
352
443
  throw new Error(`Unsupported resource type: ${JSON.stringify(resource)}`);
353
444
  }
354
445
  };
355
- async function getSkillManagers(expert, experts, setting) {
356
- const { perstackBaseSkillCommand, env } = setting;
446
+ async function getSkillManagers(expert, experts, setting, eventListener) {
447
+ const { perstackBaseSkillCommand, env, runId } = setting;
357
448
  const skillManagers = {};
358
449
  const { skills } = expert;
359
450
  if (!skills["@perstack/base"]) {
@@ -375,21 +466,29 @@ async function getSkillManagers(expert, experts, setting) {
375
466
  skill.lazyInit = false;
376
467
  }
377
468
  }
378
- const skillManager = new SkillManager({
379
- type: "mcp",
380
- skill,
381
- env
382
- });
469
+ const skillManager = new SkillManager(
470
+ {
471
+ type: "mcp",
472
+ skill,
473
+ env
474
+ },
475
+ runId,
476
+ eventListener
477
+ );
383
478
  await skillManager.init();
384
479
  return skillManager;
385
480
  })
386
481
  );
387
482
  const interactiveSkillManagers = await Promise.all(
388
483
  Object.values(skills).filter((skill) => skill.type === "interactiveSkill").map(async (interactiveSkill) => {
389
- const skillManager = new SkillManager({
390
- type: "interactive",
391
- interactiveSkill
392
- });
484
+ const skillManager = new SkillManager(
485
+ {
486
+ type: "interactive",
487
+ interactiveSkill
488
+ },
489
+ runId,
490
+ eventListener
491
+ );
393
492
  await skillManager.init();
394
493
  return skillManager;
395
494
  })
@@ -397,10 +496,14 @@ async function getSkillManagers(expert, experts, setting) {
397
496
  const delegateSkillManagers = await Promise.all(
398
497
  expert.delegates.map(async (delegateExpertName) => {
399
498
  const delegate = experts[delegateExpertName];
400
- const skillManager = new SkillManager({
401
- type: "delegate",
402
- expert: delegate
403
- });
499
+ const skillManager = new SkillManager(
500
+ {
501
+ type: "delegate",
502
+ expert: delegate
503
+ },
504
+ runId,
505
+ eventListener
506
+ );
404
507
  await skillManager.init();
405
508
  return skillManager;
406
509
  })
@@ -1618,266 +1721,20 @@ var StateMachineLogics = {
1618
1721
  CallingDelegate: callingDelegateLogic,
1619
1722
  FinishingStep: finishingStepLogic
1620
1723
  };
1621
- async function defaultRetrieveCheckpoint(runId, checkpointId) {
1622
- const runDir = getRunDir(runId);
1623
- const checkpointFiles = await readdir(runDir, { withFileTypes: true }).then(
1624
- (files) => files.filter((file) => file.isFile() && file.name.startsWith("checkpoint-"))
1625
- );
1626
- const checkpointFile = checkpointFiles.find((file) => file.name.endsWith(`-${checkpointId}.json`));
1627
- if (!checkpointFile) {
1628
- throw new Error(`checkpoint not found: ${runId} ${checkpointId}`);
1724
+ var getVersion = () => {
1725
+ if (typeof __RUNTIME_VERSION__ !== "undefined") {
1726
+ return __RUNTIME_VERSION__;
1629
1727
  }
1630
- const checkpointPath = `${runDir}/${checkpointFile.name}`;
1631
- const checkpoint = await readFile(checkpointPath, "utf8");
1632
- return checkpointSchema.parse(JSON.parse(checkpoint));
1633
- }
1634
- async function defaultStoreCheckpoint(checkpoint, timestamp) {
1635
- const { id, runId, stepNumber } = checkpoint;
1636
- const runDir = getRunDir(runId);
1637
- const checkpointPath = `${runDir}/checkpoint-${timestamp}-${stepNumber}-${id}.json`;
1638
- await mkdir(runDir, { recursive: true });
1639
- await writeFile(checkpointPath, JSON.stringify(checkpoint, null, 2));
1640
- }
1641
- async function defaultStoreEvent(event) {
1642
- const { timestamp, runId, stepNumber, type } = event;
1643
- const runDir = getRunDir(runId);
1644
- const eventPath = `${runDir}/event-${timestamp}-${stepNumber}-${type}.json`;
1645
- await mkdir(runDir, { recursive: true });
1646
- await writeFile(eventPath, JSON.stringify(event, null, 2));
1647
- }
1648
-
1649
- // package.json
1650
- var package_default = {
1651
- version: "0.0.38"};
1652
-
1653
- // src/events/default-event-listener.ts
1654
- var log = console.info;
1655
- var debug = console.debug;
1656
- var header = (e) => {
1657
- const t = (/* @__PURE__ */ new Date()).toISOString();
1658
- const stepNumber = e.stepNumber;
1659
- const key = e.expertKey;
1660
- return `${t} ${stepNumber} ${key}`;
1728
+ const require2 = createRequire(import.meta.url);
1729
+ const pkg = require2("../package.json");
1730
+ return pkg.version;
1661
1731
  };
1662
- async function defaultEventListener(e) {
1663
- await defaultStoreEvent(e);
1664
- switch (e.type) {
1665
- case "startRun": {
1666
- log(`${header(e)} Perstack@${package_default.version} started`);
1667
- break;
1668
- }
1669
- case "startGeneration": {
1670
- log(`${header(e)} Generating tool call`);
1671
- break;
1672
- }
1673
- case "retry": {
1674
- log(`${header(e)} Retrying tool call generation`);
1675
- debug(e.reason);
1676
- break;
1677
- }
1678
- case "callTool": {
1679
- log(`${header(e)} Calling tool`);
1680
- if (e.toolCall.skillName === "@perstack/base") {
1681
- switch (e.toolCall.toolName) {
1682
- case "think": {
1683
- const thought = e.toolCall.args.thought;
1684
- log(`${header(e)} Thought Updated:`);
1685
- debug(thought);
1686
- break;
1687
- }
1688
- case "readPdfFile": {
1689
- const path2 = e.toolCall.args.path;
1690
- log(`${header(e)} Reading PDF: ${path2}`);
1691
- break;
1692
- }
1693
- case "readImageFile": {
1694
- const path2 = e.toolCall.args.path;
1695
- log(`${header(e)} Reading Image: ${path2}`);
1696
- break;
1697
- }
1698
- default: {
1699
- log(`${header(e)} Tool: ${e.toolCall.skillName}/${e.toolCall.toolName}`);
1700
- debug(`${header(e)} Args: ${JSON.stringify(e.toolCall.args, null, 2)}`);
1701
- break;
1702
- }
1703
- }
1704
- } else {
1705
- log(`${header(e)} Tool: ${e.toolCall.skillName}/${e.toolCall.toolName}`);
1706
- debug(`${header(e)} Args: ${JSON.stringify(e.toolCall.args, null, 2)}`);
1707
- }
1708
- break;
1709
- }
1710
- case "callInteractiveTool": {
1711
- log(`${header(e)} Calling interactive tool`);
1712
- log(`${header(e)} Tool: ${e.toolCall.skillName}/${e.toolCall.toolName}`);
1713
- debug(`${header(e)} Args: ${JSON.stringify(e.toolCall.args, null, 2)}`);
1714
- break;
1715
- }
1716
- case "callDelegate": {
1717
- log(`${header(e)} Calling delegate`);
1718
- log(`${header(e)} Tool: ${e.toolCall.toolName}`);
1719
- debug(`${header(e)} Args: ${JSON.stringify(e.toolCall.args, null, 2)}`);
1720
- break;
1721
- }
1722
- case "resolveToolResult": {
1723
- log(`${header(e)} Resolved Tool Result`);
1724
- if (e.toolResult.skillName === "@perstack/base") {
1725
- switch (e.toolResult.toolName) {
1726
- case "todo": {
1727
- const text = e.toolResult.result.find((r) => r.type === "textPart")?.text;
1728
- const { todos } = JSON.parse(text ?? "{}");
1729
- log(`${header(e)} Todo:`);
1730
- for (const todo of todos) {
1731
- debug(`${todo.completed ? "[x]" : "[ ]"} ${todo.id}: ${todo.title}`);
1732
- }
1733
- break;
1734
- }
1735
- default: {
1736
- log(`${header(e)} Tool: ${e.toolResult.skillName}/${e.toolResult.toolName}`);
1737
- debug(`${header(e)} Result: ${JSON.stringify(e.toolResult.result, null, 2)}`);
1738
- break;
1739
- }
1740
- }
1741
- } else {
1742
- log(`${header(e)} Tool: ${e.toolResult.skillName}/${e.toolResult.toolName}`);
1743
- debug(`${header(e)} Result: ${JSON.stringify(e.toolResult.result, null, 2)}`);
1744
- }
1745
- break;
1746
- }
1747
- case "resolveThought": {
1748
- log(`${header(e)} Resolved Thought:`, e.toolResult);
1749
- break;
1750
- }
1751
- case "resolvePdfFile": {
1752
- log(`${header(e)} Resolved PDF:`, e.toolResult);
1753
- break;
1754
- }
1755
- case "resolveImageFile": {
1756
- log(`${header(e)} Resolved Image:`, e.toolResult);
1757
- break;
1758
- }
1759
- case "attemptCompletion": {
1760
- log(`${header(e)} Attempting completion`);
1761
- break;
1762
- }
1763
- case "completeRun": {
1764
- logUsage(e);
1765
- log(`${header(e)} Completing run`);
1766
- debug(`${header(e)} Result:`, e.text);
1767
- break;
1768
- }
1769
- case "stopRunByInteractiveTool": {
1770
- logUsage(e);
1771
- log(`${header(e)} Stopping run by interactive tool`);
1772
- break;
1773
- }
1774
- case "stopRunByDelegate": {
1775
- logUsage(e);
1776
- log(`${header(e)} Stopping run by delegate`);
1777
- break;
1778
- }
1779
- case "stopRunByExceededMaxSteps": {
1780
- logUsage(e);
1781
- log(`${header(e)} Stopping run by exceeded max steps`);
1782
- break;
1783
- }
1784
- case "continueToNextStep": {
1785
- logUsage(e);
1786
- log(`${header(e)} Continuing to next step`);
1787
- if (e.checkpoint.contextWindowUsage) {
1788
- log(`${header(e)} Context window usage: ${e.checkpoint.contextWindowUsage.toFixed(2)}%`);
1789
- }
1790
- break;
1791
- }
1792
- }
1793
- }
1794
- function logUsage(e) {
1795
- const usageByStep = [
1796
- `In: ${e.step.usage.inputTokens.toLocaleString()}`,
1797
- `Reasoning: ${e.step.usage.reasoningTokens.toLocaleString()}`,
1798
- `Out: ${e.step.usage.outputTokens.toLocaleString()}`,
1799
- `Total: ${e.step.usage.totalTokens.toLocaleString()}`,
1800
- `Cache-read: ${e.step.usage.cachedInputTokens.toLocaleString()}`
1801
- ].join(", ");
1802
- const usageByRun = [
1803
- `In: ${e.checkpoint.usage.inputTokens.toLocaleString()}`,
1804
- `Reasoning: ${e.checkpoint.usage.reasoningTokens.toLocaleString()}`,
1805
- `Out: ${e.checkpoint.usage.outputTokens.toLocaleString()}`,
1806
- `Total: ${e.checkpoint.usage.totalTokens.toLocaleString()}`,
1807
- `Cache-read: ${e.checkpoint.usage.cachedInputTokens.toLocaleString()}`
1808
- ].join(", ");
1809
- log(`${header(e)} Tokens usage by step: ${usageByStep}`);
1810
- log(`${header(e)} Tokens usage by run: ${usageByRun}`);
1811
- }
1812
- var RunEventEmitter = class {
1813
- listeners = [];
1814
- subscribe(listener) {
1815
- this.listeners.push(listener);
1816
- }
1817
- async emit(event) {
1818
- for (const listener of this.listeners) {
1819
- await listener({
1820
- ...event,
1821
- id: createId(),
1822
- timestamp: Date.now()
1823
- });
1824
- }
1825
- }
1826
- };
1827
- async function resolveExpertToRun(expertKey, experts, clientOptions) {
1828
- console.log(experts);
1829
- if (experts[expertKey]) {
1830
- return experts[expertKey];
1831
- }
1832
- const client = new ApiV1Client({
1833
- baseUrl: clientOptions.perstackApiBaseUrl,
1834
- apiKey: clientOptions.perstackApiKey
1835
- });
1836
- const { expert } = await client.registry.experts.get({ expertKey });
1837
- experts[expertKey] = toRuntimeExpert(expert);
1838
- return experts[expertKey];
1839
- }
1840
- function toRuntimeExpert(expert) {
1841
- const skills = Object.fromEntries(
1842
- Object.entries(expert.skills).map(([name, skill]) => {
1843
- switch (skill.type) {
1844
- case "mcpStdioSkill":
1845
- return [
1846
- name,
1847
- {
1848
- ...skill,
1849
- name
1850
- }
1851
- ];
1852
- case "mcpSseSkill":
1853
- return [
1854
- name,
1855
- {
1856
- ...skill,
1857
- name
1858
- }
1859
- ];
1860
- case "interactiveSkill":
1861
- return [
1862
- name,
1863
- {
1864
- ...skill,
1865
- name
1866
- }
1867
- ];
1868
- }
1869
- })
1870
- );
1871
- return {
1872
- ...expert,
1873
- skills
1874
- };
1875
- }
1732
+ var RUNTIME_VERSION = getVersion();
1876
1733
 
1877
1734
  // src/runtime.ts
1878
1735
  async function run(runInput, options) {
1879
1736
  const runParams = runParamsSchema.parse(runInput);
1880
- const eventListener = options?.eventListener ?? defaultEventListener;
1737
+ const eventListener = getEventListener(options);
1881
1738
  const retrieveCheckpoint = options?.retrieveCheckpoint ?? defaultRetrieveCheckpoint;
1882
1739
  const storeCheckpoint = options?.storeCheckpoint ?? defaultStoreCheckpoint;
1883
1740
  const eventEmitter = new RunEventEmitter();
@@ -1893,8 +1750,27 @@ async function run(runInput, options) {
1893
1750
  await storeRunSetting(setting);
1894
1751
  while (true) {
1895
1752
  const { expertToRun, experts } = await setupExperts(setting);
1896
- printRunSetting(expertToRun.name, experts, setting);
1897
- const skillManagers = await getSkillManagers(expertToRun, experts, setting);
1753
+ if (options?.eventListener) {
1754
+ const initEvent = createRuntimeEvent("initializeRuntime", setting.runId, {
1755
+ runtimeVersion: RUNTIME_VERSION,
1756
+ expertName: expertToRun.name,
1757
+ experts: Object.keys(experts),
1758
+ model: setting.model,
1759
+ temperature: setting.temperature,
1760
+ maxSteps: setting.maxSteps,
1761
+ maxRetries: setting.maxRetries,
1762
+ timeout: setting.timeout,
1763
+ query: setting.input.text,
1764
+ interactiveToolCall: setting.input.interactiveToolCallResult
1765
+ });
1766
+ options.eventListener(initEvent);
1767
+ }
1768
+ const skillManagers = await getSkillManagers(
1769
+ expertToRun,
1770
+ experts,
1771
+ setting,
1772
+ options?.eventListener
1773
+ );
1898
1774
  const runActor = createActor(runtimeStateMachine, {
1899
1775
  input: {
1900
1776
  setting: {
@@ -2060,23 +1936,14 @@ async function setupExperts(setting) {
2060
1936
  }
2061
1937
  return { expertToRun, experts };
2062
1938
  }
2063
- function printRunSetting(expertName, experts, setting) {
2064
- console.log("Starting Perstack");
2065
- console.log(`Expert To Run: ${expertName}`);
2066
- console.log(`Experts: ${Object.keys(experts).join(", ")}`);
2067
- console.log(`Model: ${setting.model}`);
2068
- console.log(`Temperature: ${setting.temperature}`);
2069
- console.log(`Max Steps: ${setting.maxSteps}`);
2070
- console.log(`Max Retries: ${setting.maxRetries}`);
2071
- console.log(`Timeout: ${setting.timeout}`);
2072
- if (setting.input.text) {
2073
- console.log(`Query: ${setting.input.text}`);
2074
- }
2075
- if (setting.input.interactiveToolCallResult) {
2076
- console.log(`Tool: ${setting.input.interactiveToolCallResult.toolName}`);
2077
- console.log(`Tool Call ID: ${setting.input.interactiveToolCallResult.toolCallId}`);
2078
- console.log(`Tool Result: ${setting.input.interactiveToolCallResult.text}`);
2079
- }
1939
+ function getEventListener(options) {
1940
+ const listener = options?.eventListener ?? ((e) => console.log(JSON.stringify(e)));
1941
+ return async (event) => {
1942
+ if ("stepNumber" in event) {
1943
+ await defaultStoreEvent(event);
1944
+ }
1945
+ listener(event);
1946
+ };
2080
1947
  }
2081
1948
  async function storeRunSetting(setting) {
2082
1949
  const runDir = getRunDir(setting.runId);
@@ -2084,20 +1951,16 @@ async function storeRunSetting(setting) {
2084
1951
  const runSettingPath = path.resolve(runDir, "run-setting.json");
2085
1952
  const runSetting = JSON.parse(await readFile(runSettingPath, "utf-8"));
2086
1953
  runSetting.updatedAt = Date.now();
2087
- await writeFile(runSettingPath, JSON.stringify(runSetting, null, 2), "utf-8");
1954
+ await writeFile(runSettingPath, JSON.stringify(runSetting), "utf-8");
2088
1955
  } else {
2089
1956
  await mkdir(runDir, { recursive: true });
2090
- await writeFile(
2091
- path.resolve(runDir, "run-setting.json"),
2092
- JSON.stringify(setting, null, 2),
2093
- "utf-8"
2094
- );
1957
+ await writeFile(path.resolve(runDir, "run-setting.json"), JSON.stringify(setting), "utf-8");
2095
1958
  }
2096
1959
  }
2097
1960
  function getRunDir(runId) {
2098
1961
  return `${process.cwd()}/perstack/runs/${runId}`;
2099
1962
  }
2100
1963
 
2101
- export { StateMachineLogics, calculateContextWindowUsage, defaultEventListener, getContextWindow, getModel, getRunDir, run, runtimeStateMachine };
1964
+ export { RUNTIME_VERSION, StateMachineLogics, calculateContextWindowUsage, getContextWindow, getModel, getRunDir, run, runtimeStateMachine };
2102
1965
  //# sourceMappingURL=index.js.map
2103
1966
  //# sourceMappingURL=index.js.map