@samrahimi/smol-js 0.7.0 → 0.7.1

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.mjs CHANGED
@@ -724,7 +724,7 @@ Total time: ${(duration / 1e3).toFixed(2)}s`);
724
724
  }
725
725
  /** Sleep for a specified duration */
726
726
  sleep(ms) {
727
- return new Promise((resolve6) => setTimeout(resolve6, ms));
727
+ return new Promise((resolve7) => setTimeout(resolve7, ms));
728
728
  }
729
729
  };
730
730
 
@@ -1393,12 +1393,12 @@ var UserInputTool = class extends Tool {
1393
1393
  input: process.stdin,
1394
1394
  output: process.stdout
1395
1395
  });
1396
- return new Promise((resolve6) => {
1396
+ return new Promise((resolve7) => {
1397
1397
  rl.question(`
1398
1398
  [Agent asks]: ${question}
1399
1399
  Your response: `, (answer) => {
1400
1400
  rl.close();
1401
- resolve6(answer);
1401
+ resolve7(answer);
1402
1402
  });
1403
1403
  });
1404
1404
  }
@@ -2727,7 +2727,7 @@ var ExaResearchTool = class extends Tool {
2727
2727
  while (Date.now() - startTime < this.maxPollTime) {
2728
2728
  attempts++;
2729
2729
  if (attempts > 1) {
2730
- await new Promise((resolve6) => setTimeout(resolve6, this.pollInterval));
2730
+ await new Promise((resolve7) => setTimeout(resolve7, this.pollInterval));
2731
2731
  }
2732
2732
  const statusResponse = await fetch(`https://api.exa.ai/research/v1/${researchId}`, {
2733
2733
  method: "GET",
