agency-lang 0.0.96 → 0.0.98

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.
@@ -8,7 +8,7 @@ import { spawn } from "child_process";
8
8
  import { transformSync } from "esbuild";
9
9
  import * as fs from "fs";
10
10
  import * as path from "path";
11
- import { getStdlibDir, isPkgImport, isStdlibImport, resolveAgencyImportPath, } from "../importPaths.js";
11
+ import { getStdlibDir, isPkgImport, isStdlibImport, resolveAgencyImportPath, resolveFlexibleExtension, } from "../importPaths.js";
12
12
  import { parseAgency } from "../parser.js";
13
13
  import { findRecursively, getImports } from "./util.js";
14
14
  // Load configuration from agency.json
@@ -136,10 +136,31 @@ export function compile(config, inputFile, _outputFile, options) {
136
136
  }
137
137
  compile(config, absPath, undefined, { ...options, symbolTable });
138
138
  }
139
- // Update the import path in the AST to reference the new .ts file
139
+ // Update import paths in the AST
140
140
  resolvedProgram.nodes.forEach((node) => {
141
- if (node.type === "importStatement" && !isStdlibImport(node.modulePath) && !isPkgImport(node.modulePath)) {
141
+ if (node.type !== "importStatement")
142
+ return;
143
+ if (isStdlibImport(node.modulePath) || isPkgImport(node.modulePath))
144
+ return;
145
+ if (node.modulePath.endsWith(".agency")) {
142
146
  node.modulePath = node.modulePath.replace(".agency", ext);
147
+ return;
148
+ }
149
+ // For .js/.ts imports, resolve flexibly: if the specified file doesn't
150
+ // exist, try the other extension. This lets users write .js imports that
151
+ // work in dist/ while the debugger finds the .ts source (and vice versa).
152
+ if (node.modulePath.endsWith(".js") || node.modulePath.endsWith(".ts")) {
153
+ const resolved = resolveFlexibleExtension(node.modulePath, absoluteInputFile);
154
+ if (resolved === null) {
155
+ const altExt = node.modulePath.endsWith(".js") ? ".ts" : ".js";
156
+ const altPath = node.modulePath.replace(/\.(js|ts)$/, altExt);
157
+ console.error(`Error: Cannot resolve import '${node.modulePath}' from '${inputFile}'.\n` +
158
+ `Tried: ${node.modulePath}, ${altPath} — neither file exists.`);
159
+ process.exit(1);
160
+ }
161
+ // Rewrite the import to use whatever extension actually exists on disk
162
+ const resolvedExt = path.extname(resolved);
163
+ node.modulePath = node.modulePath.replace(/\.(js|ts)$/, resolvedExt);
143
164
  }
144
165
  });
145
166
  const moduleId = path.relative(process.cwd(), absoluteInputFile);
@@ -4,4 +4,5 @@ export declare function debug(config: AgencyConfig, _inputFile: string, options?
4
4
  rewindSize?: number;
5
5
  trace?: string;
6
6
  checkpoint?: string;
7
+ distDir?: string;
7
8
  }): Promise<void>;
@@ -77,25 +77,51 @@ export async function debug(config, _inputFile, options = {}) {
77
77
  }
78
78
  traceCheckpoints = [cp];
79
79
  }
