agency-lang 0.0.100 → 0.0.102
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/backends/typescriptBuilder.d.ts +5 -1
- package/dist/lib/backends/typescriptBuilder.js +38 -7
- package/dist/lib/backends/typescriptGenerator/builtins.js +3 -0
- package/dist/lib/backends/typescriptGenerator.d.ts +1 -1
- package/dist/lib/backends/typescriptGenerator.js +2 -2
- package/dist/lib/cli/auth.d.ts +4 -0
- package/dist/lib/cli/auth.js +60 -0
- package/dist/lib/cli/commands.js +23 -2
- package/dist/lib/cli/debug.js +8 -1
- package/dist/lib/config.d.ts +69 -0
- package/dist/lib/config.js +105 -0
- package/dist/lib/config.test.d.ts +1 -0
- package/dist/lib/config.test.js +178 -0
- package/dist/lib/debugger/hotReload.d.ts +11 -0
- package/dist/lib/debugger/hotReload.js +73 -0
- package/dist/lib/debugger/uiState.js +4 -3
- package/dist/lib/importStrategy.d.ts +3 -0
- package/dist/lib/importStrategy.js +40 -15
- package/dist/lib/runtime/hooks.d.ts +6 -0
- package/dist/lib/runtime/index.d.ts +2 -0
- package/dist/lib/runtime/index.js +1 -0
- package/dist/lib/runtime/mcp/__tests__/testServer.d.ts +1 -0
- package/dist/lib/runtime/mcp/__tests__/testServer.js +14 -0
- package/dist/lib/runtime/mcp/callbackServer.d.ts +20 -0
- package/dist/lib/runtime/mcp/callbackServer.js +86 -0
- package/dist/lib/runtime/mcp/callbackServer.test.d.ts +1 -0
- package/dist/lib/runtime/mcp/callbackServer.test.js +57 -0
- package/dist/lib/runtime/mcp/mcp.integration.test.d.ts +1 -0
- package/dist/lib/runtime/mcp/mcp.integration.test.js +37 -0
- package/dist/lib/runtime/mcp/mcpConnection.d.ts +23 -0
- package/dist/lib/runtime/mcp/mcpConnection.js +71 -0
- package/dist/lib/runtime/mcp/mcpConnection.test.d.ts +1 -0
- package/dist/lib/runtime/mcp/mcpConnection.test.js +58 -0
- package/dist/lib/runtime/mcp/mcpManager.d.ts +20 -0
- package/dist/lib/runtime/mcp/mcpManager.js +91 -0
- package/dist/lib/runtime/mcp/mcpManager.test.d.ts +1 -0
- package/dist/lib/runtime/mcp/mcpManager.test.js +128 -0
- package/dist/lib/runtime/mcp/oauthConnector.d.ts +41 -0
- package/dist/lib/runtime/mcp/oauthConnector.js +81 -0
- package/dist/lib/runtime/mcp/oauthConnector.test.d.ts +1 -0
- package/dist/lib/runtime/mcp/oauthConnector.test.js +26 -0
- package/dist/lib/runtime/mcp/oauthProvider.d.ts +52 -0
- package/dist/lib/runtime/mcp/oauthProvider.js +157 -0
- package/dist/lib/runtime/mcp/oauthProvider.test.d.ts +1 -0
- package/dist/lib/runtime/mcp/oauthProvider.test.js +151 -0
- package/dist/lib/runtime/mcp/tokenStore.d.ts +22 -0
- package/dist/lib/runtime/mcp/tokenStore.js +103 -0
- package/dist/lib/runtime/mcp/tokenStore.test.d.ts +1 -0
- package/dist/lib/runtime/mcp/tokenStore.test.js +80 -0
- package/dist/lib/runtime/mcp/toolAdapter.d.ts +6 -0
- package/dist/lib/runtime/mcp/toolAdapter.js +46 -0
- package/dist/lib/runtime/mcp/toolAdapter.test.d.ts +1 -0
- package/dist/lib/runtime/mcp/toolAdapter.test.js +68 -0
- package/dist/lib/runtime/mcp/types.d.ts +26 -0
- package/dist/lib/runtime/mcp/types.js +9 -0
- package/dist/lib/runtime/node.js +1 -0
- package/dist/lib/runtime/prompt.js +9 -1
- package/dist/lib/runtime/state/context.d.ts +5 -0
- package/dist/lib/runtime/state/context.js +14 -0
- package/dist/lib/templates/backends/typescriptGenerator/builtinFunctions/mcp.d.ts +4 -0
- package/dist/lib/templates/backends/typescriptGenerator/builtinFunctions/mcp.js +11 -0
- package/dist/lib/templates/backends/typescriptGenerator/imports.d.ts +1 -1
- package/dist/lib/templates/backends/typescriptGenerator/imports.js +1 -1
- package/dist/lib/types/function.d.ts +1 -1
- package/dist/lib/types/function.js +1 -0
- package/dist/lib/version.d.ts +1 -1
- package/dist/lib/version.js +1 -1
- package/dist/scripts/agency.js +22 -0
- package/package.json +2 -1
- package/stdlib/agent.js +3 -0
- package/stdlib/array.js +3 -0
- package/stdlib/clipboard.js +3 -0
- package/stdlib/fs.js +3 -0
- package/stdlib/http.js +3 -0
- package/stdlib/index.js +3 -0
- package/stdlib/lib/system.js +17 -1
- package/stdlib/math.js +3 -0
- package/stdlib/object.js +3 -0
- package/stdlib/path.js +3 -0
- package/stdlib/shell.js +3 -0
- package/stdlib/speech.js +3 -0
- package/stdlib/strategy.js +3 -0
- package/stdlib/system.agency +8 -1
- package/stdlib/system.js +112 -2
- package/stdlib/ui.js +3 -0
- package/stdlib/weather.js +3 -0
- package/stdlib/wikipedia.js +3 -0
|
@@ -29,14 +29,18 @@ export declare class TypeScriptBuilder {
|
|
|
29
29
|
private _sourceMapBuilder;
|
|
30
30
|
private programInfo;
|
|
31
31
|
private moduleId;
|
|
32
|
+
private outputFile;
|
|
32
33
|
/**
|
|
33
34
|
* @param config - Agency compiler configuration (model defaults, logging, etc.)
|
|
34
35
|
* @param info - Pre-collected program metadata (function definitions, graph nodes, imports, type hints)
|
|
35
36
|
* @param moduleId - Unique identifier for this module (e.g., "foo.agency"), used to
|
|
36
37
|
* namespace global variables in the GlobalStore so that different modules' globals
|
|
37
38
|
* don't collide. Must be consistent between the defining module and any importers.
|
|
39
|
+
* @param outputFile - Absolute path where the generated code will be written.
|
|
40
|
+
* Used to compute relative import paths for stdlib. If not provided, falls
|
|
41
|
+
* back to resolving moduleId against cwd.
|
|
38
42
|
*/
|
|
39
|
-
constructor(config: AgencyConfig | undefined, info: ProgramInfo, moduleId: string);
|
|
43
|
+
constructor(config: AgencyConfig | undefined, info: ProgramInfo, moduleId: string, outputFile?: string);
|
|
40
44
|
private configDefaults;
|
|
41
45
|
/** Convert a TsNode to string (for use in template-based methods) */
|
|
42
46
|
private str;
|
|
@@ -76,17 +76,22 @@ export class TypeScriptBuilder {
|
|
|
76
76
|
_sourceMapBuilder = new SourceMapBuilder();
|
|
77
77
|
programInfo;
|
|
78
78
|
moduleId;
|
|
79
|
+
outputFile;
|
|
79
80
|
/**
|
|
80
81
|
* @param config - Agency compiler configuration (model defaults, logging, etc.)
|
|
81
82
|
* @param info - Pre-collected program metadata (function definitions, graph nodes, imports, type hints)
|
|
82
83
|
* @param moduleId - Unique identifier for this module (e.g., "foo.agency"), used to
|
|
83
84
|
* namespace global variables in the GlobalStore so that different modules' globals
|
|
84
85
|
* don't collide. Must be consistent between the defining module and any importers.
|
|
86
|
+
* @param outputFile - Absolute path where the generated code will be written.
|
|
87
|
+
* Used to compute relative import paths for stdlib. If not provided, falls
|
|
88
|
+
* back to resolving moduleId against cwd.
|
|
85
89
|
*/
|
|
86
|
-
constructor(config, info, moduleId) {
|
|
90
|
+
constructor(config, info, moduleId, outputFile) {
|
|
87
91
|
this.agencyConfig = mergeDeep(this.configDefaults(), config || {});
|
|
88
92
|
this.programInfo = info;
|
|
89
93
|
this.moduleId = moduleId;
|
|
94
|
+
this.outputFile = outputFile;
|
|
90
95
|
}
|
|
91
96
|
configDefaults() {
|
|
92
97
|
return {
|
|
@@ -1042,7 +1047,7 @@ export class TypeScriptBuilder {
|
|
|
1042
1047
|
return ts.runnerIfElse({ id, branches, elseBranch });
|
|
1043
1048
|
}
|
|
1044
1049
|
processImportStatement(node) {
|
|
1045
|
-
const from = toCompiledImportPath(node.modulePath, path.resolve(this.moduleId));
|
|
1050
|
+
const from = toCompiledImportPath(node.modulePath, this.outputFile ?? path.resolve(this.moduleId));
|
|
1046
1051
|
const imports = node.importedNames.map((nameType) => {
|
|
1047
1052
|
switch (nameType.type) {
|
|
1048
1053
|
case "namedImport":
|
|
@@ -1093,7 +1098,7 @@ export class TypeScriptBuilder {
|
|
|
1093
1098
|
return ts.importDecl({
|
|
1094
1099
|
importKind: "named",
|
|
1095
1100
|
names: importNames,
|
|
1096
|
-
from: toCompiledImportPath(node.agencyFile, path.resolve(this.moduleId)),
|
|
1101
|
+
from: toCompiledImportPath(node.agencyFile, this.outputFile ?? path.resolve(this.moduleId)),
|
|
1097
1102
|
});
|
|
1098
1103
|
}
|
|
1099
1104
|
// ------- TsRaw wrapper methods (template-heavy) -------
|
|
@@ -1636,6 +1641,12 @@ export class TypeScriptBuilder {
|
|
|
1636
1641
|
})),
|
|
1637
1642
|
]), ts.statements([
|
|
1638
1643
|
ts.if(ts.raw("__error instanceof RestoreSignal"), ts.statements([ts.throw("__error")])),
|
|
1644
|
+
ts.consoleError(ts.template([
|
|
1645
|
+
{
|
|
1646
|
+
text: "\\nAgent crashed: ",
|
|
1647
|
+
expr: $(ts.id("__error")).prop("message").done(),
|
|
1648
|
+
},
|
|
1649
|
+
])),
|
|
1639
1650
|
ts.return(ts.obj({
|
|
1640
1651
|
messages: ts.runtime.threads,
|
|
1641
1652
|
data: ts.raw(`failure(__error instanceof Error ? __error.message : String(__error), { functionName: ${JSON.stringify(nodeName)} })`),
|
|
@@ -1863,6 +1874,7 @@ export class TypeScriptBuilder {
|
|
|
1863
1874
|
const configArg = node.arguments[1];
|
|
1864
1875
|
let clientConfig;
|
|
1865
1876
|
let configToolNames = [];
|
|
1877
|
+
let configToolExprs = [];
|
|
1866
1878
|
if (configArg && configArg.type === "agencyObject") {
|
|
1867
1879
|
// Extract tools from config object
|
|
1868
1880
|
const toolsEntry = configArg.entries.find((e) => !("type" in e && e.type === "splat") &&
|
|
@@ -1882,6 +1894,10 @@ export class TypeScriptBuilder {
|
|
|
1882
1894
|
configToolNames.push(toolArg.value);
|
|
1883
1895
|
}
|
|
1884
1896
|
}
|
|
1897
|
+
else if (item.type === "splat") {
|
|
1898
|
+
// Pass-through: spread MCP tool arrays (or any other spread) directly
|
|
1899
|
+
configToolExprs.push(ts.spread(this.processNode(item.value)));
|
|
1900
|
+
}
|
|
1885
1901
|
}
|
|
1886
1902
|
}
|
|
1887
1903
|
// Build clientConfig without known keys
|
|
@@ -1913,12 +1929,14 @@ export class TypeScriptBuilder {
|
|
|
1913
1929
|
const toolNodes = allToolNames.map((name) => $(ts.id("tool"))
|
|
1914
1930
|
.call([ts.str(name)])
|
|
1915
1931
|
.done());
|
|
1932
|
+
// Merge registry-resolved tools with pass-through expressions (spreads of MCP tools, etc.)
|
|
1933
|
+
const allToolNodes = [...toolNodes, ...configToolExprs];
|
|
1916
1934
|
// Merge tools into clientConfig
|
|
1917
1935
|
let mergedConfig;
|
|
1918
|
-
if (
|
|
1936
|
+
if (allToolNodes.length > 0) {
|
|
1919
1937
|
// Spread user config and add tools
|
|
1920
1938
|
mergedConfig = ts.obj([
|
|
1921
|
-
ts.set("tools", ts.arr(
|
|
1939
|
+
ts.set("tools", ts.arr(allToolNodes)),
|
|
1922
1940
|
ts.setSpread(clientConfig),
|
|
1923
1941
|
]);
|
|
1924
1942
|
}
|
|
@@ -2419,10 +2437,23 @@ export class TypeScriptBuilder {
|
|
|
2419
2437
|
traceConfigFields.traceFile = ts.str(this.agencyConfig.traceFile);
|
|
2420
2438
|
}
|
|
2421
2439
|
runtimeCtxArgs.traceConfig = ts.obj(traceConfigFields);
|
|
2422
|
-
|
|
2440
|
+
const runtimeCtxStatements = [
|
|
2423
2441
|
ts.constDecl("__globalCtx", ts.new(ts.id("RuntimeContext"), [ts.obj(runtimeCtxArgs)])),
|
|
2424
2442
|
ts.constDecl("graph", $(ts.runtime.globalCtx).prop("graph").done()),
|
|
2425
|
-
]
|
|
2443
|
+
];
|
|
2444
|
+
if (this.agencyConfig.mcpServers) {
|
|
2445
|
+
// Strip secrets from the config before embedding in generated code.
|
|
2446
|
+
// clientId and clientSecret are resolved at runtime from env vars.
|
|
2447
|
+
const sanitizedServers = Object.fromEntries(Object.entries(this.agencyConfig.mcpServers).map(([name, cfg]) => {
|
|
2448
|
+
if ("type" in cfg && cfg.type === "http") {
|
|
2449
|
+
const { clientSecret, clientId, ...rest } = cfg;
|
|
2450
|
+
return [name, rest];
|
|
2451
|
+
}
|
|
2452
|
+
return [name, cfg];
|
|
2453
|
+
}));
|
|
2454
|
+
runtimeCtxStatements.push(ts.raw(`__globalCtx.createMcpManager(${JSON.stringify(sanitizedServers)});`));
|
|
2455
|
+
}
|
|
2456
|
+
let runtimeCtx = ts.statements(runtimeCtxStatements);
|
|
2426
2457
|
return renderImports.default({
|
|
2427
2458
|
runtimeContextCode: printTs(runtimeCtx),
|
|
2428
2459
|
});
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as builtinFunctionsInput from "../../templates/backends/typescriptGenerator/builtinFunctions/input.js";
|
|
2
2
|
import * as builtinFunctionsRead from "../../templates/backends/typescriptGenerator/builtinFunctions/read.js";
|
|
3
3
|
import * as builtinFunctionsFetchJSON from "../../templates/backends/typescriptGenerator/builtinFunctions/fetchJSON.js";
|
|
4
|
+
import * as builtinFunctionsMcp from "../../templates/backends/typescriptGenerator/builtinFunctions/mcp.js";
|
|
4
5
|
import { BUILTIN_FUNCTIONS } from "../../config.js";
|
|
5
6
|
/**
|
|
6
7
|
* Maps an Agency function name to its TypeScript equivalent
|
|
@@ -46,5 +47,7 @@ export function generateBuiltinHelpers(functionsUsed) {
|
|
|
46
47
|
helpers.push(sleepFunc);
|
|
47
48
|
}
|
|
48
49
|
*/
|
|
50
|
+
const mcpFunc = builtinFunctionsMcp.default({});
|
|
51
|
+
helpers.push(mcpFunc);
|
|
49
52
|
return helpers.join("\n\n");
|
|
50
53
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { AgencyProgram } from "../types.js";
|
|
2
2
|
import { type ProgramInfo } from "../programInfo.js";
|
|
3
3
|
import { AgencyConfig } from "../config.js";
|
|
4
|
-
export declare function generateTypeScript(program: AgencyProgram, config?: AgencyConfig, info?: ProgramInfo, moduleId?: string): string;
|
|
4
|
+
export declare function generateTypeScript(program: AgencyProgram, config?: AgencyConfig, info?: ProgramInfo, moduleId?: string, outputFile?: string): string;
|
|
@@ -2,14 +2,14 @@ import { TypescriptPreprocessor } from "../preprocessors/typescriptPreprocessor.
|
|
|
2
2
|
import { collectProgramInfo } from "../programInfo.js";
|
|
3
3
|
import { TypeScriptBuilder } from "./typescriptBuilder.js";
|
|
4
4
|
import { printTs } from "../ir/prettyPrint.js";
|
|
5
|
-
export function generateTypeScript(program, config, info, moduleId) {
|
|
5
|
+
export function generateTypeScript(program, config, info, moduleId, outputFile) {
|
|
6
6
|
if (!moduleId) {
|
|
7
7
|
throw new Error("moduleId is required for generateTypeScript");
|
|
8
8
|
}
|
|
9
9
|
const programInfo = info ?? collectProgramInfo(program);
|
|
10
10
|
const preprocessor = new TypescriptPreprocessor(program, config, programInfo);
|
|
11
11
|
const preprocessedProgram = preprocessor.preprocess();
|
|
12
|
-
const builder = new TypeScriptBuilder(config, programInfo, moduleId);
|
|
12
|
+
const builder = new TypeScriptBuilder(config, programInfo, moduleId, outputFile);
|
|
13
13
|
const ir = builder.build(preprocessedProgram);
|
|
14
14
|
return printTs(ir);
|
|
15
15
|
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { TokenStore } from "../runtime/mcp/tokenStore.js";
|
|
2
|
+
import { OAuthConnector } from "../runtime/mcp/oauthConnector.js";
|
|
3
|
+
import { isOAuthServer } from "../runtime/mcp/types.js";
|
|
4
|
+
const store = new TokenStore();
|
|
5
|
+
export async function authServer(serverName, config) {
|
|
6
|
+
const mcpServers = config.mcpServers;
|
|
7
|
+
if (!mcpServers || !mcpServers[serverName]) {
|
|
8
|
+
console.error(`MCP server "${serverName}" not found in agency.json. Available servers: ${mcpServers ? Object.keys(mcpServers).join(", ") : "(none)"}`);
|
|
9
|
+
process.exit(1);
|
|
10
|
+
}
|
|
11
|
+
const serverConfig = mcpServers[serverName];
|
|
12
|
+
if (!isOAuthServer(serverConfig)) {
|
|
13
|
+
console.error(`MCP server "${serverName}" is not configured with auth: "oauth".`);
|
|
14
|
+
process.exit(1);
|
|
15
|
+
}
|
|
16
|
+
const httpConfig = serverConfig;
|
|
17
|
+
const existing = await store.loadTokens(serverName);
|
|
18
|
+
if (existing) {
|
|
19
|
+
console.log(`Token already exists for "${serverName}". Use --revoke to remove it first.`);
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
console.log(`Starting OAuth authorization for "${serverName}"...`);
|
|
23
|
+
const connector = new OAuthConnector(serverName, httpConfig.url, store, {
|
|
24
|
+
timeoutMs: httpConfig.authTimeout,
|
|
25
|
+
clientId: httpConfig.clientId,
|
|
26
|
+
clientSecret: httpConfig.clientSecret,
|
|
27
|
+
});
|
|
28
|
+
try {
|
|
29
|
+
const { client } = await connector.connect();
|
|
30
|
+
console.log(`Successfully authorized "${serverName}". Token stored.`);
|
|
31
|
+
await client.close();
|
|
32
|
+
}
|
|
33
|
+
catch (error) {
|
|
34
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
35
|
+
console.error(`Authorization failed for "${serverName}": ${msg}`);
|
|
36
|
+
process.exit(1);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
export async function listAuth() {
|
|
40
|
+
const servers = await store.listServers();
|
|
41
|
+
if (servers.length === 0) {
|
|
42
|
+
console.log("No stored OAuth tokens.");
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
console.log("Stored OAuth tokens:");
|
|
46
|
+
for (const name of servers) {
|
|
47
|
+
const tokens = await store.loadTokens(name);
|
|
48
|
+
const hasRefresh = tokens?.refresh_token ? "yes" : "no";
|
|
49
|
+
console.log(` ${name} (refresh token: ${hasRefresh})`);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
export async function revokeAuth(serverName) {
|
|
53
|
+
const tokens = await store.loadTokens(serverName);
|
|
54
|
+
if (!tokens) {
|
|
55
|
+
console.log(`No stored token for "${serverName}".`);
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
await store.deleteTokens(serverName);
|
|
59
|
+
console.log(`Removed stored token for "${serverName}".`);
|
|
60
|
+
}
|
package/dist/lib/cli/commands.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { generateAgency } from "../backends/agencyGenerator.js";
|
|
2
|
+
import { AgencyConfigSchema } from "../config.js";
|
|
2
3
|
import { generateTypeScript } from "../index.js";
|
|
3
4
|
import { resolveImports } from "../preprocessors/importResolver.js";
|
|
4
5
|
import { collectProgramInfo } from "../programInfo.js";
|
|
@@ -26,6 +27,15 @@ export function loadConfig(configPath, verbose = false) {
|
|
|
26
27
|
try {
|
|
27
28
|
const configContent = fs.readFileSync(finalConfigPath, "utf-8");
|
|
28
29
|
config = JSON.parse(configContent);
|
|
30
|
+
const parseResult = AgencyConfigSchema.safeParse(config);
|
|
31
|
+
if (!parseResult.success) {
|
|
32
|
+
console.error(`Invalid agency.json config:`);
|
|
33
|
+
for (const issue of parseResult.error.issues) {
|
|
34
|
+
console.error(` - ${issue.path.join(".")}: ${issue.message}`);
|
|
35
|
+
}
|
|
36
|
+
process.exit(1);
|
|
37
|
+
}
|
|
38
|
+
config = parseResult.data;
|
|
29
39
|
if (config.verbose) {
|
|
30
40
|
console.log(`Loaded config from ${finalConfigPath}`);
|
|
31
41
|
}
|
|
@@ -79,6 +89,10 @@ export function resetCompilationCache() {
|
|
|
79
89
|
compiledFiles.clear();
|
|
80
90
|
}
|
|
81
91
|
export function compile(config, inputFile, _outputFile, options) {
|
|
92
|
+
if (!fs.existsSync(inputFile)) {
|
|
93
|
+
console.error(`Error: Input file '${inputFile}' not found`);
|
|
94
|
+
process.exit(1);
|
|
95
|
+
}
|
|
82
96
|
// Check if the input is a directory
|
|
83
97
|
const stats = fs.statSync(inputFile);
|
|
84
98
|
const verbose = config.verbose ?? false;
|
|
@@ -154,9 +168,16 @@ export function compile(config, inputFile, _outputFile, options) {
|
|
|
154
168
|
nonAgencyImports.push(node.modulePath);
|
|
155
169
|
}
|
|
156
170
|
});
|
|
157
|
-
|
|
171
|
+
try {
|
|
172
|
+
strategy.prepareDependencies(nonAgencyImports, absoluteInputFile);
|
|
173
|
+
}
|
|
174
|
+
catch (error) {
|
|
175
|
+
console.error(error instanceof Error ? error.message : String(error));
|
|
176
|
+
process.exit(1);
|
|
177
|
+
}
|
|
158
178
|
const moduleId = path.relative(process.cwd(), absoluteInputFile);
|
|
159
|
-
const
|
|
179
|
+
const absoluteOutputFile = path.resolve(outputFile);
|
|
180
|
+
const generatedCode = generateTypeScript(resolvedProgram, config, info, moduleId, absoluteOutputFile);
|
|
160
181
|
if (options?.ts) {
|
|
161
182
|
// TypeScript output — add @ts-nocheck so type errors don't block compilation
|
|
162
183
|
fs.writeFileSync(outputFile, "// @ts-nocheck\n" + generatedCode, "utf-8");
|
package/dist/lib/cli/debug.js
CHANGED
|
@@ -83,7 +83,14 @@ export async function debug(config, _inputFile, options = {}) {
|
|
|
83
83
|
let absOutput;
|
|
84
84
|
if (distDir) {
|
|
85
85
|
// distDir mode: import pre-compiled JS from the dist directory
|
|
86
|
-
|
|
86
|
+
let compiledPath;
|
|
87
|
+
try {
|
|
88
|
+
compiledPath = resolveCompiledFile(distDir, inputFile);
|
|
89
|
+
}
|
|
90
|
+
catch (error) {
|
|
91
|
+
console.error(error instanceof Error ? error.message : String(error));
|
|
92
|
+
process.exit(1);
|
|
93
|
+
}
|
|
87
94
|
// Warn if source is newer than compiled output
|
|
88
95
|
const sourceMtime = fs.statSync(inputFile).mtimeMs;
|
|
89
96
|
const compiledMtime = fs.statSync(compiledPath).mtimeMs;
|
package/dist/lib/config.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { AgencyNode } from "./types.js";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import type { McpServerConfig } from "./runtime/mcp/types.js";
|
|
2
4
|
export declare const TYPES_THAT_DONT_TRIGGER_NEW_PART: AgencyNode["type"][];
|
|
3
5
|
/**
|
|
4
6
|
* Maps Agency built-in function names to TypeScript equivalents.
|
|
@@ -117,4 +119,71 @@ export interface AgencyConfig {
|
|
|
117
119
|
/** Base URL for source links in generated docs */
|
|
118
120
|
baseUrl?: string;
|
|
119
121
|
};
|
|
122
|
+
/** MCP server configurations */
|
|
123
|
+
mcpServers?: Record<string, McpServerConfig>;
|
|
120
124
|
}
|
|
125
|
+
export declare const AgencyConfigSchema: z.ZodObject<{
|
|
126
|
+
verbose: z.ZodOptional<z.ZodBoolean>;
|
|
127
|
+
outDir: z.ZodOptional<z.ZodString>;
|
|
128
|
+
excludeNodeTypes: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
129
|
+
excludeBuiltinFunctions: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
130
|
+
allowedFetchDomains: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
131
|
+
disallowedFetchDomains: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
132
|
+
tarsecTraceHost: z.ZodOptional<z.ZodString>;
|
|
133
|
+
maxToolCallRounds: z.ZodOptional<z.ZodNumber>;
|
|
134
|
+
log: z.ZodOptional<z.ZodObject<{
|
|
135
|
+
host: z.ZodOptional<z.ZodString>;
|
|
136
|
+
projectId: z.ZodOptional<z.ZodString>;
|
|
137
|
+
debugMode: z.ZodOptional<z.ZodBoolean>;
|
|
138
|
+
apiKey: z.ZodOptional<z.ZodString>;
|
|
139
|
+
}, z.core.$strip>>;
|
|
140
|
+
client: z.ZodOptional<z.ZodObject<{
|
|
141
|
+
logLevel: z.ZodOptional<z.ZodEnum<{
|
|
142
|
+
error: "error";
|
|
143
|
+
warn: "warn";
|
|
144
|
+
info: "info";
|
|
145
|
+
debug: "debug";
|
|
146
|
+
}>>;
|
|
147
|
+
defaultModel: z.ZodOptional<z.ZodString>;
|
|
148
|
+
openAiApiKey: z.ZodOptional<z.ZodString>;
|
|
149
|
+
googleApiKey: z.ZodOptional<z.ZodString>;
|
|
150
|
+
statelog: z.ZodOptional<z.ZodObject<{
|
|
151
|
+
host: z.ZodOptional<z.ZodString>;
|
|
152
|
+
projectId: z.ZodOptional<z.ZodString>;
|
|
153
|
+
apiKey: z.ZodOptional<z.ZodString>;
|
|
154
|
+
}, z.core.$strip>>;
|
|
155
|
+
}, z.core.$strip>>;
|
|
156
|
+
strictTypes: z.ZodOptional<z.ZodBoolean>;
|
|
157
|
+
typeCheck: z.ZodOptional<z.ZodBoolean>;
|
|
158
|
+
typeCheckStrict: z.ZodOptional<z.ZodBoolean>;
|
|
159
|
+
restrictImports: z.ZodOptional<z.ZodBoolean>;
|
|
160
|
+
debugger: z.ZodOptional<z.ZodBoolean>;
|
|
161
|
+
instrument: z.ZodOptional<z.ZodBoolean>;
|
|
162
|
+
checkpoints: z.ZodOptional<z.ZodObject<{
|
|
163
|
+
maxRestores: z.ZodOptional<z.ZodNumber>;
|
|
164
|
+
}, z.core.$strip>>;
|
|
165
|
+
trace: z.ZodOptional<z.ZodBoolean>;
|
|
166
|
+
traceFile: z.ZodOptional<z.ZodString>;
|
|
167
|
+
traceDir: z.ZodOptional<z.ZodString>;
|
|
168
|
+
distDir: z.ZodOptional<z.ZodString>;
|
|
169
|
+
test: z.ZodOptional<z.ZodObject<{
|
|
170
|
+
parallel: z.ZodOptional<z.ZodNumber>;
|
|
171
|
+
}, z.core.$strip>>;
|
|
172
|
+
doc: z.ZodOptional<z.ZodObject<{
|
|
173
|
+
outDir: z.ZodOptional<z.ZodString>;
|
|
174
|
+
baseUrl: z.ZodOptional<z.ZodString>;
|
|
175
|
+
}, z.core.$strip>>;
|
|
176
|
+
mcpServers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodObject<{
|
|
177
|
+
command: z.ZodString;
|
|
178
|
+
args: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
179
|
+
env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
180
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
181
|
+
type: z.ZodLiteral<"http">;
|
|
182
|
+
url: z.ZodString;
|
|
183
|
+
auth: z.ZodOptional<z.ZodLiteral<"oauth">>;
|
|
184
|
+
authTimeout: z.ZodOptional<z.ZodNumber>;
|
|
185
|
+
clientId: z.ZodOptional<z.ZodString>;
|
|
186
|
+
clientSecret: z.ZodOptional<z.ZodString>;
|
|
187
|
+
headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
188
|
+
}, z.core.$strict>]>>>;
|
|
189
|
+
}, z.core.$loose>;
|
package/dist/lib/config.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
1
2
|
export const TYPES_THAT_DONT_TRIGGER_NEW_PART = [
|
|
2
3
|
"typeAlias",
|
|
3
4
|
"usesTool",
|
|
@@ -16,3 +17,107 @@ export const BUILTIN_TOOLS = [
|
|
|
16
17
|
"readSkill",
|
|
17
18
|
];
|
|
18
19
|
export const BUILTIN_VARIABLES = ["color"];
|
|
20
|
+
// --- Zod schema for runtime validation of agency.json ---
|
|
21
|
+
const McpStdioServerSchema = z.object({
|
|
22
|
+
command: z.string(),
|
|
23
|
+
args: z.array(z.string()).optional(),
|
|
24
|
+
env: z.record(z.string(), z.string()).optional(),
|
|
25
|
+
}).strict();
|
|
26
|
+
const McpHttpServerSchema = z.object({
|
|
27
|
+
type: z.literal("http"),
|
|
28
|
+
url: z.string(),
|
|
29
|
+
auth: z.literal("oauth").optional(),
|
|
30
|
+
authTimeout: z.number().optional(),
|
|
31
|
+
clientId: z.string().optional(),
|
|
32
|
+
clientSecret: z.string().optional(),
|
|
33
|
+
headers: z.record(z.string(), z.string()).optional(),
|
|
34
|
+
}).strict();
|
|
35
|
+
const McpServerSchema = z.union([McpStdioServerSchema, McpHttpServerSchema]);
|
|
36
|
+
export const AgencyConfigSchema = z.object({
|
|
37
|
+
verbose: z.boolean(),
|
|
38
|
+
outDir: z.string(),
|
|
39
|
+
excludeNodeTypes: z.array(z.string()),
|
|
40
|
+
excludeBuiltinFunctions: z.array(z.string()),
|
|
41
|
+
allowedFetchDomains: z.array(z.string()),
|
|
42
|
+
disallowedFetchDomains: z.array(z.string()),
|
|
43
|
+
tarsecTraceHost: z.string(),
|
|
44
|
+
maxToolCallRounds: z.number(),
|
|
45
|
+
log: z.object({ host: z.string(), projectId: z.string(), debugMode: z.boolean(), apiKey: z.string() }).partial(),
|
|
46
|
+
client: z.object({
|
|
47
|
+
logLevel: z.enum(["error", "warn", "info", "debug"]),
|
|
48
|
+
defaultModel: z.string(),
|
|
49
|
+
openAiApiKey: z.string(),
|
|
50
|
+
googleApiKey: z.string(),
|
|
51
|
+
statelog: z.object({ host: z.string(), projectId: z.string(), apiKey: z.string() }).partial(),
|
|
52
|
+
}).partial(),
|
|
53
|
+
strictTypes: z.boolean(),
|
|
54
|
+
typeCheck: z.boolean(),
|
|
55
|
+
typeCheckStrict: z.boolean(),
|
|
56
|
+
restrictImports: z.boolean(),
|
|
57
|
+
debugger: z.boolean(),
|
|
58
|
+
instrument: z.boolean(),
|
|
59
|
+
checkpoints: z.object({ maxRestores: z.number() }).partial(),
|
|
60
|
+
trace: z.boolean(),
|
|
61
|
+
traceFile: z.string(),
|
|
62
|
+
traceDir: z.string(),
|
|
63
|
+
distDir: z.string(),
|
|
64
|
+
test: z.object({ parallel: z.number() }).partial(),
|
|
65
|
+
doc: z.object({ outDir: z.string(), baseUrl: z.string() }).partial(),
|
|
66
|
+
mcpServers: z.record(z.string().regex(/^[A-Za-z0-9_-]+$/, "MCP server names must contain only letters, numbers, hyphens, and underscores"), McpServerSchema),
|
|
67
|
+
}).partial().passthrough().superRefine((data, ctx) => {
|
|
68
|
+
if (!data.mcpServers)
|
|
69
|
+
return;
|
|
70
|
+
for (const [name, server] of Object.entries(data.mcpServers)) {
|
|
71
|
+
if ("type" in server && server.type === "http") {
|
|
72
|
+
const httpServer = server;
|
|
73
|
+
if (httpServer.auth && httpServer.headers) {
|
|
74
|
+
ctx.addIssue({
|
|
75
|
+
code: z.ZodIssueCode.custom,
|
|
76
|
+
message: `MCP server "${name}": cannot specify both 'auth' and 'headers'`,
|
|
77
|
+
path: ["mcpServers", name],
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
if (httpServer.authTimeout && httpServer.auth !== "oauth") {
|
|
81
|
+
ctx.addIssue({
|
|
82
|
+
code: z.ZodIssueCode.custom,
|
|
83
|
+
message: `MCP server "${name}": 'authTimeout' requires 'auth: "oauth"'`,
|
|
84
|
+
path: ["mcpServers", name],
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
if (httpServer.clientId && httpServer.auth !== "oauth") {
|
|
88
|
+
ctx.addIssue({
|
|
89
|
+
code: z.ZodIssueCode.custom,
|
|
90
|
+
message: `MCP server "${name}": 'clientId' requires 'auth: "oauth"'`,
|
|
91
|
+
path: ["mcpServers", name],
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
if (httpServer.clientSecret && httpServer.auth !== "oauth") {
|
|
95
|
+
ctx.addIssue({
|
|
96
|
+
code: z.ZodIssueCode.custom,
|
|
97
|
+
message: `MCP server "${name}": 'clientSecret' requires 'auth: "oauth"'`,
|
|
98
|
+
path: ["mcpServers", name],
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
if (httpServer.auth === "oauth") {
|
|
102
|
+
try {
|
|
103
|
+
const parsed = new URL(httpServer.url);
|
|
104
|
+
const isLocalhost = ["127.0.0.1", "localhost"].includes(parsed.hostname);
|
|
105
|
+
if (parsed.protocol !== "https:" && !isLocalhost) {
|
|
106
|
+
ctx.addIssue({
|
|
107
|
+
code: z.ZodIssueCode.custom,
|
|
108
|
+
message: `MCP server "${name}": OAuth requires HTTPS (or localhost for development)`,
|
|
109
|
+
path: ["mcpServers", name, "url"],
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
catch {
|
|
114
|
+
ctx.addIssue({
|
|
115
|
+
code: z.ZodIssueCode.custom,
|
|
116
|
+
message: `MCP server "${name}": invalid URL "${httpServer.url}"`,
|
|
117
|
+
path: ["mcpServers", name, "url"],
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|