@@ -2780,6 +2780,7 @@ var ExaResearchTool = class extends Tool {
2780
2780
 
2781
2781
  // src/tools/ProxyTool.ts
2782
2782
  import { spawn } from "child_process";
2783
+ import * as path6 from "path";
2783
2784
 
2784
2785
  // src/utils/bunInstaller.ts
2785
2786
  import { execSync } from "child_process";
@@ -2838,10 +2839,12 @@ function whichBun() {
2838
2839
  }
2839
2840
 
2840
2841
  // src/tools/ProxyTool.ts
2841
- var TOOL_OUTPUT_PREFIX = "[TOOL_OUTPUT]";
2842
2842
  var TOOL_RESULT_PREFIX = "[TOOL_RESULT]";
2843
2843
  var TOOL_ERROR_PREFIX = "[TOOL_ERROR]";
2844
2844
  var DEFAULT_TOOL_TIMEOUT_MS = 6e4;
2845
+ function resolveHarnessPath() {
2846
+ return path6.resolve(__dirname, "..", "toolHarness.ts");
2847
+ }
2845
2848
  var ProxyTool = class extends Tool {
2846
2849
  name;
2847
2850
  description;
@@ -2850,6 +2853,7 @@ var ProxyTool = class extends Tool {
2850
2853
  toolPath;
2851
2854
  timeout;
2852
2855
  bunPath = null;
2856
+ harnessPath = null;
2853
2857
  constructor(config) {
2854
2858
  super();
2855
2859
  this.name = config.name;
@@ -2860,23 +2864,25 @@ var ProxyTool = class extends Tool {
2860
2864
  this.timeout = config.timeout ?? DEFAULT_TOOL_TIMEOUT_MS;
2861
2865
  }
2862
2866
  /**
2863
- * Ensure Bun is available before first invocation.
2867
+ * Ensure Bun is available and locate the harness before first invocation.
2864
2868
  */
2865
2869
  async setup() {
2866
2870
  this.bunPath = await ensureBunAvailable();
2871
+ this.harnessPath = resolveHarnessPath();
2867
2872
  this.isSetup = true;
2868
2873
  }
2869
2874
  /**
2870
- * Spawn the tool in a Bun child process, pass serialized args via CLI,
2871
- * stream stdout back as log lines, and parse the final result.
2875
+ * Spawn the harness in a Bun child process. The harness imports the tool,
2876
+ * calls execute(args), and writes the protocol lines. Any console.log from
2877
+ * the tool flows through stdout as plain lines.
2872
2878
  */
2873
2879
  async execute(args) {
2874
- if (!this.bunPath) {
2880
+ if (!this.bunPath || !this.harnessPath) {
2875
2881
  await this.setup();
2876
2882
  }
2877
2883
  const serializedArgs = JSON.stringify(args);
2878
- return new Promise((resolve6, reject) => {
2879
- const child = spawn(this.bunPath, ["run", this.toolPath, serializedArgs], {
2884
+ return new Promise((resolve7, reject) => {
2885
+ const child = spawn(this.bunPath, ["run", this.harnessPath, this.toolPath, serializedArgs], {
2880
2886
  stdio: ["pipe", "pipe", "pipe"],
2881
2887
  env: { ...process.env }
2882
2888
  });
@@ -2941,12 +2947,12 @@ ${logBuffer.join("\n")}
2941
2947
  [Tool result]
2942
2948
  `;
2943
2949
  if (typeof result === "string") {
2944
- resolve6(logPrefix + result);
2950
+ resolve7(logPrefix + result);
2945
2951
  } else {
2946
- resolve6({ logs: logBuffer.join("\n"), result });
2952
+ resolve7({ logs: logBuffer.join("\n"), result });
2947
2953
  }
2948
2954
  } else {
2949
- resolve6(result);
2955
+ resolve7(result);
2950
2956
  }
2951
2957
  return;
2952
2958
  }
@@ -2956,7 +2962,7 @@ ${logBuffer.join("\n")}
2956
2962
  `Custom tool "${this.name}" exited with code ${code}. Output: ${combined || "(none)"}`
2957
2963
  ));
2958
2964
  } else {
2959
- resolve6(combined || `Tool "${this.name}" produced no output.`);
2965
+ resolve7(combined || `Tool "${this.name}" produced no output.`);
2960
2966
  }
2961
2967
  });
2962
2968
  child.on("error", (err) => {
@@ -2967,7 +2973,7 @@ ${logBuffer.join("\n")}
2967
2973
  });
2968
2974
  });
2969
2975
  }
2970
- // --- internal line parser ---
2976
+ // --- line parser: protocol is spoken by harness, interpreted here ---
2971
2977
  processLine(line, handlers) {
2972
2978
  const trimmed = line.trimEnd();
2973
2979
  if (!trimmed) return;
@@ -2980,8 +2986,6 @@ ${logBuffer.join("\n")}
2980
2986
  }
2981
2987
  } else if (trimmed.startsWith(TOOL_ERROR_PREFIX)) {
2982
2988
  handlers.onError(trimmed.slice(TOOL_ERROR_PREFIX.length).trim());
2983
- } else if (trimmed.startsWith(TOOL_OUTPUT_PREFIX)) {
2984
- handlers.onOutput(trimmed.slice(TOOL_OUTPUT_PREFIX.length).trim());
2985
2989
  } else {
2986
2990
  handlers.onOutput(trimmed);
2987
2991
  }
@@ -2990,7 +2994,7 @@ ${logBuffer.join("\n")}
2990
2994
 
2991
2995
  // src/tools/CustomToolScanner.ts
2992
2996
  import * as fs6 from "fs";
2993
- import * as path6 from "path";
2997
+ import * as path7 from "path";
2994
2998
  var METADATA_REGEX = /export\s+const\s+TOOL_METADATA\s*=\s*(\{[\s\S]*?\});\s*$/m;
2995
2999
  function scanCustomTools(folderPath) {
2996
3000
  if (!fs6.existsSync(folderPath)) {
@@ -3002,10 +3006,10 @@ function scanCustomTools(folderPath) {
3002
3006
  const discovered = [];
3003
3007
  for (const entry of entries) {
3004
3008
  if (entry.isDirectory()) continue;
3005
- const ext = path6.extname(entry.name).toLowerCase();
3009
+ const ext = path7.extname(entry.name).toLowerCase();
3006
3010
  if (ext !== ".ts" && ext !== ".js") continue;
3007
- const filePath = path6.resolve(folderPath, entry.name);
3008
- const baseName = path6.basename(entry.name, ext);
3011
+ const filePath = path7.resolve(folderPath, entry.name);
3012
+ const baseName = path7.basename(entry.name, ext);
3009
3013
  let metadata;
3010
3014
  try {
3011
3015
  metadata = extractMetadata(filePath);
@@ -3073,7 +3077,7 @@ function loadCustomTools(folderPath) {
3073
3077
 
3074
3078
  // src/orchestrator/YAMLLoader.ts
3075
3079
  import * as fs7 from "fs";
3076
- import * as path7 from "path";
3080
+ import * as path8 from "path";
3077
3081
  import YAML from "yaml";
3078
3082
  var TOOL_REGISTRY = {
3079
3083
  read_file: ReadFileTool,
@@ -3105,7 +3109,7 @@ var YAMLLoader = class {
3105
3109
  * Load a workflow from a YAML file path.
3106
3110
  */
3107
3111
  loadFromFile(filePath) {
3108
- const absolutePath = path7.isAbsolute(filePath) ? filePath : path7.resolve(process.cwd(), filePath);
3112
+ const absolutePath = path8.isAbsolute(filePath) ? filePath : path8.resolve(process.cwd(), filePath);
3109
3113
  if (!fs7.existsSync(absolutePath)) {
3110
3114
  throw new Error(`Workflow file not found: ${absolutePath}`);
3111
3115
  }