agency-lang 0.0.97 → 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.
- package/dist/lib/cli/commands.js +24 -3
- package/dist/lib/cli/debug.d.ts +1 -0
- package/dist/lib/cli/debug.js +35 -9
- package/dist/lib/cli/util.js +33 -5
- package/dist/lib/config.d.ts +4 -0
- package/dist/lib/importPaths.d.ts +6 -0
- package/dist/lib/importPaths.js +23 -0
- package/dist/lib/importPaths.test.js +51 -2
- package/dist/lib/version.d.ts +1 -1
- package/dist/lib/version.js +1 -1
- package/dist/scripts/agency.js +2 -0
- package/package.json +1 -1
- package/stdlib/_clipboard.js +29 -0
- package/stdlib/_speech.js +69 -0
- package/stdlib/_system.js +29 -0
- package/stdlib/agent.js +43 -43
- package/stdlib/array.js +414 -365
- package/stdlib/clipboard.js +290 -0
- package/stdlib/consensus.js +359 -0
- package/stdlib/firstValid.js +384 -0
- package/stdlib/fs.js +95 -95
- package/stdlib/index.js +214 -215
- package/stdlib/math.js +43 -43
- package/stdlib/object.js +836 -1160
- package/stdlib/path.js +95 -95
- package/stdlib/{weather.js → retry.js} +143 -319
- package/stdlib/sample.js +350 -0
- package/stdlib/shell.js +95 -95
- package/stdlib/speech.js +307 -0
- package/stdlib/strategy.js +69 -69
- package/stdlib/system.js +56 -56
- package/stdlib/_utils.js +0 -51
- package/stdlib/ui.js +0 -1722
package/dist/lib/cli/commands.js
CHANGED
|
@@ -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
|
|
139
|
+
// Update import paths in the AST
|
|
140
140
|
resolvedProgram.nodes.forEach((node) => {
|
|
141
|
-
if (node.type
|
|
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);
|
package/dist/lib/cli/debug.d.ts
CHANGED
package/dist/lib/cli/debug.js
CHANGED
|
@@ -77,25 +77,51 @@ export async function debug(config, _inputFile, options = {}) {
|
|
|
77
77
|
}
|
|
78
78
|
traceCheckpoints = [cp];
|
|
79
79
|
}
|
|
80
|
-
//
|
|
81
|
-
const
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
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,
|
|
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);
|
package/dist/lib/cli/util.js
CHANGED
|
@@ -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
|
-
|
|
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:
|
|
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
|
|
141
|
-
|
|
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:
|
|
171
|
+
filename: compiledFilename,
|
|
144
172
|
nodeName: args.nodeName,
|
|
145
173
|
hasArgs: args.hasArgs,
|
|
146
174
|
args: args.argsString,
|
package/dist/lib/config.d.ts
CHANGED
|
@@ -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.
|
package/dist/lib/importPaths.js
CHANGED
|
@@ -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
|
+
});
|
package/dist/lib/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const VERSION = "0.0.
|
|
1
|
+
export declare const VERSION = "0.0.98";
|
package/dist/lib/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const VERSION = "0.0.
|
|
1
|
+
export const VERSION = "0.0.98";
|
package/dist/scripts/agency.js
CHANGED
|
@@ -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
|
@@ -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,4 +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-
|
|
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";
|
|
2
2
|
import { fileURLToPath } from "url";
|
|
3
3
|
import __process from "process";
|
|
4
4
|
import { z } from "zod";
|
|
@@ -33,7 +33,7 @@ const __filename = fileURLToPath(import.meta.url);
|
|
|
33
33
|
const __dirname = path.dirname(__filename);
|
|
34
34
|
const __cwd = __process.cwd();
|
|
35
35
|
const getDirname = () => __dirname;
|
|
36
|
-
|
|
36
|
+
const __globalCtx = new RuntimeContext({
|
|
37
37
|
statelogConfig: {
|
|
38
38
|
host: "https://statelog.adit.io",
|
|
39
39
|
apiKey: __process.env["STATELOG_API_KEY"] || "",
|
|
@@ -58,7 +58,7 @@ var __globalCtx = new RuntimeContext({
|
|
|
58
58
|
traceDir: "traces"
|
|
59
59
|
}
|
|
60
60
|
});
|
|
61
|
-
|
|
61
|
+
const graph = __globalCtx.graph;
|
|
62
62
|
function readSkill({ filepath }) {
|
|
63
63
|
return _readSkillRaw({ filepath, dirname: __dirname });
|
|
64
64
|
}
|
|
@@ -91,25 +91,25 @@ async function __initializeGlobals(__ctx) {
|
|
|
91
91
|
__ctx.globals.markInitialized("stdlib/agent.agency");
|
|
92
92
|
__ctx.globals.set("stdlib/agent.agency", "_todos", []);
|
|
93
93
|
}
|
|
94
|
-
|
|
94
|
+
const __todoWriteTool = {
|
|
95
95
|
name: "todoWrite",
|
|
96
96
|
description: `Replace the current todo list. Each todo has an id, text, and status (one of 'pending', 'in_progress', 'completed'). Use this to track multi-step work as you go: mark a todo 'in_progress' before starting it and 'completed' when done. Returns the new list.`,
|
|
97
97
|
schema: z.object({ "todos": z.array(z.object({ "id": z.string(), "text": z.string(), "status": z.union([z.literal("pending"), z.literal("in_progress"), z.literal("completed")]) })) })
|
|
98
98
|
};
|
|
99
|
-
|
|
100
|
-
|
|
99
|
+
const __todoWriteToolParams = ["todos"];
|
|
100
|
+
const __todoListTool = {
|
|
101
101
|
name: "todoList",
|
|
102
102
|
description: `Return the current todo list.`,
|
|
103
103
|
schema: z.object({})
|
|
104
104
|
};
|
|
105
|
-
|
|
106
|
-
|
|
105
|
+
const __todoListToolParams = [];
|
|
106
|
+
const __questionTool = {
|
|
107
107
|
name: "question",
|
|
108
108
|
description: `Ask the user a question and wait for their reply. Unlike input(), this raises an interrupt so the host (CLI, web UI, etc.) can present the prompt in its own way; the host resolves the interrupt with the answer string.`,
|
|
109
109
|
schema: z.object({ "prompt": z.string() })
|
|
110
110
|
};
|
|
111
|
-
|
|
112
|
-
|
|
111
|
+
const __questionToolParams = ["prompt"];
|
|
112
|
+
const __toolRegistry = {
|
|
113
113
|
todoWrite: {
|
|
114
114
|
definition: __todoWriteTool,
|
|
115
115
|
handler: {
|
|
@@ -292,22 +292,22 @@ var __toolRegistry = {
|
|
|
292
292
|
}
|
|
293
293
|
};
|
|
294
294
|
async function todoWrite(todos, __state = void 0) {
|
|
295
|
-
|
|
295
|
+
const __setupData = setupFunction({
|
|
296
296
|
state: __state
|
|
297
297
|
});
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
298
|
+
const __stack = __setupData.stack;
|
|
299
|
+
const __step = __setupData.step;
|
|
300
|
+
const __self = __setupData.self;
|
|
301
|
+
const __threads = __setupData.threads;
|
|
302
|
+
const __ctx = __state?.ctx || __globalCtx;
|
|
303
|
+
const statelogClient = __ctx.statelogClient;
|
|
304
|
+
const __graph = __ctx.graph;
|
|
305
|
+
let __forked;
|
|
306
|
+
let __functionCompleted = false;
|
|
307
307
|
if (!__ctx.globals.isInitialized("stdlib/agent.agency")) {
|
|
308
308
|
await __initializeGlobals(__ctx);
|
|
309
309
|
}
|
|
310
|
-
|
|
310
|
+
let __funcStartTime = performance.now();
|
|
311
311
|
await callHook({
|
|
312
312
|
callbacks: __ctx.callbacks,
|
|
313
313
|
name: "onFunctionStart",
|
|
@@ -380,22 +380,22 @@ async function todoWrite(todos, __state = void 0) {
|
|
|
380
380
|
}
|
|
381
381
|
}
|
|
382
382
|
async function todoList(__state = void 0) {
|
|
383
|
-
|
|
383
|
+
const __setupData = setupFunction({
|
|
384
384
|
state: __state
|
|
385
385
|
});
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
386
|
+
const __stack = __setupData.stack;
|
|
387
|
+
const __step = __setupData.step;
|
|
388
|
+
const __self = __setupData.self;
|
|
389
|
+
const __threads = __setupData.threads;
|
|
390
|
+
const __ctx = __state?.ctx || __globalCtx;
|
|
391
|
+
const statelogClient = __ctx.statelogClient;
|
|
392
|
+
const __graph = __ctx.graph;
|
|
393
|
+
let __forked;
|
|
394
|
+
let __functionCompleted = false;
|
|
395
395
|
if (!__ctx.globals.isInitialized("stdlib/agent.agency")) {
|
|
396
396
|
await __initializeGlobals(__ctx);
|
|
397
397
|
}
|
|
398
|
-
|
|
398
|
+
let __funcStartTime = performance.now();
|
|
399
399
|
await callHook({
|
|
400
400
|
callbacks: __ctx.callbacks,
|
|
401
401
|
name: "onFunctionStart",
|
|
@@ -458,22 +458,22 @@ async function todoList(__state = void 0) {
|
|
|
458
458
|
}
|
|
459
459
|
}
|
|
460
460
|
async function question(prompt, __state = void 0) {
|
|
461
|
-
|
|
461
|
+
const __setupData = setupFunction({
|
|
462
462
|
state: __state
|
|
463
463
|
});
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
464
|
+
const __stack = __setupData.stack;
|
|
465
|
+
const __step = __setupData.step;
|
|
466
|
+
const __self = __setupData.self;
|
|
467
|
+
const __threads = __setupData.threads;
|
|
468
|
+
const __ctx = __state?.ctx || __globalCtx;
|
|
469
|
+
const statelogClient = __ctx.statelogClient;
|
|
470
|
+
const __graph = __ctx.graph;
|
|
471
|
+
let __forked;
|
|
472
|
+
let __functionCompleted = false;
|
|
473
473
|
if (!__ctx.globals.isInitialized("stdlib/agent.agency")) {
|
|
474
474
|
await __initializeGlobals(__ctx);
|
|
475
475
|
}
|
|
476
|
-
|
|
476
|
+
let __funcStartTime = performance.now();
|
|
477
477
|
await callHook({
|
|
478
478
|
callbacks: __ctx.callbacks,
|
|
479
479
|
name: "onFunctionStart",
|