melchizedek-agents 1.6.0 → 1.8.0
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/CHANGELOG.md +113 -0
- package/DOCUMENTATION.md +16 -7
- package/config/agents/syndicate.schema.json +63 -0
- package/config/agents/syndicateSchema.yaml +50 -0
- package/dist/lib/a2a/executor.js +21 -0
- package/dist/lib/compile.d.ts +4 -3
- package/dist/lib/compile.js +8 -3
- package/dist/lib/doctor.d.ts +10 -0
- package/dist/lib/doctor.js +33 -4
- package/dist/lib/index.d.ts +9 -0
- package/dist/lib/index.js +7 -0
- package/dist/lib/loadSyndicate.d.ts +13 -0
- package/dist/lib/loadSyndicate.js +14 -5
- package/dist/lib/observability/supabaseSpanExporter.js +2 -1
- package/dist/lib/observability/tracer.d.ts +2 -2
- package/dist/lib/observability/tracer.js +2 -2
- package/dist/lib/project.d.ts +116 -0
- package/dist/lib/project.js +274 -0
- package/dist/lib/runtime/native/checkpoint.d.ts +2 -1
- package/dist/lib/runtime/native/checkpoint.js +6 -2
- package/dist/lib/runtime/native/interrupts.js +9 -2
- package/dist/lib/runtime/nativeTurn.d.ts +2 -1
- package/dist/lib/runtime/nativeTurn.js +5 -1
- package/dist/lib/runtime/syndicateTurn.d.ts +11 -1
- package/dist/lib/runtime/syndicateTurn.js +383 -5
- package/dist/lib/sandbox/sandbox.d.ts +121 -0
- package/dist/lib/sandbox/sandbox.js +276 -0
- package/dist/lib/sandbox/worker.d.ts +29 -0
- package/dist/lib/sandbox/worker.js +280 -0
- package/dist/lib/script/config.d.ts +35 -0
- package/dist/lib/script/config.js +17 -0
- package/dist/lib/script/journal.d.ts +137 -0
- package/dist/lib/script/journal.js +193 -0
- package/dist/lib/script/run.d.ts +138 -0
- package/dist/lib/script/run.js +364 -0
- package/dist/lib/syndicateSchema.d.ts +20 -0
- package/dist/lib/syndicateSchema.js +98 -6
- package/dist/lib/toolRegistry.js +4 -0
- package/dist/lib/tools/runCodeTool.d.ts +50 -0
- package/dist/lib/tools/runCodeTool.js +59 -0
- package/dist/scripts/a2a_server.js +3 -3
- package/dist/scripts/doctor.js +2 -1
- package/dist/scripts/mcp_server.js +2 -1
- package/package.json +6 -1
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* lib/tools/runCodeTool.ts — `run_code`: an agent runs JavaScript in the
|
|
3
|
+
* engine's sandbox and rests its answer on what the code returned
|
|
4
|
+
* (ADR 0137 items 2 to 4).
|
|
5
|
+
*
|
|
6
|
+
* WHY a registry tool: any agent on any provider can list it
|
|
7
|
+
* (`tools: [run_code]`), since the model only writes text, and it gets what
|
|
8
|
+
* every registry tool gets: `require_approval`, MCP exposure (ADR 0125), the
|
|
9
|
+
* result bound and `retries.tool_errors`. `code_execution: gemini` stays,
|
|
10
|
+
* for Python in Gemini's own sandbox on Gemini models (ADR 0033).
|
|
11
|
+
*
|
|
12
|
+
* THE CONTRACT: `{ code, input? }`. The code is a JavaScript module whose
|
|
13
|
+
* default export is called with `input`; the tool returns
|
|
14
|
+
* `{ result, logs, error }`: the export's JSON-serializable return, the
|
|
15
|
+
* `console.log` output, and what stopped it, if anything. Each is bounded at
|
|
16
|
+
* MAX_RESULT_CHARS. The code reaches nothing but `input` and `console`: no
|
|
17
|
+
* network, no host, no keys, no clock, no randomness (lib/sandbox/).
|
|
18
|
+
*
|
|
19
|
+
* THE SWITCH: nothing runs unless the operator set MELCHIZEDEK_CODE_SANDBOX=on;
|
|
20
|
+
* a syndicate listing run_code without it is refused at load (refuseOnNative),
|
|
21
|
+
* and a call that reaches here anyway answers with the reason.
|
|
22
|
+
*
|
|
23
|
+
* ATTACH: an agent's `run_code: { attach: true }` puts each run's code and
|
|
24
|
+
* result on the reply as a `code_run` data part (lib/runtime/syndicateTurn.ts
|
|
25
|
+
* collects them, the A2A executor publishes them). Off by default.
|
|
26
|
+
*/
|
|
27
|
+
import { z } from 'zod';
|
|
28
|
+
import { codeSandboxEnabled, codeSandboxOffMessage, runInSandbox } from '../sandbox/sandbox.js';
|
|
29
|
+
import { MAX_RESULT_CHARS } from './tool.js';
|
|
30
|
+
import { defineTool } from './toolContract.js';
|
|
31
|
+
/** The registry name. */
|
|
32
|
+
export const RUN_CODE = 'run_code';
|
|
33
|
+
/** The largest program a call may send. */
|
|
34
|
+
export const MAX_CODE_CHARS = 64_000;
|
|
35
|
+
export const runCodeTool = defineTool({
|
|
36
|
+
name: RUN_CODE,
|
|
37
|
+
description: 'Run JavaScript and get back what it returns, so an answer can rest on a computation instead of mental arithmetic: totals, conversions, statistics, dates from given timestamps, parsing, sorting, checking a formula. '
|
|
38
|
+
+ '`code` is an ES module whose default export is called with `input` and returns a JSON-serializable value, e.g. `export default ({ xs }) => xs.reduce((a, b) => a + b, 0)`. '
|
|
39
|
+
+ 'console.log output comes back in `logs`. The code has no network, no files, no clock and no randomness (Date.now, new Date() and Math.random throw); pass any data it needs in `input`. '
|
|
40
|
+
+ 'It returns { result, logs, error }; when error is set, fix the code and run it again.',
|
|
41
|
+
schema: z.object({
|
|
42
|
+
code: z.string().min(1).max(MAX_CODE_CHARS).describe('An ES module: `export default (input) => value`. May be async.'),
|
|
43
|
+
input: z.unknown().optional().describe('JSON the default export is called with.'),
|
|
44
|
+
}),
|
|
45
|
+
async execute({ code, input }, ctx) {
|
|
46
|
+
if (!codeSandboxEnabled())
|
|
47
|
+
return { result: null, logs: '', error: codeSandboxOffMessage(RUN_CODE) };
|
|
48
|
+
const run = await runInSandbox({
|
|
49
|
+
source: code,
|
|
50
|
+
value: input ?? null,
|
|
51
|
+
...(ctx.signal ? { signal: ctx.signal } : {}),
|
|
52
|
+
limits: { maxLogChars: MAX_RESULT_CHARS, maxResultChars: MAX_RESULT_CHARS },
|
|
53
|
+
});
|
|
54
|
+
const logs = run.logsTruncated ? `${run.logs}\n[logs truncated at ${MAX_RESULT_CHARS.toLocaleString('en-US')} characters]` : run.logs;
|
|
55
|
+
if (!run.ok)
|
|
56
|
+
return { result: null, logs, error: `${run.error?.code ?? 'CODE_ERROR'}: ${run.error?.message ?? 'the code did not finish'}` };
|
|
57
|
+
return { result: run.result ?? null, logs, error: null };
|
|
58
|
+
},
|
|
59
|
+
});
|
|
@@ -97,7 +97,6 @@ var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExte
|
|
|
97
97
|
*/
|
|
98
98
|
import { randomBytes } from 'node:crypto';
|
|
99
99
|
import { readdirSync, realpathSync, writeFileSync } from 'node:fs';
|
|
100
|
-
import path from 'node:path';
|
|
101
100
|
import { pathToFileURL } from 'node:url';
|
|
102
101
|
import { createA2AApp } from '../lib/a2a/app.js';
|
|
103
102
|
import { callerTokens, firstOf, hashCallerToken, jwtIdentity, parseCallers, sharedSecret, trustedHeader, } from '../lib/a2a/identity.js';
|
|
@@ -116,6 +115,7 @@ import { callbackIdentity, callbackIdentityProblem, oauthServerSetup } from '../
|
|
|
116
115
|
import { postgresCredentialRows } from '../lib/storage/postgres/credentialStore.js';
|
|
117
116
|
import { setOAuthHosts } from '../lib/tools/oauthHosts.js';
|
|
118
117
|
import { setCredentialHosts } from '../lib/tools/credentialHosts.js';
|
|
118
|
+
import { resolveAgentsDir } from '../lib/project.js';
|
|
119
119
|
// Re-exported for existing importers (tests/failNarration.test.ts).
|
|
120
120
|
export { describeTurnError } from '../lib/a2a/executor.js';
|
|
121
121
|
/** Minimum bearer-secret length below which the server warns. */
|
|
@@ -181,7 +181,7 @@ export function servedFileSyndicates(syndicateName, servedAgents, registryAgents
|
|
|
181
181
|
add(id);
|
|
182
182
|
}
|
|
183
183
|
else {
|
|
184
|
-
const agentsDir =
|
|
184
|
+
const agentsDir = resolveAgentsDir();
|
|
185
185
|
let names = [];
|
|
186
186
|
try {
|
|
187
187
|
names = readdirSync(agentsDir);
|
|
@@ -633,7 +633,7 @@ if (invokedAsMain) {
|
|
|
633
633
|
if (error?.code === 'ENOENT') {
|
|
634
634
|
console.error(`[A2A] Syndicate not found: ${arg || 'syndicate.yaml'}.\n`
|
|
635
635
|
+ ' Pass your syndicate: melchizedek-serve <name>.yaml\n'
|
|
636
|
-
+ ' (agents directory: MELCHIZEDEK_AGENTS_DIR,
|
|
636
|
+
+ ' (agents directory: MELCHIZEDEK_AGENTS_DIR, else the agents folder in melchizedek.json, else <cwd>/config/agents)');
|
|
637
637
|
process.exit(1);
|
|
638
638
|
}
|
|
639
639
|
console.error(error);
|
package/dist/scripts/doctor.js
CHANGED
|
@@ -33,6 +33,7 @@ import { loadEnv } from '../lib/loadEnv.js';
|
|
|
33
33
|
import { checkProblems, renderDoctor, runDoctor } from '../lib/doctor.js';
|
|
34
34
|
import { renderCapabilityMatrix } from '../lib/models/capabilities.js';
|
|
35
35
|
import { assignMemoryNamespace, LEGACY_MEMORY_APP_NAME } from '../lib/memory/namespace.js';
|
|
36
|
+
import { resolveAgentsDir } from '../lib/project.js';
|
|
36
37
|
loadEnv();
|
|
37
38
|
const args = process.argv.slice(2);
|
|
38
39
|
const json = args.includes('--json');
|
|
@@ -52,7 +53,7 @@ function packageScripts() {
|
|
|
52
53
|
if (fixAt !== -1) {
|
|
53
54
|
// ADR 0020: give each named long-term syndicate its own memory namespace.
|
|
54
55
|
// Only the files named are touched; with none named, list the candidates.
|
|
55
|
-
const agentsDir =
|
|
56
|
+
const agentsDir = resolveAgentsDir();
|
|
56
57
|
const files = args.slice(fixAt + 1).filter((a) => !a.startsWith('--'));
|
|
57
58
|
if (files.length === 0) {
|
|
58
59
|
const pending = runDoctor({ agentsDir }).syndicates.filter((s) => s.memory && !s.memory.declared && !s.file.includes('/'));
|
|
@@ -38,6 +38,7 @@
|
|
|
38
38
|
import { readdirSync, realpathSync } from 'node:fs';
|
|
39
39
|
import path from 'node:path';
|
|
40
40
|
import { pathToFileURL } from 'node:url';
|
|
41
|
+
import { resolveAgentsDir } from '../lib/project.js';
|
|
41
42
|
/** The bin's flags. Throws, naming the flag, on one it does not know. */
|
|
42
43
|
export function parseMcpArgs(argv) {
|
|
43
44
|
const out = { syndicates: [], http: false, help: false };
|
|
@@ -160,7 +161,7 @@ export async function startMcpServer(argv = process.argv.slice(2)) {
|
|
|
160
161
|
const bindings = () => ({
|
|
161
162
|
current_date: new Date().toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric' }),
|
|
162
163
|
});
|
|
163
|
-
const agentsDir =
|
|
164
|
+
const agentsDir = resolveAgentsDir();
|
|
164
165
|
let files = args.syndicates.map((id) => (id.endsWith('.yaml') || id.endsWith('.yml') ? id : `${id}.yaml`));
|
|
165
166
|
const named = files.length > 0;
|
|
166
167
|
if (!named) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "melchizedek-agents",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.8.0",
|
|
4
4
|
"description": "A multi-model, multi-agent orchestration framework — YAML-defined syndicates on the engine's own agent loop, Supabase or Postgres session persistence, pgvector long-term memory. Companion repo to the lyceumagents.com curriculum.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -21,6 +21,8 @@
|
|
|
21
21
|
"./loadSyndicate": "./dist/lib/loadSyndicate.js",
|
|
22
22
|
"./loadEnv": "./dist/lib/loadEnv.js",
|
|
23
23
|
"./dispatch": "./dist/lib/dispatch.js",
|
|
24
|
+
"./script": "./dist/lib/script/run.js",
|
|
25
|
+
"./sandbox": "./dist/lib/sandbox/sandbox.js",
|
|
24
26
|
"./compile": "./dist/lib/compile.js",
|
|
25
27
|
"./runtime": "./dist/lib/runtime/syndicateTurn.js",
|
|
26
28
|
"./runtime/turnControl": "./dist/lib/runtime/turnControl.js",
|
|
@@ -31,6 +33,7 @@
|
|
|
31
33
|
"./a2a/limits": "./dist/lib/a2a/redisLimits.js",
|
|
32
34
|
"./mcp": "./dist/lib/mcp/server.js",
|
|
33
35
|
"./registry": "./dist/lib/registry.js",
|
|
36
|
+
"./project": "./dist/lib/project.js",
|
|
34
37
|
"./server": "./dist/scripts/a2a_server.js",
|
|
35
38
|
"./guards": "./dist/lib/guards/index.js",
|
|
36
39
|
"./storage/postgres": "./dist/lib/storage/postgres/index.js",
|
|
@@ -148,6 +151,7 @@
|
|
|
148
151
|
"@a2a-js/sdk": "^1.3.0",
|
|
149
152
|
"@anthropic-ai/sdk": "^0.131.0",
|
|
150
153
|
"@google/genai": "2.27.0",
|
|
154
|
+
"@jitl/quickjs-wasmfile-release-sync": "0.32.0",
|
|
151
155
|
"@modelcontextprotocol/sdk": "^1.32.1",
|
|
152
156
|
"@opentelemetry/api": "^1.9.1",
|
|
153
157
|
"@opentelemetry/core": "^2.8.0",
|
|
@@ -161,6 +165,7 @@
|
|
|
161
165
|
"jose": "^6.2.12",
|
|
162
166
|
"openai": "^7.28.0",
|
|
163
167
|
"pg": "^8.23.1",
|
|
168
|
+
"quickjs-emscripten-core": "0.32.0",
|
|
164
169
|
"yaml": "^2.9.0",
|
|
165
170
|
"zod": "4.6.5"
|
|
166
171
|
},
|