@cef-ai/cli 0.2.6 → 0.3.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/README.md +75 -1247
- package/dist/build/duration.d.ts +22 -0
- package/dist/build/duration.d.ts.map +1 -0
- package/dist/build/duration.js +44 -0
- package/dist/build/duration.js.map +1 -0
- package/dist/build/esbuild-plugin.d.ts +32 -0
- package/dist/build/esbuild-plugin.d.ts.map +1 -0
- package/dist/build/esbuild-plugin.js +53 -0
- package/dist/build/esbuild-plugin.js.map +1 -0
- package/dist/build/lints.d.ts +55 -0
- package/dist/build/lints.d.ts.map +1 -0
- package/dist/build/lints.js +214 -0
- package/dist/build/lints.js.map +1 -0
- package/dist/build/load-config.d.ts +114 -0
- package/dist/build/load-config.d.ts.map +1 -0
- package/dist/build/load-config.js +150 -0
- package/dist/build/load-config.js.map +1 -0
- package/dist/build/manifest.d.ts +156 -0
- package/dist/build/manifest.d.ts.map +1 -0
- package/dist/build/manifest.js +111 -0
- package/dist/build/manifest.js.map +1 -0
- package/dist/build/targeting.d.ts +15 -0
- package/dist/build/targeting.d.ts.map +1 -0
- package/dist/build/targeting.js +69 -0
- package/dist/build/targeting.js.map +1 -0
- package/dist/cli.d.ts +2 -2
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +107 -62
- package/dist/cli.js.map +1 -0
- package/dist/commands/build.d.ts +41 -0
- package/dist/commands/build.d.ts.map +1 -0
- package/dist/commands/build.js +252 -0
- package/dist/commands/build.js.map +1 -0
- package/dist/commands/inspect.d.ts +49 -0
- package/dist/commands/inspect.d.ts.map +1 -0
- package/dist/commands/inspect.js +135 -0
- package/dist/commands/inspect.js.map +1 -0
- package/dist/commands/typegen.d.ts +36 -0
- package/dist/commands/typegen.d.ts.map +1 -0
- package/dist/commands/typegen.js +210 -0
- package/dist/commands/typegen.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/lib.d.ts +12 -0
- package/dist/lib.d.ts.map +1 -0
- package/dist/lib.js +9 -0
- package/dist/lib.js.map +1 -0
- package/dist/typegen/augment.d.ts +57 -0
- package/dist/typegen/augment.d.ts.map +1 -0
- package/dist/typegen/augment.js +87 -0
- package/dist/typegen/augment.js.map +1 -0
- package/dist/typegen/fetch.d.ts +30 -0
- package/dist/typegen/fetch.d.ts.map +1 -0
- package/dist/typegen/fetch.js +38 -0
- package/dist/typegen/fetch.js.map +1 -0
- package/dist/typegen/lockfile.d.ts +42 -0
- package/dist/typegen/lockfile.d.ts.map +1 -0
- package/dist/typegen/lockfile.js +58 -0
- package/dist/typegen/lockfile.js.map +1 -0
- package/dist/typegen/schema-to-ts.d.ts +21 -0
- package/dist/typegen/schema-to-ts.d.ts.map +1 -0
- package/dist/typegen/schema-to-ts.js +29 -0
- package/dist/typegen/schema-to-ts.js.map +1 -0
- package/package.json +20 -58
- package/dist/commands/auth/index.d.ts +0 -2
- package/dist/commands/auth/index.js +0 -162
- package/dist/commands/deploy/clone.d.ts +0 -13
- package/dist/commands/deploy/clone.js +0 -143
- package/dist/commands/deploy/delete.d.ts +0 -14
- package/dist/commands/deploy/delete.js +0 -134
- package/dist/commands/deploy/deploy.d.ts +0 -24
- package/dist/commands/deploy/deploy.js +0 -654
- package/dist/commands/deploy/index.d.ts +0 -2
- package/dist/commands/deploy/index.js +0 -216
- package/dist/commands/deploy/status.d.ts +0 -14
- package/dist/commands/deploy/status.js +0 -61
- package/dist/commands/dev/index.d.ts +0 -2
- package/dist/commands/dev/index.js +0 -134
- package/dist/commands/dev/server.d.ts +0 -14
- package/dist/commands/dev/server.js +0 -195
- package/dist/commands/dev/static/app.js +0 -633
- package/dist/commands/dev/static/index.html +0 -205
- package/dist/commands/dev/static/static/app.js +0 -633
- package/dist/commands/dev/static/static/index.html +0 -205
- package/dist/commands/dev/static/static/style.css +0 -184
- package/dist/commands/dev/static/style.css +0 -184
- package/dist/commands/playground/index.d.ts +0 -2
- package/dist/commands/playground/index.js +0 -75
- package/dist/commands/playground/test.d.ts +0 -15
- package/dist/commands/playground/test.js +0 -166
- package/dist/commands/service/index.d.ts +0 -2
- package/dist/commands/service/index.js +0 -75
- package/dist/lib/api.d.ts +0 -146
- package/dist/lib/api.js +0 -330
- package/dist/lib/config.d.ts +0 -12
- package/dist/lib/config.js +0 -145
- package/dist/lib/credentials.d.ts +0 -19
- package/dist/lib/credentials.js +0 -68
- package/dist/lib/runtime/agent-router.d.ts +0 -12
- package/dist/lib/runtime/agent-router.js +0 -67
- package/dist/lib/runtime/context-builder.d.ts +0 -27
- package/dist/lib/runtime/context-builder.js +0 -166
- package/dist/lib/runtime/cubby-manager.d.ts +0 -20
- package/dist/lib/runtime/cubby-manager.js +0 -162
- package/dist/lib/runtime/index.d.ts +0 -51
- package/dist/lib/runtime/index.js +0 -181
- package/dist/lib/runtime/log-collector.d.ts +0 -17
- package/dist/lib/runtime/log-collector.js +0 -61
- package/dist/lib/runtime/stream-manager.d.ts +0 -10
- package/dist/lib/runtime/stream-manager.js +0 -77
- package/dist/lib/runtime/types.d.ts +0 -76
- package/dist/lib/runtime/types.js +0 -2
- package/dist/lib/transpile.d.ts +0 -1
- package/dist/lib/transpile.js +0 -9
- package/dist/lib/typecheck.d.ts +0 -31
- package/dist/lib/typecheck.js +0 -175
- package/dist/lib/types.d.ts +0 -246
- package/dist/lib/types.js +0 -2
- package/dist/lib/utils.d.ts +0 -4
- package/dist/lib/utils.js +0 -33
- package/example/.env.example +0 -6
- package/example/agents/object-detection/tasks/yolo.ts +0 -28
- package/example/agents/parking-violation-detector/tasks/detect.ts +0 -326
- package/example/cef.config.yaml +0 -91
- package/example/engagements/engagement.ts +0 -902
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import crypto from "node:crypto";
|
|
2
|
+
import fs from "node:fs/promises";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { pathToFileURL } from "node:url";
|
|
5
|
+
import * as esbuild from "esbuild";
|
|
6
|
+
/**
|
|
7
|
+
* Walk up from `start` looking for an existing `node_modules` directory.
|
|
8
|
+
* We need this because the externalised `@cef-ai/agent-sdk` reference in the
|
|
9
|
+
* compiled config file is resolved by node's ESM loader from the file's
|
|
10
|
+
* location — so the temp file must sit somewhere whose ancestors include
|
|
11
|
+
* a `node_modules` containing `@cef-ai/agent-sdk`.
|
|
12
|
+
*
|
|
13
|
+
* Returns the *parent* directory (i.e. the directory that *contains* the
|
|
14
|
+
* `node_modules`), or `null` if none was found.
|
|
15
|
+
*/
|
|
16
|
+
async function findNodeModulesParent(start) {
|
|
17
|
+
let dir = path.resolve(start);
|
|
18
|
+
while (true) {
|
|
19
|
+
try {
|
|
20
|
+
const stat = await fs.stat(path.join(dir, "node_modules"));
|
|
21
|
+
if (stat.isDirectory())
|
|
22
|
+
return dir;
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
// not here, keep walking up
|
|
26
|
+
}
|
|
27
|
+
const parent = path.dirname(dir);
|
|
28
|
+
if (parent === dir)
|
|
29
|
+
return null;
|
|
30
|
+
dir = parent;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Compile `cef.config.ts` to a temp ESM file and dynamically import it.
|
|
35
|
+
*
|
|
36
|
+
* `@cef-ai/agent-sdk` and `@cef-ai/agent-sdk/config` are externalised so the
|
|
37
|
+
* `defineAgent` identity helper resolves from the host's node_modules at
|
|
38
|
+
* runtime — we don't want to bundle the SDK into the user's config.
|
|
39
|
+
*
|
|
40
|
+
* The temp file is placed inside an existing `node_modules` ancestor of
|
|
41
|
+
* the config (under `node_modules/.cef/config-cache/`), so node's ESM
|
|
42
|
+
* resolver finds the externalised packages without us having to create a
|
|
43
|
+
* stub `node_modules` next to the user's config.
|
|
44
|
+
*
|
|
45
|
+
* Shared by `cef build` and `cef typegen`.
|
|
46
|
+
*/
|
|
47
|
+
export async function loadConfig(configPath, configDir) {
|
|
48
|
+
const nmParent = await findNodeModulesParent(configDir);
|
|
49
|
+
if (!nmParent) {
|
|
50
|
+
throw new Error(`[@cef-ai/cli] could not find a node_modules ancestor of ${configDir}; install dependencies first`);
|
|
51
|
+
}
|
|
52
|
+
const tmpDir = path.join(nmParent, "node_modules", ".cef", "config-cache");
|
|
53
|
+
await fs.mkdir(tmpDir, { recursive: true });
|
|
54
|
+
const tmpFile = path.join(tmpDir, `config-${process.pid}-${crypto.randomBytes(6).toString("hex")}.mjs`);
|
|
55
|
+
try {
|
|
56
|
+
await esbuild.build({
|
|
57
|
+
entryPoints: [configPath],
|
|
58
|
+
bundle: true,
|
|
59
|
+
format: "esm",
|
|
60
|
+
platform: "node",
|
|
61
|
+
target: "es2022",
|
|
62
|
+
outfile: tmpFile,
|
|
63
|
+
logLevel: "silent",
|
|
64
|
+
// Resolve these from the host package's node_modules at runtime.
|
|
65
|
+
external: ["@cef-ai/agent-sdk", "@cef-ai/agent-sdk/*"],
|
|
66
|
+
});
|
|
67
|
+
const mod = await import(pathToFileURL(tmpFile).href);
|
|
68
|
+
const cfg = mod.default;
|
|
69
|
+
if (!cfg || typeof cfg !== "object") {
|
|
70
|
+
throw new Error(`[@cef-ai/cli] ${configPath} must default-export an AgentConfig (got ${typeof cfg})`);
|
|
71
|
+
}
|
|
72
|
+
return cfg;
|
|
73
|
+
}
|
|
74
|
+
finally {
|
|
75
|
+
// Best-effort cleanup; ignore if already gone.
|
|
76
|
+
await fs.unlink(tmpFile).catch(() => { });
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Flatten a (possibly nested) `AgentConfig` into a list of leaf agents.
|
|
81
|
+
* The single-agent case is a top-level config with `entry` (or
|
|
82
|
+
* `engagements`). The nested-agents case has an `agents[]` field; each
|
|
83
|
+
* entry is a full AgentConfig and is recursed into. We require either
|
|
84
|
+
* `entry` or `engagements[]` on every leaf.
|
|
85
|
+
*/
|
|
86
|
+
export function flattenAgents(cfg) {
|
|
87
|
+
if (cfg.agents && cfg.agents.length > 0) {
|
|
88
|
+
return cfg.agents.flatMap((a) => flattenAgents(a));
|
|
89
|
+
}
|
|
90
|
+
if (!cfg.entry && (!cfg.engagements || cfg.engagements.length === 0)) {
|
|
91
|
+
throw new Error(`[@cef-ai/cli] AgentConfig "${cfg.id}" has no \`entry\`, no \`engagements[]\`, and no nested \`agents[]\``);
|
|
92
|
+
}
|
|
93
|
+
return [cfg];
|
|
94
|
+
}
|
|
95
|
+
/** Regex for a stable engagement id. Letters/digits/underscore/dash, must
|
|
96
|
+
* start with a letter (mirrors typical identifier rules; "default" is fine). */
|
|
97
|
+
const ENGAGEMENT_ID_RE = /^[a-zA-Z][a-zA-Z0-9_-]*$/;
|
|
98
|
+
/**
|
|
99
|
+
* Normalize an agent's engagement-layer declaration into a list with absolute
|
|
100
|
+
* entry paths. Accepts either:
|
|
101
|
+
*
|
|
102
|
+
* - `entry: "./src/agent.ts"` shorthand → one engagement with id `"default"`.
|
|
103
|
+
* - `engagements: [{ id, entry }, ...]` explicit form → returned as-is with
|
|
104
|
+
* relative entry paths resolved against `configDir`.
|
|
105
|
+
*
|
|
106
|
+
* Validates:
|
|
107
|
+
* - exactly one of `entry`/`engagements` is provided,
|
|
108
|
+
* - `engagements[]` has at least one entry when present,
|
|
109
|
+
* - every engagement id matches `[a-zA-Z][a-zA-Z0-9_-]*`,
|
|
110
|
+
* - engagement ids are unique within the agent.
|
|
111
|
+
*
|
|
112
|
+
* Throws on any violation with `[@cef-ai/cli]`-prefixed errors so failures point
|
|
113
|
+
* authors at their `cef.config.ts`.
|
|
114
|
+
*/
|
|
115
|
+
export function normalizeEngagements(agent, configDir) {
|
|
116
|
+
const hasEntry = typeof agent.entry === "string" && agent.entry.length > 0;
|
|
117
|
+
const hasList = Array.isArray(agent.engagements) && agent.engagements.length > 0;
|
|
118
|
+
if (hasEntry && hasList) {
|
|
119
|
+
throw new Error(`[@cef-ai/cli] agent "${agent.id}": specify either 'entry' or 'engagements', not both`);
|
|
120
|
+
}
|
|
121
|
+
if (!hasEntry && !hasList) {
|
|
122
|
+
throw new Error(`[@cef-ai/cli] agent "${agent.id}": missing 'entry' or 'engagements'`);
|
|
123
|
+
}
|
|
124
|
+
if (agent.engagements && agent.engagements.length === 0) {
|
|
125
|
+
throw new Error(`[@cef-ai/cli] agent "${agent.id}": 'engagements' must contain at least one entry`);
|
|
126
|
+
}
|
|
127
|
+
const list = hasList
|
|
128
|
+
? agent.engagements
|
|
129
|
+
: [{ id: "default", entry: agent.entry }];
|
|
130
|
+
const seen = new Set();
|
|
131
|
+
const out = [];
|
|
132
|
+
for (const e of list) {
|
|
133
|
+
if (typeof e.id !== "string" || e.id.length === 0) {
|
|
134
|
+
throw new Error(`[@cef-ai/cli] agent "${agent.id}": engagement entry has empty 'id'`);
|
|
135
|
+
}
|
|
136
|
+
if (!ENGAGEMENT_ID_RE.test(e.id)) {
|
|
137
|
+
throw new Error(`[@cef-ai/cli] engagement id "${e.id}" must match /^[a-zA-Z][a-zA-Z0-9_-]*$/`);
|
|
138
|
+
}
|
|
139
|
+
if (seen.has(e.id)) {
|
|
140
|
+
throw new Error(`[@cef-ai/cli] duplicate engagement id "${e.id}"`);
|
|
141
|
+
}
|
|
142
|
+
seen.add(e.id);
|
|
143
|
+
if (typeof e.entry !== "string" || e.entry.length === 0) {
|
|
144
|
+
throw new Error(`[@cef-ai/cli] agent "${agent.id}": engagement "${e.id}" has empty 'entry'`);
|
|
145
|
+
}
|
|
146
|
+
out.push({ id: e.id, entry: path.resolve(configDir, e.entry) });
|
|
147
|
+
}
|
|
148
|
+
return out;
|
|
149
|
+
}
|
|
150
|
+
//# sourceMappingURL=load-config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"load-config.js","sourceRoot":"","sources":["../../src/build/load-config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import type { AgentCard, JSONSchema, Targeting } from "./load-config.js";
|
|
2
|
+
/**
|
|
3
|
+
* Per-engagement manifest input. Each engagement carries its own routing
|
|
4
|
+
* (`events` map) and its lifecycle method names (extracted from decorator
|
|
5
|
+
* metadata). The manifest emitter:
|
|
6
|
+
*
|
|
7
|
+
* - copies `events` into the per-engagement `handles` map (eventType →
|
|
8
|
+
* handlerName, per `prototype.md` §"AgentManifest.Engagements");
|
|
9
|
+
* - aggregates `events` keys + caller-provided `publishes` into the
|
|
10
|
+
* top-level derived unions;
|
|
11
|
+
* - drops `lifecycle` from the manifest output entirely — `onStart` /
|
|
12
|
+
* `onClose` are conventional method names invoked by the runtime if
|
|
13
|
+
* defined on the class (per prototype.md §"Notes on the simplifications").
|
|
14
|
+
*/
|
|
15
|
+
export interface ManifestEngagementInput {
|
|
16
|
+
id: string;
|
|
17
|
+
goal?: string;
|
|
18
|
+
events: Record<string, string>;
|
|
19
|
+
/** Recorded for the simulator — not emitted into the wire manifest. */
|
|
20
|
+
lifecycle: {
|
|
21
|
+
start?: string;
|
|
22
|
+
close?: string;
|
|
23
|
+
};
|
|
24
|
+
/** Event types this engagement publishes (lint-derived or author-pinned). */
|
|
25
|
+
publishes: string[];
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Subset of `AgentConfig` (from `@cef-ai/agent-sdk/config`) that the manifest
|
|
29
|
+
* emitter consumes at the agent level. Per-engagement state lives on
|
|
30
|
+
* {@link ManifestEngagementInput}.
|
|
31
|
+
*/
|
|
32
|
+
export interface ManifestConfigInput {
|
|
33
|
+
alias?: string;
|
|
34
|
+
source?: string;
|
|
35
|
+
card?: AgentCard;
|
|
36
|
+
requiredScopes?: string[];
|
|
37
|
+
/** Per-Job idle timeout as a duration string (e.g. `"15m"`); the
|
|
38
|
+
* manifest emitter parses this into integer ms. Defaults to `"30m"`. */
|
|
39
|
+
idleTimeout?: string;
|
|
40
|
+
cubbies?: Array<{
|
|
41
|
+
alias: string;
|
|
42
|
+
migrations?: string;
|
|
43
|
+
}>;
|
|
44
|
+
settings?: Array<{
|
|
45
|
+
key: string;
|
|
46
|
+
type: "string" | "number" | "boolean" | "url" | "secret";
|
|
47
|
+
required?: boolean;
|
|
48
|
+
label?: string;
|
|
49
|
+
description?: string;
|
|
50
|
+
default?: unknown;
|
|
51
|
+
}>;
|
|
52
|
+
models?: Record<string, string>;
|
|
53
|
+
uses?: Record<string, string>;
|
|
54
|
+
eventSchemas?: Record<string, JSONSchema>;
|
|
55
|
+
}
|
|
56
|
+
export interface ManifestInput {
|
|
57
|
+
/** Marketplace alias / build id (becomes `manifest.alias`). */
|
|
58
|
+
agentId: string;
|
|
59
|
+
version: string;
|
|
60
|
+
/** Absolute path to the IIFE bundle whose source is embedded as
|
|
61
|
+
* `manifest.bundle` (per prototype.md §"AgentManifest.Bundle"). */
|
|
62
|
+
bundlePath: string;
|
|
63
|
+
/** One entry per engagement. At least one required. */
|
|
64
|
+
engagements: ManifestEngagementInput[];
|
|
65
|
+
/** Declarative bits taken from cef.config.ts (agent-level). */
|
|
66
|
+
config: ManifestConfigInput;
|
|
67
|
+
/**
|
|
68
|
+
* Directory containing the user's cef.config.ts — used to resolve
|
|
69
|
+
* relative `cubbies[].migrations` paths.
|
|
70
|
+
*/
|
|
71
|
+
configDir: string;
|
|
72
|
+
/**
|
|
73
|
+
* Validated targeting decision table. Caller (build pipeline) is
|
|
74
|
+
* responsible for running `validateTargeting` first; the manifest
|
|
75
|
+
* emitter just writes this verbatim into the JSON.
|
|
76
|
+
*/
|
|
77
|
+
targeting: Targeting;
|
|
78
|
+
}
|
|
79
|
+
export interface InlinedCubby {
|
|
80
|
+
alias: string;
|
|
81
|
+
migrations?: Array<{
|
|
82
|
+
version: number;
|
|
83
|
+
up: string;
|
|
84
|
+
}>;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Per-engagement slice of the emitted manifest (per prototype.md
|
|
88
|
+
* §"EngagementDecl"). `handles` is a map (eventType → handlerName); per-
|
|
89
|
+
* engagement `publishes` and `lifecycleHandlers` are intentionally NOT
|
|
90
|
+
* emitted — the contract carries publishes at the agent level only and
|
|
91
|
+
* lifecycle hook resolution is conventional (instance.onStart /
|
|
92
|
+
* instance.onClose if defined).
|
|
93
|
+
*/
|
|
94
|
+
export interface ManifestEngagement {
|
|
95
|
+
id: string;
|
|
96
|
+
goal: string;
|
|
97
|
+
handles: Record<string, string>;
|
|
98
|
+
}
|
|
99
|
+
/** Settings declaration as emitted into the manifest. */
|
|
100
|
+
export type ManifestSetting = NonNullable<ManifestConfigInput["settings"]>[number];
|
|
101
|
+
/**
|
|
102
|
+
* Manifest body per `prototype.md` §"AgentManifest". Identity / signature
|
|
103
|
+
* fields (`agentId`, `agentServicePubkey`, `signature`) are filled in by
|
|
104
|
+
* `cef publish` after Ed25519 signing — they are emitted as empty strings
|
|
105
|
+
* by `cef build`.
|
|
106
|
+
*/
|
|
107
|
+
export interface CefManifest {
|
|
108
|
+
agentId: string;
|
|
109
|
+
agentServicePubkey: string;
|
|
110
|
+
version: string;
|
|
111
|
+
alias: string;
|
|
112
|
+
card: AgentCard;
|
|
113
|
+
requiredScopes: string[];
|
|
114
|
+
/** Per-Job idle timeout in milliseconds (orchestrator sweeper marks the
|
|
115
|
+
* Job terminal after this much inactivity). `0` disables idle-based
|
|
116
|
+
* termination. */
|
|
117
|
+
idleTimeout: number;
|
|
118
|
+
settings: ManifestSetting[];
|
|
119
|
+
bundle: string;
|
|
120
|
+
engagements: ManifestEngagement[];
|
|
121
|
+
/** Derived union of every engagement's `handles` keys (sorted). */
|
|
122
|
+
handles: string[];
|
|
123
|
+
/** Derived union of every engagement's lint-derived publishes (sorted). */
|
|
124
|
+
publishes: string[];
|
|
125
|
+
eventSchemas: Record<string, JSONSchema>;
|
|
126
|
+
cubbies: InlinedCubby[];
|
|
127
|
+
models: Record<string, string>;
|
|
128
|
+
uses: Record<string, string>;
|
|
129
|
+
targeting: Targeting;
|
|
130
|
+
source: string;
|
|
131
|
+
signature: string;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Build the manifest object per `prototype.md` §"AgentManifest". The shape
|
|
135
|
+
* is the single self-contained artifact used by Marketplace, Vault API,
|
|
136
|
+
* Cubby Manager, Event Runtime, Orchestrator, Agent Runtime, and `cef
|
|
137
|
+
* typegen` — everything an agent needs at runtime is inline.
|
|
138
|
+
*
|
|
139
|
+
* Per-engagement: `handles` is a map (eventType → handlerName), sorted
|
|
140
|
+
* alphabetically by key. Per-engagement publishes / lifecycleHandlers are
|
|
141
|
+
* NOT emitted — see `prototype.md` §"Notes on the simplifications" and
|
|
142
|
+
* the `EngagementDecl` go type.
|
|
143
|
+
*
|
|
144
|
+
* Agent-level: `cubbies[]` inlines each cubby's migration directory;
|
|
145
|
+
* `bundle` embeds the JS source as a JSON-escaped string (no separate
|
|
146
|
+
* `codeCid`); `handles[]` and `publishes[]` are derived unions over the
|
|
147
|
+
* engagements; identity / signature fields are placeholders to be set by
|
|
148
|
+
* `cef publish`.
|
|
149
|
+
*/
|
|
150
|
+
export declare function buildManifest(input: ManifestInput): Promise<CefManifest>;
|
|
151
|
+
/**
|
|
152
|
+
* Build the manifest and write it as pretty-printed JSON to `out`. Returns
|
|
153
|
+
* the manifest object so callers don't need to re-read the file.
|
|
154
|
+
*/
|
|
155
|
+
export declare function emitManifest(out: string, input: ManifestInput): Promise<CefManifest>;
|
|
156
|
+
//# sourceMappingURL=manifest.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../src/build/manifest.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { parseDuration } from "./duration.js";
|
|
4
|
+
const EMPTY_CARD = { name: "", description: "" };
|
|
5
|
+
/** Default idle timeout — author-facing string; see `AgentConfig.idleTimeout`. */
|
|
6
|
+
const DEFAULT_IDLE_TIMEOUT = "30m";
|
|
7
|
+
/**
|
|
8
|
+
* Read `<dir>/*.sql` in lexical order and return inlined migrations. The
|
|
9
|
+
* version is parsed from the leading integer of the filename (`001-init.sql`
|
|
10
|
+
* → 1). Files whose name does not start with digits are rejected with an
|
|
11
|
+
* Error so authors don't silently get unordered migrations.
|
|
12
|
+
*/
|
|
13
|
+
async function readMigrations(dir) {
|
|
14
|
+
const entries = await fs.readdir(dir);
|
|
15
|
+
const sql = entries.filter((f) => f.toLowerCase().endsWith(".sql")).sort();
|
|
16
|
+
const out = [];
|
|
17
|
+
for (const file of sql) {
|
|
18
|
+
const m = /^(\d+)/.exec(file);
|
|
19
|
+
if (!m) {
|
|
20
|
+
throw new Error(`[@cef-ai/cli] migration filename must start with digits (got "${file}" in ${dir})`);
|
|
21
|
+
}
|
|
22
|
+
const version = Number.parseInt(m[1], 10);
|
|
23
|
+
const up = await fs.readFile(path.join(dir, file), "utf8");
|
|
24
|
+
out.push({ version, up });
|
|
25
|
+
}
|
|
26
|
+
return out;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Build the manifest object per `prototype.md` §"AgentManifest". The shape
|
|
30
|
+
* is the single self-contained artifact used by Marketplace, Vault API,
|
|
31
|
+
* Cubby Manager, Event Runtime, Orchestrator, Agent Runtime, and `cef
|
|
32
|
+
* typegen` — everything an agent needs at runtime is inline.
|
|
33
|
+
*
|
|
34
|
+
* Per-engagement: `handles` is a map (eventType → handlerName), sorted
|
|
35
|
+
* alphabetically by key. Per-engagement publishes / lifecycleHandlers are
|
|
36
|
+
* NOT emitted — see `prototype.md` §"Notes on the simplifications" and
|
|
37
|
+
* the `EngagementDecl` go type.
|
|
38
|
+
*
|
|
39
|
+
* Agent-level: `cubbies[]` inlines each cubby's migration directory;
|
|
40
|
+
* `bundle` embeds the JS source as a JSON-escaped string (no separate
|
|
41
|
+
* `codeCid`); `handles[]` and `publishes[]` are derived unions over the
|
|
42
|
+
* engagements; identity / signature fields are placeholders to be set by
|
|
43
|
+
* `cef publish`.
|
|
44
|
+
*/
|
|
45
|
+
export async function buildManifest(input) {
|
|
46
|
+
const { agentId, version, bundlePath, engagements, config, configDir, targeting, } = input;
|
|
47
|
+
if (engagements.length === 0) {
|
|
48
|
+
throw new Error(`[@cef-ai/cli] agent "${agentId}": manifest needs at least one engagement`);
|
|
49
|
+
}
|
|
50
|
+
const sortedEngagements = [...engagements].sort((a, b) => a.id.localeCompare(b.id));
|
|
51
|
+
const allHandles = new Set();
|
|
52
|
+
const allPublishes = new Set();
|
|
53
|
+
const manifestEngagements = sortedEngagements.map((e) => {
|
|
54
|
+
const handles = {};
|
|
55
|
+
for (const type of Object.keys(e.events).sort()) {
|
|
56
|
+
handles[type] = e.events[type];
|
|
57
|
+
allHandles.add(type);
|
|
58
|
+
}
|
|
59
|
+
for (const t of e.publishes)
|
|
60
|
+
allPublishes.add(t);
|
|
61
|
+
return {
|
|
62
|
+
id: e.id,
|
|
63
|
+
goal: e.goal ?? "",
|
|
64
|
+
handles,
|
|
65
|
+
};
|
|
66
|
+
});
|
|
67
|
+
const cubbies = [];
|
|
68
|
+
for (const c of config.cubbies ?? []) {
|
|
69
|
+
const inlined = { alias: c.alias };
|
|
70
|
+
if (c.migrations) {
|
|
71
|
+
const dir = path.resolve(configDir, c.migrations);
|
|
72
|
+
inlined.migrations = await readMigrations(dir);
|
|
73
|
+
}
|
|
74
|
+
cubbies.push(inlined);
|
|
75
|
+
}
|
|
76
|
+
const bundle = await fs.readFile(bundlePath, "utf8");
|
|
77
|
+
return {
|
|
78
|
+
// Identity placeholders — `cef publish` sets these after signing
|
|
79
|
+
// (per prototype.md → POST /api/v1/marketplace/agents).
|
|
80
|
+
agentId: "",
|
|
81
|
+
agentServicePubkey: "",
|
|
82
|
+
version,
|
|
83
|
+
alias: config.alias ?? agentId,
|
|
84
|
+
card: config.card ?? EMPTY_CARD,
|
|
85
|
+
requiredScopes: config.requiredScopes ?? ["default"],
|
|
86
|
+
idleTimeout: parseDuration(config.idleTimeout ?? DEFAULT_IDLE_TIMEOUT, `agent "${agentId}" idleTimeout`),
|
|
87
|
+
settings: config.settings ?? [],
|
|
88
|
+
bundle,
|
|
89
|
+
engagements: manifestEngagements,
|
|
90
|
+
handles: [...allHandles].sort(),
|
|
91
|
+
publishes: [...allPublishes].sort(),
|
|
92
|
+
eventSchemas: config.eventSchemas ?? {},
|
|
93
|
+
cubbies,
|
|
94
|
+
models: config.models ?? {},
|
|
95
|
+
uses: config.uses ?? {},
|
|
96
|
+
targeting,
|
|
97
|
+
source: config.source ?? "",
|
|
98
|
+
signature: "",
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Build the manifest and write it as pretty-printed JSON to `out`. Returns
|
|
103
|
+
* the manifest object so callers don't need to re-read the file.
|
|
104
|
+
*/
|
|
105
|
+
export async function emitManifest(out, input) {
|
|
106
|
+
const manifest = await buildManifest(input);
|
|
107
|
+
await fs.mkdir(path.dirname(out), { recursive: true });
|
|
108
|
+
await fs.writeFile(out, JSON.stringify(manifest, null, 2) + "\n", "utf8");
|
|
109
|
+
return manifest;
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=manifest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../src/build/manifest.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Targeting } from "./load-config.js";
|
|
2
|
+
export interface ValidateTargetingInput {
|
|
3
|
+
/** Agent id used in error messages. */
|
|
4
|
+
agentId: string;
|
|
5
|
+
/** Declared engagement ids (post-normalize). At least one required. */
|
|
6
|
+
engagementIds: string[];
|
|
7
|
+
/** The user's optional targeting block. */
|
|
8
|
+
targeting?: Targeting;
|
|
9
|
+
}
|
|
10
|
+
export interface ValidateTargetingResult {
|
|
11
|
+
/** Validated targeting (defaulted when input was absent). */
|
|
12
|
+
targeting: Targeting;
|
|
13
|
+
}
|
|
14
|
+
export declare function validateTargeting(input: ValidateTargetingInput): ValidateTargetingResult;
|
|
15
|
+
//# sourceMappingURL=targeting.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"targeting.d.ts","sourceRoot":"","sources":["../../src/build/targeting.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAQ,SAAS,EAAuB,MAAM,kBAAkB,CAAC;AAwB7E,MAAM,WAAW,sBAAsB;IACrC,uCAAuC;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,uEAAuE;IACvE,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,2CAA2C;IAC3C,SAAS,CAAC,EAAE,SAAS,CAAC;CACvB;AAED,MAAM,WAAW,uBAAuB;IACtC,6DAA6D;IAC7D,SAAS,EAAE,SAAS,CAAC;CACtB;AAED,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,sBAAsB,GAC5B,uBAAuB,CA8BzB"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Build-time targeting validator (per prototype.md → "Targeting on the
|
|
3
|
+
* Manifest body"). The user authors a `targeting` block in `cef.config.ts`
|
|
4
|
+
* matching the platform's selection-table shape; the build step:
|
|
5
|
+
*
|
|
6
|
+
* - defaults `targeting` to a single entry over the first declared
|
|
7
|
+
* engagement when omitted (single-engagement agents don't need a block);
|
|
8
|
+
* - rejects ids that do not match a declared engagement;
|
|
9
|
+
* - rejects rule names outside the v1 vocabulary (`priority` | `weight` |
|
|
10
|
+
* `limit`) so authors get a fail-fast message instead of silently
|
|
11
|
+
* misrouted traffic.
|
|
12
|
+
*
|
|
13
|
+
* Failures throw with `[@cef-ai/cli]`-prefixed messages so authors get a
|
|
14
|
+
* pointer back to their config file.
|
|
15
|
+
*/
|
|
16
|
+
const SUPPORTED_RULE_NAMES = new Set([
|
|
17
|
+
"priority",
|
|
18
|
+
"weight",
|
|
19
|
+
"limit",
|
|
20
|
+
]);
|
|
21
|
+
export function validateTargeting(input) {
|
|
22
|
+
const { agentId, engagementIds, targeting } = input;
|
|
23
|
+
if (engagementIds.length === 0) {
|
|
24
|
+
throw new Error(`[@cef-ai/cli] agent "${agentId}": cannot validate targeting without any declared engagements`);
|
|
25
|
+
}
|
|
26
|
+
if (!targeting) {
|
|
27
|
+
return {
|
|
28
|
+
targeting: {
|
|
29
|
+
engagements: [{ id: engagementIds[0], rules: [] }],
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
if (!Array.isArray(targeting.engagements) || targeting.engagements.length === 0) {
|
|
34
|
+
throw new Error(`[@cef-ai/cli] agent "${agentId}": targeting.engagements must contain at least one entry`);
|
|
35
|
+
}
|
|
36
|
+
const idsSet = new Set(engagementIds);
|
|
37
|
+
const seen = new Set();
|
|
38
|
+
for (const e of targeting.engagements) {
|
|
39
|
+
validateEngagementEntry(agentId, e, idsSet, seen, engagementIds);
|
|
40
|
+
}
|
|
41
|
+
return { targeting };
|
|
42
|
+
}
|
|
43
|
+
function validateEngagementEntry(agentId, entry, declared, seen, declaredList) {
|
|
44
|
+
if (typeof entry.id !== "string" || entry.id.length === 0) {
|
|
45
|
+
throw new Error(`[@cef-ai/cli] agent "${agentId}": targeting engagement entry has empty 'id'`);
|
|
46
|
+
}
|
|
47
|
+
if (!declared.has(entry.id)) {
|
|
48
|
+
throw new Error(`[@cef-ai/cli] agent "${agentId}": targeting references engagement "${entry.id}" which is not declared (declared: ${declaredList.join(", ")})`);
|
|
49
|
+
}
|
|
50
|
+
if (seen.has(entry.id)) {
|
|
51
|
+
throw new Error(`[@cef-ai/cli] agent "${agentId}": targeting lists engagement "${entry.id}" more than once`);
|
|
52
|
+
}
|
|
53
|
+
seen.add(entry.id);
|
|
54
|
+
for (const rule of entry.rules ?? []) {
|
|
55
|
+
validateRule(agentId, entry.id, rule);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
function validateRule(agentId, engagementId, rule) {
|
|
59
|
+
if (!rule || typeof rule !== "object") {
|
|
60
|
+
throw new Error(`[@cef-ai/cli] agent "${agentId}": targeting engagement "${engagementId}" has invalid rule ${JSON.stringify(rule)}`);
|
|
61
|
+
}
|
|
62
|
+
if (!SUPPORTED_RULE_NAMES.has(rule.name)) {
|
|
63
|
+
throw new Error(`[@cef-ai/cli] agent "${agentId}": targeting engagement "${engagementId}" has unknown rule name "${rule.name}" (supported: priority, weight, limit)`);
|
|
64
|
+
}
|
|
65
|
+
if (typeof rule.value !== "number" || !Number.isFinite(rule.value)) {
|
|
66
|
+
throw new Error(`[@cef-ai/cli] agent "${agentId}": targeting engagement "${engagementId}" rule "${rule.name}" must have a numeric value`);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=targeting.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"targeting.js","sourceRoot":"","sources":["../../src/build/targeting.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
export {};
|
|
3
|
+
//# sourceMappingURL=cli.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
|