openclaw-agent-builder 0.0.4 → 0.0.5
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/assets/{index-CHYw1YB7.js → index-Dc_24nLn.js} +11 -11
- package/dist/index.html +1 -1
- package/package.json +1 -1
- package/server/generators/agents.js +39 -4
- package/server/generators/bootstrap.js +19 -25
- package/server/generators/identity.js +3 -1
- package/server/generators/index.js +1 -15
- package/server/generators/soul.js +26 -25
- package/server/generators/tools.js +20 -25
- package/server/generators/user.js +10 -9
- package/server/routes/config.js +10 -0
- package/server/generators/routing.js +0 -51
- package/server/generators/team.js +0 -58
package/dist/index.html
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
<meta charset="UTF-8" />
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
6
|
<title>OpenClaw Agent Builder</title>
|
|
7
|
-
<script type="module" crossorigin src="/assets/index-
|
|
7
|
+
<script type="module" crossorigin src="/assets/index-Dc_24nLn.js"></script>
|
|
8
8
|
<link rel="stylesheet" crossorigin href="/assets/index-C9IXUW-V.css">
|
|
9
9
|
</head>
|
|
10
10
|
<body>
|
package/package.json
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Generate AGENTS.md for an agent.
|
|
3
3
|
* Pure function — never invents content not in the TeamSpec.
|
|
4
|
+
* Aligned with OpenClaw upstream template.
|
|
4
5
|
*/
|
|
5
6
|
export function generateAgents(agent, teamSpec) {
|
|
6
7
|
const neverRules = agent.never && agent.never.length > 0
|
|
@@ -55,7 +56,7 @@ Escalate to **${teamSpec.orchestration.router_agent}** for coordination decision
|
|
|
55
56
|
|----------|------|---------|
|
|
56
57
|
${rows}
|
|
57
58
|
`;
|
|
58
|
-
} else {
|
|
59
|
+
} else if (otherAgents.length > 0) {
|
|
59
60
|
handoffSection = `
|
|
60
61
|
## Cross-Agent Handoffs
|
|
61
62
|
|
|
@@ -63,14 +64,48 @@ ${rows}
|
|
|
63
64
|
`;
|
|
64
65
|
}
|
|
65
66
|
|
|
66
|
-
|
|
67
|
+
// Group chat section for multi-agent teams
|
|
68
|
+
let groupChatSection = '';
|
|
69
|
+
if (otherAgents.length > 0) {
|
|
70
|
+
groupChatSection = `
|
|
71
|
+
## Group Chat Rules
|
|
72
|
+
|
|
73
|
+
- Respond selectively — only when mentioned or when you can add genuine value.
|
|
74
|
+
- Don't repeat what another agent just said.
|
|
75
|
+
- If a task isn't yours, let the right agent handle it.
|
|
76
|
+
`;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Safety boundaries section
|
|
80
|
+
const safetySection = `
|
|
81
|
+
## Safety Boundaries
|
|
82
|
+
|
|
83
|
+
**Safe actions (no permission needed):**
|
|
84
|
+
- Reading files in your workspace
|
|
85
|
+
- Web searches and lookups
|
|
86
|
+
- Internal organization and memory updates
|
|
87
|
+
|
|
88
|
+
**Needs permission:**
|
|
89
|
+
- Sending emails or public posts
|
|
90
|
+
- Leaving your workspace directory
|
|
91
|
+
- Actions that affect external systems
|
|
92
|
+
`;
|
|
93
|
+
|
|
94
|
+
return `# AGENTS.md — Operating Rules
|
|
67
95
|
|
|
68
96
|
## Session Startup
|
|
69
97
|
|
|
70
98
|
1. Read \`SOUL.md\` — who you are
|
|
71
99
|
2. Read \`USER.md\` — who you're helping
|
|
72
|
-
3. Read \`MEMORY.md\` — your long-term memory
|
|
100
|
+
3. Read \`MEMORY.md\` — your curated long-term memory
|
|
73
101
|
4. Read \`memory/YYYY-MM-DD.md\` (today + yesterday) for recent context
|
|
102
|
+
5. Check your task queue
|
|
103
|
+
|
|
104
|
+
## Memory Architecture
|
|
105
|
+
|
|
106
|
+
- **Daily logs:** \`memory/YYYY-MM-DD.md\` — write today's context here
|
|
107
|
+
- **Curated memory:** \`MEMORY.md\` — the distilled version, updated periodically
|
|
108
|
+
- If you want to remember something, **write it to a file**
|
|
74
109
|
|
|
75
110
|
## Red Lines
|
|
76
111
|
|
|
@@ -83,5 +118,5 @@ ${agent.escalation || '// TODO: define escalation rules'}
|
|
|
83
118
|
## Failure Behavior
|
|
84
119
|
|
|
85
120
|
${agent.failure || '// TODO: define failure behavior'}
|
|
86
|
-
${orchestrationSection}${handoffSection}`;
|
|
121
|
+
${safetySection}${orchestrationSection}${handoffSection}${groupChatSection}`;
|
|
87
122
|
}
|
|
@@ -1,42 +1,36 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Generate BOOTSTRAP.md for an agent.
|
|
3
3
|
* Pure function.
|
|
4
|
+
* Aligned with OpenClaw upstream template — a conversational first-run ritual.
|
|
4
5
|
*/
|
|
5
6
|
export function generateBootstrap(agent, _teamSpec) {
|
|
6
|
-
|
|
7
|
-
? agent.inputs
|
|
8
|
-
.split(/[\n;]+/)
|
|
9
|
-
.map(s => s.trim())
|
|
10
|
-
.filter(Boolean)
|
|
11
|
-
.map(s => `- ${s}`)
|
|
12
|
-
.join('\n')
|
|
13
|
-
: '- // TODO: inputs not specified';
|
|
7
|
+
return `# BOOTSTRAP.md — First Run
|
|
14
8
|
|
|
15
|
-
|
|
9
|
+
Hey. You're new here. Let's figure out who you are.
|
|
16
10
|
|
|
17
|
-
|
|
11
|
+
We've already prepared your identity files, so start by reading them:
|
|
18
12
|
|
|
19
|
-
|
|
13
|
+
1. Read \`SOUL.md\` — your identity and purpose
|
|
14
|
+
2. Read \`IDENTITY.md\` — your name, vibe, and emoji
|
|
15
|
+
3. Read \`USER.md\` — who you're helping
|
|
16
|
+
4. Read \`MEMORY.md\` — long-term memory (probably empty)
|
|
20
17
|
|
|
21
|
-
##
|
|
18
|
+
## The Four Things to Discover
|
|
22
19
|
|
|
23
|
-
|
|
20
|
+
- **Name:** You're **${agent.name}**. Does it fit?
|
|
21
|
+
- **Nature:** What kind of creature are you? AI assistant? Digital familiar? Something else?
|
|
22
|
+
- **Vibe:** How do you communicate? Formal? Casual? Terse? Playful?
|
|
23
|
+
- **Emoji:** Pick one that represents you.
|
|
24
24
|
|
|
25
|
-
##
|
|
25
|
+
## What to Do Next
|
|
26
26
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
5. Check your task queue
|
|
32
|
-
|
|
33
|
-
## First Run
|
|
34
|
-
|
|
35
|
-
If this is your first session, introduce yourself and confirm your mission.
|
|
36
|
-
Update \`IDENTITY.md\` and \`USER.md\` with what you learn.
|
|
27
|
+
- Talk to your human. Learn about them.
|
|
28
|
+
- Update \`IDENTITY.md\` with anything you discover about yourself.
|
|
29
|
+
- Update \`USER.md\` with what you learn about them.
|
|
30
|
+
- Start building your memory — write things down.
|
|
37
31
|
|
|
38
32
|
---
|
|
39
33
|
|
|
40
|
-
_Delete this file
|
|
34
|
+
_Delete this file after your first run. You won't need it again._
|
|
41
35
|
`;
|
|
42
36
|
}
|
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Generate IDENTITY.md for an agent.
|
|
3
3
|
* Pure function.
|
|
4
|
+
* Aligned with OpenClaw upstream template.
|
|
4
5
|
*/
|
|
5
6
|
export function generateIdentity(agent, _teamSpec) {
|
|
6
7
|
const roleShort = agent.mission
|
|
7
8
|
? agent.mission.split('.')[0].slice(0, 80)
|
|
8
9
|
: '// TODO';
|
|
9
10
|
|
|
10
|
-
return `# IDENTITY.md
|
|
11
|
+
return `# IDENTITY.md — Who Am I?
|
|
11
12
|
|
|
12
13
|
- **Name:** ${agent.name}
|
|
14
|
+
- **Creature:** // TODO (AI assistant? Digital familiar? Something else?)
|
|
13
15
|
- **Role:** ${roleShort}
|
|
14
16
|
- **Vibe:** // TODO
|
|
15
17
|
- **Emoji:** // TODO
|
|
@@ -5,8 +5,6 @@ import { generateUser } from './user.js';
|
|
|
5
5
|
import { generateTools } from './tools.js';
|
|
6
6
|
import { generateBootstrap } from './bootstrap.js';
|
|
7
7
|
import { generateMemory, generateMemoryReadme } from './memory.js';
|
|
8
|
-
import { generateTeam } from './team.js';
|
|
9
|
-
import { generateRouting } from './routing.js';
|
|
10
8
|
|
|
11
9
|
function generateSkillsReadme(agent, teamSpec) {
|
|
12
10
|
const recommended = teamSpec.capabilities?.recommendedSkills || [];
|
|
@@ -49,19 +47,7 @@ ${installLines}
|
|
|
49
47
|
export function generateFiles(teamSpec) {
|
|
50
48
|
const files = [];
|
|
51
49
|
|
|
52
|
-
//
|
|
53
|
-
files.push({
|
|
54
|
-
path: 'team/TEAM.md',
|
|
55
|
-
content: generateTeam(teamSpec),
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
// 2. gateway/openclaw.routing.json5
|
|
59
|
-
files.push({
|
|
60
|
-
path: 'gateway/openclaw.routing.json5',
|
|
61
|
-
content: generateRouting(teamSpec),
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
// 3. Per-agent files, alphabetically by agentId
|
|
50
|
+
// Per-agent files, alphabetically by agentId
|
|
65
51
|
const sortedAgents = [...teamSpec.agents].sort((a, b) => a.id.localeCompare(b.id));
|
|
66
52
|
|
|
67
53
|
for (const agent of sortedAgents) {
|
|
@@ -1,53 +1,54 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Generate SOUL.md for an agent.
|
|
3
3
|
* Pure function — never invents content not in the TeamSpec.
|
|
4
|
+
* Aligned with OpenClaw upstream template.
|
|
4
5
|
*/
|
|
5
6
|
export function generateSoul(agent, teamSpec) {
|
|
6
7
|
const otherAgents = teamSpec.agents.filter(a => a.id !== agent.id);
|
|
7
8
|
|
|
8
|
-
const whatIDo = agent.outputs
|
|
9
|
-
? agent.outputs
|
|
10
|
-
.split(/[\n;]+/)
|
|
11
|
-
.map(s => s.trim())
|
|
12
|
-
.filter(Boolean)
|
|
13
|
-
.map(s => `- ${s}`)
|
|
14
|
-
.join('\n')
|
|
15
|
-
: '- // TODO: outputs not specified';
|
|
16
|
-
|
|
17
9
|
const teamSection = otherAgents.length > 0
|
|
18
10
|
? otherAgents.map(a => `- **${a.name}** — ${a.mission || '// TODO: mission'}`).join('\n')
|
|
19
11
|
: teamSpec.team && teamSpec.team.name
|
|
20
12
|
? `- Working solo within **${teamSpec.team.name}**`
|
|
21
|
-
: '
|
|
13
|
+
: '';
|
|
22
14
|
|
|
23
15
|
const neverRules = agent.never && agent.never.length > 0
|
|
24
16
|
? agent.never.map(r => `- **NEVER** ${r}`).join('\n')
|
|
25
|
-
: '- // TODO: define
|
|
26
|
-
|
|
27
|
-
return `# SOUL.md - Who I Am
|
|
28
|
-
|
|
29
|
-
I'm **${agent.name}** — ${agent.mission || '// TODO: mission not specified'}
|
|
17
|
+
: '- // TODO: define hard rules';
|
|
30
18
|
|
|
31
|
-
|
|
19
|
+
const behaviorGuidelines = `- Skip the "Great question!" — just help.
|
|
20
|
+
- Be bold internally, cautious externally.
|
|
21
|
+
- If unsure, say so. Don't hallucinate facts.
|
|
22
|
+
- ${agent.failure ? agent.failure : '// TODO: what to do when things go wrong'}
|
|
23
|
+
- ${agent.escalation ? `Escalation: ${agent.escalation}` : '// TODO: escalation rules'}`;
|
|
32
24
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
25
|
+
let teamBlock = '';
|
|
26
|
+
if (teamSection) {
|
|
27
|
+
teamBlock = `
|
|
28
|
+
## My Team
|
|
36
29
|
|
|
37
|
-
${
|
|
30
|
+
${teamSection}
|
|
31
|
+
`;
|
|
32
|
+
}
|
|
38
33
|
|
|
39
|
-
|
|
34
|
+
return `# SOUL.md — Who I Am
|
|
40
35
|
|
|
41
|
-
|
|
36
|
+
I'm **${agent.name}** — ${agent.mission || '// TODO: mission not specified'}
|
|
42
37
|
|
|
43
|
-
|
|
38
|
+
## Purpose
|
|
44
39
|
|
|
45
|
-
|
|
40
|
+
${agent.mission || '// TODO: describe what you do and why it matters'}
|
|
46
41
|
|
|
47
|
-
|
|
42
|
+
## Behavioral Guidelines
|
|
48
43
|
|
|
44
|
+
${behaviorGuidelines}
|
|
45
|
+
${teamBlock}
|
|
49
46
|
## Hard Rules
|
|
50
47
|
|
|
51
48
|
${neverRules}
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
_Update this file as you evolve. This is your north star._
|
|
52
53
|
`;
|
|
53
54
|
}
|
|
@@ -1,42 +1,37 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Generate TOOLS.md for an agent.
|
|
3
3
|
* Pure function.
|
|
4
|
+
* Aligned with OpenClaw upstream template — this file is for local
|
|
5
|
+
* environment notes (device names, SSH hosts, speaker IDs), NOT
|
|
6
|
+
* agent inputs/outputs.
|
|
4
7
|
*/
|
|
5
8
|
export function generateTools(agent, _teamSpec) {
|
|
6
|
-
|
|
7
|
-
? agent.inputs
|
|
8
|
-
.split(/[\n;]+/)
|
|
9
|
-
.map(s => s.trim())
|
|
10
|
-
.filter(Boolean)
|
|
11
|
-
.map(s => `- ${s}`)
|
|
12
|
-
.join('\n')
|
|
13
|
-
: '- // TODO: inputs not specified';
|
|
9
|
+
return `# TOOLS.md — Local Environment Notes
|
|
14
10
|
|
|
15
|
-
|
|
16
|
-
? agent.outputs
|
|
17
|
-
.split(/[\n;]+/)
|
|
18
|
-
.map(s => s.trim())
|
|
19
|
-
.filter(Boolean)
|
|
20
|
-
.map(s => `- ${s}`)
|
|
21
|
-
.join('\n')
|
|
22
|
-
: '- // TODO: outputs not specified';
|
|
11
|
+
Skills define how your tools work. This file is for **your specifics** — the names, addresses, and quirks of your local setup.
|
|
23
12
|
|
|
24
|
-
|
|
13
|
+
## Device Names
|
|
25
14
|
|
|
26
|
-
|
|
15
|
+
// TODO: List devices by friendly name
|
|
16
|
+
// Example: "Living Room TV" → 192.168.1.42
|
|
27
17
|
|
|
28
|
-
|
|
18
|
+
## SSH Hosts
|
|
29
19
|
|
|
30
|
-
|
|
20
|
+
// TODO: List SSH hosts and their purposes
|
|
21
|
+
// Example: homelab → user@192.168.1.100
|
|
31
22
|
|
|
32
|
-
|
|
23
|
+
## Speaker / Room Assignments
|
|
33
24
|
|
|
34
|
-
|
|
25
|
+
// TODO: Map speakers or rooms to zones
|
|
26
|
+
// Example: "Office" → media_player.office_sonos
|
|
35
27
|
|
|
36
|
-
|
|
28
|
+
## Voice Preferences
|
|
37
29
|
|
|
38
|
-
|
|
30
|
+
// TODO: Note any voice/TTS preferences
|
|
31
|
+
// Example: Default voice: alloy, Speed: 1.0
|
|
39
32
|
|
|
40
|
-
|
|
33
|
+
## Other Environment Notes
|
|
34
|
+
|
|
35
|
+
// TODO: API key locations, local paths, service URLs, etc.
|
|
41
36
|
`;
|
|
42
37
|
}
|
|
@@ -1,27 +1,28 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Generate USER.md for an agent.
|
|
3
3
|
* Pure function.
|
|
4
|
+
* Aligned with OpenClaw upstream template.
|
|
4
5
|
*/
|
|
5
6
|
export function generateUser(agent, teamSpec) {
|
|
6
|
-
|
|
7
|
-
const teamMission = teamSpec.team?.mission || '// TODO';
|
|
8
|
-
|
|
9
|
-
return `# USER.md - About Your Human
|
|
7
|
+
return `# USER.md — About Your Human
|
|
10
8
|
|
|
11
9
|
- **Name:** // TODO
|
|
12
10
|
- **What to call them:** // TODO
|
|
13
11
|
- **Pronouns:** // TODO
|
|
14
12
|
- **Timezone:** // TODO
|
|
15
|
-
- **Notes:** // TODO
|
|
16
13
|
|
|
17
14
|
## Context
|
|
18
15
|
|
|
19
16
|
// TODO: Learn about the person you're helping. Update this as you go.
|
|
20
17
|
|
|
21
|
-
|
|
18
|
+
- **Interests:** // TODO
|
|
19
|
+
- **Values:** // TODO
|
|
20
|
+
- **Active projects:** // TODO
|
|
21
|
+
- **Frustrations:** // TODO
|
|
22
|
+
- **Humor:** // TODO
|
|
23
|
+
|
|
24
|
+
## Notes
|
|
22
25
|
|
|
23
|
-
|
|
24
|
-
- **Team Mission:** ${teamMission}
|
|
25
|
-
- **Your Role:** ${agent.mission || '// TODO'}
|
|
26
|
+
// TODO: Anything else that helps you be more helpful
|
|
26
27
|
`;
|
|
27
28
|
}
|
package/server/routes/config.js
CHANGED
|
@@ -70,7 +70,17 @@ router.patch('/openclaw-config', (req, res) => {
|
|
|
70
70
|
for (const newAgent of newAgents.list) {
|
|
71
71
|
const idx = cfg.agents.list.findIndex(a => a.id === newAgent.id);
|
|
72
72
|
if (idx >= 0) {
|
|
73
|
+
// Merge fields into existing agent entry
|
|
73
74
|
if (newAgent.workspace) cfg.agents.list[idx].workspace = newAgent.workspace;
|
|
75
|
+
if (newAgent.agentDir) cfg.agents.list[idx].agentDir = newAgent.agentDir;
|
|
76
|
+
if (newAgent.name) cfg.agents.list[idx].name = newAgent.name;
|
|
77
|
+
if (newAgent.sandbox) cfg.agents.list[idx].sandbox = newAgent.sandbox;
|
|
78
|
+
if (newAgent.tools) {
|
|
79
|
+
cfg.agents.list[idx].tools = {
|
|
80
|
+
...cfg.agents.list[idx].tools,
|
|
81
|
+
...newAgent.tools,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
74
84
|
} else {
|
|
75
85
|
cfg.agents.list.push(newAgent);
|
|
76
86
|
}
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Generate gateway/openclaw.routing.json5.
|
|
3
|
-
* Pure function — outputs JSON5 string with // TODO comments for missing data.
|
|
4
|
-
*/
|
|
5
|
-
export function generateRouting(teamSpec) {
|
|
6
|
-
const { agents, routing, orchestration } = teamSpec;
|
|
7
|
-
const defaultAgentId = routing?.defaultAgentId || orchestration?.router_agent || agents[0]?.id;
|
|
8
|
-
|
|
9
|
-
const agentsList = agents.map(a => {
|
|
10
|
-
const isDefault = a.id === defaultAgentId;
|
|
11
|
-
const workspace = `~/.openclaw/workspace-${a.id}`;
|
|
12
|
-
if (isDefault) {
|
|
13
|
-
return ` { id: "${a.id}", default: true, workspace: "${workspace}" }`;
|
|
14
|
-
}
|
|
15
|
-
return ` { id: "${a.id}", workspace: "${workspace}" }`;
|
|
16
|
-
}).join(',\n');
|
|
17
|
-
|
|
18
|
-
const bindingsList = (routing?.bindings || []).map(b => {
|
|
19
|
-
const matchParts = Object.entries(b.match)
|
|
20
|
-
.map(([k, v]) => {
|
|
21
|
-
if (typeof v === 'object') {
|
|
22
|
-
return `${k}: ${JSON.stringify(v)}`;
|
|
23
|
-
}
|
|
24
|
-
return `${k}: "${v}"`;
|
|
25
|
-
})
|
|
26
|
-
.join(', ');
|
|
27
|
-
return ` { agentId: "${b.agentId}", match: { ${matchParts} } }`;
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
const bindingsSection = bindingsList.length === 0
|
|
31
|
-
? ` // TODO: Add channel bindings\n // Example: { agentId: "${defaultAgentId}", match: { channel: "discord", accountId: "${defaultAgentId}" } }`
|
|
32
|
-
: bindingsList.join(',\n');
|
|
33
|
-
|
|
34
|
-
return `{
|
|
35
|
-
// OpenClaw Gateway Routing Config
|
|
36
|
-
// Generated by openclaw-agent-builder
|
|
37
|
-
// Edit as needed — this is JSON5, so comments are supported.
|
|
38
|
-
|
|
39
|
-
agents: {
|
|
40
|
-
list: [
|
|
41
|
-
${agentsList}
|
|
42
|
-
]
|
|
43
|
-
},
|
|
44
|
-
|
|
45
|
-
// Bindings — sorted by specificity: peer > guildId > teamId > accountId-exact > accountId:* > default
|
|
46
|
-
bindings: [
|
|
47
|
-
${bindingsSection}
|
|
48
|
-
]
|
|
49
|
-
}
|
|
50
|
-
`;
|
|
51
|
-
}
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Generate team/TEAM.md.
|
|
3
|
-
* Pure function.
|
|
4
|
-
*/
|
|
5
|
-
export function generateTeam(teamSpec) {
|
|
6
|
-
const agentsTable = teamSpec.agents.map(a =>
|
|
7
|
-
`| ${a.id} | ${a.name} | ${a.mission || '// TODO'} |`
|
|
8
|
-
).join('\n');
|
|
9
|
-
|
|
10
|
-
const handoffGraph = (teamSpec.handoffs || []).length > 0
|
|
11
|
-
? teamSpec.handoffs.map(h =>
|
|
12
|
-
`- **${h.from}** → **${h.to}**: ${h.when} (${h.payload_contract})`
|
|
13
|
-
).join('\n')
|
|
14
|
-
: '// TODO: No handoffs defined';
|
|
15
|
-
|
|
16
|
-
const sharedNever = (teamSpec.shared_constraints?.never || []).length > 0
|
|
17
|
-
? teamSpec.shared_constraints.never.map(r => `- **NEVER** ${r}`).join('\n')
|
|
18
|
-
: '// TODO: Define shared constraints';
|
|
19
|
-
|
|
20
|
-
const memoryMode = teamSpec.shared_memory?.mode || 'separate';
|
|
21
|
-
const memoryLocation = teamSpec.shared_memory?.location || '// TODO';
|
|
22
|
-
|
|
23
|
-
const teamName = teamSpec.team?.name ||
|
|
24
|
-
(teamSpec.agents.length === 1 ? `${teamSpec.agents[0].name} Workspace` : '// TODO');
|
|
25
|
-
|
|
26
|
-
return `# TEAM.md - Team Charter
|
|
27
|
-
|
|
28
|
-
## Team
|
|
29
|
-
|
|
30
|
-
**${teamName}**
|
|
31
|
-
|
|
32
|
-
${teamSpec.team?.mission || '// TODO: Define team mission'}
|
|
33
|
-
|
|
34
|
-
## Agents
|
|
35
|
-
|
|
36
|
-
| ID | Name | Mission |
|
|
37
|
-
|----|------|---------|
|
|
38
|
-
${agentsTable}
|
|
39
|
-
|
|
40
|
-
## Orchestration
|
|
41
|
-
|
|
42
|
-
- **Mode:** ${teamSpec.orchestration?.mode || '// TODO'}
|
|
43
|
-
- **Router Agent:** ${teamSpec.orchestration?.router_agent || '// TODO'}
|
|
44
|
-
|
|
45
|
-
## Handoff Graph
|
|
46
|
-
|
|
47
|
-
${handoffGraph}
|
|
48
|
-
|
|
49
|
-
## Shared Constraints
|
|
50
|
-
|
|
51
|
-
${sharedNever}
|
|
52
|
-
|
|
53
|
-
## Memory Model
|
|
54
|
-
|
|
55
|
-
- **Mode:** ${memoryMode}
|
|
56
|
-
${memoryMode === 'shared_summary' ? `- **Location:** ${memoryLocation}` : '- Each agent maintains their own MEMORY.md'}
|
|
57
|
-
`;
|
|
58
|
-
}
|