80
- // Force debugger mode so the builder emits debugStep() calls
81
- const debugConfig = { ...config, debugger: true };
82
- // Compile the .agency file to .js
83
- const outputFile = compile(debugConfig, inputFile);
84
- if (outputFile === null) {
85
- console.error("Error: No output file generated.");
86
- process.exit(1);
80
+ // Resolve distDir from CLI flag or config
81
+ const distDir = options.distDir ?? config.distDir;
82
+ let absOutput;
83
+ if (distDir) {
84
+ // distDir mode: import pre-compiled JS from the dist directory
85
+ const basename = path.basename(inputFile, ".agency") + ".js";
86
+ const compiledPath = path.resolve(distDir, basename);
87
+ if (!fs.existsSync(compiledPath)) {
88
+ console.error(`Error: Compiled file not found: ${compiledPath}\n` +
89
+ `Make sure you have compiled your Agency files and that distDir is correct.`);
90
+ process.exit(1);
91
+ }
92
+ // Warn if source is newer than compiled output
93
+ const sourceMtime = fs.statSync(inputFile).mtimeMs;
94
+ const compiledMtime = fs.statSync(compiledPath).mtimeMs;
95
+ if (sourceMtime > compiledMtime) {
96
+ console.warn(`Warning: ${inputFile} is newer than ${compiledPath}.\n` +
97
+ `You may need to recompile before debugging.`);
98
+ }
99
+ absOutput = compiledPath;
100
+ }
101
+ else {
102
+ // Normal mode: compile the .agency file to .js on the fly
103
+ const debugConfig = { ...config, debugger: true };
104
+ const outputFile = compile(debugConfig, inputFile);
105
+ if (outputFile === null) {
106
+ console.error("Error: No output file generated.");
107
+ process.exit(1);
108
+ }
109
+ absOutput = path.resolve(outputFile);
87
110
  }
88
111
  // Signal to stdlib UI components that they should fall back to console.log
89
112
  // instead of drawing their own TUI, which would conflict with the debugger.
90
113
  process.env.AGENCY_DEBUGGER = "1";
91
114
  // Dynamically import the compiled module
92
- const absOutput = path.resolve(outputFile);
93
115
  const mod = await import(absOutput);
94
116
  // Get the source map from the module
95
117
  const sourceMap = mod.__sourceMap ?? {};
118
+ if (distDir && Object.keys(sourceMap).length === 0) {
119
+ console.warn("Warning: The compiled module has an empty source map. Was it compiled with instrument: false?\n" +
120
+ "The debugger may not be able to step through code.");
121
+ }
96
122
  // Parse the .agency file to get the list of graph nodes
97
123
  const contents = fs.readFileSync(inputFile, "utf-8");
98
- const parseResult = parseAgency(contents, debugConfig);
124
+ const parseResult = parseAgency(contents, config);
99
125
  if (!parseResult.success) {
100
126
  console.error("Error: Could not parse Agency file.");
101
127
  process.exit(1);
@@ -104,12 +104,27 @@ export async function promptForArgs(selectedNode) {
104
104
  return { hasArgs, argsString };
105
105
  }
106
106
  export async function executeNodeAsync({ config, agencyFile, nodeName, hasArgs, argsString, interruptHandlers, }) {
107
- compile(config, agencyFile);
107
+ const distDir = config.distDir;
108
+ let compiledFilename;
109
+ if (distDir) {
110
+ // distDir mode: skip compilation, import pre-compiled JS from distDir
111
+ const basename = path.basename(agencyFile, ".agency") + ".js";
112
+ const compiledPath = path.resolve(distDir, basename);
113
+ if (!fs.existsSync(compiledPath)) {
114
+ throw new Error(`Compiled file not found: ${compiledPath}\n` +
115
+ `Make sure you have compiled your Agency files and that distDir is correct.`);
116
+ }
117
+ compiledFilename = compiledPath;
118
+ }
119
+ else {
120
+ compile(config, agencyFile);
121
+ compiledFilename = path.basename(agencyFile).replace(".agency", ".js");
122
+ }
108
123
  const baseName = agencyFile.replace(".agency", "");
109
124
  const evaluateFile = `${baseName}.evaluate.js`;
110
125
  const resultsFile = `${baseName}.evaluate.json`;
111
126
  const evaluateScript = renderEvaluate({
112
- filename: path.basename(agencyFile).replace(".agency", ".js"),
127
+ filename: compiledFilename,
113
128
  nodeName,
114
129
  hasArgs,
115
130
  args: argsString,
@@ -137,10 +152,23 @@ export async function executeNodeAsync({ config, agencyFile, nodeName, hasArgs,
137
152
  }
138
153
  }
139
154
  export function executeNode(args) {
140
- const outFile = args.agencyFile.replace(".agency", ".js");
141
- compile(args.config, args.agencyFile);
155
+ const distDir = args.config.distDir;
156
+ let compiledFilename;
157
+ if (distDir) {
158
+ const basename = path.basename(args.agencyFile, ".agency") + ".js";
159
+ const compiledPath = path.resolve(distDir, basename);
160
+ if (!fs.existsSync(compiledPath)) {
161
+ throw new Error(`Compiled file not found: ${compiledPath}\n` +
162
+ `Make sure you have compiled your Agency files and that distDir is correct.`);
163
+ }
164
+ compiledFilename = compiledPath;
165
+ }
166
+ else {
167
+ compile(args.config, args.agencyFile);
168
+ compiledFilename = args.agencyFile.replace(".agency", ".js");
169
+ }
142
170
  const evaluateScript = renderEvaluate({
143
- filename: outFile,
171
+ filename: compiledFilename,
144
172
  nodeName: args.nodeName,
145
173
  hasArgs: args.hasArgs,
146
174
  args: args.argsString,
@@ -102,6 +102,10 @@ export interface AgencyConfig {
102
102
  /** Directory for auto-generated trace files. Each execution creates a new file
103
103
  * named <timestamp>_<id>.agencytrace. */
104
104
  traceDir?: string;
105
+ /** Directory containing pre-compiled JS output (e.g., "dist").
106
+ * When set, the debugger imports compiled modules from this directory
107
+ * instead of compiling on the fly. Resolved relative to cwd. */
108
+ distDir?: string;
105
109
  /** Test runner configuration */
106
110
  test?: {
107
111
  /** Number of test files to run in parallel. Default: 1 (sequential). */
@@ -64,6 +64,12 @@ export declare function resolvePkgAgencyPath(importPath: string, fromFile: strin
64
64
  * - "./foo.js" -> resolved relative to the importing file (non-agency, kept as-is)
65
65
  */
66
66
  export declare function resolveAgencyImportPath(importPath: string, fromFile: string): string;
67
+ /**
68
+ * Resolve a .js or .ts import path, trying the other extension if the
69
+ * specified file doesn't exist. Returns the resolved absolute path, or
70
+ * null if neither extension exists on disk.
71
+ */
72
+ export declare function resolveFlexibleExtension(importPath: string, fromFile: string): string | null;
67
73
  /**
68
74
  * Convert an Agency import path to the path that should appear in generated
69
75
  * TypeScript import statements.
@@ -216,6 +216,29 @@ export function resolveAgencyImportPath(importPath, fromFile) {
216
216
  // Relative or other imports: resolve against the importing file's directory
217
217
  return path.resolve(path.dirname(fromFile), importPath);
218
218
  }
219
+ const FLEXIBLE_EXTENSIONS = {
220
+ ".js": ".ts",
221
+ ".ts": ".js",
222
+ };
223
+ /**
224
+ * Resolve a .js or .ts import path, trying the other extension if the
225
+ * specified file doesn't exist. Returns the resolved absolute path, or
226
+ * null if neither extension exists on disk.
227
+ */
228
+ export function resolveFlexibleExtension(importPath, fromFile) {
229
+ const ext = path.extname(importPath);
230
+ const altExt = FLEXIBLE_EXTENSIONS[ext];
231
+ if (!altExt)
232
+ return null; // not a .js/.ts import
233
+ const dir = path.dirname(fromFile);
234
+ const resolved = path.resolve(dir, importPath);
235
+ if (fs.existsSync(resolved))
236
+ return resolved;
237
+ const altPath = resolved.slice(0, -ext.length) + altExt;
238
+ if (fs.existsSync(altPath))
239
+ return altPath;
240
+ return null;
241
+ }
219
242
  /**
220
243
  * Convert an Agency import path to the path that should appear in generated
221
244
  * TypeScript import statements.
@@ -1,5 +1,5 @@
1
- import { describe, it, expect } from "vitest";
2
- import { findPackageRoot, resolveAgencyImportPath, getStdlibDir, toCompiledImportPath, isPkgImport, isAgencyImport, parsePkgImport, resolvePkgAgencyPath, } from "./importPaths.js";
1
+ import { describe, it, expect, beforeEach, afterEach } from "vitest";
2
+ import { findPackageRoot, resolveAgencyImportPath, resolveFlexibleExtension, getStdlibDir, toCompiledImportPath, isPkgImport, isAgencyImport, parsePkgImport, resolvePkgAgencyPath, } from "./importPaths.js";
3
3
  import { buildSymbolTable } from "./symbolTable.js";
4
4
  import * as fs from "fs";
5
5
  import * as os from "os";
@@ -235,3 +235,52 @@ describe("buildSymbolTable with pkg:: imports", () => {
235
235
  }
236
236
  });
237
237
  });
238
+ describe("resolveFlexibleExtension", () => {
239
+ let tmpDir;
240
+ beforeEach(() => {
241
+ tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "agency-flex-ext-"));
242
+ });
243
+ afterEach(() => {
244
+ fs.rmSync(tmpDir, { recursive: true, force: true });
245
+ });
246
+ it("should return the resolved path when the file exists as-is", () => {
247
+ const tsFile = path.join(tmpDir, "bar.ts");
248
+ fs.writeFileSync(tsFile, "export const x = 1;");
249
+ const fromFile = path.join(tmpDir, "main.agency");
250
+ const result = resolveFlexibleExtension("./bar.ts", fromFile);
251
+ expect(result).toBe(tsFile);
252
+ });
253
+ it("should fall back from .js to .ts when .js doesn't exist", () => {
254
+ const tsFile = path.join(tmpDir, "bar.ts");
255
+ fs.writeFileSync(tsFile, "export const x = 1;");
256
+ const fromFile = path.join(tmpDir, "main.agency");
257
+ const result = resolveFlexibleExtension("./bar.js", fromFile);
258
+ expect(result).toBe(tsFile);
259
+ });
260
+ it("should fall back from .ts to .js when .ts doesn't exist", () => {
261
+ const jsFile = path.join(tmpDir, "bar.js");
262
+ fs.writeFileSync(jsFile, "export const x = 1;");
263
+ const fromFile = path.join(tmpDir, "main.agency");
264
+ const result = resolveFlexibleExtension("./bar.ts", fromFile);
265
+ expect(result).toBe(jsFile);
266
+ });
267
+ it("should return null when neither .js nor .ts exists", () => {
268
+ const fromFile = path.join(tmpDir, "main.agency");
269
+ const result = resolveFlexibleExtension("./bar.js", fromFile);
270
+ expect(result).toBeNull();
271
+ });
272
+ it("should return null for non-.js/.ts extensions", () => {
273
+ const fromFile = path.join(tmpDir, "main.agency");
274
+ const result = resolveFlexibleExtension("./bar.css", fromFile);
275
+ expect(result).toBeNull();
276
+ });
277
+ it("should prefer the exact extension when both files exist", () => {
278
+ const jsFile = path.join(tmpDir, "bar.js");
279
+ const tsFile = path.join(tmpDir, "bar.ts");
280
+ fs.writeFileSync(jsFile, "export const x = 1;");
281
+ fs.writeFileSync(tsFile, "export const x = 1;");
282
+ const fromFile = path.join(tmpDir, "main.agency");
283
+ expect(resolveFlexibleExtension("./bar.js", fromFile)).toBe(jsFile);
284
+ expect(resolveFlexibleExtension("./bar.ts", fromFile)).toBe(tsFile);
285
+ });
286
+ });
@@ -59,8 +59,8 @@ export function printTs(node, indent = 0) {
59
59
  }
60
60
  }
61
61
  case "varDecl": {
62
- //let s = `${node.declKind} ${node.name}`;
63
- let s = `var ${node.name}`;
62
+ let s = `${node.declKind} ${node.name}`;
63
+ // let s = `var ${node.name}`;
64
64
  if (node.typeAnnotation)
65
65
  s += `: ${node.typeAnnotation}`;
66
66
  if (node.initializer)
@@ -1 +1 @@
1
- export declare const VERSION = "0.0.96";
1
+ export declare const VERSION = "0.0.98";
@@ -1 +1 @@
1
- export const VERSION = "0.0.96";
1
+ export const VERSION = "0.0.98";
@@ -339,6 +339,7 @@ program
339
339
  .option("--rewind-size <n>", "Rolling checkpoint window size", "30")
340
340
  .option("--trace <file>", "Load and inspect a trace file")
341
341
  .option("--checkpoint <file>", "Load and inspect a checkpoint file")
342
+ .option("--dist-dir <dir>", "Import pre-compiled JS from this directory instead of compiling on the fly")
342
343
  .action(async (file, options) => {
343
344
  const config = getConfig();
344
345
  await debug(config, file, {
@@ -346,6 +347,7 @@ program
346
347
  rewindSize: parseInt(options.rewindSize, 10),
347
348
  trace: options.trace,
348
349
  checkpoint: options.checkpoint,
350
+ distDir: options.distDir,
349
351
  });
350
352
  });
351
353
  program
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agency-lang",
3
- "version": "0.0.96",
3
+ "version": "0.0.98",
4
4
  "description": "The Agency language",
5
5
  "main": "lib/index.js",
6
6
  "scripts": {
@@ -0,0 +1,29 @@
1
+ import { execFileSync } from "child_process";
2
+ import { detectPlatform } from "./_utils.js";
3
+ export function _copy(text) {
4
+ const platform = detectPlatform();
5
+ if (platform === "macos") {
6
+ execFileSync("pbcopy", [], { input: text });
7
+ }
8
+ else if (platform === "linux") {
9
+ execFileSync("xclip", ["-selection", "clipboard"], { input: text });
10
+ }
11
+ else {
12
+ console.error(`copy is not supported on platform: ${platform}. ` +
13
+ `Supported platforms: macOS, Linux.`);
14
+ }
15
+ }
16
+ export function _paste() {
17
+ const platform = detectPlatform();
18
+ if (platform === "macos") {
19
+ return execFileSync("pbpaste").toString();
20
+ }
21
+ else if (platform === "linux") {
22
+ return execFileSync("xclip", ["-selection", "clipboard", "-o"]).toString();
23
+ }
24
+ else {
25
+ console.error(`paste is not supported on platform: ${platform}. ` +
26
+ `Supported platforms: macOS, Linux.`);
27
+ return "";
28
+ }
29
+ }
@@ -0,0 +1,69 @@
1
+ import { execFileSync } from "child_process";
2
+ import fsSync from "fs";
3
+ import fs from "fs/promises";
4
+ import { nanoid } from "nanoid";
5
+ import os from "os";
6
+ import path from "path";
7
+ import process from "process";
8
+ import { detectPlatform } from "./_utils.js";
9
+ export function _speak(text, voice, rate, outputFile) {
10
+ if (text === "")
11
+ return;
12
+ const platform = detectPlatform();
13
+ if (platform === "macos") {
14
+ const tmpFile = path.join(os.tmpdir(), `agency-speak-${nanoid()}.txt`);
15
+ try {
16
+ fsSync.writeFileSync(tmpFile, text, "utf8");
17
+ const args = ["-f", tmpFile];
18
+ if (voice !== "") {
19
+ args.push("-v", voice);
20
+ }
21
+ if (rate > 0) {
22
+ args.push("-r", String(rate));
23
+ }
24
+ if (outputFile !== "") {
25
+ args.push("-o", path.resolve(process.cwd(), outputFile));
26
+ }
27
+ execFileSync("say", args);
28
+ }
29
+ finally {
30
+ try {
31
+ fsSync.unlinkSync(tmpFile);
32
+ }
33
+ catch { }
34
+ }
35
+ }
36
+ else {
37
+ console.error(`speak is not supported on platform: ${platform}. ` +
38
+ `Supported platforms: macOS.`);
39
+ }
40
+ }
41
+ export async function _transcribe(filepath, language) {
42
+ const apiKey = process.env["OPENAI_API_KEY"];
43
+ if (!apiKey) {
44
+ throw new Error("transcribe requires an OPENAI_API_KEY environment variable to be set.");
45
+ }
46
+ const resolvedPath = path.resolve(process.cwd(), filepath);
47
+ const fileData = await fs.readFile(resolvedPath);
48
+ const filename = path.basename(resolvedPath);
49
+ const formData = new FormData();
50
+ formData.append("file", new Blob([fileData]), filename);
51
+ formData.append("model", "whisper-1");
52
+ if (language !== "") {
53
+ formData.append("language", language);
54
+ }
55
+ const response = await fetch("https://api.openai.com/v1/audio/transcriptions", {
56
+ method: "POST",
57
+ headers: {
58
+ "Authorization": `Bearer ${apiKey}`,
59
+ },
60
+ body: formData,
61
+ });
62
+ if (!response.ok) {
63
+ const errorBody = await response.json();
64
+ const message = errorBody?.error?.message ?? JSON.stringify(errorBody);
65
+ throw new Error(`Whisper API error (${response.status}): ${message}`);
66
+ }
67
+ const result = await response.json();
68
+ return result.text;
69
+ }
@@ -0,0 +1,29 @@
1
+ import { execFileSync } from "child_process";
2
+ import path from "path";
3
+ import process from "process";
4
+ import { detectPlatform } from "./_utils.js";
5
+ export function _screenshot(filepath, x, y, width, height) {
6
+ const platform = detectPlatform();
7
+ const resolvedPath = path.resolve(process.cwd(), filepath);
8
+ const hasRegion = x >= 0 && y >= 0 && width >= 0 && height >= 0;
9
+ if (platform === "macos") {
10
+ if (hasRegion) {
11
+ execFileSync("screencapture", ["-R", `${x},${y},${width},${height}`, resolvedPath]);
12
+ }
13
+ else {
14
+ execFileSync("screencapture", ["-x", resolvedPath]);
15
+ }
16
+ }
17
+ else if (platform === "linux") {
18
+ if (hasRegion) {
19
+ execFileSync("import", ["-crop", `${width}x${height}+${x}+${y}`, "-window", "root", resolvedPath]);
20
+ }
21
+ else {
22
+ execFileSync("import", ["-window", "root", resolvedPath]);
23
+ }
24
+ }
25
+ else {
26
+ console.error(`screenshot is not supported on platform: ${platform}. ` +
27
+ `Supported platforms: macOS, Linux.`);
28
+ }
29
+ }
package/stdlib/agent.js CHANGED
@@ -1,5 +1,4 @@
1
- import { print, __printTool, __printToolParams, printJSON, __printJSONTool, __printJSONToolParams, input, __inputTool, __inputToolParams, sleep, __sleepTool, __sleepToolParams, round, __roundTool, __roundToolParams, fetch, __fetchTool, __fetchToolParams, fetchJSON, __fetchJSONTool, __fetchJSONToolParams, read, __readTool, __readToolParams, write, __writeTool, __writeToolParams, readImage, __readImageTool, __readImageToolParams, notify, __notifyTool, __notifyToolParams, range, __rangeTool, __rangeToolParams, mostCommon, __mostCommonTool, __mostCommonToolParams, keys, __keysTool, __keysToolParams, values, __valuesTool, __valuesToolParams, entries, __entriesTool, __entriesToolParams } from "/Users/adityabhargava/worktrees/agency-lang/stdlib/index.js";
2
- import { map, __mapTool, __mapToolParams, filter, __filterTool, __filterToolParams, exclude, __excludeTool, __excludeToolParams, find, __findTool, __findToolParams, findIndex, __findIndexTool, __findIndexToolParams, reduce, __reduceTool, __reduceToolParams, flatMap, __flatMapTool, __flatMapToolParams, every, __everyTool, __everyToolParams, some, __someTool, __someToolParams, count, __countTool, __countToolParams, sortBy, __sortByTool, __sortByToolParams, unique, __uniqueTool, __uniqueToolParams, groupBy, __groupByTool, __groupByToolParams } from "/Users/adityabhargava/worktrees/agency-lang/stdlib/array.js";
1
+ import { print, __printTool, __printToolParams, printJSON, __printJSONTool, __printJSONToolParams, input, __inputTool, __inputToolParams, sleep, __sleepTool, __sleepToolParams, round, __roundTool, __roundToolParams, fetch, __fetchTool, __fetchToolParams, fetchJSON, __fetchJSONTool, __fetchJSONToolParams, read, __readTool, __readToolParams, write, __writeTool, __writeToolParams, readImage, __readImageTool, __readImageToolParams, notify, __notifyTool, __notifyToolParams, range, __rangeTool, __rangeToolParams, mostCommon, __mostCommonTool, __mostCommonToolParams, keys, __keysTool, __keysToolParams, values, __valuesTool, __valuesToolParams, entries, __entriesTool, __entriesToolParams } from "/Users/adityabhargava/worktrees/agency-lang2/stdlib/index.js";
3
2
  import { fileURLToPath } from "url";
4
3
  import __process from "process";
5
4
  import { z } from "zod";
@@ -282,123 +281,6 @@ const __toolRegistry = {
282
281
  isBuiltin: false
283
282
  }
284
283
  },
285
- map: {
286
- definition: __mapTool,
287
- handler: {
288
- name: "map",
289
- params: __mapToolParams,
290
- execute: map,
291
- isBuiltin: false
292
- }
293
- },
294
- filter: {
295
- definition: __filterTool,
296
- handler: {
297
- name: "filter",
298
- params: __filterToolParams,
299
- execute: filter,
300
- isBuiltin: false
301
- }
302
- },
303
- exclude: {
304
- definition: __excludeTool,
305
- handler: {
306
- name: "exclude",
307
- params: __excludeToolParams,
308
- execute: exclude,
309
- isBuiltin: false
310
- }
311
- },
312
- find: {
313
- definition: __findTool,
314
- handler: {
315
- name: "find",
316
- params: __findToolParams,
317
- execute: find,
318
- isBuiltin: false
319
- }
320
- },
321
- findIndex: {
322
- definition: __findIndexTool,
323
- handler: {
324
- name: "findIndex",
325
- params: __findIndexToolParams,
326
- execute: findIndex,
327
- isBuiltin: false
328
- }
329
- },
330
- reduce: {
331
- definition: __reduceTool,
332
- handler: {
333
- name: "reduce",
334
- params: __reduceToolParams,
335
- execute: reduce,
336
- isBuiltin: false
337
- }
338
- },
339
- flatMap: {
340
- definition: __flatMapTool,
341
- handler: {
342
- name: "flatMap",
343
- params: __flatMapToolParams,
344
- execute: flatMap,
345
- isBuiltin: false
346
- }
347
- },
348
- every: {
349
- definition: __everyTool,
350
- handler: {
351
- name: "every",
352
- params: __everyToolParams,
353
- execute: every,
354
- isBuiltin: false
355
- }
356
- },
357
- some: {
358
- definition: __someTool,
359
- handler: {
360
- name: "some",
361
- params: __someToolParams,
362
- execute: some,
363
- isBuiltin: false
364
- }
365
- },
366
- count: {
367
- definition: __countTool,
368
- handler: {
369
- name: "count",
370
- params: __countToolParams,
371
- execute: count,
372
- isBuiltin: false
373
- }
374
- },
375
- sortBy: {
376
- definition: __sortByTool,
377
- handler: {
378
- name: "sortBy",
379
- params: __sortByToolParams,
380
- execute: sortBy,
381
- isBuiltin: false
382
- }
383
- },
384
- unique: {
385
- definition: __uniqueTool,
386
- handler: {
387
- name: "unique",
388
- params: __uniqueToolParams,
389
- execute: unique,
390
- isBuiltin: false
391
- }
392
- },
393
- groupBy: {
394
- definition: __groupByTool,
395
- handler: {
396
- name: "groupBy",
397
- params: __groupByToolParams,
398
- execute: groupBy,
399
- isBuiltin: false
400
- }
401
- },
402
284
  readSkill: {
403
285
  definition: __readSkillTool,
404
286
  handler: {