create-bk-agent 0.21.2 → 0.22.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/README.md +2 -0
- package/dist/src/index.js +26 -1
- package/dist/src/prompts.js +39 -0
- package/dist/src/scaffold.js +57 -0
- package/package.json +1 -1
- package/templates/base/orchestrator/_common/.env.example +14 -0
- package/templates/base/orchestrator/_common/package.json +16 -0
- package/templates/base/orchestrator/blank/flows/.gitkeep +0 -0
- package/templates/base/orchestrator/blank/orchestrator.yaml +34 -0
- package/templates/base/orchestrator/blank/vault/lecciones/.gitkeep +0 -0
- package/templates/base/orchestrator/marketing/flows/articulo-blog.yaml +97 -0
- package/templates/base/orchestrator/marketing/flows/campana-leads.yaml +115 -0
- package/templates/base/orchestrator/marketing/orchestrator.yaml +92 -0
- package/templates/base/orchestrator/marketing/test-flow.mjs +205 -0
- package/templates/base/orchestrator/marketing/vault/audiencia/buyer-personas.md +87 -0
- package/templates/base/orchestrator/marketing/vault/canales/estrategia-canales.md +53 -0
- package/templates/base/orchestrator/marketing/vault/contenido/tipos-de-contenido.md +71 -0
- package/templates/base/orchestrator/marketing/vault/lecciones/.gitkeep +0 -0
- package/templates/base/orchestrator/marketing/vault/marca/tono-y-voz.md +49 -0
- package/templates/base/orchestrator/marketing/vault/metricas/kpis-y-benchmarks.md +72 -0
- package/templates/base/orchestrator/marketing/vault/procesos/calendario-editorial.md +65 -0
- package/templates/base/orchestrator/soporte/flows/atencion-ticket.yaml +159 -0
- package/templates/base/orchestrator/soporte/flows/incidente-critico.yaml +218 -0
- package/templates/base/orchestrator/soporte/orchestrator.yaml +98 -0
- package/templates/base/orchestrator/soporte/test-flow.mjs +210 -0
- package/templates/base/orchestrator/soporte/vault/comunicacion/plantillas.md +211 -0
- package/templates/base/orchestrator/soporte/vault/lecciones/.gitkeep +0 -0
- package/templates/base/orchestrator/soporte/vault/procesos/escalacion.md +106 -0
- package/templates/base/orchestrator/soporte/vault/procesos/manejo-de-tickets.md +101 -0
- package/templates/base/orchestrator/soporte/vault/productos/coberturas-de-soporte.md +94 -0
- package/templates/base/orchestrator/soporte/vault/sla/niveles-de-servicio.md +104 -0
- package/templates/base/orchestrator/ventas/flows/calificacion-lead.yaml +113 -0
- package/templates/base/orchestrator/ventas/flows/propuesta-comercial.yaml +179 -0
- package/templates/base/orchestrator/ventas/orchestrator.yaml +93 -0
- package/templates/base/orchestrator/ventas/test-flow.mjs +207 -0
- package/templates/base/orchestrator/ventas/vault/lecciones/.gitkeep +0 -0
- package/templates/base/orchestrator/ventas/vault/politicas/condiciones-comerciales.md +65 -0
- package/templates/base/orchestrator/ventas/vault/procesos/calificacion-bant.md +50 -0
- package/templates/base/orchestrator/ventas/vault/procesos/ciclo-venta.md +61 -0
- package/templates/base/orchestrator/ventas/vault/productos/catalogo-servicios.md +103 -0
- package/templates/base/orchestrator/ventas/vault/productos/pricing-policy.md +84 -0
package/README.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# create-bk-agent
|
|
2
2
|
|
|
3
|
+
> **Status: `stable`** — Maintained and production-ready. No new features during the pilot phase.
|
|
4
|
+
|
|
3
5
|
CLI scaffolding tool for the BackendKit Labs agent framework. Generates a fully configured TypeScript agent project in seconds — choose your architecture, deployment mode, and LLM provider, and get a working project with all dependencies wired.
|
|
4
6
|
|
|
5
7
|
## Usage
|
package/dist/src/index.js
CHANGED
|
@@ -58,6 +58,7 @@ function describeChoices(choices) {
|
|
|
58
58
|
autonomous: 'Autonomous daemon',
|
|
59
59
|
minimal: 'Minimal / embedded',
|
|
60
60
|
enterprise: 'Enterprise (local LLM + RAG)',
|
|
61
|
+
orchestrator: 'Orchestrator',
|
|
61
62
|
};
|
|
62
63
|
const deploy = {
|
|
63
64
|
repl: 'Terminal REPL',
|
|
@@ -68,6 +69,10 @@ function describeChoices(choices) {
|
|
|
68
69
|
web: 'Web Server (chat + kanban)',
|
|
69
70
|
};
|
|
70
71
|
const archLabel = arch[choices.architecture] ?? choices.architecture;
|
|
72
|
+
if (choices.architecture === 'orchestrator') {
|
|
73
|
+
const tmpl = choices.workflowTemplate ?? 'blank';
|
|
74
|
+
return `${archLabel} — ${tmpl} template`;
|
|
75
|
+
}
|
|
71
76
|
if (!choices.deployMode)
|
|
72
77
|
return archLabel;
|
|
73
78
|
return `${archLabel} — ${deploy[choices.deployMode] ?? choices.deployMode}`;
|
|
@@ -82,6 +87,23 @@ function buildNextSteps(choices) {
|
|
|
82
87
|
return ['Configure triggers in src/index.ts', 'npm run dev'];
|
|
83
88
|
if (arch === 'minimal')
|
|
84
89
|
return ['Implement your LLM provider in src/index.ts', 'npm run dev'];
|
|
90
|
+
// Orchestrator
|
|
91
|
+
if (arch === 'orchestrator') {
|
|
92
|
+
const tmpl = choices.workflowTemplate ?? 'blank';
|
|
93
|
+
const testCmd = tmpl === 'ventas'
|
|
94
|
+
? 'node test-flow.mjs calificacion-lead # or propuesta-comercial'
|
|
95
|
+
: tmpl === 'marketing'
|
|
96
|
+
? 'node test-flow.mjs articulo-blog # or campana-leads'
|
|
97
|
+
: tmpl === 'soporte'
|
|
98
|
+
? 'node test-flow.mjs atencion-ticket # or incidente-critico'
|
|
99
|
+
: '# Define your flows in flows/ and run: node test-flow.mjs';
|
|
100
|
+
return [
|
|
101
|
+
'Add your API key to .env',
|
|
102
|
+
'Edit orchestrator.yaml to customize agents for your domain',
|
|
103
|
+
tmpl !== 'blank' ? 'Review and adapt vault/ knowledge files to your company' : 'Define your agents and flows in orchestrator.yaml',
|
|
104
|
+
testCmd,
|
|
105
|
+
];
|
|
106
|
+
}
|
|
85
107
|
// Enterprise — local LLM + RAG
|
|
86
108
|
if (arch === 'enterprise') {
|
|
87
109
|
if (mode === 'web') {
|
|
@@ -149,11 +171,14 @@ async function main(argv) {
|
|
|
149
171
|
console.log('Installing dependencies...\n');
|
|
150
172
|
(0, scaffold_1.installDeps)(targetDir);
|
|
151
173
|
const steps = buildNextSteps(choices);
|
|
174
|
+
const envLine = choices.architecture === 'orchestrator'
|
|
175
|
+
? ' # .env created — add your API key'
|
|
176
|
+
: ' cp .env.example .env # add your API key';
|
|
152
177
|
console.log(`
|
|
153
178
|
✅ Done! Your agent is ready.
|
|
154
179
|
|
|
155
180
|
cd ${choices.projectName}
|
|
156
|
-
|
|
181
|
+
${envLine}
|
|
157
182
|
${steps.map(s => ` ${s}`).join('\n')}
|
|
158
183
|
|
|
159
184
|
Documentation: https://github.com/BackendKit-labs/backendkit-agent-framework
|
package/dist/src/prompts.js
CHANGED
|
@@ -38,6 +38,11 @@ const ARCHITECTURE_CHOICES = [
|
|
|
38
38
|
value: 'enterprise',
|
|
39
39
|
description: 'Business agent with RAG over your company docs, runs 100% on-premise',
|
|
40
40
|
},
|
|
41
|
+
{
|
|
42
|
+
title: p('Orchestrator', 22) + 'Multi-step workflows with specialist agents and approval gates',
|
|
43
|
+
value: 'orchestrator',
|
|
44
|
+
description: 'Static flows triggered by task patterns + dynamic LLM planning as fallback',
|
|
45
|
+
},
|
|
41
46
|
];
|
|
42
47
|
const SKILL_PACK_CHOICES = [
|
|
43
48
|
{ title: p('Node.js / TypeScript', 24) + 'npm, jest, tsc, eslint', value: 'node' },
|
|
@@ -83,6 +88,29 @@ const PROVIDER_CHOICES = [
|
|
|
83
88
|
{ title: p('DeepSeek / OpenAI-compatible', 32) + 'deepseek-chat or any OpenAI-compatible endpoint', value: 'deepseek' },
|
|
84
89
|
{ title: p('Ollama (local)', 32) + 'llama3.2, codellama — no API key needed', value: 'ollama' },
|
|
85
90
|
];
|
|
91
|
+
// ── Workflow template choices (orchestrator only) ─────────────────────────────
|
|
92
|
+
const WORKFLOW_TEMPLATE_CHOICES = [
|
|
93
|
+
{
|
|
94
|
+
title: p('Ventas B2B', 22) + 'Lead qualification (BANT) + commercial proposal with approval gates',
|
|
95
|
+
value: 'ventas',
|
|
96
|
+
description: '6 agents: lead, proposal, pricing, legal, CRM, writer',
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
title: p('Marketing', 22) + 'Blog articles + lead gen campaigns with parallel steps',
|
|
100
|
+
value: 'marketing',
|
|
101
|
+
description: '6 agents: content strategist, copywriter, SEO, social, campaign, analytics',
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
title: p('Soporte al cliente', 22) + 'Ticket triage, L1/L2/L3 escalation and critical incident management',
|
|
105
|
+
value: 'soporte',
|
|
106
|
+
description: '6 agents: triage, support L1, technical L2, escalation L3, communication, knowledge',
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
title: p('Blank', 22) + 'Empty orchestrator.yaml — define your own agents and flows',
|
|
110
|
+
value: 'blank',
|
|
111
|
+
description: 'Start from scratch with a minimal config stub',
|
|
112
|
+
},
|
|
113
|
+
];
|
|
86
114
|
// ── Conditional question helpers ──────────────────────────────────────────────
|
|
87
115
|
const NEEDS_SKILLS = ['multi-agent', 'single'];
|
|
88
116
|
const NEEDS_DEPLOY = ['multi-agent', 'single', 'coding', 'enterprise'];
|
|
@@ -93,6 +121,8 @@ const whenSkills = (_prev, v) => NEEDS_SKILLS.includes(v.architecture) ? 'multis
|
|
|
93
121
|
const whenDeploy = (_prev, v) => NEEDS_DEPLOY.includes(v.architecture) ? 'select' : null;
|
|
94
122
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
95
123
|
const whenVault = (_prev, v) => v.architecture === 'enterprise' ? 'text' : null;
|
|
124
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
125
|
+
const whenWorkflowTemplate = (_prev, v) => v.architecture === 'orchestrator' ? 'select' : null;
|
|
96
126
|
// ── Main question flow ────────────────────────────────────────────────────────
|
|
97
127
|
async function askQuestions(defaultName) {
|
|
98
128
|
const raw = await (0, prompts_1.default)([
|
|
@@ -135,6 +165,14 @@ async function askQuestions(defaultName) {
|
|
|
135
165
|
initial: '',
|
|
136
166
|
validate: (v) => v.trim().length > 0 || 'Vault path is required for enterprise agents',
|
|
137
167
|
},
|
|
168
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
169
|
+
{
|
|
170
|
+
type: whenWorkflowTemplate,
|
|
171
|
+
name: 'workflowTemplate',
|
|
172
|
+
message: 'Workflow template:',
|
|
173
|
+
choices: WORKFLOW_TEMPLATE_CHOICES,
|
|
174
|
+
initial: 0,
|
|
175
|
+
},
|
|
138
176
|
{
|
|
139
177
|
type: 'select',
|
|
140
178
|
name: 'provider',
|
|
@@ -152,5 +190,6 @@ async function askQuestions(defaultName) {
|
|
|
152
190
|
deployMode: (raw.deployMode ?? undefined),
|
|
153
191
|
provider: raw.provider,
|
|
154
192
|
vaultPath: (raw.vaultPath ?? undefined),
|
|
193
|
+
workflowTemplate: (raw.workflowTemplate ?? undefined),
|
|
155
194
|
};
|
|
156
195
|
}
|
package/dist/src/scaffold.js
CHANGED
|
@@ -160,11 +160,68 @@ function injectSkillPack(targetDir, pack) {
|
|
|
160
160
|
].join('\n');
|
|
161
161
|
fs.appendFileSync(engineFile, block + '\n');
|
|
162
162
|
}
|
|
163
|
+
const ORCHESTRATOR_PROVIDERS = {
|
|
164
|
+
deepseek: { id: 'deepseek', keyVar: 'DEEPSEEK_API_KEY', model: 'deepseek-chat', baseUrl: 'https://api.deepseek.com/v1' },
|
|
165
|
+
anthropic: { id: 'anthropic', keyVar: 'ANTHROPIC_API_KEY', model: 'claude-sonnet-4-6' },
|
|
166
|
+
openai: { id: 'openai', keyVar: 'OPENAI_API_KEY', model: 'gpt-4o', baseUrl: 'https://api.openai.com/v1' },
|
|
167
|
+
ollama: { id: 'ollama', keyVar: '', model: 'llama3.2', baseUrl: 'http://localhost:11434' },
|
|
168
|
+
};
|
|
169
|
+
function buildProvidersBlock(provider) {
|
|
170
|
+
const p = ORCHESTRATOR_PROVIDERS[provider];
|
|
171
|
+
const lines = ['providers:', ` ${p.id}:`];
|
|
172
|
+
if (p.keyVar)
|
|
173
|
+
lines.push(` api_key: \${${p.keyVar}}`);
|
|
174
|
+
if (p.baseUrl)
|
|
175
|
+
lines.push(` base_url: ${p.baseUrl}`);
|
|
176
|
+
lines.push(` model: ${p.model}`);
|
|
177
|
+
return lines.join('\n');
|
|
178
|
+
}
|
|
179
|
+
function scaffoldOrchestrator(choices, targetDir) {
|
|
180
|
+
const orchDir = path.join(BASE_DIR, 'orchestrator');
|
|
181
|
+
const commonDir = path.join(orchDir, '_common');
|
|
182
|
+
const template = (choices.workflowTemplate ?? 'blank');
|
|
183
|
+
const tmplDir = path.join(orchDir, template);
|
|
184
|
+
// 1. Common files: package.json, .gitignore, .env.example
|
|
185
|
+
copyDir(commonDir, targetDir);
|
|
186
|
+
// 2. Template files: orchestrator.yaml, flows/, vault/, test-flow.mjs
|
|
187
|
+
copyDir(tmplDir, targetDir);
|
|
188
|
+
// 3. Patch orchestrator.yaml — replace __PROVIDER_ID__ and __PROVIDERS_BLOCK__
|
|
189
|
+
const orchYaml = path.join(targetDir, 'orchestrator.yaml');
|
|
190
|
+
if (fs.existsSync(orchYaml)) {
|
|
191
|
+
let content = fs.readFileSync(orchYaml, 'utf-8');
|
|
192
|
+
const providerId = ORCHESTRATOR_PROVIDERS[choices.provider].id;
|
|
193
|
+
const providersBlock = buildProvidersBlock(choices.provider);
|
|
194
|
+
content = content.replace(/__PROVIDER_ID__/g, providerId);
|
|
195
|
+
content = content.replace('__PROVIDERS_BLOCK__', providersBlock);
|
|
196
|
+
fs.writeFileSync(orchYaml, content);
|
|
197
|
+
}
|
|
198
|
+
// 4. Patch package.json name
|
|
199
|
+
const pkgPath = path.join(targetDir, 'package.json');
|
|
200
|
+
if (fs.existsSync(pkgPath)) {
|
|
201
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
|
|
202
|
+
pkg.name = choices.projectName;
|
|
203
|
+
fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + '\n');
|
|
204
|
+
}
|
|
205
|
+
// 5. Write .env from .env.example (inject active provider key)
|
|
206
|
+
const envExample = path.join(targetDir, '.env.example');
|
|
207
|
+
const envFile = path.join(targetDir, '.env');
|
|
208
|
+
if (fs.existsSync(envExample) && !fs.existsSync(envFile)) {
|
|
209
|
+
const p = ORCHESTRATOR_PROVIDERS[choices.provider];
|
|
210
|
+
const keyLine = p.keyVar
|
|
211
|
+
? `${p.keyVar}=your-api-key-here`
|
|
212
|
+
: `# No API key needed for Ollama\nOLLAMA_BASE_URL=${p.baseUrl}`;
|
|
213
|
+
fs.writeFileSync(envFile, `# Generated by create-bk-agent\n${keyLine}\n`);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
163
216
|
// ── Main scaffold ─────────────────────────────────────────────────────────────
|
|
164
217
|
function scaffold(choices, targetDir) {
|
|
165
218
|
if (fs.existsSync(targetDir)) {
|
|
166
219
|
throw new Error(`Directory already exists: ${targetDir}`);
|
|
167
220
|
}
|
|
221
|
+
if (choices.architecture === 'orchestrator') {
|
|
222
|
+
scaffoldOrchestrator(choices, targetDir);
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
168
225
|
const isLayered = LAYERED.includes(choices.architecture);
|
|
169
226
|
// 1. Base layer — always copied
|
|
170
227
|
const baseDir = path.join(BASE_DIR, choices.architecture);
|
package/package.json
CHANGED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Add your LLM provider API key
|
|
2
|
+
# Uncomment the one matching the provider in orchestrator.yaml
|
|
3
|
+
|
|
4
|
+
# DeepSeek (recommended — cost-effective reasoning)
|
|
5
|
+
DEEPSEEK_API_KEY=sk-...
|
|
6
|
+
|
|
7
|
+
# Anthropic Claude
|
|
8
|
+
# ANTHROPIC_API_KEY=sk-ant-...
|
|
9
|
+
|
|
10
|
+
# OpenAI
|
|
11
|
+
# OPENAI_API_KEY=sk-...
|
|
12
|
+
|
|
13
|
+
# Ollama (local — no API key needed)
|
|
14
|
+
# OLLAMA_BASE_URL=http://localhost:11434
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "my-orchestrator",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"start": "node node_modules/@backendkit-labs/orchestrator-agent/dist/server.js",
|
|
8
|
+
"test:flow": "node test-flow.mjs"
|
|
9
|
+
},
|
|
10
|
+
"dependencies": {
|
|
11
|
+
"@backendkit-labs/orchestrator-agent": "^0.2.3"
|
|
12
|
+
},
|
|
13
|
+
"engines": {
|
|
14
|
+
"node": ">=20.0.0"
|
|
15
|
+
}
|
|
16
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
version: 1
|
|
2
|
+
|
|
3
|
+
orchestrator:
|
|
4
|
+
name: "My Orchestrator"
|
|
5
|
+
provider: __PROVIDER_ID__
|
|
6
|
+
vault:
|
|
7
|
+
path: ./vault
|
|
8
|
+
embedder: simple # or "ollama" for semantic search (requires Ollama running)
|
|
9
|
+
|
|
10
|
+
__PROVIDERS_BLOCK__
|
|
11
|
+
|
|
12
|
+
# Optional: define static flows triggered by regex patterns on the task string.
|
|
13
|
+
# If no flow matches, the orchestrator plans steps dynamically using the LLM.
|
|
14
|
+
#
|
|
15
|
+
# flows:
|
|
16
|
+
# - id: my-flow
|
|
17
|
+
# file: ./flows/my-flow.yaml
|
|
18
|
+
# trigger: "keyword1|keyword2|phrase to match"
|
|
19
|
+
|
|
20
|
+
# Define your specialist agents below.
|
|
21
|
+
# Each agent = the same LLM called with a different system prompt.
|
|
22
|
+
# gate: true means the output requires human approval before the flow continues.
|
|
23
|
+
agents:
|
|
24
|
+
- id: my-agent
|
|
25
|
+
name: "My Specialist Agent"
|
|
26
|
+
description: >
|
|
27
|
+
Describe what this agent does and what tasks it handles.
|
|
28
|
+
Be specific — the orchestrator uses this description to decide
|
|
29
|
+
which agent to assign each step to.
|
|
30
|
+
capabilities: [list, your, keywords, here]
|
|
31
|
+
provider: __PROVIDER_ID__
|
|
32
|
+
# gate: true
|
|
33
|
+
# gate_criteria:
|
|
34
|
+
# - "Criterion that must be met before continuing"
|
|
File without changes
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
id: articulo-blog
|
|
2
|
+
name: "Creación de Artículo de Blog"
|
|
3
|
+
description: >
|
|
4
|
+
Pipeline completo para crear y distribuir un artículo de blog técnico.
|
|
5
|
+
Desde el brief estratégico hasta los posts de redes sociales para distribución.
|
|
6
|
+
|
|
7
|
+
steps:
|
|
8
|
+
- id: s1-brief
|
|
9
|
+
agent: content-strategist
|
|
10
|
+
task: |
|
|
11
|
+
Crear el brief editorial completo para el artículo de blog.
|
|
12
|
+
|
|
13
|
+
PARÁMETROS:
|
|
14
|
+
- Tema: {{payload.tema}}
|
|
15
|
+
- Objetivo: {{payload.objetivo}}
|
|
16
|
+
- Audiencia: {{payload.audiencia}}
|
|
17
|
+
- Keywords objetivo: {{payload.keywords}}
|
|
18
|
+
- Tono: {{payload.tono}}
|
|
19
|
+
|
|
20
|
+
El brief debe incluir:
|
|
21
|
+
1. Ángulo editorial y propuesta de valor única (por qué este artículo, por qué ahora)
|
|
22
|
+
2. Estructura sugerida con H2 y H3 (mínimo 6 secciones)
|
|
23
|
+
3. Buyer persona primario al que apunta y en qué etapa del funnel está
|
|
24
|
+
4. 3-5 puntos clave que el lector debe llevarse
|
|
25
|
+
5. Llamado a la acción recomendado al final del artículo
|
|
26
|
+
6. Longitud recomendada (palabras)
|
|
27
|
+
depends_on: []
|
|
28
|
+
|
|
29
|
+
- id: s2-redaccion
|
|
30
|
+
agent: copywriter
|
|
31
|
+
task: |
|
|
32
|
+
Redactar el artículo de blog completo siguiendo el brief estratégico.
|
|
33
|
+
|
|
34
|
+
BRIEF:
|
|
35
|
+
{{steps.s1-brief.output}}
|
|
36
|
+
|
|
37
|
+
PARÁMETROS ORIGINALES:
|
|
38
|
+
- Tema: {{payload.tema}}
|
|
39
|
+
- Tono: {{payload.tono}}
|
|
40
|
+
- Audiencia: {{payload.audiencia}}
|
|
41
|
+
|
|
42
|
+
Requisitos de redacción:
|
|
43
|
+
- Seguir exactamente la estructura del brief
|
|
44
|
+
- Incluir ejemplos concretos y datos cuando sea posible
|
|
45
|
+
- Párrafos cortos (máximo 3-4 líneas) para buena legibilidad web
|
|
46
|
+
- Incluir al menos 2 listas o tablas para scanabilidad
|
|
47
|
+
- CTA al final según lo indicado en el brief
|
|
48
|
+
- Incluir propuesta de título principal (H1) y subtítulo
|
|
49
|
+
depends_on: [s1-brief]
|
|
50
|
+
|
|
51
|
+
- id: s3-seo
|
|
52
|
+
agent: seo-agent
|
|
53
|
+
gate: true
|
|
54
|
+
task: |
|
|
55
|
+
Revisar y optimizar el artículo para SEO. Proponer mejoras específicas y concretas.
|
|
56
|
+
|
|
57
|
+
ARTÍCULO REDACTADO:
|
|
58
|
+
{{steps.s2-redaccion.output}}
|
|
59
|
+
|
|
60
|
+
KEYWORDS OBJETIVO: {{payload.keywords}}
|
|
61
|
+
|
|
62
|
+
Entregables:
|
|
63
|
+
1. Meta título (50-60 caracteres) con keyword principal
|
|
64
|
+
2. Meta descripción (140-160 caracteres) con CTA
|
|
65
|
+
3. Lista de mejoras SEO on-page con prioridad (alta/media/baja)
|
|
66
|
+
4. Sugerencias de internal linking
|
|
67
|
+
5. Densidad de keyword actual vs recomendada
|
|
68
|
+
6. Artículo revisado con las mejoras de alta prioridad aplicadas
|
|
69
|
+
depends_on: [s2-redaccion]
|
|
70
|
+
|
|
71
|
+
- id: s4-redes
|
|
72
|
+
agent: social-media-agent
|
|
73
|
+
task: |
|
|
74
|
+
Crear el plan de distribución en redes sociales para el artículo publicado.
|
|
75
|
+
|
|
76
|
+
ARTÍCULO (optimizado para SEO):
|
|
77
|
+
{{steps.s3-seo.output}}
|
|
78
|
+
|
|
79
|
+
TEMA: {{payload.tema}}
|
|
80
|
+
AUDIENCIA: {{payload.audiencia}}
|
|
81
|
+
|
|
82
|
+
Crear para cada plataforma:
|
|
83
|
+
|
|
84
|
+
LinkedIn (principal):
|
|
85
|
+
- Post de lanzamiento (hook poderoso + 3-5 insights + CTA)
|
|
86
|
+
- Post de seguimiento a los 7 días (punto de vista diferente del mismo tema)
|
|
87
|
+
- Formato: texto largo nativo, link en comentarios
|
|
88
|
+
|
|
89
|
+
Twitter/X:
|
|
90
|
+
- Hilo de 5-7 tweets con los puntos más destacados
|
|
91
|
+
- Tweet individual de impacto (el insight más potente)
|
|
92
|
+
|
|
93
|
+
Calendario sugerido:
|
|
94
|
+
- Día 0: LinkedIn lanzamiento + Twitter hilo
|
|
95
|
+
- Día 3: Twitter tweet individual
|
|
96
|
+
- Día 7: LinkedIn seguimiento
|
|
97
|
+
depends_on: [s3-seo]
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
id: campana-leads
|
|
2
|
+
name: "Campaña de Generación de Leads"
|
|
3
|
+
description: >
|
|
4
|
+
Diseño completo de una campaña de lead generation: estrategia, copies,
|
|
5
|
+
optimización SEO del contenido ancla, y definición de métricas y tracking.
|
|
6
|
+
|
|
7
|
+
steps:
|
|
8
|
+
- id: s1-estrategia
|
|
9
|
+
agent: campaign-agent
|
|
10
|
+
gate: true
|
|
11
|
+
task: |
|
|
12
|
+
Diseñar la estrategia completa de la campaña de lead generation.
|
|
13
|
+
|
|
14
|
+
PARÁMETROS DE LA CAMPAÑA:
|
|
15
|
+
- Servicio/producto a promocionar: {{payload.servicio}}
|
|
16
|
+
- Segmento objetivo: {{payload.segmento}}
|
|
17
|
+
- Objetivo de la campaña: {{payload.objetivo}}
|
|
18
|
+
- Presupuesto disponible: {{payload.presupuesto}}
|
|
19
|
+
- Duración: {{payload.duracion}}
|
|
20
|
+
- Canal principal: {{payload.canal}}
|
|
21
|
+
|
|
22
|
+
La estrategia debe incluir:
|
|
23
|
+
1. Objetivo SMART con número concreto de leads esperados
|
|
24
|
+
2. Segmento primario y secundario con criterios ICP detallados
|
|
25
|
+
3. Propuesta de valor central de la campaña (el "gancho")
|
|
26
|
+
4. Mapa de canales: qué rol juega cada canal
|
|
27
|
+
5. Contenido ancla propuesto (lead magnet, webinar, artículo, etc.)
|
|
28
|
+
6. Journey del lead: touchpoints desde el primer contacto hasta MQL
|
|
29
|
+
7. Presupuesto sugerido por canal
|
|
30
|
+
8. Cronograma de activación semana a semana
|
|
31
|
+
9. Hipótesis principal y cómo la validaremos
|
|
32
|
+
depends_on: []
|
|
33
|
+
|
|
34
|
+
- id: s2-copies
|
|
35
|
+
agent: copywriter
|
|
36
|
+
task: |
|
|
37
|
+
Redactar todos los copies necesarios para la campaña aprobada.
|
|
38
|
+
|
|
39
|
+
ESTRATEGIA DE CAMPAÑA:
|
|
40
|
+
{{steps.s1-estrategia.output}}
|
|
41
|
+
|
|
42
|
+
SERVICIO: {{payload.servicio}}
|
|
43
|
+
SEGMENTO: {{payload.segmento}}
|
|
44
|
+
|
|
45
|
+
Entregar copies para:
|
|
46
|
+
|
|
47
|
+
1. ANUNCIOS (LinkedIn Ads o Google Ads según canal definido):
|
|
48
|
+
- 3 variantes de headline (hasta 150 caracteres)
|
|
49
|
+
- 3 variantes de descripción (hasta 300 caracteres)
|
|
50
|
+
- 1 copy largo para sponsored content en LinkedIn
|
|
51
|
+
|
|
52
|
+
2. LANDING PAGE:
|
|
53
|
+
- Headline principal (H1)
|
|
54
|
+
- Subtítulo de soporte
|
|
55
|
+
- 3-5 bullets de propuesta de valor
|
|
56
|
+
- Copy del formulario
|
|
57
|
+
- CTA button copy (3 variantes)
|
|
58
|
+
|
|
59
|
+
3. EMAIL DE BIENVENIDA (post-conversión):
|
|
60
|
+
- Subject line (3 variantes)
|
|
61
|
+
- Preheader
|
|
62
|
+
- Cuerpo del email de bienvenida (300-400 palabras)
|
|
63
|
+
|
|
64
|
+
4. SECUENCIA DE NURTURING (3 emails):
|
|
65
|
+
- Email 2 (día 3): entregar valor, sin vender
|
|
66
|
+
- Email 3 (día 7): caso de uso relevante
|
|
67
|
+
- Email 4 (día 14): propuesta directa con CTA a reunión
|
|
68
|
+
depends_on: [s1-estrategia]
|
|
69
|
+
|
|
70
|
+
- id: s3-seo-contenido
|
|
71
|
+
agent: seo-agent
|
|
72
|
+
task: |
|
|
73
|
+
Optimizar el contenido ancla de la campaña para SEO orgánico.
|
|
74
|
+
|
|
75
|
+
ESTRATEGIA DE CAMPAÑA:
|
|
76
|
+
{{steps.s1-estrategia.output}}
|
|
77
|
+
|
|
78
|
+
SERVICIO: {{payload.servicio}}
|
|
79
|
+
SEGMENTO: {{payload.segmento}}
|
|
80
|
+
|
|
81
|
+
Entregar:
|
|
82
|
+
1. 5-10 keywords relacionadas ordenadas por prioridad
|
|
83
|
+
2. Estructura SEO para el contenido ancla
|
|
84
|
+
3. Meta título y meta descripción para la landing page
|
|
85
|
+
4. Recomendaciones de link building
|
|
86
|
+
5. Estimación de timeline para resultados orgánicos
|
|
87
|
+
depends_on: [s1-estrategia]
|
|
88
|
+
|
|
89
|
+
- id: s4-metricas
|
|
90
|
+
agent: analytics-agent
|
|
91
|
+
task: |
|
|
92
|
+
Definir el plan de medición completo para la campaña.
|
|
93
|
+
|
|
94
|
+
ESTRATEGIA APROBADA:
|
|
95
|
+
{{steps.s1-estrategia.output}}
|
|
96
|
+
|
|
97
|
+
COPIES CREADOS:
|
|
98
|
+
{{steps.s2-copies.output}}
|
|
99
|
+
|
|
100
|
+
SEO Y KEYWORDS:
|
|
101
|
+
{{steps.s3-seo-contenido.output}}
|
|
102
|
+
|
|
103
|
+
SERVICIO: {{payload.servicio}}
|
|
104
|
+
PRESUPUESTO: {{payload.presupuesto}}
|
|
105
|
+
DURACIÓN: {{payload.duracion}}
|
|
106
|
+
|
|
107
|
+
Entregar:
|
|
108
|
+
1. KPIs primarios (máximo 3, vinculados al objetivo de negocio)
|
|
109
|
+
2. KPIs secundarios por canal (CTR, CPC, CPL, tasa de conversión)
|
|
110
|
+
3. Benchmarks de referencia por canal
|
|
111
|
+
4. Plan de tracking: qué eventos configurar en GA4 / pixel de LinkedIn
|
|
112
|
+
5. Dashboard sugerido: métricas a reportar semanalmente
|
|
113
|
+
6. Criterios de optimización: cuándo pausar un anuncio, cuándo escalar
|
|
114
|
+
7. ROI target: CPL máximo aceptable para que la campaña sea rentable
|
|
115
|
+
depends_on: [s2-copies, s3-seo-contenido]
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
version: 1
|
|
2
|
+
|
|
3
|
+
orchestrator:
|
|
4
|
+
name: "Orquestador de Marketing"
|
|
5
|
+
provider: __PROVIDER_ID__
|
|
6
|
+
vault:
|
|
7
|
+
path: ./vault
|
|
8
|
+
embedder: simple # change to "ollama" in production for better semantic search
|
|
9
|
+
|
|
10
|
+
__PROVIDERS_BLOCK__
|
|
11
|
+
|
|
12
|
+
flows:
|
|
13
|
+
- id: articulo-blog
|
|
14
|
+
file: ./flows/articulo-blog.yaml
|
|
15
|
+
trigger: "artículo|blog|post|contenido|publicación|nota técnica"
|
|
16
|
+
|
|
17
|
+
- id: campana-leads
|
|
18
|
+
file: ./flows/campana-leads.yaml
|
|
19
|
+
trigger: "campaña|lead generation|generación de leads|demand gen|adquisición"
|
|
20
|
+
|
|
21
|
+
agents:
|
|
22
|
+
- id: content-strategist
|
|
23
|
+
name: "Estratega de Contenido"
|
|
24
|
+
description: >
|
|
25
|
+
Define la estrategia de contenido: estructura, ángulo editorial, keywords objetivo,
|
|
26
|
+
buyer persona al que apunta, qué problema resuelve y cómo encaja en el funnel.
|
|
27
|
+
Produce un brief detallado que guía al resto del equipo.
|
|
28
|
+
capabilities: [estrategia, brief, editorial, funnel, buyer-persona, keywords, estructura]
|
|
29
|
+
provider: __PROVIDER_ID__
|
|
30
|
+
domain: marketing
|
|
31
|
+
|
|
32
|
+
- id: copywriter
|
|
33
|
+
name: "Copywriter"
|
|
34
|
+
description: >
|
|
35
|
+
Redacta contenido de alta calidad: artículos de blog, emails, copies para ads,
|
|
36
|
+
landing pages y newsletters. Adapta tono, extensión y formato al canal y a la
|
|
37
|
+
audiencia indicada en el brief. Sigue la guía de marca y voz de la empresa.
|
|
38
|
+
capabilities: [redaccion, copywriting, blog, email, ads, landing-page, newsletter]
|
|
39
|
+
provider: __PROVIDER_ID__
|
|
40
|
+
domain: marketing
|
|
41
|
+
|
|
42
|
+
- id: seo-agent
|
|
43
|
+
name: "Especialista SEO"
|
|
44
|
+
description: >
|
|
45
|
+
Optimiza contenido para motores de búsqueda. Revisa densidad de keywords, estructura
|
|
46
|
+
de headings, meta descripción, alt text, internal linking y legibilidad. Propone
|
|
47
|
+
mejoras concretas y valida que el contenido responda la intención de búsqueda.
|
|
48
|
+
capabilities: [seo, keywords, meta, headings, optimizacion, busqueda, ranking]
|
|
49
|
+
provider: __PROVIDER_ID__
|
|
50
|
+
domain: marketing
|
|
51
|
+
gate: true
|
|
52
|
+
gate_criteria:
|
|
53
|
+
- "El título y H1 contienen la keyword principal de forma natural"
|
|
54
|
+
- "La meta descripción tiene entre 140-160 caracteres con CTA claro"
|
|
55
|
+
- "El contenido responde completamente la intención de búsqueda del keyword objetivo"
|
|
56
|
+
- "Hay al menos 2 oportunidades de internal linking identificadas"
|
|
57
|
+
|
|
58
|
+
- id: social-media-agent
|
|
59
|
+
name: "Especialista en Redes Sociales"
|
|
60
|
+
description: >
|
|
61
|
+
Crea la estrategia de distribución en redes sociales. Adapta el contenido a LinkedIn,
|
|
62
|
+
Instagram y Twitter/X con el formato, tono y hashtags apropiados para cada plataforma.
|
|
63
|
+
Propone el calendario de publicación y horarios óptimos.
|
|
64
|
+
capabilities: [linkedin, instagram, twitter, redes, distribucion, hashtags, calendario]
|
|
65
|
+
provider: __PROVIDER_ID__
|
|
66
|
+
domain: marketing
|
|
67
|
+
|
|
68
|
+
- id: campaign-agent
|
|
69
|
+
name: "Especialista en Campañas"
|
|
70
|
+
description: >
|
|
71
|
+
Diseña campañas de marketing: objetivo, segmento, canales, mensajes clave, presupuesto
|
|
72
|
+
sugerido, cronograma y métricas de éxito. Define el journey del lead desde el awareness
|
|
73
|
+
hasta la conversión. Propone A/B tests y criterios de optimización.
|
|
74
|
+
capabilities: [campañas, lead-gen, funnel, presupuesto, segmentacion, journey, abtesting]
|
|
75
|
+
provider: __PROVIDER_ID__
|
|
76
|
+
domain: marketing
|
|
77
|
+
gate: true
|
|
78
|
+
gate_criteria:
|
|
79
|
+
- "El objetivo de la campaña es SMART (específico, medible, alcanzable, relevante, temporal)"
|
|
80
|
+
- "El segmento objetivo está definido con criterios de ICP claros"
|
|
81
|
+
- "El presupuesto propuesto está dentro de los rangos históricos de la empresa"
|
|
82
|
+
- "Los KPIs incluyen métricas de negocio (leads calificados) y no solo métricas de vanidad"
|
|
83
|
+
|
|
84
|
+
- id: analytics-agent
|
|
85
|
+
name: "Analista de Marketing"
|
|
86
|
+
description: >
|
|
87
|
+
Define métricas, configura el tracking y analiza resultados de campañas y contenido.
|
|
88
|
+
Calcula CPL, CAC, ROI y LTV. Identifica qué funciona, qué no, y propone optimizaciones
|
|
89
|
+
basadas en datos. Genera reportes ejecutivos para dirección.
|
|
90
|
+
capabilities: [analytics, metricas, roi, cpl, cac, ltv, reporting, optimizacion, datos]
|
|
91
|
+
provider: __PROVIDER_ID__
|
|
92
|
+
domain: marketing
|