@domesystems/templates 0.4.0 → 0.4.1
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/package.json +1 -1
- package/src/generate.mjs +28 -6
- package/src/manifest.mjs +16 -3
package/package.json
CHANGED
package/src/generate.mjs
CHANGED
|
@@ -64,6 +64,29 @@ function quotaBlocks(quotas, agents) {
|
|
|
64
64
|
});
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
+
function managedModelReference(manifest, name) {
|
|
68
|
+
if (manifest.pools.some((pool) => pool.name === name)) return `dome_llm_pool.${label(name)}.name`;
|
|
69
|
+
if (manifest.models.some((model) => model.name === name)) return `dome_llm_connection.${label(name)}.name`;
|
|
70
|
+
throw new Error(`Managed agent default_model ${name} must name a pool or model.`);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function triggerBlocks(triggers) {
|
|
74
|
+
return triggers.map((trigger) => {
|
|
75
|
+
const kind = required(trigger, "kind", `Trigger ${trigger.name} needs kind.`);
|
|
76
|
+
if (!["schedule", "webhook"].includes(kind)) throw new Error(`Trigger ${trigger.name} has unsupported kind ${kind}.`);
|
|
77
|
+
if (kind === "schedule" && !trigger.cron) throw new Error(`Schedule trigger ${trigger.name} needs cron.`);
|
|
78
|
+
const lines = [attr("workspace_id", "var.workspace_id"), attr("name", q(required(trigger, "name", "Every trigger needs a name."))), ...(trigger.description ? [attr("description", q(trigger.description))] : []), attr("kind", q(kind))];
|
|
79
|
+
for (const key of ["enabled", "cron", "timezone", "input", "max_concurrent_runs", "catch_up", "catch_up_deadline_seconds", "max_retries"]) if (trigger[key] !== undefined) lines.push(attr(key, typeof trigger[key] === "string" ? q(trigger[key]) : String(trigger[key])));
|
|
80
|
+
const targets = trigger.targets ?? [];
|
|
81
|
+
if (!Array.isArray(targets) || !targets.length) throw new Error(`Trigger ${trigger.name} needs at least one target.`);
|
|
82
|
+
lines.push(`targets = [${targets.map((target) => {
|
|
83
|
+
if (target?.kind !== "managed_agent" || typeof target.name !== "string") throw new Error(`Trigger ${trigger.name} targets must name a managed_agent.`);
|
|
84
|
+
return `{ kind = "managed_agent", name = dome_managed_agent.${label(target.name)}.name${target.disabled === undefined ? "" : `, disabled = ${Boolean(target.disabled)}`} }`;
|
|
85
|
+
}).join(", ")}]`);
|
|
86
|
+
return block("dome_trigger", label(trigger.name), lines);
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
|
|
67
90
|
export function renderDomeTerraform(manifest) {
|
|
68
91
|
if (!manifest.gateways.length) throw new Error("template.yaml must declare at least one gateway.");
|
|
69
92
|
const blocks = [];
|
|
@@ -94,7 +117,8 @@ export function renderDomeTerraform(manifest) {
|
|
|
94
117
|
}
|
|
95
118
|
for (const agent of manifest.agents) {
|
|
96
119
|
const agentLabel = label(agent.name); const managed = agent.type === "managed"; const resourceType = managed ? "dome_managed_agent" : "dome_agent";
|
|
97
|
-
const lines = [attr("workspace_id", "var.workspace_id"), attr("name", q(agent.name))
|
|
120
|
+
const lines = [attr("workspace_id", "var.workspace_id"), attr("name", q(agent.name))];
|
|
121
|
+
if (!managed) lines.push(attr("allowed_gateways", `[${(agent.allowed_gateways ?? []).map((gateway) => `dome_gateway.${label(gateway)}.name`).join(", ")}]`));
|
|
98
122
|
if (!managed && agent.act_as) {
|
|
99
123
|
const { method, required: actAsRequired, hmac_secret: hmacSecret, allowed_subjects: allowedSubjects } = agent.act_as;
|
|
100
124
|
if (!method) throw new Error(`Agent ${agent.name} act_as needs method.`);
|
|
@@ -103,15 +127,13 @@ export function renderDomeTerraform(manifest) {
|
|
|
103
127
|
if (allowedSubjects) lines.push(attr("actas_allowed_subjects", `[${allowedSubjects.map(q).join(", ")}]`));
|
|
104
128
|
}
|
|
105
129
|
if (managed) {
|
|
106
|
-
if (!agent.system_prompt?.
|
|
107
|
-
lines.push(attr("system_prompt",
|
|
108
|
-
const trigger = agent.trigger ?? {}; const config = { ...(trigger.manual === undefined ? {} : { manual: { enabled: Boolean(trigger.manual) } }), ...(trigger.webhook === undefined ? {} : { webhook: { enabled: Boolean(trigger.webhook) } }), ...(trigger.schedule ? { schedule: trigger.schedule } : {}) };
|
|
109
|
-
if (Object.keys(config).length) lines.push(attr("trigger_config", `jsonencode(${JSON.stringify(config)})`));
|
|
130
|
+
if (!agent.system_prompt?.content || !agent.default_model) throw new Error(`Managed agent ${agent.name} needs system_prompt and default_model.`);
|
|
131
|
+
lines.push(attr("system_prompt", "<<-PROMPT"), ...agent.system_prompt.content.split("\n").map((line) => line.trimEnd()), "PROMPT", attr("default_model", managedModelReference(manifest, agent.default_model)), attr("gateway", `dome_gateway.${label(agent.gateway)}.name`));
|
|
110
132
|
}
|
|
111
133
|
blocks.push(block(resourceType, agentLabel, lines), ...rulesBlock(agent, resourceType, agentLabel));
|
|
112
134
|
if (!managed) for (const key of agent.keys ?? []) blocks.push(block("dome_agent_key", `${agentLabel}_${label(required(key, "name", `Agent ${agent.name} keys need a name.`))}`, [attr("workspace_id", "var.workspace_id"), attr("agent", `dome_agent.${agentLabel}.name`), attr("name", q(key.name))]));
|
|
113
135
|
}
|
|
114
|
-
blocks.push(...filterBlocks(manifest.filters), ...quotaBlocks(manifest.quotas, new Map(manifest.agents.map((agent) => [agent.name, agent.type]))));
|
|
136
|
+
blocks.push(...filterBlocks(manifest.filters), ...quotaBlocks(manifest.quotas, new Map(manifest.agents.map((agent) => [agent.name, agent.type]))), ...triggerBlocks(manifest.triggers));
|
|
115
137
|
const header = `# Generated by @domesystems/templates from template.yaml. Do not edit.\nterraform {\n required_providers {\n dome = { source = ${q("dome-systems/dome")}, version = ${q(">= 0.1.0")} }\n }\n}\n\nvariable "workspace_id" { type = string }`;
|
|
116
138
|
const outputs = manifest.agents.filter((agent) => agent.type === "external").flatMap((agent) => (agent.keys ?? []).map((key) => {
|
|
117
139
|
const agentLabel = label(agent.name); const keyLabel = label(key.name);
|
package/src/manifest.mjs
CHANGED
|
@@ -67,6 +67,18 @@ function normalizeRuleFiles(root, agent, index) {
|
|
|
67
67
|
return { ...agent, rules: { ...agent.rules, files: normalized } };
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
+
function normalizeManagedAgent(root, agent, index) {
|
|
71
|
+
if (agent.type !== "managed") return agent;
|
|
72
|
+
const prompt = agent.system_prompt;
|
|
73
|
+
if (!prompt || typeof prompt !== "object" || Array.isArray(prompt)) throw new Error(`agents[${index}].system_prompt must declare path or inline.`);
|
|
74
|
+
const hasPath = typeof prompt.path === "string";
|
|
75
|
+
const hasInline = typeof prompt.inline === "string";
|
|
76
|
+
if (hasPath === hasInline) throw new Error(`agents[${index}].system_prompt must declare exactly one of path or inline.`);
|
|
77
|
+
if (typeof agent.gateway !== "string" || !agent.gateway.trim()) throw new Error(`Managed agent ${agent.name} needs gateway.`);
|
|
78
|
+
if (agent.allowed_gateways !== undefined || agent.trigger !== undefined) throw new Error(`Managed agent ${agent.name} uses gateway and top-level triggers; allowed_gateways and trigger are not supported.`);
|
|
79
|
+
return { ...agent, system_prompt: { content: hasPath ? fs.readFileSync(sourcePath(root, prompt.path, `agents[${index}].system_prompt`), "utf8") : prompt.inline, source: hasPath ? prompt.path : "inline" } };
|
|
80
|
+
}
|
|
81
|
+
|
|
70
82
|
function named(items, label) {
|
|
71
83
|
const names = new Set();
|
|
72
84
|
for (const item of items ?? []) {
|
|
@@ -84,7 +96,7 @@ export function readManifest(templateDirectory) {
|
|
|
84
96
|
if (manifest.apiVersion !== "templates.domesystems.ai/v1" || manifest.kind !== "Template") throw new Error("template.yaml must declare apiVersion templates.domesystems.ai/v1 and kind Template.");
|
|
85
97
|
if (!Array.isArray(manifest.agents) || manifest.agents.length === 0) throw new Error("template.yaml must declare at least one agent.");
|
|
86
98
|
const agents = manifest.agents.map((entry, index) => {
|
|
87
|
-
const agent = normalizeRuleFiles(root, expandAgent(root, entry, index), index);
|
|
99
|
+
const agent = normalizeManagedAgent(root, normalizeRuleFiles(root, expandAgent(root, entry, index), index), index);
|
|
88
100
|
if (typeof agent.name !== "string" || !agent.name.trim()) throw new Error(`agents[${index}].name is required.`);
|
|
89
101
|
const type = agent.type;
|
|
90
102
|
if (!type) throw new Error(`agents[${index}].type is required.`);
|
|
@@ -93,8 +105,9 @@ export function readManifest(templateDirectory) {
|
|
|
93
105
|
return { ...agent, type };
|
|
94
106
|
});
|
|
95
107
|
const filters = normalizeFilterConfigs(root, expandFilters(root, manifest.filters));
|
|
96
|
-
|
|
97
|
-
|
|
108
|
+
const triggers = manifest.triggers ?? [];
|
|
109
|
+
named(agents, "agents"); named(manifest.gateways ?? [], "gateways"); named(manifest.tool_connections ?? [], "tool_connections"); named(manifest.models ?? [], "models"); named(manifest.pools ?? [], "pools"); named(filters, "filters"); named(triggers, "triggers");
|
|
110
|
+
return { ...manifest, variables: manifest.variables ?? {}, gateways: manifest.gateways ?? [], tool_connections: manifest.tool_connections ?? [], models: manifest.models ?? [], pools: manifest.pools ?? [], filters, quotas: manifest.quotas ?? [], triggers, agents };
|
|
98
111
|
}
|
|
99
112
|
|
|
100
113
|
const PACKAGE_NAME = /^[a-z0-9](?:[a-z0-9-]{0,62}[a-z0-9])?\/[a-z0-9](?:[a-z0-9-]{0,62}[a-z0-9])?$/;
|