melchizedek-agents 0.9.6 → 0.16.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/.env.example +272 -0
- package/AGENT_SETUP.md +39 -23
- package/CHANGELOG.md +623 -0
- package/DOCUMENTATION.md +429 -109
- package/QUICKSTART.md +92 -18
- package/README.md +45 -5
- package/config/agents/README.md +46 -1
- package/config/agents/examples/ares.yaml +117 -40
- package/config/agents/examples/assistant.yaml +159 -0
- package/config/agents/examples/augustin.yaml +154 -51
- package/config/agents/examples/cartographers.yaml +91 -23
- package/config/agents/examples/claude.yaml +45 -6
- package/config/agents/examples/council.yaml +23 -8
- package/config/agents/examples/critic.yaml +57 -21
- package/config/agents/examples/delegation.yaml +76 -9
- package/config/agents/examples/hierarchical.yaml +55 -8
- package/config/agents/examples/image_production.yaml +54 -16
- package/config/agents/examples/librarian.yaml +70 -14
- package/config/agents/examples/model_zoo.yaml +105 -29
- package/config/agents/examples/patient_advocate.yaml +102 -34
- package/config/agents/examples/research.yaml +250 -0
- package/config/agents/examples/scribe.yaml +242 -0
- package/config/agents/examples/scriptorium.yaml +87 -24
- package/config/agents/examples/style_council.yaml +31 -9
- package/config/agents/examples/syndicate.yaml +29 -10
- package/config/agents/examples/tutor.yaml +10 -3
- package/config/agents/syndicateSchema.yaml +44 -9
- package/config/agents/templates/README.md +58 -0
- package/config/agents/templates/account_memory.yaml +153 -0
- package/config/agents/templates/case_desk.yaml +188 -0
- package/config/agents/templates/conversational.yaml +110 -0
- package/config/agents/templates/draft_review.yaml +130 -0
- package/config/agents/templates/intake_extractor.yaml +152 -0
- package/config/agents/templates/research_brief.yaml +169 -0
- package/config/agents/templates/research_desk.yaml +152 -0
- package/config/agents/templates/review_panel.yaml +188 -0
- package/config/agents/templates/support_triage.yaml +273 -0
- package/config/agents/templates/systems_operator.yaml +157 -0
- package/db/hardening.sql +202 -0
- package/db/memory_v2.sql +77 -0
- package/db/migrations/0001_base.sql +167 -0
- package/db/migrations/0002_erase_scope.sql +172 -0
- package/db/migrations/0003_postgres_storage.sql +58 -0
- package/db/migrations/0004_usage.sql +94 -0
- package/db/migrations/0005_agent_registry.sql +200 -0
- package/db/migrations/0006_task_leases.sql +25 -0
- package/db/migrations/0007_memory_commit.sql +134 -0
- package/db/migrations/0008_memory_retention.sql +37 -0
- package/db/migrations/0009_task_queue.sql +51 -0
- package/db/migrations/0010_erase_complete.sql +180 -0
- package/db/telemetry.sql +401 -0
- package/demo/README.md +77 -0
- package/demo/a2a_demo.mjs +95 -0
- package/dist/lib/a2a/app.d.ts +253 -0
- package/dist/lib/a2a/app.js +751 -0
- package/dist/lib/a2a/executor.d.ts +167 -0
- package/dist/lib/a2a/executor.js +548 -0
- package/dist/lib/a2a/identity.d.ts +122 -0
- package/dist/lib/a2a/identity.js +254 -0
- package/dist/lib/a2a/policy.d.ts +110 -0
- package/dist/lib/a2a/policy.js +178 -0
- package/dist/lib/a2a/redisLimits.d.ts +26 -0
- package/dist/lib/a2a/redisLimits.js +31 -0
- package/dist/lib/a2a/remoteAgent.d.ts +91 -0
- package/dist/lib/a2a/remoteAgent.js +268 -0
- package/dist/lib/a2a/turnLock.d.ts +28 -0
- package/dist/lib/a2a/turnLock.js +76 -0
- package/dist/lib/compile.d.ts +11 -1
- package/dist/lib/compile.js +109 -8
- package/dist/lib/config.d.ts +7 -7
- package/dist/lib/config.js +7 -7
- package/dist/lib/doctor.d.ts +145 -0
- package/dist/lib/doctor.js +517 -0
- package/dist/lib/grounding.d.ts +2 -2
- package/dist/lib/grounding.js +2 -2
- package/dist/lib/guards/index.d.ts +37 -0
- package/dist/lib/guards/index.js +66 -0
- package/dist/lib/guards/science.d.ts +117 -0
- package/dist/lib/guards/science.js +444 -0
- package/dist/lib/index.d.ts +37 -2
- package/dist/lib/index.js +35 -4
- package/dist/lib/loadEnv.d.ts +23 -11
- package/dist/lib/loadEnv.js +77 -29
- package/dist/lib/loadSyndicate.d.ts +97 -5
- package/dist/lib/loadSyndicate.js +176 -76
- package/dist/lib/memory/erase.d.ts +24 -0
- package/dist/lib/memory/erase.js +47 -0
- package/dist/lib/memory/namespace.d.ts +37 -0
- package/dist/lib/memory/namespace.js +74 -0
- package/dist/lib/memory/providers.d.ts +99 -0
- package/dist/lib/memory/providers.js +240 -0
- package/dist/lib/memory/store.d.ts +74 -0
- package/dist/lib/memory/store.js +108 -0
- package/dist/lib/memory/supabaseMemoryService.d.ts +69 -9
- package/dist/lib/memory/supabaseMemoryService.js +239 -125
- package/dist/lib/models/capabilities.d.ts +103 -0
- package/dist/lib/models/capabilities.js +291 -0
- package/dist/lib/models/claudeLlm.d.ts +10 -1
- package/dist/lib/models/claudeLlm.js +57 -27
- package/dist/lib/models/endpoints.d.ts +100 -0
- package/dist/lib/models/endpoints.js +282 -0
- package/dist/lib/models/gateway.d.ts +107 -0
- package/dist/lib/models/gateway.js +157 -0
- package/dist/lib/models/gatewayLlm.d.ts +57 -0
- package/dist/lib/models/gatewayLlm.js +105 -0
- package/dist/lib/models/gptLlm.d.ts +51 -2
- package/dist/lib/models/gptLlm.js +169 -26
- package/dist/lib/models/grokLlm.d.ts +19 -10
- package/dist/lib/models/grokLlm.js +29 -14
- package/dist/lib/models/ollamaLlm.d.ts +26 -0
- package/dist/lib/models/ollamaLlm.js +43 -1
- package/dist/lib/models/openAiCompatibleLlm.d.ts +67 -2
- package/dist/lib/models/openAiCompatibleLlm.js +200 -37
- package/dist/lib/models/providerMap.js +9 -2
- package/dist/lib/models/registry.d.ts +42 -5
- package/dist/lib/models/registry.js +140 -29
- package/dist/lib/models/retry.d.ts +146 -0
- package/dist/lib/models/retry.js +305 -0
- package/dist/lib/models/schemaNormalize.d.ts +20 -0
- package/dist/lib/models/schemaNormalize.js +43 -0
- package/dist/lib/net/addressGuard.d.ts +60 -0
- package/dist/lib/net/addressGuard.js +216 -0
- package/dist/lib/observability/embeddings.d.ts +11 -2
- package/dist/lib/observability/embeddings.js +18 -14
- package/dist/lib/observability/metrics.d.ts +36 -0
- package/dist/lib/observability/metrics.js +86 -0
- package/dist/lib/observability/redact.d.ts +29 -0
- package/dist/lib/observability/redact.js +102 -0
- package/dist/lib/observability/supabaseSpanExporter.d.ts +2 -0
- package/dist/lib/observability/supabaseSpanExporter.js +22 -6
- package/dist/lib/observability/tracer.d.ts +10 -0
- package/dist/lib/observability/tracer.js +70 -3
- package/dist/lib/persistence/supabaseProvider.d.ts +11 -0
- package/dist/lib/persistence/supabaseProvider.js +32 -6
- package/dist/lib/registry.d.ts +87 -0
- package/dist/lib/registry.js +146 -0
- package/dist/lib/runtime/approvals.d.ts +44 -0
- package/dist/lib/runtime/approvals.js +67 -0
- package/dist/lib/runtime/syndicateTurn.d.ts +233 -0
- package/dist/lib/runtime/syndicateTurn.js +597 -0
- package/dist/lib/runtime/turnControl.d.ts +90 -0
- package/dist/lib/runtime/turnControl.js +131 -0
- package/dist/lib/session/supabaseSessionService.js +1 -1
- package/dist/lib/session/transcript.d.ts +9 -1
- package/dist/lib/session/transcript.js +15 -7
- package/dist/lib/skills.d.ts +50 -0
- package/dist/lib/skills.js +138 -0
- package/dist/lib/storage/postgres/index.d.ts +98 -0
- package/dist/lib/storage/postgres/index.js +146 -0
- package/dist/lib/storage/postgres/memoryStore.d.ts +11 -0
- package/dist/lib/storage/postgres/memoryStore.js +82 -0
- package/dist/lib/storage/postgres/sessionService.d.ts +51 -0
- package/dist/lib/storage/postgres/sessionService.js +225 -0
- package/dist/lib/storage/postgres/taskQueue.d.ts +22 -0
- package/dist/lib/storage/postgres/taskQueue.js +101 -0
- package/dist/lib/storage/postgres/taskStore.d.ts +55 -0
- package/dist/lib/storage/postgres/taskStore.js +168 -0
- package/dist/lib/storage/schema.d.ts +27 -0
- package/dist/lib/storage/schema.js +50 -0
- package/dist/lib/storage/schemaVersion.d.ts +25 -0
- package/dist/lib/storage/schemaVersion.js +46 -0
- package/dist/lib/syndicateSchema.d.ts +275 -0
- package/dist/lib/syndicateSchema.js +534 -0
- package/dist/lib/toolRegistry.d.ts +15 -0
- package/dist/lib/toolRegistry.js +59 -10
- package/dist/lib/tools/collectionsSearchTool.js +1 -1
- package/dist/lib/tools/mcpServe.d.ts +45 -0
- package/dist/lib/tools/mcpServe.js +88 -0
- package/dist/lib/tools/mcpToolFactory.d.ts +2 -0
- package/dist/lib/tools/mcpToolFactory.js +41 -21
- package/dist/lib/tools/science/corrections.d.ts +42 -0
- package/dist/lib/tools/science/corrections.js +115 -0
- package/dist/lib/tools/science/europepmc.d.ts +51 -0
- package/dist/lib/tools/science/europepmc.js +127 -0
- package/dist/lib/tools/science/http.d.ts +31 -0
- package/dist/lib/tools/science/http.js +104 -0
- package/dist/lib/tools/science/openalex.d.ts +30 -0
- package/dist/lib/tools/science/openalex.js +81 -0
- package/dist/lib/tools/science/trials.d.ts +58 -0
- package/dist/lib/tools/science/trials.js +203 -0
- package/dist/lib/tools/science/types.d.ts +69 -0
- package/dist/lib/tools/science/types.js +48 -0
- package/dist/lib/tools/scienceTools.d.ts +100 -0
- package/dist/lib/tools/scienceTools.js +277 -0
- package/dist/lib/tools/taskTools.d.ts +204 -0
- package/dist/lib/tools/taskTools.js +374 -0
- package/dist/lib/tools/toolContract.d.ts +17 -4
- package/dist/lib/tools/toolContract.js +13 -5
- package/dist/lib/tools/webExtractTool.d.ts +13 -10
- package/dist/lib/tools/webExtractTool.js +23 -55
- package/dist/lib/tools/webSearchTool.d.ts +2 -1
- package/dist/lib/tools/webSearchTool.js +4 -3
- package/dist/lib/tools/wikiTools.d.ts +2 -2
- package/dist/lib/tools/wikiTools.js +12 -12
- package/dist/lib/tools/xApiSearchTool.d.ts +194 -0
- package/dist/lib/tools/xApiSearchTool.js +583 -0
- package/dist/lib/tools/xSearchTool.js +1 -1
- package/dist/lib/wiki/agentRun.js +1 -1
- package/dist/lib/wiki/builder.js +21 -6
- package/dist/lib/wiki/dive.js +2 -2
- package/dist/lib/wiki/entities.d.ts +2 -2
- package/dist/lib/wiki/entities.js +7 -7
- package/dist/lib/wiki/extract.js +5 -1
- package/dist/lib/wiki/fill.js +5 -5
- package/dist/lib/wiki/format.d.ts +7 -5
- package/dist/lib/wiki/format.js +2 -2
- package/dist/lib/wiki/graph.js +2 -2
- package/dist/lib/wiki/lint.js +2 -2
- package/dist/lib/wiki/markdown.d.ts +1 -1
- package/dist/lib/wiki/markdown.js +6 -1
- package/dist/lib/wiki/pipeline.js +2 -2
- package/dist/lib/wiki/vault.js +2 -2
- package/dist/scripts/a2a_server.d.ts +17 -11
- package/dist/scripts/a2a_server.js +405 -1028
- package/dist/scripts/assistant_worker.d.ts +33 -0
- package/dist/scripts/assistant_worker.js +193 -0
- package/dist/scripts/db.d.ts +26 -0
- package/dist/scripts/db.js +179 -0
- package/dist/scripts/doctor.d.ts +23 -0
- package/dist/scripts/doctor.js +90 -0
- package/dist/scripts/init.d.ts +43 -0
- package/dist/scripts/init.js +152 -0
- package/dist/scripts/registry.d.ts +25 -0
- package/dist/scripts/registry.js +182 -0
- package/dist/scripts/skills_install.d.ts +7 -0
- package/dist/scripts/skills_install.js +137 -0
- package/dist/scripts/syndicate_chat.js +159 -276
- package/package.json +90 -16
- package/skills/README.md +74 -0
- package/skills/briefs/README.md +16 -0
- package/skills/briefs/_shared.md +16 -0
- package/skills/briefs/melchizedek-author.md +60 -0
- package/skills/briefs/melchizedek-memory.md +47 -0
- package/skills/briefs/melchizedek-models.md +47 -0
- package/skills/briefs/melchizedek-scribe.md +37 -0
- package/skills/briefs/melchizedek-serve.md +56 -0
- package/skills/briefs/melchizedek.md +69 -0
- package/skills/briefs/skills-readme.md +33 -0
- package/skills/melchizedek/SKILL.md +159 -0
- package/skills/melchizedek-author/SKILL.md +99 -0
- package/skills/melchizedek-author/templates/minimal.yaml +60 -0
- package/skills/melchizedek-memory/SKILL.md +138 -0
- package/skills/melchizedek-models/SKILL.md +137 -0
- package/skills/melchizedek-scribe/SKILL.md +72 -0
- package/skills/melchizedek-scribe/templates/brief.md +27 -0
- package/skills/melchizedek-serve/SKILL.md +119 -0
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* lib/storage/postgres/taskStore.ts — the A2A SDK's TaskStore on Postgres.
|
|
3
|
+
*
|
|
4
|
+
* Tasks outlive the process that started them and are visible to every
|
|
5
|
+
* instance, so a client that polls a different replica, or polls after a
|
|
6
|
+
* restart, still finds its task. Each task is filed under the tenant and
|
|
7
|
+
* owner the SDK's own scoping rule derives from the call context (the
|
|
8
|
+
* default resolver reads the authenticated user name), so one caller cannot
|
|
9
|
+
* load or list another's task. `list` mirrors the SDK's InMemoryTaskStore:
|
|
10
|
+
* same filters, same newest-first order, same page-token format.
|
|
11
|
+
*/
|
|
12
|
+
import type { Pool } from 'pg';
|
|
13
|
+
import type { TaskStore } from '@a2a-js/sdk/server';
|
|
14
|
+
type Task = Parameters<TaskStore['save']>[0];
|
|
15
|
+
type Context = Parameters<TaskStore['save']>[1];
|
|
16
|
+
type ListParams = Parameters<TaskStore['list']>[0];
|
|
17
|
+
type ListResult = Awaited<ReturnType<TaskStore['list']>>;
|
|
18
|
+
export interface PostgresTaskStoreOptions {
|
|
19
|
+
/** Owner of a call. Default: the SDK's resolveUserScope (the authenticated user name). */
|
|
20
|
+
ownerResolver?: (context: Context) => string;
|
|
21
|
+
/** Days a task is kept after its last update (expire_at). Default 7. */
|
|
22
|
+
ttlDays?: number;
|
|
23
|
+
/**
|
|
24
|
+
* While a task is running (submitted or working) it is leased to this
|
|
25
|
+
* instance until `ttlMs` from its last save or renewal (migration 0006).
|
|
26
|
+
*/
|
|
27
|
+
lease?: TaskLease;
|
|
28
|
+
}
|
|
29
|
+
export interface TaskLease {
|
|
30
|
+
/** This process's id: what a lease names as its owner. */
|
|
31
|
+
instanceId: string;
|
|
32
|
+
ttlMs: number;
|
|
33
|
+
}
|
|
34
|
+
/** Extends every lease this instance holds. Returns how many it renewed. */
|
|
35
|
+
export declare function renewTaskLeases(pool: Pool, lease: TaskLease): Promise<number>;
|
|
36
|
+
/**
|
|
37
|
+
* Marks running tasks whose lease expired (their instance died) as failed,
|
|
38
|
+
* with a message saying so. Any instance may run it: rows are claimed with
|
|
39
|
+
* SKIP LOCKED, so two reapers never fail the same task twice. Returns how
|
|
40
|
+
* many it failed.
|
|
41
|
+
*/
|
|
42
|
+
export declare function reapExpiredTasks(pool: Pool, limit?: number): Promise<number>;
|
|
43
|
+
export declare class PostgresTaskStore implements TaskStore {
|
|
44
|
+
private readonly owner;
|
|
45
|
+
private readonly ttlMs;
|
|
46
|
+
private readonly pool;
|
|
47
|
+
private readonly agentId;
|
|
48
|
+
private readonly lease?;
|
|
49
|
+
constructor(pool: Pool, agentId: string, options?: PostgresTaskStoreOptions);
|
|
50
|
+
private scope;
|
|
51
|
+
save(task: Task, context: Context): Promise<void>;
|
|
52
|
+
load(taskId: string, context: Context): Promise<Task | undefined>;
|
|
53
|
+
list(params: ListParams, context: Context): Promise<ListResult>;
|
|
54
|
+
}
|
|
55
|
+
export {};
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* lib/storage/postgres/taskStore.ts — the A2A SDK's TaskStore on Postgres.
|
|
3
|
+
*
|
|
4
|
+
* Tasks outlive the process that started them and are visible to every
|
|
5
|
+
* instance, so a client that polls a different replica, or polls after a
|
|
6
|
+
* restart, still finds its task. Each task is filed under the tenant and
|
|
7
|
+
* owner the SDK's own scoping rule derives from the call context (the
|
|
8
|
+
* default resolver reads the authenticated user name), so one caller cannot
|
|
9
|
+
* load or list another's task. `list` mirrors the SDK's InMemoryTaskStore:
|
|
10
|
+
* same filters, same newest-first order, same page-token format.
|
|
11
|
+
*/
|
|
12
|
+
import { randomUUID } from 'node:crypto';
|
|
13
|
+
import { Role, TaskState } from '@a2a-js/sdk';
|
|
14
|
+
import { resolveUserScope } from '@a2a-js/sdk/server';
|
|
15
|
+
const DEFAULT_PAGE_SIZE = 50;
|
|
16
|
+
/** States in which a task is being worked on by some instance. */
|
|
17
|
+
const RUNNING = new Set([TaskState.TASK_STATE_SUBMITTED, TaskState.TASK_STATE_WORKING]);
|
|
18
|
+
/** Extends every lease this instance holds. Returns how many it renewed. */
|
|
19
|
+
export async function renewTaskLeases(pool, lease) {
|
|
20
|
+
const r = await pool.query(`UPDATE adk_a2a_tasks SET lease_until = now() + ($2::int * interval '1 millisecond')
|
|
21
|
+
WHERE lease_owner = $1 AND lease_until IS NOT NULL`, [lease.instanceId, lease.ttlMs]);
|
|
22
|
+
return r.rowCount ?? 0;
|
|
23
|
+
}
|
|
24
|
+
/** The status a task gets when the instance running it is gone. */
|
|
25
|
+
const ORPHANED = 'The server running this task stopped before it finished; send the message again.';
|
|
26
|
+
/**
|
|
27
|
+
* Marks running tasks whose lease expired (their instance died) as failed,
|
|
28
|
+
* with a message saying so. Any instance may run it: rows are claimed with
|
|
29
|
+
* SKIP LOCKED, so two reapers never fail the same task twice. Returns how
|
|
30
|
+
* many it failed.
|
|
31
|
+
*/
|
|
32
|
+
export async function reapExpiredTasks(pool, limit = 100) {
|
|
33
|
+
const client = await pool.connect();
|
|
34
|
+
try {
|
|
35
|
+
await client.query('BEGIN');
|
|
36
|
+
const r = await client.query(`SELECT tenant, owner, agent_id, id, task FROM adk_a2a_tasks
|
|
37
|
+
WHERE lease_until IS NOT NULL AND lease_until < now()
|
|
38
|
+
ORDER BY lease_until LIMIT $1 FOR UPDATE SKIP LOCKED`, [limit]);
|
|
39
|
+
for (const row of r.rows) {
|
|
40
|
+
const task = row.task;
|
|
41
|
+
const timestamp = new Date().toISOString();
|
|
42
|
+
task.status = {
|
|
43
|
+
state: TaskState.TASK_STATE_FAILED,
|
|
44
|
+
timestamp,
|
|
45
|
+
message: {
|
|
46
|
+
messageId: randomUUID(),
|
|
47
|
+
contextId: task.contextId ?? '',
|
|
48
|
+
taskId: task.id,
|
|
49
|
+
role: Role.ROLE_AGENT,
|
|
50
|
+
parts: [{ content: { $case: 'text', value: ORPHANED }, filename: '', mediaType: 'text/plain' }],
|
|
51
|
+
extensions: [],
|
|
52
|
+
referenceTaskIds: [],
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
await client.query(`UPDATE adk_a2a_tasks SET task = $5::jsonb, state = $6, status_ts = $7, updated_at = now(),
|
|
56
|
+
lease_owner = NULL, lease_until = NULL
|
|
57
|
+
WHERE tenant = $1 AND owner = $2 AND agent_id = $3 AND id = $4`, [row.tenant, row.owner, row.agent_id, row.id, JSON.stringify(task), TaskState.TASK_STATE_FAILED, timestamp]);
|
|
58
|
+
}
|
|
59
|
+
await client.query('COMMIT');
|
|
60
|
+
return r.rows.length;
|
|
61
|
+
}
|
|
62
|
+
catch (err) {
|
|
63
|
+
await client.query('ROLLBACK').catch(() => { });
|
|
64
|
+
throw err;
|
|
65
|
+
}
|
|
66
|
+
finally {
|
|
67
|
+
client.release();
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
function encodePageToken(timestamp, id) {
|
|
71
|
+
return Buffer.from(`${timestamp}|${id}`).toString('base64');
|
|
72
|
+
}
|
|
73
|
+
function decodePageToken(token) {
|
|
74
|
+
const [timestamp, ...idParts] = Buffer.from(token, 'base64').toString('utf-8').split('|');
|
|
75
|
+
if (idParts.length === 0)
|
|
76
|
+
throw new Error('Invalid page token format.');
|
|
77
|
+
return { timestamp, id: idParts.join('|') };
|
|
78
|
+
}
|
|
79
|
+
export class PostgresTaskStore {
|
|
80
|
+
owner;
|
|
81
|
+
ttlMs;
|
|
82
|
+
pool;
|
|
83
|
+
agentId;
|
|
84
|
+
lease;
|
|
85
|
+
constructor(pool, agentId, options = {}) {
|
|
86
|
+
this.pool = pool;
|
|
87
|
+
this.agentId = agentId;
|
|
88
|
+
this.owner = options.ownerResolver ?? resolveUserScope;
|
|
89
|
+
this.ttlMs = (options.ttlDays ?? 7) * 24 * 60 * 60 * 1000;
|
|
90
|
+
this.lease = options.lease;
|
|
91
|
+
}
|
|
92
|
+
scope(context) {
|
|
93
|
+
return [context.tenant ?? '', this.owner(context)];
|
|
94
|
+
}
|
|
95
|
+
async save(task, context) {
|
|
96
|
+
const [tenant, owner] = this.scope(context);
|
|
97
|
+
const t = task;
|
|
98
|
+
// A running task is leased to this instance; any other state holds none.
|
|
99
|
+
const leased = !!this.lease && RUNNING.has(t.status?.state ?? -1);
|
|
100
|
+
await this.pool.query(`INSERT INTO adk_a2a_tasks (tenant, owner, agent_id, id, context_id, state, status_ts, task, updated_at, expire_at, lease_owner, lease_until)
|
|
101
|
+
VALUES ($1, $2, $3, $4, $5, $6, $7, $8::jsonb, now(), $9, $10,
|
|
102
|
+
CASE WHEN $10::text IS NULL THEN NULL ELSE now() + ($11::int * interval '1 millisecond') END)
|
|
103
|
+
ON CONFLICT (tenant, owner, agent_id, id) DO UPDATE
|
|
104
|
+
SET context_id = EXCLUDED.context_id, state = EXCLUDED.state, status_ts = EXCLUDED.status_ts,
|
|
105
|
+
task = EXCLUDED.task, updated_at = now(), expire_at = EXCLUDED.expire_at,
|
|
106
|
+
lease_owner = EXCLUDED.lease_owner, lease_until = EXCLUDED.lease_until`, [
|
|
107
|
+
tenant,
|
|
108
|
+
owner,
|
|
109
|
+
this.agentId,
|
|
110
|
+
t.id,
|
|
111
|
+
t.contextId ?? null,
|
|
112
|
+
t.status?.state ?? null,
|
|
113
|
+
t.status?.timestamp ?? '',
|
|
114
|
+
JSON.stringify(task),
|
|
115
|
+
new Date(Date.now() + this.ttlMs).toISOString(),
|
|
116
|
+
leased ? this.lease.instanceId : null,
|
|
117
|
+
this.lease?.ttlMs ?? 0,
|
|
118
|
+
]);
|
|
119
|
+
}
|
|
120
|
+
async load(taskId, context) {
|
|
121
|
+
const [tenant, owner] = this.scope(context);
|
|
122
|
+
const r = await this.pool.query('SELECT task FROM adk_a2a_tasks WHERE tenant = $1 AND owner = $2 AND agent_id = $3 AND id = $4', [tenant, owner, this.agentId, taskId]);
|
|
123
|
+
return r.rowCount ? r.rows[0].task : undefined;
|
|
124
|
+
}
|
|
125
|
+
async list(params, context) {
|
|
126
|
+
const [tenant, owner] = this.scope(context);
|
|
127
|
+
const p = params;
|
|
128
|
+
const pageSize = p.pageSize || DEFAULT_PAGE_SIZE;
|
|
129
|
+
const args = [tenant, owner, this.agentId];
|
|
130
|
+
let where = 'tenant = $1 AND owner = $2 AND agent_id = $3';
|
|
131
|
+
if (p.contextId) {
|
|
132
|
+
args.push(p.contextId);
|
|
133
|
+
where += ` AND context_id = $${args.length}`;
|
|
134
|
+
}
|
|
135
|
+
if (p.status !== undefined && p.status !== 0) {
|
|
136
|
+
args.push(p.status);
|
|
137
|
+
where += ` AND state = $${args.length}`;
|
|
138
|
+
}
|
|
139
|
+
if (p.statusTimestampAfter) {
|
|
140
|
+
args.push(new Date(p.statusTimestampAfter).toISOString());
|
|
141
|
+
where += ` AND status_ts <> '' AND status_ts::timestamptz > $${args.length}::timestamptz`;
|
|
142
|
+
}
|
|
143
|
+
const total = await this.pool.query(`SELECT count(*)::int AS n FROM adk_a2a_tasks WHERE ${where}`, args);
|
|
144
|
+
let cursor = '';
|
|
145
|
+
if (p.pageToken) {
|
|
146
|
+
const c = decodePageToken(p.pageToken);
|
|
147
|
+
args.push(c.timestamp, c.id);
|
|
148
|
+
cursor = ` AND (status_ts, id) < ($${args.length - 1}, $${args.length})`;
|
|
149
|
+
}
|
|
150
|
+
args.push(pageSize + 1);
|
|
151
|
+
const rows = await this.pool.query(`SELECT task, status_ts, id FROM adk_a2a_tasks WHERE ${where}${cursor}
|
|
152
|
+
ORDER BY status_ts DESC, id DESC LIMIT $${args.length}`, args);
|
|
153
|
+
const page = rows.rows.slice(0, pageSize);
|
|
154
|
+
const tasks = page.map((row) => {
|
|
155
|
+
const task = row.task;
|
|
156
|
+
if (!p.includeArtifacts)
|
|
157
|
+
task.artifacts = [];
|
|
158
|
+
return task;
|
|
159
|
+
});
|
|
160
|
+
const last = page[page.length - 1];
|
|
161
|
+
return {
|
|
162
|
+
tasks,
|
|
163
|
+
nextPageToken: rows.rows.length > pageSize && last ? encodePageToken(last.status_ts ?? '', last.id) : '',
|
|
164
|
+
pageSize,
|
|
165
|
+
totalSize: total.rows[0].n,
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* lib/storage/schema.ts — the database schema the tables live in
|
|
3
|
+
* (ADR 0021 item 2).
|
|
4
|
+
*
|
|
5
|
+
* The default is `public`, where every existing deployment's tables are.
|
|
6
|
+
* A deployment on its own Postgres can keep them in a private schema
|
|
7
|
+
* instead (MELCHIZEDEK_DB_SCHEMA, e.g. `melchizedek`): a REST layer such as
|
|
8
|
+
* Supabase's exposes `public` by default, so a private schema has no anon
|
|
9
|
+
* REST path at all. It is reached over DATABASE_URL (postgresStorage), which
|
|
10
|
+
* sets the connection's search_path; supabase-js storage cannot use it.
|
|
11
|
+
*
|
|
12
|
+
* The SQL in db/ names `public` in three places, which `sqlForSchema`
|
|
13
|
+
* rewrites, and nowhere else (pinned by tests):
|
|
14
|
+
* - `SET search_path = public` on function definitions;
|
|
15
|
+
* - `'public.<table>'` in to_regclass lookups;
|
|
16
|
+
* - `= 'public'` in catalog filters;
|
|
17
|
+
* plus the pg_cron jobs, which run outside any search_path and so call
|
|
18
|
+
* their function by its qualified name. `public` stays on the path after
|
|
19
|
+
* the schema, for the pgvector type and functions.
|
|
20
|
+
*/
|
|
21
|
+
export declare const SCHEMA_NAME: RegExp;
|
|
22
|
+
/** The configured schema: MELCHIZEDEK_DB_SCHEMA, else `public`. */
|
|
23
|
+
export declare function dbSchema(env?: NodeJS.ProcessEnv): string;
|
|
24
|
+
/** A db/ file's SQL for `schema` (unchanged for `public`). */
|
|
25
|
+
export declare function sqlForSchema(sql: string, schema: string): string;
|
|
26
|
+
/** The pg connection option that puts `schema` first on the search_path. */
|
|
27
|
+
export declare function searchPathOption(schema: string): string | undefined;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* lib/storage/schema.ts — the database schema the tables live in
|
|
3
|
+
* (ADR 0021 item 2).
|
|
4
|
+
*
|
|
5
|
+
* The default is `public`, where every existing deployment's tables are.
|
|
6
|
+
* A deployment on its own Postgres can keep them in a private schema
|
|
7
|
+
* instead (MELCHIZEDEK_DB_SCHEMA, e.g. `melchizedek`): a REST layer such as
|
|
8
|
+
* Supabase's exposes `public` by default, so a private schema has no anon
|
|
9
|
+
* REST path at all. It is reached over DATABASE_URL (postgresStorage), which
|
|
10
|
+
* sets the connection's search_path; supabase-js storage cannot use it.
|
|
11
|
+
*
|
|
12
|
+
* The SQL in db/ names `public` in three places, which `sqlForSchema`
|
|
13
|
+
* rewrites, and nowhere else (pinned by tests):
|
|
14
|
+
* - `SET search_path = public` on function definitions;
|
|
15
|
+
* - `'public.<table>'` in to_regclass lookups;
|
|
16
|
+
* - `= 'public'` in catalog filters;
|
|
17
|
+
* plus the pg_cron jobs, which run outside any search_path and so call
|
|
18
|
+
* their function by its qualified name. `public` stays on the path after
|
|
19
|
+
* the schema, for the pgvector type and functions.
|
|
20
|
+
*/
|
|
21
|
+
export const SCHEMA_NAME = /^[a-z_][a-z0-9_]{0,62}$/;
|
|
22
|
+
/** The configured schema: MELCHIZEDEK_DB_SCHEMA, else `public`. */
|
|
23
|
+
export function dbSchema(env = process.env) {
|
|
24
|
+
const s = env.MELCHIZEDEK_DB_SCHEMA?.trim() || 'public';
|
|
25
|
+
if (!SCHEMA_NAME.test(s)) {
|
|
26
|
+
throw new Error(`MELCHIZEDEK_DB_SCHEMA must be a lower-case identifier (letters, digits, _), got "${s}"`);
|
|
27
|
+
}
|
|
28
|
+
return s;
|
|
29
|
+
}
|
|
30
|
+
/** A db/ file's SQL for `schema` (unchanged for `public`). */
|
|
31
|
+
export function sqlForSchema(sql, schema) {
|
|
32
|
+
if (schema === 'public')
|
|
33
|
+
return sql;
|
|
34
|
+
if (!SCHEMA_NAME.test(schema))
|
|
35
|
+
throw new Error(`invalid schema name "${schema}"`);
|
|
36
|
+
const body = sql
|
|
37
|
+
.replaceAll('SET search_path = public', `SET search_path = ${schema}, public`)
|
|
38
|
+
.replaceAll("'public.", `'${schema}.`)
|
|
39
|
+
.replaceAll("= 'public'", `= '${schema}'`)
|
|
40
|
+
.replace(/'SELECT (melchizedek_[a-z_]+\(\))'/g, `'SELECT ${schema}.$1'`);
|
|
41
|
+
return `CREATE SCHEMA IF NOT EXISTS ${schema};\nSET search_path = ${schema}, public;\n${body}`;
|
|
42
|
+
}
|
|
43
|
+
/** The pg connection option that puts `schema` first on the search_path. */
|
|
44
|
+
export function searchPathOption(schema) {
|
|
45
|
+
if (schema === 'public')
|
|
46
|
+
return undefined;
|
|
47
|
+
if (!SCHEMA_NAME.test(schema))
|
|
48
|
+
throw new Error(`invalid schema name "${schema}"`);
|
|
49
|
+
return `-c search_path=${schema},public`;
|
|
50
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* lib/storage/schemaVersion.ts — the database schema this package expects
|
|
3
|
+
* (ADR 0021 item 3).
|
|
4
|
+
*
|
|
5
|
+
* Every numbered migration in db/migrations/ records itself in
|
|
6
|
+
* `melchizedek_schema_version`. The highest number shipped with the package
|
|
7
|
+
* is the schema this code is written against; a database below it is missing
|
|
8
|
+
* tables or functions the server will call, so the server refuses to start on
|
|
9
|
+
* it and names the fix. A database ABOVE it is a newer migration applied
|
|
10
|
+
* before this server was upgraded (a rolling deploy): migrations are additive,
|
|
11
|
+
* so that only warns.
|
|
12
|
+
*/
|
|
13
|
+
/** db/ of this package, from the source tree or from dist/. */
|
|
14
|
+
export declare function packageDbDir(): string;
|
|
15
|
+
/** The highest migration number in db/migrations/ (NNNN_name.sql). */
|
|
16
|
+
export declare function shippedSchemaVersion(migrationsDir?: string): number;
|
|
17
|
+
export interface SchemaCheck {
|
|
18
|
+
/** Version recorded in the database; null when it has none. */
|
|
19
|
+
db: number | null;
|
|
20
|
+
shipped: number;
|
|
21
|
+
state: 'match' | 'behind' | 'ahead';
|
|
22
|
+
}
|
|
23
|
+
export declare function compareSchema(db: number | null, shipped: number): SchemaCheck;
|
|
24
|
+
/** The message for a database behind the code: what is missing and the fix. */
|
|
25
|
+
export declare function schemaBehindMessage(check: SchemaCheck): string;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* lib/storage/schemaVersion.ts — the database schema this package expects
|
|
3
|
+
* (ADR 0021 item 3).
|
|
4
|
+
*
|
|
5
|
+
* Every numbered migration in db/migrations/ records itself in
|
|
6
|
+
* `melchizedek_schema_version`. The highest number shipped with the package
|
|
7
|
+
* is the schema this code is written against; a database below it is missing
|
|
8
|
+
* tables or functions the server will call, so the server refuses to start on
|
|
9
|
+
* it and names the fix. A database ABOVE it is a newer migration applied
|
|
10
|
+
* before this server was upgraded (a rolling deploy): migrations are additive,
|
|
11
|
+
* so that only warns.
|
|
12
|
+
*/
|
|
13
|
+
import { existsSync, readdirSync } from 'node:fs';
|
|
14
|
+
import { dirname, join } from 'node:path';
|
|
15
|
+
import { fileURLToPath } from 'node:url';
|
|
16
|
+
/** db/ of this package, from the source tree or from dist/. */
|
|
17
|
+
export function packageDbDir() {
|
|
18
|
+
let dir = dirname(fileURLToPath(import.meta.url));
|
|
19
|
+
for (let i = 0; i < 6; i++) {
|
|
20
|
+
if (existsSync(join(dir, 'db', 'migrations')))
|
|
21
|
+
return join(dir, 'db');
|
|
22
|
+
dir = dirname(dir);
|
|
23
|
+
}
|
|
24
|
+
throw new Error('db/migrations/ not found next to this package');
|
|
25
|
+
}
|
|
26
|
+
/** The highest migration number in db/migrations/ (NNNN_name.sql). */
|
|
27
|
+
export function shippedSchemaVersion(migrationsDir = join(packageDbDir(), 'migrations')) {
|
|
28
|
+
let max = 0;
|
|
29
|
+
for (const f of readdirSync(migrationsDir)) {
|
|
30
|
+
const m = /^(\d{4})_[a-z0-9_]+\.sql$/.exec(f);
|
|
31
|
+
if (m)
|
|
32
|
+
max = Math.max(max, Number(m[1]));
|
|
33
|
+
}
|
|
34
|
+
return max;
|
|
35
|
+
}
|
|
36
|
+
export function compareSchema(db, shipped) {
|
|
37
|
+
const v = db ?? 0;
|
|
38
|
+
return { db, shipped, state: v === shipped ? 'match' : v < shipped ? 'behind' : 'ahead' };
|
|
39
|
+
}
|
|
40
|
+
/** The message for a database behind the code: what is missing and the fix. */
|
|
41
|
+
export function schemaBehindMessage(check) {
|
|
42
|
+
const have = check.db === null ? 'no recorded schema version' : `schema version ${check.db}`;
|
|
43
|
+
return (`The database has ${have}; this server needs version ${check.shipped}. ` +
|
|
44
|
+
'Run `npx melchizedek-db apply` (or `npm run db -- apply`) against it, ' +
|
|
45
|
+
'or set ALLOW_SCHEMA_MISMATCH=true to start anyway.');
|
|
46
|
+
}
|
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* lib/syndicateSchema.ts — the syndicate YAML contract, as a validator.
|
|
3
|
+
*
|
|
4
|
+
* WHY this file exists:
|
|
5
|
+
* A syndicate YAML is the framework's primary authoring surface, and the
|
|
6
|
+
* loader used to type-cast it (`parse(...) as SyndicateYamlConfig`). A typo
|
|
7
|
+
* either crashed deep inside the compiler (`orchestator:` → "cannot read
|
|
8
|
+
* 'model' of undefined") or, worse, was accepted and silently changed
|
|
9
|
+
* behaviour (`memory_system: internl-only` disabled memory in the A2A
|
|
10
|
+
* server). Here the shape the interfaces in lib/loadSyndicate.ts declare is
|
|
11
|
+
* written once as a zod schema, checked at load, and every problem is
|
|
12
|
+
* reported with its key path and, for a misspelt key, the key it was meant
|
|
13
|
+
* to be.
|
|
14
|
+
*
|
|
15
|
+
* The same schema emits config/agents/syndicate.schema.json (npm run
|
|
16
|
+
* schema:gen) so an editor can flag the typo before a run does; a test
|
|
17
|
+
* keeps the committed file equal to the generated one.
|
|
18
|
+
*
|
|
19
|
+
* Strictness is deliberate at the syndicate, agent and dispatch levels — the
|
|
20
|
+
* places a misspelt key silently does nothing — and deliberately ABSENT inside
|
|
21
|
+
* `generateContentConfig` and `outputSchema`, which pass through to provider
|
|
22
|
+
* SDKs whose fields this repo does not own.
|
|
23
|
+
*/
|
|
24
|
+
import { z } from 'zod';
|
|
25
|
+
import type { SyndicateYamlConfig } from './loadSyndicate.ts';
|
|
26
|
+
export declare const MEMORY_SYSTEMS: readonly ['internal-only', 'session-only', 'long-term'];
|
|
27
|
+
export declare const agentSchema: z.ZodObject<{
|
|
28
|
+
name: z.ZodString;
|
|
29
|
+
description: z.ZodOptional<z.ZodString>;
|
|
30
|
+
model: z.ZodString;
|
|
31
|
+
instruction: z.ZodString;
|
|
32
|
+
globalInstruction: z.ZodOptional<z.ZodString>;
|
|
33
|
+
tools: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
34
|
+
require_approval: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
35
|
+
includeContents: z.ZodOptional<z.ZodEnum<{
|
|
36
|
+
default: "default";
|
|
37
|
+
none: "none";
|
|
38
|
+
}>>;
|
|
39
|
+
disallowTransferToParent: z.ZodOptional<z.ZodBoolean>;
|
|
40
|
+
disallowTransferToPeers: z.ZodOptional<z.ZodBoolean>;
|
|
41
|
+
outputKey: z.ZodOptional<z.ZodString>;
|
|
42
|
+
generateContentConfig: z.ZodOptional<z.ZodObject<{
|
|
43
|
+
temperature: z.ZodOptional<z.ZodNumber>;
|
|
44
|
+
topP: z.ZodOptional<z.ZodNumber>;
|
|
45
|
+
topK: z.ZodOptional<z.ZodNumber>;
|
|
46
|
+
maxOutputTokens: z.ZodOptional<z.ZodNumber>;
|
|
47
|
+
stopSequences: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
48
|
+
candidateCount: z.ZodOptional<z.ZodNumber>;
|
|
49
|
+
presencePenalty: z.ZodOptional<z.ZodNumber>;
|
|
50
|
+
frequencyPenalty: z.ZodOptional<z.ZodNumber>;
|
|
51
|
+
seed: z.ZodOptional<z.ZodNumber>;
|
|
52
|
+
responseMimeType: z.ZodOptional<z.ZodString>;
|
|
53
|
+
safetySettings: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
54
|
+
category: z.ZodString;
|
|
55
|
+
threshold: z.ZodString;
|
|
56
|
+
}, z.core.$loose>>>;
|
|
57
|
+
thinkingConfig: z.ZodOptional<z.ZodObject<{
|
|
58
|
+
thinkingBudget: z.ZodOptional<z.ZodNumber>;
|
|
59
|
+
includeThoughts: z.ZodOptional<z.ZodBoolean>;
|
|
60
|
+
}, z.core.$loose>>;
|
|
61
|
+
}, z.core.$loose>>;
|
|
62
|
+
outputSchema: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
63
|
+
mcp_server_url: z.ZodOptional<z.ZodString>;
|
|
64
|
+
orchestration: z.ZodOptional<z.ZodObject<{
|
|
65
|
+
role: z.ZodOptional<z.ZodEnum<{
|
|
66
|
+
primary: "primary";
|
|
67
|
+
"sub-agent": "sub-agent";
|
|
68
|
+
}>>;
|
|
69
|
+
delegates: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
70
|
+
}, z.core.$strict>>;
|
|
71
|
+
}, z.core.$strict>;
|
|
72
|
+
/**
|
|
73
|
+
* Model and instruction are optional at the type level because a nested
|
|
74
|
+
* (`yaml_reference`) or remote (`a2a_agent_url`) subagent brings its own; the
|
|
75
|
+
* "an ordinary subagent needs an instruction" rule is checked in
|
|
76
|
+
* crossFieldProblems so it can name the alternative keys in its message.
|
|
77
|
+
*/
|
|
78
|
+
export declare const subagentSchema: z.ZodObject<{
|
|
79
|
+
name: z.ZodString;
|
|
80
|
+
globalInstruction: z.ZodOptional<z.ZodString>;
|
|
81
|
+
tools: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
82
|
+
require_approval: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
83
|
+
includeContents: z.ZodOptional<z.ZodEnum<{
|
|
84
|
+
default: "default";
|
|
85
|
+
none: "none";
|
|
86
|
+
}>>;
|
|
87
|
+
disallowTransferToParent: z.ZodOptional<z.ZodBoolean>;
|
|
88
|
+
disallowTransferToPeers: z.ZodOptional<z.ZodBoolean>;
|
|
89
|
+
outputKey: z.ZodOptional<z.ZodString>;
|
|
90
|
+
generateContentConfig: z.ZodOptional<z.ZodObject<{
|
|
91
|
+
temperature: z.ZodOptional<z.ZodNumber>;
|
|
92
|
+
topP: z.ZodOptional<z.ZodNumber>;
|
|
93
|
+
topK: z.ZodOptional<z.ZodNumber>;
|
|
94
|
+
maxOutputTokens: z.ZodOptional<z.ZodNumber>;
|
|
95
|
+
stopSequences: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
96
|
+
candidateCount: z.ZodOptional<z.ZodNumber>;
|
|
97
|
+
presencePenalty: z.ZodOptional<z.ZodNumber>;
|
|
98
|
+
frequencyPenalty: z.ZodOptional<z.ZodNumber>;
|
|
99
|
+
seed: z.ZodOptional<z.ZodNumber>;
|
|
100
|
+
responseMimeType: z.ZodOptional<z.ZodString>;
|
|
101
|
+
safetySettings: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
102
|
+
category: z.ZodString;
|
|
103
|
+
threshold: z.ZodString;
|
|
104
|
+
}, z.core.$loose>>>;
|
|
105
|
+
thinkingConfig: z.ZodOptional<z.ZodObject<{
|
|
106
|
+
thinkingBudget: z.ZodOptional<z.ZodNumber>;
|
|
107
|
+
includeThoughts: z.ZodOptional<z.ZodBoolean>;
|
|
108
|
+
}, z.core.$loose>>;
|
|
109
|
+
}, z.core.$loose>>;
|
|
110
|
+
outputSchema: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
111
|
+
mcp_server_url: z.ZodOptional<z.ZodString>;
|
|
112
|
+
orchestration: z.ZodOptional<z.ZodObject<{
|
|
113
|
+
role: z.ZodOptional<z.ZodEnum<{
|
|
114
|
+
primary: "primary";
|
|
115
|
+
"sub-agent": "sub-agent";
|
|
116
|
+
}>>;
|
|
117
|
+
delegates: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
118
|
+
}, z.core.$strict>>;
|
|
119
|
+
description: z.ZodString;
|
|
120
|
+
model: z.ZodOptional<z.ZodString>;
|
|
121
|
+
instruction: z.ZodOptional<z.ZodString>;
|
|
122
|
+
yaml_reference: z.ZodOptional<z.ZodString>;
|
|
123
|
+
a2a_agent_url: z.ZodOptional<z.ZodString>;
|
|
124
|
+
}, z.core.$strict>;
|
|
125
|
+
export declare const syndicateSchema: z.ZodObject<{
|
|
126
|
+
syndicate_name: z.ZodString;
|
|
127
|
+
orchestrator: z.ZodObject<{
|
|
128
|
+
name: z.ZodString;
|
|
129
|
+
description: z.ZodOptional<z.ZodString>;
|
|
130
|
+
model: z.ZodString;
|
|
131
|
+
instruction: z.ZodString;
|
|
132
|
+
globalInstruction: z.ZodOptional<z.ZodString>;
|
|
133
|
+
tools: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
134
|
+
require_approval: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
135
|
+
includeContents: z.ZodOptional<z.ZodEnum<{
|
|
136
|
+
default: "default";
|
|
137
|
+
none: "none";
|
|
138
|
+
}>>;
|
|
139
|
+
disallowTransferToParent: z.ZodOptional<z.ZodBoolean>;
|
|
140
|
+
disallowTransferToPeers: z.ZodOptional<z.ZodBoolean>;
|
|
141
|
+
outputKey: z.ZodOptional<z.ZodString>;
|
|
142
|
+
generateContentConfig: z.ZodOptional<z.ZodObject<{
|
|
143
|
+
temperature: z.ZodOptional<z.ZodNumber>;
|
|
144
|
+
topP: z.ZodOptional<z.ZodNumber>;
|
|
145
|
+
topK: z.ZodOptional<z.ZodNumber>;
|
|
146
|
+
maxOutputTokens: z.ZodOptional<z.ZodNumber>;
|
|
147
|
+
stopSequences: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
148
|
+
candidateCount: z.ZodOptional<z.ZodNumber>;
|
|
149
|
+
presencePenalty: z.ZodOptional<z.ZodNumber>;
|
|
150
|
+
frequencyPenalty: z.ZodOptional<z.ZodNumber>;
|
|
151
|
+
seed: z.ZodOptional<z.ZodNumber>;
|
|
152
|
+
responseMimeType: z.ZodOptional<z.ZodString>;
|
|
153
|
+
safetySettings: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
154
|
+
category: z.ZodString;
|
|
155
|
+
threshold: z.ZodString;
|
|
156
|
+
}, z.core.$loose>>>;
|
|
157
|
+
thinkingConfig: z.ZodOptional<z.ZodObject<{
|
|
158
|
+
thinkingBudget: z.ZodOptional<z.ZodNumber>;
|
|
159
|
+
includeThoughts: z.ZodOptional<z.ZodBoolean>;
|
|
160
|
+
}, z.core.$loose>>;
|
|
161
|
+
}, z.core.$loose>>;
|
|
162
|
+
outputSchema: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
163
|
+
mcp_server_url: z.ZodOptional<z.ZodString>;
|
|
164
|
+
orchestration: z.ZodOptional<z.ZodObject<{
|
|
165
|
+
role: z.ZodOptional<z.ZodEnum<{
|
|
166
|
+
primary: "primary";
|
|
167
|
+
"sub-agent": "sub-agent";
|
|
168
|
+
}>>;
|
|
169
|
+
delegates: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
170
|
+
}, z.core.$strict>>;
|
|
171
|
+
}, z.core.$strict>;
|
|
172
|
+
subagents: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
173
|
+
name: z.ZodString;
|
|
174
|
+
globalInstruction: z.ZodOptional<z.ZodString>;
|
|
175
|
+
tools: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
176
|
+
require_approval: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
177
|
+
includeContents: z.ZodOptional<z.ZodEnum<{
|
|
178
|
+
default: "default";
|
|
179
|
+
none: "none";
|
|
180
|
+
}>>;
|
|
181
|
+
disallowTransferToParent: z.ZodOptional<z.ZodBoolean>;
|
|
182
|
+
disallowTransferToPeers: z.ZodOptional<z.ZodBoolean>;
|
|
183
|
+
outputKey: z.ZodOptional<z.ZodString>;
|
|
184
|
+
generateContentConfig: z.ZodOptional<z.ZodObject<{
|
|
185
|
+
temperature: z.ZodOptional<z.ZodNumber>;
|
|
186
|
+
topP: z.ZodOptional<z.ZodNumber>;
|
|
187
|
+
topK: z.ZodOptional<z.ZodNumber>;
|
|
188
|
+
maxOutputTokens: z.ZodOptional<z.ZodNumber>;
|
|
189
|
+
stopSequences: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
190
|
+
candidateCount: z.ZodOptional<z.ZodNumber>;
|
|
191
|
+
presencePenalty: z.ZodOptional<z.ZodNumber>;
|
|
192
|
+
frequencyPenalty: z.ZodOptional<z.ZodNumber>;
|
|
193
|
+
seed: z.ZodOptional<z.ZodNumber>;
|
|
194
|
+
responseMimeType: z.ZodOptional<z.ZodString>;
|
|
195
|
+
safetySettings: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
196
|
+
category: z.ZodString;
|
|
197
|
+
threshold: z.ZodString;
|
|
198
|
+
}, z.core.$loose>>>;
|
|
199
|
+
thinkingConfig: z.ZodOptional<z.ZodObject<{
|
|
200
|
+
thinkingBudget: z.ZodOptional<z.ZodNumber>;
|
|
201
|
+
includeThoughts: z.ZodOptional<z.ZodBoolean>;
|
|
202
|
+
}, z.core.$loose>>;
|
|
203
|
+
}, z.core.$loose>>;
|
|
204
|
+
outputSchema: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
205
|
+
mcp_server_url: z.ZodOptional<z.ZodString>;
|
|
206
|
+
orchestration: z.ZodOptional<z.ZodObject<{
|
|
207
|
+
role: z.ZodOptional<z.ZodEnum<{
|
|
208
|
+
primary: "primary";
|
|
209
|
+
"sub-agent": "sub-agent";
|
|
210
|
+
}>>;
|
|
211
|
+
delegates: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
212
|
+
}, z.core.$strict>>;
|
|
213
|
+
description: z.ZodString;
|
|
214
|
+
model: z.ZodOptional<z.ZodString>;
|
|
215
|
+
instruction: z.ZodOptional<z.ZodString>;
|
|
216
|
+
yaml_reference: z.ZodOptional<z.ZodString>;
|
|
217
|
+
a2a_agent_url: z.ZodOptional<z.ZodString>;
|
|
218
|
+
}, z.core.$strict>>>;
|
|
219
|
+
dispatch: z.ZodOptional<z.ZodObject<{
|
|
220
|
+
default_route: z.ZodString;
|
|
221
|
+
route_key: z.ZodOptional<z.ZodString>;
|
|
222
|
+
reason_key: z.ZodOptional<z.ZodString>;
|
|
223
|
+
route_overrides: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
224
|
+
route: z.ZodString;
|
|
225
|
+
pattern: z.ZodString;
|
|
226
|
+
flags: z.ZodOptional<z.ZodString>;
|
|
227
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
228
|
+
}, z.core.$strict>>>;
|
|
229
|
+
}, z.core.$strict>>;
|
|
230
|
+
variables: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>>;
|
|
231
|
+
memory_system: z.ZodOptional<z.ZodEnum<{
|
|
232
|
+
"internal-only": "internal-only";
|
|
233
|
+
"long-term": "long-term";
|
|
234
|
+
"session-only": "session-only";
|
|
235
|
+
}>>;
|
|
236
|
+
guards: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
237
|
+
memory_namespace: z.ZodOptional<z.ZodString>;
|
|
238
|
+
memory_extraction_rules: z.ZodOptional<z.ZodString>;
|
|
239
|
+
memory_extraction_model: z.ZodOptional<z.ZodString>;
|
|
240
|
+
memory_retention_days: z.ZodOptional<z.ZodNumber>;
|
|
241
|
+
max_steps: z.ZodOptional<z.ZodNumber>;
|
|
242
|
+
bundled_references: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
|
|
243
|
+
}, z.core.$strict>;
|
|
244
|
+
/**
|
|
245
|
+
* The closest candidate, if it is close enough to be a typo. Case and
|
|
246
|
+
* snake/camel drift (`output_key` for `outputKey`) count as an exact match.
|
|
247
|
+
*/
|
|
248
|
+
export declare function suggest(input: string, candidates: readonly string[]): string | undefined;
|
|
249
|
+
/**
|
|
250
|
+
* Thrown by validateSyndicateConfig. `problems` holds one `<file>: <path> —
|
|
251
|
+
* <what>` line per problem (the message lists them all); `issues` holds the
|
|
252
|
+
* same lines without the file, for callers that already show it.
|
|
253
|
+
*/
|
|
254
|
+
export declare class SyndicateValidationError extends Error {
|
|
255
|
+
readonly file: string | undefined;
|
|
256
|
+
readonly issues: string[];
|
|
257
|
+
readonly problems: string[];
|
|
258
|
+
constructor(issues: string[], file?: string);
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Validate a parsed syndicate and return it typed, or throw ONE error that
|
|
262
|
+
* lists every problem as `<file>: <key.path> — <what is wrong>`.
|
|
263
|
+
*
|
|
264
|
+
* Runs on the interpolated config: a `{{token}}` inside a string is still a
|
|
265
|
+
* string, and a full-token number (`max_steps: "{{n}}"`) is checked as the
|
|
266
|
+
* value it resolved to.
|
|
267
|
+
*/
|
|
268
|
+
export declare function validateSyndicateConfig(raw: unknown, file?: string): SyndicateYamlConfig;
|
|
269
|
+
/**
|
|
270
|
+
* The syndicate contract as JSON Schema (draft-07: the widest editor
|
|
271
|
+
* support), for `# yaml-language-server: $schema=` and other tooling.
|
|
272
|
+
* Cross-field rules zod expresses as code are added back where JSON Schema
|
|
273
|
+
* can say them, so an editor flags a subagent with no instruction too.
|
|
274
|
+
*/
|
|
275
|
+
export declare function syndicateJsonSchema(): Record<string, unknown>;
|