@cogenta/agents 0.2.1 → 0.4.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/dist/agents/builtins.d.ts +51 -0
- package/dist/agents/builtins.d.ts.map +1 -0
- package/dist/agents/builtins.js +190 -0
- package/dist/agents/builtins.js.map +1 -0
- package/dist/agents/orchestrator.d.ts +95 -0
- package/dist/agents/orchestrator.d.ts.map +1 -0
- package/dist/agents/orchestrator.js +285 -0
- package/dist/agents/orchestrator.js.map +1 -0
- package/dist/agents/store.d.ts +71 -0
- package/dist/agents/store.d.ts.map +1 -0
- package/dist/agents/store.js +211 -0
- package/dist/agents/store.js.map +1 -0
- package/dist/agents/types.d.ts +10 -0
- package/dist/agents/types.d.ts.map +1 -1
- package/dist/assist/agent-identity.d.ts +44 -0
- package/dist/assist/agent-identity.d.ts.map +1 -0
- package/dist/assist/agent-identity.js +136 -0
- package/dist/assist/agent-identity.js.map +1 -0
- package/dist/assist/chat.d.ts +2 -0
- package/dist/assist/chat.d.ts.map +1 -1
- package/dist/assist/chat.js +14 -5
- package/dist/assist/chat.js.map +1 -1
- package/dist/assist/classify.d.ts +3 -2
- package/dist/assist/classify.d.ts.map +1 -1
- package/dist/assist/classify.js +30 -11
- package/dist/assist/classify.js.map +1 -1
- package/dist/assist/faq.d.ts +3 -2
- package/dist/assist/faq.d.ts.map +1 -1
- package/dist/assist/faq.js +31 -13
- package/dist/assist/faq.js.map +1 -1
- package/dist/assist/runtime.d.ts +8 -2
- package/dist/assist/runtime.d.ts.map +1 -1
- package/dist/assist/runtime.js +2 -2
- package/dist/assist/runtime.js.map +1 -1
- package/dist/assist/toolset.d.ts +10 -0
- package/dist/assist/toolset.d.ts.map +1 -1
- package/dist/assist/toolset.js +36 -8
- package/dist/assist/toolset.js.map +1 -1
- package/dist/assist/usage.d.ts +58 -0
- package/dist/assist/usage.d.ts.map +1 -0
- package/dist/assist/usage.js +53 -0
- package/dist/assist/usage.js.map +1 -0
- package/dist/assist/writing.d.ts +10 -9
- package/dist/assist/writing.d.ts.map +1 -1
- package/dist/assist/writing.js +126 -58
- package/dist/assist/writing.js.map +1 -1
- package/dist/audit/with-audit.d.ts +13 -0
- package/dist/audit/with-audit.d.ts.map +1 -1
- package/dist/audit/with-audit.js +6 -0
- package/dist/audit/with-audit.js.map +1 -1
- package/dist/autonomy/levels.d.ts +37 -0
- package/dist/autonomy/levels.d.ts.map +1 -0
- package/dist/autonomy/levels.js +51 -0
- package/dist/autonomy/levels.js.map +1 -0
- package/dist/conversations/store.d.ts +62 -0
- package/dist/conversations/store.d.ts.map +1 -0
- package/dist/conversations/store.js +0 -0
- package/dist/conversations/store.js.map +1 -0
- package/dist/identity/context.d.ts +8 -0
- package/dist/identity/context.d.ts.map +1 -1
- package/dist/identity/context.js +19 -4
- package/dist/identity/context.js.map +1 -1
- package/dist/identity/markdown.d.ts +38 -0
- package/dist/identity/markdown.d.ts.map +1 -0
- package/dist/identity/markdown.js +85 -0
- package/dist/identity/markdown.js.map +1 -0
- package/dist/index.d.ts +56 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +30 -3
- package/dist/index.js.map +1 -1
- package/dist/prompts/render.d.ts +23 -0
- package/dist/prompts/render.d.ts.map +1 -0
- package/dist/prompts/render.js +35 -0
- package/dist/prompts/render.js.map +1 -0
- package/dist/prompts/seeds.d.ts +34 -0
- package/dist/prompts/seeds.d.ts.map +1 -0
- package/dist/prompts/seeds.js +166 -0
- package/dist/prompts/seeds.js.map +1 -0
- package/dist/prompts/store.d.ts +8 -0
- package/dist/prompts/store.d.ts.map +1 -0
- package/dist/prompts/store.js +153 -0
- package/dist/prompts/store.js.map +1 -0
- package/dist/prompts/types.d.ts +51 -0
- package/dist/prompts/types.d.ts.map +1 -0
- package/dist/prompts/types.js +24 -0
- package/dist/prompts/types.js.map +1 -0
- package/dist/providers/anthropic.d.ts +21 -3
- package/dist/providers/anthropic.d.ts.map +1 -1
- package/dist/providers/anthropic.js +60 -12
- package/dist/providers/anthropic.js.map +1 -1
- package/dist/providers/catalog.d.ts +41 -0
- package/dist/providers/catalog.d.ts.map +1 -0
- package/dist/providers/catalog.js +85 -0
- package/dist/providers/catalog.js.map +1 -0
- package/dist/providers/content-parts.d.ts +12 -0
- package/dist/providers/content-parts.d.ts.map +1 -0
- package/dist/providers/content-parts.js +18 -0
- package/dist/providers/content-parts.js.map +1 -0
- package/dist/providers/defaults.d.ts +15 -0
- package/dist/providers/defaults.d.ts.map +1 -0
- package/dist/providers/defaults.js +15 -0
- package/dist/providers/defaults.js.map +1 -0
- package/dist/providers/google.d.ts +16 -3
- package/dist/providers/google.d.ts.map +1 -1
- package/dist/providers/google.js +54 -12
- package/dist/providers/google.js.map +1 -1
- package/dist/providers/openai.d.ts +32 -4
- package/dist/providers/openai.d.ts.map +1 -1
- package/dist/providers/openai.js +114 -21
- package/dist/providers/openai.js.map +1 -1
- package/dist/providers/registry.d.ts +31 -20
- package/dist/providers/registry.d.ts.map +1 -1
- package/dist/providers/registry.js +49 -7
- package/dist/providers/registry.js.map +1 -1
- package/dist/providers/request-signal.d.ts +23 -0
- package/dist/providers/request-signal.d.ts.map +1 -0
- package/dist/providers/request-signal.js +26 -0
- package/dist/providers/request-signal.js.map +1 -0
- package/dist/providers/resolve.d.ts +13 -0
- package/dist/providers/resolve.d.ts.map +1 -0
- package/dist/providers/resolve.js +30 -0
- package/dist/providers/resolve.js.map +1 -0
- package/dist/providers/store.d.ts +70 -0
- package/dist/providers/store.d.ts.map +1 -0
- package/dist/providers/store.js +308 -0
- package/dist/providers/store.js.map +1 -0
- package/dist/providers/tool-names.d.ts +9 -0
- package/dist/providers/tool-names.d.ts.map +1 -0
- package/dist/providers/tool-names.js +56 -0
- package/dist/providers/tool-names.js.map +1 -0
- package/dist/providers/types.d.ts +78 -3
- package/dist/providers/types.d.ts.map +1 -1
- package/dist/rag/reference-documents/ingest.d.ts +22 -0
- package/dist/rag/reference-documents/ingest.d.ts.map +1 -0
- package/dist/rag/reference-documents/ingest.js +69 -0
- package/dist/rag/reference-documents/ingest.js.map +1 -0
- package/dist/rag/reference-documents/store.d.ts +23 -0
- package/dist/rag/reference-documents/store.d.ts.map +1 -0
- package/dist/rag/reference-documents/store.js +140 -0
- package/dist/rag/reference-documents/store.js.map +1 -0
- package/dist/rag/reference-documents/types.d.ts +52 -0
- package/dist/rag/reference-documents/types.d.ts.map +1 -0
- package/dist/rag/reference-documents/types.js +32 -0
- package/dist/rag/reference-documents/types.js.map +1 -0
- package/dist/runtime/loop.d.ts +29 -7
- package/dist/runtime/loop.d.ts.map +1 -1
- package/dist/runtime/loop.js +200 -42
- package/dist/runtime/loop.js.map +1 -1
- package/dist/runtime/types.d.ts +4 -3
- package/dist/runtime/types.d.ts.map +1 -1
- package/dist/site-plan/analyse-brief.d.ts +8 -0
- package/dist/site-plan/analyse-brief.d.ts.map +1 -1
- package/dist/site-plan/analyse-brief.js +18 -7
- package/dist/site-plan/analyse-brief.js.map +1 -1
- package/dist/site-plan/approval.d.ts +2 -2
- package/dist/site-plan/approval.d.ts.map +1 -1
- package/dist/site-plan/approval.js +34 -4
- package/dist/site-plan/approval.js.map +1 -1
- package/dist/site-plan/content-model.d.ts +14 -0
- package/dist/site-plan/content-model.d.ts.map +1 -1
- package/dist/site-plan/content-model.js +52 -8
- package/dist/site-plan/content-model.js.map +1 -1
- package/dist/site-plan/demo-content.js +2 -3
- package/dist/site-plan/demo-content.js.map +1 -1
- package/dist/site-plan/propose-plan.d.ts +10 -0
- package/dist/site-plan/propose-plan.d.ts.map +1 -1
- package/dist/site-plan/propose-plan.js +25 -1
- package/dist/site-plan/propose-plan.js.map +1 -1
- package/dist/site-plan/site-context.d.ts +81 -0
- package/dist/site-plan/site-context.d.ts.map +1 -0
- package/dist/site-plan/site-context.js +76 -0
- package/dist/site-plan/site-context.js.map +1 -0
- package/dist/site-plan/skin-candidates.d.ts +7 -0
- package/dist/site-plan/skin-candidates.d.ts.map +1 -1
- package/dist/site-plan/skin-candidates.js +6 -0
- package/dist/site-plan/skin-candidates.js.map +1 -1
- package/dist/site-plan/structural-gaps.d.ts +32 -0
- package/dist/site-plan/structural-gaps.d.ts.map +1 -0
- package/dist/site-plan/structural-gaps.js +77 -0
- package/dist/site-plan/structural-gaps.js.map +1 -0
- package/dist/site-plan/types.d.ts +7 -0
- package/dist/site-plan/types.d.ts.map +1 -1
- package/dist/skills/frontmatter.d.ts +19 -1
- package/dist/skills/frontmatter.d.ts.map +1 -1
- package/dist/skills/frontmatter.js +29 -5
- package/dist/skills/frontmatter.js.map +1 -1
- package/dist/skills/library.d.ts +133 -0
- package/dist/skills/library.d.ts.map +1 -0
- package/dist/skills/library.js +332 -0
- package/dist/skills/library.js.map +1 -0
- package/dist/skills/types.d.ts +8 -1
- package/dist/skills/types.d.ts.map +1 -1
- package/dist/skin/generate.d.ts +10 -0
- package/dist/skin/generate.d.ts.map +1 -1
- package/dist/skin/generate.js +43 -4
- package/dist/skin/generate.js.map +1 -1
- package/dist/theme-creator/propose-theme.d.ts +77 -0
- package/dist/theme-creator/propose-theme.d.ts.map +1 -0
- package/dist/theme-creator/propose-theme.js +228 -0
- package/dist/theme-creator/propose-theme.js.map +1 -0
- package/dist/tools/core/agent-delegate.d.ts +8 -5
- package/dist/tools/core/agent-delegate.d.ts.map +1 -1
- package/dist/tools/core/agent-delegate.js +16 -6
- package/dist/tools/core/agent-delegate.js.map +1 -1
- package/dist/tools/core/content-browse.d.ts +74 -0
- package/dist/tools/core/content-browse.d.ts.map +1 -0
- package/dist/tools/core/content-browse.js +63 -0
- package/dist/tools/core/content-browse.js.map +1 -0
- package/dist/tools/core/content-schema.d.ts +86 -0
- package/dist/tools/core/content-schema.d.ts.map +1 -0
- package/dist/tools/core/content-schema.js +83 -0
- package/dist/tools/core/content-schema.js.map +1 -0
- package/dist/tools/core/deps-scan.d.ts +25 -0
- package/dist/tools/core/deps-scan.d.ts.map +1 -0
- package/dist/tools/core/deps-scan.js +85 -0
- package/dist/tools/core/deps-scan.js.map +1 -0
- package/dist/tools/core/media.d.ts +18 -2
- package/dist/tools/core/media.d.ts.map +1 -1
- package/dist/tools/core/media.js +8 -2
- package/dist/tools/core/media.js.map +1 -1
- package/dist/tools/core/not-found-log.d.ts +44 -0
- package/dist/tools/core/not-found-log.d.ts.map +1 -0
- package/dist/tools/core/not-found-log.js +32 -0
- package/dist/tools/core/not-found-log.js.map +1 -0
- package/dist/tools/core/redirects.d.ts +51 -0
- package/dist/tools/core/redirects.d.ts.map +1 -0
- package/dist/tools/core/redirects.js +50 -0
- package/dist/tools/core/redirects.js.map +1 -0
- package/package.json +6 -4
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { AgentDeclarationInput, AgentDeclarationStore } from './store.js';
|
|
2
|
+
/**
|
|
3
|
+
* L22 task 1 items 2 and 5, plus task 3 — the four agents every site starts
|
|
4
|
+
* with.
|
|
5
|
+
*
|
|
6
|
+
* `SUPERAGENT_NAME` ("Cogenta Agent") is active by default, with every
|
|
7
|
+
* content/media/site/document tool this build actually implements (never a
|
|
8
|
+
* placeholder permission with no tool behind it — `deps.scan` is the one
|
|
9
|
+
* this lot adds for exactly this agent). Its autonomy defaults to `propose`
|
|
10
|
+
* (the UI's "co-pilot") rather than `autonomous`: "actif par défaut" is
|
|
11
|
+
* about the agent *existing and being enabled*, not about every write it
|
|
12
|
+
* might make happening unattended from the first boot — a judgment call,
|
|
13
|
+
* flagged in this lot's report, that a site operator can raise to
|
|
14
|
+
* `autonomous` per tool or by default once they trust it.
|
|
15
|
+
*
|
|
16
|
+
* The security scanner, the content-watch example and the site monitor
|
|
17
|
+
* (task 3) are disabled by default, exactly as the lot asks, and all three
|
|
18
|
+
* ship as editable seeds: nothing about `builtin: true` freezes their tools,
|
|
19
|
+
* autonomy, budget or triggers, it only prevents deletion
|
|
20
|
+
* (`AgentDeclarationStore.remove`).
|
|
21
|
+
*
|
|
22
|
+
* `SITE_MONITOR_AGENT_NAME` ("Site Monitor") is task 3's own agent, kept
|
|
23
|
+
* separate from `SUPERAGENT_NAME` rather than folded into it: the
|
|
24
|
+
* superagent's tools are whatever an operator talks to it about, one
|
|
25
|
+
* instruction at a time, while this one exists to run unattended on a cron
|
|
26
|
+
* trigger with a narrow, fixed toolset (read the 404 log, browse content,
|
|
27
|
+
* propose or create a redirect) — a different shape of agent, not a bigger
|
|
28
|
+
* one. Its default autonomy is `propose` (co-pilot), same reasoning as the
|
|
29
|
+
* superagent's: a monitoring agent that can silently rewrite routing on its
|
|
30
|
+
* first boot is not what "disabled by default" is supposed to soften into
|
|
31
|
+
* once enabled. Raising it to `autonomous` (autopilot) is the one thing
|
|
32
|
+
* task 3's spec names as the condition for an applied, not merely
|
|
33
|
+
* suggested, redirect.
|
|
34
|
+
*/
|
|
35
|
+
export declare const SUPERAGENT_NAME = "Cogenta Agent";
|
|
36
|
+
export declare const SECURITY_AGENT_NAME = "Security Scanner";
|
|
37
|
+
export declare const CONTENT_WATCH_AGENT_NAME = "Content Watch";
|
|
38
|
+
export declare const SITE_MONITOR_AGENT_NAME = "Site Monitor";
|
|
39
|
+
export declare const THEME_CREATOR_AGENT_NAME = "Cogenta Theme Creator";
|
|
40
|
+
export declare function builtinAgentSeeds(): readonly AgentDeclarationInput[];
|
|
41
|
+
/**
|
|
42
|
+
* Idempotent: called both by `create-cogenta` at install and defensively by
|
|
43
|
+
* `cogenta serve` at every boot (an upgrade from an older site gains
|
|
44
|
+
* whichever of these it does not already have the first time it starts on
|
|
45
|
+
* the new version, not only a freshly scaffolded one). Matched by name — a
|
|
46
|
+
* seed already present (its `builtin: true` record cannot be removed, only
|
|
47
|
+
* disabled or edited) is left untouched, never overwritten with the seed's
|
|
48
|
+
* defaults again.
|
|
49
|
+
*/
|
|
50
|
+
export declare function ensureBuiltinAgents(store: AgentDeclarationStore): Promise<void>;
|
|
51
|
+
//# sourceMappingURL=builtins.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"builtins.d.ts","sourceRoot":"","sources":["../../src/agents/builtins.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,qBAAqB,EAAe,MAAM,YAAY,CAAA;AAE3F;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,eAAO,MAAM,eAAe,kBAAkB,CAAA;AAC9C,eAAO,MAAM,mBAAmB,qBAAqB,CAAA;AACrD,eAAO,MAAM,wBAAwB,kBAAkB,CAAA;AACvD,eAAO,MAAM,uBAAuB,iBAAiB,CAAA;AACrD,eAAO,MAAM,wBAAwB,0BAA0B,CAAA;AAK/D,wBAAgB,iBAAiB,IAAI,SAAS,qBAAqB,EAAE,CAiHpE;AAED;;;;;;;;GAQG;AACH,wBAAsB,mBAAmB,CAAC,KAAK,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC,CAMrF"}
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* L22 task 1 items 2 and 5, plus task 3 — the four agents every site starts
|
|
3
|
+
* with.
|
|
4
|
+
*
|
|
5
|
+
* `SUPERAGENT_NAME` ("Cogenta Agent") is active by default, with every
|
|
6
|
+
* content/media/site/document tool this build actually implements (never a
|
|
7
|
+
* placeholder permission with no tool behind it — `deps.scan` is the one
|
|
8
|
+
* this lot adds for exactly this agent). Its autonomy defaults to `propose`
|
|
9
|
+
* (the UI's "co-pilot") rather than `autonomous`: "actif par défaut" is
|
|
10
|
+
* about the agent *existing and being enabled*, not about every write it
|
|
11
|
+
* might make happening unattended from the first boot — a judgment call,
|
|
12
|
+
* flagged in this lot's report, that a site operator can raise to
|
|
13
|
+
* `autonomous` per tool or by default once they trust it.
|
|
14
|
+
*
|
|
15
|
+
* The security scanner, the content-watch example and the site monitor
|
|
16
|
+
* (task 3) are disabled by default, exactly as the lot asks, and all three
|
|
17
|
+
* ship as editable seeds: nothing about `builtin: true` freezes their tools,
|
|
18
|
+
* autonomy, budget or triggers, it only prevents deletion
|
|
19
|
+
* (`AgentDeclarationStore.remove`).
|
|
20
|
+
*
|
|
21
|
+
* `SITE_MONITOR_AGENT_NAME` ("Site Monitor") is task 3's own agent, kept
|
|
22
|
+
* separate from `SUPERAGENT_NAME` rather than folded into it: the
|
|
23
|
+
* superagent's tools are whatever an operator talks to it about, one
|
|
24
|
+
* instruction at a time, while this one exists to run unattended on a cron
|
|
25
|
+
* trigger with a narrow, fixed toolset (read the 404 log, browse content,
|
|
26
|
+
* propose or create a redirect) — a different shape of agent, not a bigger
|
|
27
|
+
* one. Its default autonomy is `propose` (co-pilot), same reasoning as the
|
|
28
|
+
* superagent's: a monitoring agent that can silently rewrite routing on its
|
|
29
|
+
* first boot is not what "disabled by default" is supposed to soften into
|
|
30
|
+
* once enabled. Raising it to `autonomous` (autopilot) is the one thing
|
|
31
|
+
* task 3's spec names as the condition for an applied, not merely
|
|
32
|
+
* suggested, redirect.
|
|
33
|
+
*/
|
|
34
|
+
export const SUPERAGENT_NAME = 'Cogenta Agent';
|
|
35
|
+
export const SECURITY_AGENT_NAME = 'Security Scanner';
|
|
36
|
+
export const CONTENT_WATCH_AGENT_NAME = 'Content Watch';
|
|
37
|
+
export const SITE_MONITOR_AGENT_NAME = 'Site Monitor';
|
|
38
|
+
export const THEME_CREATOR_AGENT_NAME = 'Cogenta Theme Creator';
|
|
39
|
+
/** Passed to `AgentDeclarationInput.model` — every seed prefers the same provider/model names an operator is most likely to configure first; `agents/orchestrator.ts` never fails to resolve a provider just because the *name* differs from what the site has enabled, it only needs `providers/store.ts` to have configured at least one. */
|
|
40
|
+
const DEFAULT_MODEL = { preferred: 'anthropic', fallback: 'openai' };
|
|
41
|
+
export function builtinAgentSeeds() {
|
|
42
|
+
return [
|
|
43
|
+
{
|
|
44
|
+
name: SUPERAGENT_NAME,
|
|
45
|
+
identity: {
|
|
46
|
+
role: 'The default, general-purpose agent for this Cogenta site — reads and writes content, media and configuration on behalf of the operator who talks to it, within whatever an admin actor may do.',
|
|
47
|
+
objectives: [
|
|
48
|
+
'Carry out the instruction it is given, using the smallest set of tool calls that does it.',
|
|
49
|
+
'Prefer reading before writing, and ask for a specific, named sub-agent when a task is squarely that sub-agent’s specialty.',
|
|
50
|
+
'Never claim an action succeeded without the tool result to show for it.',
|
|
51
|
+
],
|
|
52
|
+
style: 'Direct, concrete, and honest about what it did and did not do.',
|
|
53
|
+
},
|
|
54
|
+
model: DEFAULT_MODEL,
|
|
55
|
+
tools: [
|
|
56
|
+
'content.read',
|
|
57
|
+
// The browse pair (L22 task 3) — without them the superagent could
|
|
58
|
+
// only read an entry whose id it already knew, and a live run
|
|
59
|
+
// against DeepSeek showed it guessing ids 1..10 to count a site's
|
|
60
|
+
// posts. Same permission as `content.read`, read-only.
|
|
61
|
+
'content.collections',
|
|
62
|
+
'content.list',
|
|
63
|
+
// `content.schema` — the missing half of the browse pair: without it
|
|
64
|
+
// the superagent could see *that* a collection or entry exists, but
|
|
65
|
+
// never *what fields* it takes, and a live run asked "peux-tu
|
|
66
|
+
// générer un template ?" answered by asking the human to specify
|
|
67
|
+
// every field itself. Same permission as `content.read`, read-only.
|
|
68
|
+
'content.schema',
|
|
69
|
+
'content.write_draft',
|
|
70
|
+
'content.publish',
|
|
71
|
+
'content.delete',
|
|
72
|
+
'media.read',
|
|
73
|
+
'media.write',
|
|
74
|
+
'site.config_read',
|
|
75
|
+
'document.extract_text',
|
|
76
|
+
],
|
|
77
|
+
autonomy: { default: 'propose' },
|
|
78
|
+
budget: { tokensPerDay: 200_000, callsPerHour: 60 },
|
|
79
|
+
memory: { episodic: true, scope: 'site' },
|
|
80
|
+
enabled: true,
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
name: SECURITY_AGENT_NAME,
|
|
84
|
+
identity: {
|
|
85
|
+
role: 'Scans this site’s own declared dependencies for risky version pins on a schedule, and reports what it finds — it never patches anything itself.',
|
|
86
|
+
objectives: [
|
|
87
|
+
'Run deps.scan and summarise anything it flags (an unpinned or wildcard version).',
|
|
88
|
+
'Report findings; never call a write tool.',
|
|
89
|
+
],
|
|
90
|
+
style: 'Terse, factual, one line per finding.',
|
|
91
|
+
},
|
|
92
|
+
model: DEFAULT_MODEL,
|
|
93
|
+
tools: ['deps.scan', 'content.read'],
|
|
94
|
+
autonomy: { default: 'observe' },
|
|
95
|
+
budget: { tokensPerDay: 50_000, callsPerHour: 10 },
|
|
96
|
+
triggers: [{ on: 'schedule', cron: '0 6 * * *' }],
|
|
97
|
+
enabled: false,
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
name: CONTENT_WATCH_AGENT_NAME,
|
|
101
|
+
identity: {
|
|
102
|
+
role: 'An example agent: wakes up periodically, looks over recently published content, and proposes new draft titles worth writing about — a starting point meant to be edited, not a fixed feature.',
|
|
103
|
+
objectives: [
|
|
104
|
+
'Read recent published entries in the configured collection.',
|
|
105
|
+
'Propose 1-3 new draft entries (title + a one-line outline) via content.write_draft — never publish them.',
|
|
106
|
+
],
|
|
107
|
+
style: 'Editorial, brief, no filler.',
|
|
108
|
+
},
|
|
109
|
+
model: DEFAULT_MODEL,
|
|
110
|
+
tools: ['content.read', 'content.write_draft'],
|
|
111
|
+
autonomy: { default: 'propose' },
|
|
112
|
+
budget: { tokensPerDay: 50_000, callsPerHour: 10 },
|
|
113
|
+
triggers: [{ on: 'schedule', cron: '0 8 * * 1' }],
|
|
114
|
+
enabled: false,
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
name: SITE_MONITOR_AGENT_NAME,
|
|
118
|
+
identity: {
|
|
119
|
+
role: 'Watches this site’s own 404 log for a broken link worth fixing, and either proposes or creates a redirect to a page it picks — never anything else (it never touches content, media or site config).',
|
|
120
|
+
objectives: [
|
|
121
|
+
'Call logs.read_not_found and look at the paths with the most hits.',
|
|
122
|
+
'For the top one with no redirect yet, call content.collections then content.list to find a genuinely related, routed page.',
|
|
123
|
+
'Call redirects.create with that path as "to" — under co-pilot autonomy this only ever proposes the change for an admin to confirm in the Redirections screen; nothing is written until it does.',
|
|
124
|
+
'Skip a 404 with too few hits to be worth a redirect, or when nothing in the site’s content is actually related — proposing a bad redirect is worse than proposing none.',
|
|
125
|
+
],
|
|
126
|
+
style: 'Terse, factual, one finding per turn.',
|
|
127
|
+
},
|
|
128
|
+
model: DEFAULT_MODEL,
|
|
129
|
+
tools: ['logs.read_not_found', 'content.collections', 'content.list', 'redirects.create'],
|
|
130
|
+
autonomy: { default: 'propose' },
|
|
131
|
+
budget: { tokensPerDay: 50_000, callsPerHour: 10 },
|
|
132
|
+
triggers: [{ on: 'schedule', cron: '0 7 * * *' }],
|
|
133
|
+
enabled: false,
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
name: THEME_CREATOR_AGENT_NAME,
|
|
137
|
+
identity: {
|
|
138
|
+
role: 'Designs and adjusts this site’s visual theme from a description and, optionally, attached files (documents, screenshots) — the Appearance screen’s theme generator workshop talks to this agent, not the other way around.',
|
|
139
|
+
objectives: [
|
|
140
|
+
'Read the brief and any attachments, then call theme.propose_theme with them.',
|
|
141
|
+
'Pick the base theme from the packages this instance actually ships — never invent one.',
|
|
142
|
+
'Produce contract D skin tokens only, never raw HTML or CSS.',
|
|
143
|
+
'Propose 1-3 candidates and stop — this tool never applies anything itself (sideEffects: false); an admin activates a candidate from the workshop.',
|
|
144
|
+
],
|
|
145
|
+
style: 'Concrete design rationale, one sentence per candidate, no filler.',
|
|
146
|
+
},
|
|
147
|
+
model: DEFAULT_MODEL,
|
|
148
|
+
tools: ['theme.propose_theme'],
|
|
149
|
+
autonomy: { default: 'propose' },
|
|
150
|
+
budget: { tokensPerDay: 100_000, callsPerHour: 20 },
|
|
151
|
+
enabled: true,
|
|
152
|
+
},
|
|
153
|
+
];
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Idempotent: called both by `create-cogenta` at install and defensively by
|
|
157
|
+
* `cogenta serve` at every boot (an upgrade from an older site gains
|
|
158
|
+
* whichever of these it does not already have the first time it starts on
|
|
159
|
+
* the new version, not only a freshly scaffolded one). Matched by name — a
|
|
160
|
+
* seed already present (its `builtin: true` record cannot be removed, only
|
|
161
|
+
* disabled or edited) is left untouched, never overwritten with the seed's
|
|
162
|
+
* defaults again.
|
|
163
|
+
*/
|
|
164
|
+
export async function ensureBuiltinAgents(store) {
|
|
165
|
+
for (const seed of builtinAgentSeeds()) {
|
|
166
|
+
const existing = await store.get(seed.name);
|
|
167
|
+
if (existing === undefined)
|
|
168
|
+
await store.create(seed, true);
|
|
169
|
+
else
|
|
170
|
+
await grantContentBrowse(store, existing);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* The one exception to "never touch an existing seed": `content.collections`,
|
|
175
|
+
* `content.list` and `content.schema` are all read-only, all under
|
|
176
|
+
* `content.read` (same permission, each added after the superagent first
|
|
177
|
+
* shipped), so a built-in that already holds `content.read` gains nothing it
|
|
178
|
+
* could not already do — it only stops having to guess entry ids or field
|
|
179
|
+
* shapes. An operator who removed `content.read` on purpose is left alone.
|
|
180
|
+
*/
|
|
181
|
+
const CONTENT_BROWSE_TOOLS = ['content.collections', 'content.list', 'content.schema'];
|
|
182
|
+
async function grantContentBrowse(store, existing) {
|
|
183
|
+
if (!existing.tools.includes('content.read'))
|
|
184
|
+
return;
|
|
185
|
+
const missing = CONTENT_BROWSE_TOOLS.filter((tool) => !existing.tools.includes(tool));
|
|
186
|
+
if (missing.length === 0)
|
|
187
|
+
return;
|
|
188
|
+
await store.update(existing.name, { tools: [...existing.tools, ...missing] });
|
|
189
|
+
}
|
|
190
|
+
//# sourceMappingURL=builtins.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"builtins.js","sourceRoot":"","sources":["../../src/agents/builtins.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import type { AuditLogLike } from '../audit/types.js';
|
|
2
|
+
import type { ApprovalQueue } from '../autonomy/types.js';
|
|
3
|
+
import type { BudgetTracker, KillSwitch } from '../budget/types.js';
|
|
4
|
+
import type { ChatMessage, ProviderClient } from '../providers/types.js';
|
|
5
|
+
import type { RunResult, RunStopReason } from '../runtime/types.js';
|
|
6
|
+
import type { AgentSkillStore } from '../skills/library.js';
|
|
7
|
+
import { type ToolRegistry } from '../tools/registry.js';
|
|
8
|
+
import type { AgentDeclarationStore, StoredAgent } from './store.js';
|
|
9
|
+
/**
|
|
10
|
+
* Two different "site" shapes meet here on purpose, not by accident:
|
|
11
|
+
* `ToolContext.site` (what `buildManifest` needs — `defaultLocale`
|
|
12
|
+
* required, no `brand`/`tone`/`constraints`) and `identity/context.js`'s
|
|
13
|
+
* `SiteContext` (what `assembleContext` needs — the reverse). `RunnerSite`
|
|
14
|
+
* is the superset a caller supplies once; `siteContextOf`/`toolSiteOf` below
|
|
15
|
+
* project it down to whichever shape a given call actually needs.
|
|
16
|
+
*/
|
|
17
|
+
export interface RunnerSite {
|
|
18
|
+
readonly name: string;
|
|
19
|
+
readonly url?: string;
|
|
20
|
+
readonly locales: readonly string[];
|
|
21
|
+
readonly defaultLocale: string;
|
|
22
|
+
readonly brand?: string;
|
|
23
|
+
readonly tone?: string;
|
|
24
|
+
readonly constraints?: readonly string[];
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* L22 task 1's actual deliverable: the wiring `AgentRegistry` never had.
|
|
28
|
+
* Everything this function calls already existed and was already tested
|
|
29
|
+
* (`runAgentLoop`, `buildManifest`, `withAutonomyForManifest`,
|
|
30
|
+
* `withAuditForManifest`, `createAgentDelegateTool`, `assembleContext`,
|
|
31
|
+
* `createBudgetTracker`) — this module's own job is only to put them
|
|
32
|
+
* together in the right order for one named agent, never to reimplement any
|
|
33
|
+
* of them.
|
|
34
|
+
*
|
|
35
|
+
* Order of wrapping matters: `withAudit` is the outermost layer, so the
|
|
36
|
+
* audit trail records what actually happened (executed, observed, or
|
|
37
|
+
* proposed-and-not-yet-decided) rather than the raw tool's own behaviour —
|
|
38
|
+
* `withAutonomy` sits directly on the raw tool underneath it.
|
|
39
|
+
*/
|
|
40
|
+
export interface AgentProviderRegistryLike {
|
|
41
|
+
has(name: string): boolean;
|
|
42
|
+
get(name: string): ProviderClient;
|
|
43
|
+
}
|
|
44
|
+
export interface RunAgentOptions {
|
|
45
|
+
/** Runtime-generated instruction (a trigger, an operator's typed request) — never external content (R8's own distinction, see `identity/context.ts`). */
|
|
46
|
+
readonly instruction: string;
|
|
47
|
+
/**
|
|
48
|
+
* Prior turns of a standing conversation with this agent, oldest first —
|
|
49
|
+
* plain `user`/`assistant` text, no `toolCalls`/`toolCallId` (a past run's
|
|
50
|
+
* tool instances are gone by the next call; replaying raw tool_use/
|
|
51
|
+
* tool_result blocks across runs would assume a continuity the runtime
|
|
52
|
+
* does not have). Spliced between the R8 `dataMessages` and the fixed
|
|
53
|
+
* trigger turn, so a multi-turn caller (the chat surfaces) gets real
|
|
54
|
+
* conversational memory without folding it into `instruction`'s own
|
|
55
|
+
* `<task>` tag — the string-concatenation hack this replaces.
|
|
56
|
+
*/
|
|
57
|
+
readonly history?: readonly ChatMessage[];
|
|
58
|
+
/** What started this run — recorded in the run-level audit entry. */
|
|
59
|
+
readonly trigger?: string;
|
|
60
|
+
readonly signal?: AbortSignal;
|
|
61
|
+
readonly maxTokens?: number;
|
|
62
|
+
}
|
|
63
|
+
/** One tool call the run made, folded down for a caller that only wants "what did it touch", not the full `StepRecord` shape. */
|
|
64
|
+
export interface AgentRunToolCallSummary {
|
|
65
|
+
readonly name: string;
|
|
66
|
+
readonly input: Readonly<Record<string, unknown>>;
|
|
67
|
+
}
|
|
68
|
+
export interface AgentRunSummary {
|
|
69
|
+
readonly agent: string;
|
|
70
|
+
readonly stopReason: RunStopReason;
|
|
71
|
+
readonly finalText: string | null;
|
|
72
|
+
readonly steps: number;
|
|
73
|
+
readonly usage: RunResult['usage'];
|
|
74
|
+
/** Every tool call across every step, in call order — `[]` when the run made none. */
|
|
75
|
+
readonly toolCalls: readonly AgentRunToolCallSummary[];
|
|
76
|
+
}
|
|
77
|
+
export interface AgentRunnerOptions {
|
|
78
|
+
readonly agents: AgentDeclarationStore;
|
|
79
|
+
readonly skills: AgentSkillStore;
|
|
80
|
+
/** The site's full contract-C tool registry — content/media/site-config/http-fetch/document-extract/deps-scan, whatever this build/deployment actually implements. `buildManifest` refuses (at call time) any name an agent declares that is not in here. */
|
|
81
|
+
readonly tools: ToolRegistry;
|
|
82
|
+
readonly providers: AgentProviderRegistryLike;
|
|
83
|
+
readonly auditLog: AuditLogLike;
|
|
84
|
+
readonly approvalQueue: ApprovalQueue;
|
|
85
|
+
readonly site: RunnerSite;
|
|
86
|
+
readonly killSwitchFor: (name: string) => KillSwitch;
|
|
87
|
+
readonly now?: () => number;
|
|
88
|
+
/** Injectable for tests — defaults to a real `Date.now`-bucketed tracker per agent, cached for the runner's lifetime. */
|
|
89
|
+
readonly budgetTrackerFor?: (agent: StoredAgent) => BudgetTracker;
|
|
90
|
+
}
|
|
91
|
+
export interface AgentRunner {
|
|
92
|
+
run(name: string, options: RunAgentOptions): Promise<AgentRunSummary>;
|
|
93
|
+
}
|
|
94
|
+
export declare function createAgentRunner(options: AgentRunnerOptions): AgentRunner;
|
|
95
|
+
//# sourceMappingURL=orchestrator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orchestrator.d.ts","sourceRoot":"","sources":["../../src/agents/orchestrator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
import { CogentaError } from '@cogenta/core';
|
|
2
|
+
import { withAuditForManifest } from '../audit/with-audit.js';
|
|
3
|
+
import { withAutonomyForManifest } from '../autonomy/with-autonomy.js';
|
|
4
|
+
import { createBudgetTracker } from '../budget/tracker.js';
|
|
5
|
+
import { assembleContext } from '../identity/context.js';
|
|
6
|
+
import { runAgentLoop } from '../runtime/loop.js';
|
|
7
|
+
import { createAgentDelegateTool } from '../tools/core/agent-delegate.js';
|
|
8
|
+
import { buildManifest } from '../tools/manifest.js';
|
|
9
|
+
import { createToolRegistry } from '../tools/registry.js';
|
|
10
|
+
/**
|
|
11
|
+
* `runOptions.maxTokens` is a genuine per-call override, kept for a caller
|
|
12
|
+
* with a real reason to differ from a run's own default; when absent (every
|
|
13
|
+
* real caller today), `runAgentLoop` no longer needs a value from here at
|
|
14
|
+
* all — it falls back to `client.maxOutputTokens`, the admin-configured
|
|
15
|
+
* property of *which model this run resolved to*
|
|
16
|
+
* (`/admin/providers`). That per-provider value already fixed a reproduced,
|
|
17
|
+
* live failure this constant used to paper over with a single guess: the
|
|
18
|
+
* superagent, asked to draft a real content template, made seven legitimate
|
|
19
|
+
* tool calls and had its final answer cut off mid-generation
|
|
20
|
+
* (`stopReason: 'max_tokens'`, DeepSeek's `finish_reason: 'length'`) at a
|
|
21
|
+
* budget sized for a short conversational reply, not a generation task this
|
|
22
|
+
* runtime actively encourages — a number no single call site can size
|
|
23
|
+
* correctly for every model an admin might configure.
|
|
24
|
+
*/
|
|
25
|
+
function toolSiteOf(site) {
|
|
26
|
+
return {
|
|
27
|
+
name: site.name,
|
|
28
|
+
...(site.url === undefined ? {} : { url: site.url }),
|
|
29
|
+
locales: site.locales,
|
|
30
|
+
defaultLocale: site.defaultLocale,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
function siteContextOf(site) {
|
|
34
|
+
return {
|
|
35
|
+
name: site.name,
|
|
36
|
+
...(site.brand === undefined ? {} : { brand: site.brand }),
|
|
37
|
+
...(site.tone === undefined ? {} : { tone: site.tone }),
|
|
38
|
+
locales: site.locales,
|
|
39
|
+
...(site.constraints === undefined ? {} : { constraints: site.constraints }),
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
function agentUnknown(name) {
|
|
43
|
+
return new CogentaError({
|
|
44
|
+
code: 'AGENT_UNKNOWN',
|
|
45
|
+
message: `No agent named "${name}" is registered.`,
|
|
46
|
+
hint: 'Check the name against the Agents screen, or create it first.',
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
function agentDisabled(name) {
|
|
50
|
+
return new CogentaError({
|
|
51
|
+
code: 'AGENT_DISABLED',
|
|
52
|
+
message: `"${name}" is disabled and cannot run.`,
|
|
53
|
+
hint: 'Enable it from the Agents screen first.',
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* R2, applied at the one place a network call would otherwise happen:
|
|
58
|
+
* resolving a `ProviderClient` is a synchronous registry lookup (`get`
|
|
59
|
+
* throws `PROVIDER_UNKNOWN` without ever touching the network — see
|
|
60
|
+
* `providers/registry.ts`), so trying `preferred` then `fallback` and
|
|
61
|
+
* throwing `AGENT_NO_PROVIDER` when neither resolves guarantees zero
|
|
62
|
+
* outbound requests for a site with no provider configured — the same
|
|
63
|
+
* guarantee `packages/cli/test/serve-assistant.test.ts` already proves for
|
|
64
|
+
* `assist.*`, extended here to the agent runtime.
|
|
65
|
+
*/
|
|
66
|
+
/**
|
|
67
|
+
* Fiche 55 task 2 — `model.model` is an explicit model id, distinct from the
|
|
68
|
+
* provider name `resolveProvider` already picked a client by. A
|
|
69
|
+
* `ProviderClient` is a plain object (`{ name, model, chat }`, see every
|
|
70
|
+
* `providers/*.ts` adapter); overriding `model` this way changes nothing
|
|
71
|
+
* about `chat`'s closure over its own config (the vendor URL, the API key)
|
|
72
|
+
* — only the `model` field `runAgentLoop` reads off the client onto every
|
|
73
|
+
* `ChatRequest`. Absent or blank means "use whatever the provider config
|
|
74
|
+
* says", the behaviour every agent had before this field existed.
|
|
75
|
+
*/
|
|
76
|
+
function withModelOverride(client, model) {
|
|
77
|
+
if (model === undefined || model.trim().length === 0)
|
|
78
|
+
return client;
|
|
79
|
+
return { ...client, model: model.trim() };
|
|
80
|
+
}
|
|
81
|
+
function resolveProvider(agentName, model, providers) {
|
|
82
|
+
if (providers.has(model.preferred)) {
|
|
83
|
+
return withModelOverride(providers.get(model.preferred), model.model);
|
|
84
|
+
}
|
|
85
|
+
if (model.fallback !== undefined && providers.has(model.fallback)) {
|
|
86
|
+
return withModelOverride(providers.get(model.fallback), model.model);
|
|
87
|
+
}
|
|
88
|
+
throw new CogentaError({
|
|
89
|
+
code: 'AGENT_NO_PROVIDER',
|
|
90
|
+
message: `"${agentName}" has no configured LLM provider (wants "${model.preferred}"${model.fallback === undefined ? '' : ` or "${model.fallback}"`}).`,
|
|
91
|
+
hint: 'Configure a provider from the admin\'s "Providers" screen before running this agent.',
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
async function skillInstructionsFor(skills, names) {
|
|
95
|
+
if (names === undefined || names.length === 0)
|
|
96
|
+
return '';
|
|
97
|
+
const all = await skills.list();
|
|
98
|
+
const byId = new Map(all.map((skill) => [skill.id, skill]));
|
|
99
|
+
const blocks = names
|
|
100
|
+
.map((id) => byId.get(id))
|
|
101
|
+
.filter((skill) => skill !== undefined)
|
|
102
|
+
.map((skill) => `### ${skill.name}\n${skill.instructions}`);
|
|
103
|
+
if (blocks.length === 0)
|
|
104
|
+
return '';
|
|
105
|
+
return `\n\nAvailable skills:\n${blocks.join('\n\n')}`;
|
|
106
|
+
}
|
|
107
|
+
export function createAgentRunner(options) {
|
|
108
|
+
const now = options.now ?? Date.now;
|
|
109
|
+
const budgetTrackers = new Map();
|
|
110
|
+
function budgetTrackerFor(agent) {
|
|
111
|
+
const existing = budgetTrackers.get(agent.name);
|
|
112
|
+
if (existing !== undefined)
|
|
113
|
+
return existing;
|
|
114
|
+
const tracker = options.budgetTrackerFor?.(agent) ?? createBudgetTracker({ limits: agent.budget ?? {} });
|
|
115
|
+
budgetTrackers.set(agent.name, tracker);
|
|
116
|
+
return tracker;
|
|
117
|
+
}
|
|
118
|
+
function actorFor(agentName) {
|
|
119
|
+
// Full role, bounded not by the actor's own roles but by the manifest
|
|
120
|
+
// itself (buildManifest only ever exposes the tools this agent's own
|
|
121
|
+
// `tools` list names) — R4's real gate is what got into the manifest,
|
|
122
|
+
// not what role string rides along with the call.
|
|
123
|
+
return { id: `agent:${agentName}`, roles: ['admin', 'agent'] };
|
|
124
|
+
}
|
|
125
|
+
async function buildToolsFor(agent) {
|
|
126
|
+
const context = {
|
|
127
|
+
site: toolSiteOf(options.site),
|
|
128
|
+
actor: actorFor(agent.name),
|
|
129
|
+
logger: silentLogger,
|
|
130
|
+
};
|
|
131
|
+
const own = buildManifest(options.tools, agent.tools, context);
|
|
132
|
+
const delegates = [];
|
|
133
|
+
for (const subagentName of agent.subagents ?? []) {
|
|
134
|
+
const subagent = await options.agents.get(subagentName);
|
|
135
|
+
if (subagent === undefined)
|
|
136
|
+
continue; // validated at declaration time; a since-removed name is skipped rather than crashing a run
|
|
137
|
+
const subContext = {
|
|
138
|
+
site: toolSiteOf(options.site),
|
|
139
|
+
actor: actorFor(subagent.name),
|
|
140
|
+
logger: silentLogger,
|
|
141
|
+
};
|
|
142
|
+
// The sub-agent's own tool calls (made inside its own `runAgentLoop`,
|
|
143
|
+
// via `createAgentDelegateTool`) are gated and journalled exactly like
|
|
144
|
+
// the parent's — its own autonomy config, its own name in the audit
|
|
145
|
+
// trail — never a bare pass-through just because they were reached one
|
|
146
|
+
// hop away from the top-level run.
|
|
147
|
+
const subTools = withAuditForManifest(withAutonomyForManifest(buildManifest(options.tools, subagent.tools, subContext), {
|
|
148
|
+
agentName: subagent.name,
|
|
149
|
+
autonomy: subagent.autonomy ?? { default: 'observe' },
|
|
150
|
+
approvalQueue: options.approvalQueue,
|
|
151
|
+
}), {
|
|
152
|
+
auditLog: options.auditLog,
|
|
153
|
+
agentName: subagent.name,
|
|
154
|
+
actor: actorFor(subagent.name),
|
|
155
|
+
...(subagent.autonomy?.default === undefined
|
|
156
|
+
? {}
|
|
157
|
+
: { autonomyLevel: subagent.autonomy.default }),
|
|
158
|
+
});
|
|
159
|
+
let subClient;
|
|
160
|
+
try {
|
|
161
|
+
subClient = resolveProvider(subagent.name, subagent.model, options.providers);
|
|
162
|
+
}
|
|
163
|
+
catch {
|
|
164
|
+
continue; // no provider for the sub-agent: it simply is not offered as a delegate tool this run (R2)
|
|
165
|
+
}
|
|
166
|
+
const identity = await options.agents.readIdentity(subagent.name);
|
|
167
|
+
const { system } = assembleContext({
|
|
168
|
+
site: siteContextOf(options.site),
|
|
169
|
+
agent: { name: subagent.name, ...identity },
|
|
170
|
+
task: { instruction: 'Carry out whatever task the parent agent delegates to you.' },
|
|
171
|
+
});
|
|
172
|
+
const delegateDefinition = createAgentDelegateTool({
|
|
173
|
+
subagentName: subagent.name,
|
|
174
|
+
client: subClient,
|
|
175
|
+
tools: subTools,
|
|
176
|
+
system,
|
|
177
|
+
});
|
|
178
|
+
// `createAgentDelegateTool` returns a contract-C `ToolDefinition`, the
|
|
179
|
+
// same shape every other core tool does — `buildManifest` is the one
|
|
180
|
+
// place that already knows how to turn one into the `ExecutableTool`
|
|
181
|
+
// the loop calls, so it is reused here for a one-tool "registry"
|
|
182
|
+
// rather than duplicating that conversion.
|
|
183
|
+
const [delegateExecutable] = buildManifest(createToolRegistry([delegateDefinition]), [delegateDefinition.name], context);
|
|
184
|
+
if (delegateExecutable !== undefined)
|
|
185
|
+
delegates.push(delegateExecutable);
|
|
186
|
+
}
|
|
187
|
+
return [...own, ...delegates];
|
|
188
|
+
}
|
|
189
|
+
return {
|
|
190
|
+
async run(name, runOptions) {
|
|
191
|
+
const agent = await options.agents.get(name);
|
|
192
|
+
if (agent === undefined)
|
|
193
|
+
throw agentUnknown(name);
|
|
194
|
+
if (!agent.enabled || options.killSwitchFor(name).isActive())
|
|
195
|
+
throw agentDisabled(name);
|
|
196
|
+
// Resolved and possibly thrown (AGENT_NO_PROVIDER) *before* any tool is
|
|
197
|
+
// built or any message assembled — the R2 guarantee this module exists
|
|
198
|
+
// to keep: no provider configured means no network call, full stop.
|
|
199
|
+
const client = resolveProvider(agent.name, agent.model, options.providers);
|
|
200
|
+
const tools = withAuditForManifest(withAutonomyForManifest(await buildToolsFor(agent), {
|
|
201
|
+
agentName: agent.name,
|
|
202
|
+
autonomy: agent.autonomy ?? { default: 'observe' },
|
|
203
|
+
approvalQueue: options.approvalQueue,
|
|
204
|
+
}), {
|
|
205
|
+
auditLog: options.auditLog,
|
|
206
|
+
agentName: agent.name,
|
|
207
|
+
actor: actorFor(agent.name),
|
|
208
|
+
model: client.model,
|
|
209
|
+
...(agent.autonomy?.default === undefined
|
|
210
|
+
? {}
|
|
211
|
+
: { autonomyLevel: agent.autonomy.default }),
|
|
212
|
+
});
|
|
213
|
+
const identity = await options.agents.readIdentity(agent.name);
|
|
214
|
+
const skillsText = await skillInstructionsFor(options.skills, agent.skills);
|
|
215
|
+
const { system, dataMessages } = assembleContext({
|
|
216
|
+
site: siteContextOf(options.site),
|
|
217
|
+
agent: { name: agent.name, ...identity },
|
|
218
|
+
task: { instruction: `${runOptions.instruction}${skillsText}` },
|
|
219
|
+
});
|
|
220
|
+
const startedAt = now();
|
|
221
|
+
let result;
|
|
222
|
+
try {
|
|
223
|
+
result = await runAgentLoop({
|
|
224
|
+
client,
|
|
225
|
+
system,
|
|
226
|
+
messages: [
|
|
227
|
+
...dataMessages,
|
|
228
|
+
...(runOptions.history ?? []),
|
|
229
|
+
{ role: 'user', content: 'Carry out the TASK described in your system context.' },
|
|
230
|
+
],
|
|
231
|
+
tools,
|
|
232
|
+
...(runOptions.maxTokens === undefined ? {} : { maxTokens: runOptions.maxTokens }),
|
|
233
|
+
budget: budgetTrackerFor(agent),
|
|
234
|
+
killSwitch: options.killSwitchFor(agent.name),
|
|
235
|
+
...(runOptions.signal === undefined ? {} : { signal: runOptions.signal }),
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
catch (error) {
|
|
239
|
+
await recordRun(options.auditLog, agent.name, runOptions.trigger, {
|
|
240
|
+
ok: false,
|
|
241
|
+
error: error instanceof Error ? error.message : String(error),
|
|
242
|
+
durationMs: now() - startedAt,
|
|
243
|
+
});
|
|
244
|
+
throw error;
|
|
245
|
+
}
|
|
246
|
+
await recordRun(options.auditLog, agent.name, runOptions.trigger, {
|
|
247
|
+
ok: true,
|
|
248
|
+
stopReason: result.stopReason,
|
|
249
|
+
steps: result.steps.length,
|
|
250
|
+
usage: result.usage,
|
|
251
|
+
durationMs: now() - startedAt,
|
|
252
|
+
});
|
|
253
|
+
return {
|
|
254
|
+
agent: agent.name,
|
|
255
|
+
stopReason: result.stopReason,
|
|
256
|
+
finalText: result.finalText,
|
|
257
|
+
steps: result.steps.length,
|
|
258
|
+
usage: result.usage,
|
|
259
|
+
toolCalls: result.steps.flatMap((step) => step.toolOutcomes.map((outcome) => ({
|
|
260
|
+
name: outcome.call.name,
|
|
261
|
+
input: outcome.call.input,
|
|
262
|
+
}))),
|
|
263
|
+
};
|
|
264
|
+
},
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
const silentLogger = {
|
|
268
|
+
info: () => undefined,
|
|
269
|
+
warn: () => undefined,
|
|
270
|
+
error: () => undefined,
|
|
271
|
+
};
|
|
272
|
+
async function recordRun(auditLog, agentName, trigger, diff) {
|
|
273
|
+
try {
|
|
274
|
+
await auditLog.record({
|
|
275
|
+
actorId: `agent:${agentName}`,
|
|
276
|
+
actorRoles: ['agent'],
|
|
277
|
+
action: 'agent.run',
|
|
278
|
+
diff: { agent: agentName, trigger: trigger ?? 'manual', ...diff },
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
catch {
|
|
282
|
+
// ADR-0018: a write that fails must never fail the action it is auditing.
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
//# sourceMappingURL=orchestrator.js.map
|