@lakitu/sdk 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +166 -0
- package/convex/_generated/api.d.ts +45 -0
- package/convex/_generated/api.js +23 -0
- package/convex/_generated/dataModel.d.ts +58 -0
- package/convex/_generated/server.d.ts +143 -0
- package/convex/_generated/server.js +93 -0
- package/convex/cloud/CLAUDE.md +238 -0
- package/convex/cloud/_generated/api.ts +84 -0
- package/convex/cloud/_generated/component.ts +861 -0
- package/convex/cloud/_generated/dataModel.ts +60 -0
- package/convex/cloud/_generated/server.ts +156 -0
- package/convex/cloud/convex.config.ts +16 -0
- package/convex/cloud/index.ts +29 -0
- package/convex/cloud/intentSchema/generate.ts +447 -0
- package/convex/cloud/intentSchema/index.ts +16 -0
- package/convex/cloud/intentSchema/types.ts +418 -0
- package/convex/cloud/ksaPolicy.ts +554 -0
- package/convex/cloud/mail.ts +92 -0
- package/convex/cloud/schema.ts +322 -0
- package/convex/cloud/utils/kanbanContext.ts +229 -0
- package/convex/cloud/workflows/agentBoard.ts +451 -0
- package/convex/cloud/workflows/agentPrompt.ts +272 -0
- package/convex/cloud/workflows/agentThread.ts +374 -0
- package/convex/cloud/workflows/compileSandbox.ts +146 -0
- package/convex/cloud/workflows/crudBoard.ts +217 -0
- package/convex/cloud/workflows/crudKSAs.ts +262 -0
- package/convex/cloud/workflows/crudLorobeads.ts +371 -0
- package/convex/cloud/workflows/crudSkills.ts +205 -0
- package/convex/cloud/workflows/crudThreads.ts +708 -0
- package/convex/cloud/workflows/lifecycleSandbox.ts +1396 -0
- package/convex/cloud/workflows/sandboxConvex.ts +1046 -0
- package/convex/sandbox/README.md +90 -0
- package/convex/sandbox/_generated/api.d.ts +2934 -0
- package/convex/sandbox/_generated/api.js +23 -0
- package/convex/sandbox/_generated/dataModel.d.ts +60 -0
- package/convex/sandbox/_generated/server.d.ts +143 -0
- package/convex/sandbox/_generated/server.js +93 -0
- package/convex/sandbox/actions/bash.ts +130 -0
- package/convex/sandbox/actions/browser.ts +282 -0
- package/convex/sandbox/actions/file.ts +336 -0
- package/convex/sandbox/actions/lsp.ts +325 -0
- package/convex/sandbox/actions/pdf.ts +119 -0
- package/convex/sandbox/agent/codeExecLoop.ts +535 -0
- package/convex/sandbox/agent/decisions.ts +284 -0
- package/convex/sandbox/agent/index.ts +515 -0
- package/convex/sandbox/agent/subagents.ts +651 -0
- package/convex/sandbox/brandResearch/index.ts +417 -0
- package/convex/sandbox/context/index.ts +7 -0
- package/convex/sandbox/context/session.ts +402 -0
- package/convex/sandbox/convex.config.ts +17 -0
- package/convex/sandbox/index.ts +51 -0
- package/convex/sandbox/nodeActions/codeExec.ts +130 -0
- package/convex/sandbox/planning/beads.ts +187 -0
- package/convex/sandbox/planning/index.ts +8 -0
- package/convex/sandbox/planning/sync.ts +194 -0
- package/convex/sandbox/prompts/codeExec.ts +852 -0
- package/convex/sandbox/prompts/modes.ts +231 -0
- package/convex/sandbox/prompts/system.ts +142 -0
- package/convex/sandbox/schema.ts +510 -0
- package/convex/sandbox/state/artifacts.ts +99 -0
- package/convex/sandbox/state/checkpoints.ts +341 -0
- package/convex/sandbox/state/files.ts +383 -0
- package/convex/sandbox/state/index.ts +10 -0
- package/convex/sandbox/state/verification.actions.ts +268 -0
- package/convex/sandbox/state/verification.ts +101 -0
- package/convex/sandbox/tsconfig.json +25 -0
- package/convex/sandbox/utils/codeExecHelpers.ts +52 -0
- package/dist/cli/commands/build.d.ts +19 -0
- package/dist/cli/commands/build.d.ts.map +1 -0
- package/dist/cli/commands/build.js +223 -0
- package/dist/cli/commands/init.d.ts +16 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +148 -0
- package/dist/cli/commands/publish.d.ts +12 -0
- package/dist/cli/commands/publish.d.ts.map +1 -0
- package/dist/cli/commands/publish.js +33 -0
- package/dist/cli/index.d.ts +14 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +40 -0
- package/dist/sdk/builders.d.ts +104 -0
- package/dist/sdk/builders.d.ts.map +1 -0
- package/dist/sdk/builders.js +214 -0
- package/dist/sdk/index.d.ts +29 -0
- package/dist/sdk/index.d.ts.map +1 -0
- package/dist/sdk/index.js +38 -0
- package/dist/sdk/types.d.ts +107 -0
- package/dist/sdk/types.d.ts.map +1 -0
- package/dist/sdk/types.js +6 -0
- package/ksa/README.md +263 -0
- package/ksa/_generated/REFERENCE.md +2954 -0
- package/ksa/_generated/registry.ts +257 -0
- package/ksa/_shared/configReader.ts +302 -0
- package/ksa/_shared/configSchemas.ts +649 -0
- package/ksa/_shared/gateway.ts +175 -0
- package/ksa/_shared/ksaBehaviors.ts +411 -0
- package/ksa/_shared/ksaProxy.ts +248 -0
- package/ksa/_shared/localDb.ts +302 -0
- package/ksa/index.ts +134 -0
- package/package.json +93 -0
- package/runtime/browser/agent-browser.ts +330 -0
- package/runtime/entrypoint.ts +194 -0
- package/runtime/lsp/manager.ts +366 -0
- package/runtime/pdf/pdf-generator.ts +50 -0
- package/runtime/pdf/renderer.ts +357 -0
- package/runtime/pdf/schema.ts +97 -0
- package/runtime/services/file-watcher.ts +191 -0
- package/template/build.ts +307 -0
- package/template/e2b/Dockerfile +69 -0
- package/template/e2b/e2b.toml +13 -0
- package/template/e2b/prebuild.sh +68 -0
- package/template/e2b/start.sh +14 -0
|
@@ -0,0 +1,852 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Code Execution System Prompt
|
|
3
|
+
*
|
|
4
|
+
* This prompt tells the agent how to work with the code execution model.
|
|
5
|
+
* The agent writes TypeScript code that imports from KSAs (Knowledge, Skills, Abilities).
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
// KSA registry info (inlined to avoid importing Node.js modules that Convex can't bundle)
|
|
9
|
+
const CORE_KSAS = ["file", "context", "artifacts", "beads"];
|
|
10
|
+
const ALL_KSA_NAMES = [
|
|
11
|
+
// Core
|
|
12
|
+
"file", "context", "artifacts", "beads",
|
|
13
|
+
// Research
|
|
14
|
+
"web", "news", "social", "ads", "companies", "browser",
|
|
15
|
+
// Deliverables
|
|
16
|
+
"pdf", "email",
|
|
17
|
+
// App services
|
|
18
|
+
"boards", "brandscan", "workspaces", "frames"
|
|
19
|
+
];
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* KSA detailed examples for the system prompt
|
|
23
|
+
* Only included for KSAs that are actually available
|
|
24
|
+
*/
|
|
25
|
+
const KSA_EXAMPLES: Record<string, string> = {
|
|
26
|
+
web: `### Web KSA (\`./ksa/web\`) - PREFERRED FOR RESEARCH
|
|
27
|
+
\`\`\`typescript
|
|
28
|
+
import { search, scrape, news, webResearch, brandNews } from './ksa/web';
|
|
29
|
+
|
|
30
|
+
// RECOMMENDED: Comprehensive web research
|
|
31
|
+
const research = await webResearch('topic', { depth: 'thorough' });
|
|
32
|
+
console.log(research.sources); // Web search results
|
|
33
|
+
console.log(research.articles); // News articles
|
|
34
|
+
|
|
35
|
+
// Search the web (uses Valyu)
|
|
36
|
+
const results = await search('query');
|
|
37
|
+
|
|
38
|
+
// Get news articles
|
|
39
|
+
const articles = await news('topic');
|
|
40
|
+
|
|
41
|
+
// Extract content from URL
|
|
42
|
+
const content = await scrape('https://example.com');
|
|
43
|
+
\`\`\``,
|
|
44
|
+
|
|
45
|
+
file: `### File KSA (\`./ksa/file\`)
|
|
46
|
+
\`\`\`typescript
|
|
47
|
+
import { read, write, edit, glob, grep, ls } from './ksa/file';
|
|
48
|
+
|
|
49
|
+
// Read a file
|
|
50
|
+
const content = await read('/home/user/workspace/file.txt');
|
|
51
|
+
|
|
52
|
+
// Write a file
|
|
53
|
+
await write('/home/user/workspace/output.txt', 'content');
|
|
54
|
+
|
|
55
|
+
// Edit a file (find and replace)
|
|
56
|
+
await edit('/home/user/workspace/file.txt', 'old text', 'new text');
|
|
57
|
+
|
|
58
|
+
// Find files matching pattern
|
|
59
|
+
const files = await glob('**/*.ts');
|
|
60
|
+
\`\`\``,
|
|
61
|
+
|
|
62
|
+
artifacts: `### Artifacts KSA (\`./ksa/artifacts\`)
|
|
63
|
+
\`\`\`typescript
|
|
64
|
+
import { saveArtifact, readArtifact, listArtifacts } from './ksa/artifacts';
|
|
65
|
+
|
|
66
|
+
// Save a markdown artifact
|
|
67
|
+
await saveArtifact({
|
|
68
|
+
name: 'market-analysis.md',
|
|
69
|
+
type: 'markdown',
|
|
70
|
+
content: '# Market Analysis\\n\\n...'
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
// Read a previous artifact
|
|
74
|
+
const artifact = await readArtifact('artifact-id');
|
|
75
|
+
|
|
76
|
+
// List all artifacts
|
|
77
|
+
const { artifacts } = await listArtifacts();
|
|
78
|
+
\`\`\``,
|
|
79
|
+
|
|
80
|
+
context: `### Context KSA (\`./ksa/context\`)
|
|
81
|
+
\`\`\`typescript
|
|
82
|
+
import { getContext, setVariable, getVariable } from './ksa/context';
|
|
83
|
+
|
|
84
|
+
// Get card context (variables, artifact count)
|
|
85
|
+
const ctx = await getContext();
|
|
86
|
+
console.log(ctx.variables);
|
|
87
|
+
|
|
88
|
+
// Set a variable for later stages
|
|
89
|
+
await setVariable('targetAudience', 'enterprise developers');
|
|
90
|
+
|
|
91
|
+
// Get a specific variable
|
|
92
|
+
const audience = await getVariable('targetAudience');
|
|
93
|
+
\`\`\``,
|
|
94
|
+
|
|
95
|
+
beads: `### Task Tracking KSA (\`./ksa/beads\`) - **REQUIRED FOR PLANNING**
|
|
96
|
+
\`\`\`typescript
|
|
97
|
+
import { create, update, close, list, get } from './ksa/beads';
|
|
98
|
+
|
|
99
|
+
// IMPORTANT: create() returns { success, id, error? } - use .id for updates
|
|
100
|
+
const task1 = await create({ title: 'Research topic', type: 'task', priority: 1 });
|
|
101
|
+
console.log('Created task:', task1.id); // Use task1.id, NOT task1
|
|
102
|
+
|
|
103
|
+
// Update as you work - pass the ID string
|
|
104
|
+
await update(task1.id, { status: 'in_progress' });
|
|
105
|
+
|
|
106
|
+
// Mark complete when done - pass the ID string
|
|
107
|
+
await close(task1.id, 'Found 5 relevant sources');
|
|
108
|
+
|
|
109
|
+
// List remaining tasks
|
|
110
|
+
const remaining = await list({ status: 'open' });
|
|
111
|
+
\`\`\``,
|
|
112
|
+
|
|
113
|
+
pdf: `### PDF KSA (\`./ksa/pdf\`)
|
|
114
|
+
\`\`\`typescript
|
|
115
|
+
import { generate } from './ksa/pdf';
|
|
116
|
+
|
|
117
|
+
// Generate PDF from markdown (auto-saves to artifacts)
|
|
118
|
+
await generate({
|
|
119
|
+
filename: 'quarterly-report',
|
|
120
|
+
content: '# Quarterly Report\\n\\n## Summary\\n...'
|
|
121
|
+
});
|
|
122
|
+
\`\`\``,
|
|
123
|
+
|
|
124
|
+
browser: `### Browser KSA (\`./ksa/browser\`)
|
|
125
|
+
\`\`\`typescript
|
|
126
|
+
import { open, screenshot, click, type, getText } from './ksa/browser';
|
|
127
|
+
|
|
128
|
+
// Open a URL
|
|
129
|
+
await open('https://example.com');
|
|
130
|
+
|
|
131
|
+
// Take screenshot
|
|
132
|
+
const { path } = await screenshot('name');
|
|
133
|
+
|
|
134
|
+
// Interact with page
|
|
135
|
+
await click('button.submit');
|
|
136
|
+
await type('input[name="email"]', 'user@example.com');
|
|
137
|
+
\`\`\``,
|
|
138
|
+
|
|
139
|
+
news: `### News KSA (\`./ksa/news\`)
|
|
140
|
+
\`\`\`typescript
|
|
141
|
+
import { search, trending, monitorBrand, analyzeSentiment } from './ksa/news';
|
|
142
|
+
|
|
143
|
+
// Advanced news search with filters
|
|
144
|
+
const articles = await search({
|
|
145
|
+
query: 'AI regulation',
|
|
146
|
+
category: 'politics',
|
|
147
|
+
sentiment: 'negative',
|
|
148
|
+
limit: 20
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
// Get trending news by category
|
|
152
|
+
const tech = await trending('science', 10);
|
|
153
|
+
\`\`\``,
|
|
154
|
+
|
|
155
|
+
social: `### Social Media KSA (\`./ksa/social\`)
|
|
156
|
+
\`\`\`typescript
|
|
157
|
+
import { tiktokProfile, instagramPosts, twitterProfile, searchSocial } from './ksa/social';
|
|
158
|
+
|
|
159
|
+
// Get social profiles
|
|
160
|
+
const tiktok = await tiktokProfile('charlidamelio');
|
|
161
|
+
const twitter = await twitterProfile('elonmusk');
|
|
162
|
+
|
|
163
|
+
// Get recent posts
|
|
164
|
+
const posts = await instagramPosts('instagram', 10);
|
|
165
|
+
\`\`\``,
|
|
166
|
+
|
|
167
|
+
ads: `### Ads KSA (\`./ksa/ads\`) - **USE THIS for Facebook/Instagram/Meta ads and Google ads**
|
|
168
|
+
\`\`\`typescript
|
|
169
|
+
import { searchMetaAds, searchGoogleAds, searchAllAds, searchMetaCompanies, getMetaAdsByPageId } from './ksa/ads';
|
|
170
|
+
|
|
171
|
+
// Search Meta Ad Library by brand name (RECOMMENDED)
|
|
172
|
+
const result = await searchMetaAds('Liquid Death');
|
|
173
|
+
console.log(\`Found \${result.ads.length} Meta ads for \${result.company?.name}\`);
|
|
174
|
+
for (const ad of result.ads.slice(0, 5)) {
|
|
175
|
+
console.log(\`- \${ad.body?.substring(0, 100)}...\`);
|
|
176
|
+
console.log(\` Platform: \${ad.platform}, Status: \${ad.status}\`);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// Search Google Ads Transparency by domain
|
|
180
|
+
const googleResult = await searchGoogleAds('liquiddeath.com');
|
|
181
|
+
console.log(\`Found \${googleResult.ads.length} Google ads\`);
|
|
182
|
+
|
|
183
|
+
// Search both platforms at once
|
|
184
|
+
const { meta, google } = await searchAllAds('Nike', 'nike.com');
|
|
185
|
+
console.log(\`Meta: \${meta.ads.length}, Google: \${google.ads.length}\`);
|
|
186
|
+
|
|
187
|
+
// For advanced use: search companies first, then get ads by Page ID
|
|
188
|
+
const companies = await searchMetaCompanies('Apple');
|
|
189
|
+
const appleAds = await getMetaAdsByPageId(companies[0].pageId, { maxAds: 20 });
|
|
190
|
+
\`\`\``,
|
|
191
|
+
|
|
192
|
+
companies: `### Companies KSA (\`./ksa/companies\`)
|
|
193
|
+
\`\`\`typescript
|
|
194
|
+
import { enrichDomain, searchCompanies, getTechStack } from './ksa/companies';
|
|
195
|
+
|
|
196
|
+
// Enrich company by domain
|
|
197
|
+
const company = await enrichDomain('stripe.com');
|
|
198
|
+
console.log(company.name, company.industry, company.employeeRange);
|
|
199
|
+
|
|
200
|
+
// Search companies
|
|
201
|
+
const saas = await searchCompanies({
|
|
202
|
+
industry: 'SaaS',
|
|
203
|
+
employeeMin: 50,
|
|
204
|
+
employeeMax: 500
|
|
205
|
+
});
|
|
206
|
+
\`\`\``,
|
|
207
|
+
|
|
208
|
+
email: `### Email KSA (\`./ksa/email\`)
|
|
209
|
+
\`\`\`typescript
|
|
210
|
+
import { send, sendText, sendWithAttachment } from './ksa/email';
|
|
211
|
+
|
|
212
|
+
// Send a simple email
|
|
213
|
+
await sendText('user@example.com', 'Report Ready', 'Your analysis is complete.');
|
|
214
|
+
|
|
215
|
+
// Send with attachment
|
|
216
|
+
await sendWithAttachment(
|
|
217
|
+
'user@example.com',
|
|
218
|
+
'Quarterly Report',
|
|
219
|
+
'Please find the report attached.',
|
|
220
|
+
{ content: base64Content, filename: 'report.pdf', type: 'application/pdf' }
|
|
221
|
+
);
|
|
222
|
+
\`\`\``,
|
|
223
|
+
|
|
224
|
+
// App service KSAs
|
|
225
|
+
boards: `### Boards KSA - Create workflow boards using YAML DSL
|
|
226
|
+
|
|
227
|
+
**PREFERRED: Use boardDSL for creating boards** - Write a YAML definition file, then create the board atomically.
|
|
228
|
+
|
|
229
|
+
\`\`\`typescript
|
|
230
|
+
import { createBoardFromYAML, validateBoardYAML } from './ksa/boardDSL';
|
|
231
|
+
import { saveArtifact } from './ksa/artifacts';
|
|
232
|
+
|
|
233
|
+
// Define the board as YAML - much simpler and cleaner!
|
|
234
|
+
const boardYAML = \`
|
|
235
|
+
name: Brand Analysis Pipeline
|
|
236
|
+
description: Analyze brands and generate strategic reports
|
|
237
|
+
|
|
238
|
+
trigger:
|
|
239
|
+
name: Brand Analysis
|
|
240
|
+
methods:
|
|
241
|
+
prompt: true
|
|
242
|
+
webform: true
|
|
243
|
+
chat:
|
|
244
|
+
systemPrompt: Analyze the provided brand and generate insights
|
|
245
|
+
placeholder: Enter a brand domain to analyze...
|
|
246
|
+
images: true
|
|
247
|
+
files: true
|
|
248
|
+
urls: true
|
|
249
|
+
|
|
250
|
+
stages:
|
|
251
|
+
- name: Brand Scan
|
|
252
|
+
type: agent
|
|
253
|
+
goals:
|
|
254
|
+
- Scan brand website and extract key information
|
|
255
|
+
- Extract logos, colors, and typography
|
|
256
|
+
- Identify products and services
|
|
257
|
+
skills:
|
|
258
|
+
- brandscan
|
|
259
|
+
- web
|
|
260
|
+
deliverables:
|
|
261
|
+
- name: Brand Profile
|
|
262
|
+
type: data
|
|
263
|
+
description: Structured brand data
|
|
264
|
+
|
|
265
|
+
- name: Social Analysis
|
|
266
|
+
type: agent
|
|
267
|
+
goals:
|
|
268
|
+
- Audit social media presence across platforms
|
|
269
|
+
- Analyze engagement metrics and trends
|
|
270
|
+
- Identify top performing content
|
|
271
|
+
skills:
|
|
272
|
+
- social
|
|
273
|
+
- instagram
|
|
274
|
+
- tiktok
|
|
275
|
+
deliverables:
|
|
276
|
+
- name: Social Metrics
|
|
277
|
+
type: data
|
|
278
|
+
description: Engagement data by platform
|
|
279
|
+
- name: Content Analysis
|
|
280
|
+
type: report
|
|
281
|
+
|
|
282
|
+
- name: Report Generation
|
|
283
|
+
type: agent
|
|
284
|
+
goals:
|
|
285
|
+
- Synthesize findings into comprehensive report
|
|
286
|
+
- Generate actionable recommendations
|
|
287
|
+
- Create executive summary
|
|
288
|
+
skills:
|
|
289
|
+
- pdf
|
|
290
|
+
- artifacts
|
|
291
|
+
deliverables:
|
|
292
|
+
- name: Brand Report
|
|
293
|
+
type: pdf
|
|
294
|
+
description: Full analysis PDF
|
|
295
|
+
|
|
296
|
+
- name: Human Review
|
|
297
|
+
type: human
|
|
298
|
+
goals:
|
|
299
|
+
- Review report accuracy and completeness
|
|
300
|
+
- Approve or request revisions
|
|
301
|
+
\`;
|
|
302
|
+
|
|
303
|
+
// Validate first (optional but recommended)
|
|
304
|
+
const validation = validateBoardYAML(boardYAML);
|
|
305
|
+
if (!validation.valid) {
|
|
306
|
+
console.error('Invalid board definition:', validation.errors);
|
|
307
|
+
} else {
|
|
308
|
+
// Create the board atomically from YAML
|
|
309
|
+
const boardId = await createBoardFromYAML(boardYAML);
|
|
310
|
+
console.log('Created board:', boardId);
|
|
311
|
+
|
|
312
|
+
// ALWAYS save an artifact link so user can access the board
|
|
313
|
+
await saveArtifact({
|
|
314
|
+
name: 'Brand Analysis Pipeline Board',
|
|
315
|
+
type: 'link',
|
|
316
|
+
content: JSON.stringify({
|
|
317
|
+
type: 'board',
|
|
318
|
+
id: boardId,
|
|
319
|
+
url: \\\`/board/\\\${boardId}\\\`,
|
|
320
|
+
title: 'Brand Analysis Pipeline',
|
|
321
|
+
description: 'Click to open your new board'
|
|
322
|
+
})
|
|
323
|
+
});
|
|
324
|
+
}
|
|
325
|
+
\`\`\`
|
|
326
|
+
|
|
327
|
+
**YAML DSL Reference:**
|
|
328
|
+
- \`name\`: Board name (required)
|
|
329
|
+
- \`description\`: What the board does
|
|
330
|
+
- \`trigger\`: How cards are created (prompt, webform, webhook, schedule, email)
|
|
331
|
+
- \`stages\`: Pipeline steps (each with name, type, goals, skills, deliverables)
|
|
332
|
+
- \`type\`: "agent" (AI-powered) or "human" (manual)
|
|
333
|
+
- \`goals\`: List of objectives (strings)
|
|
334
|
+
- \`skills\`: KSAs needed (strings like "web", "pdf", "social")
|
|
335
|
+
- \`deliverables\`: Expected outputs with name, type, description
|
|
336
|
+
|
|
337
|
+
For existing boards, use the standard boards KSA:
|
|
338
|
+
\`\`\`typescript
|
|
339
|
+
import { listBoards, getBoard, addCard, runCard } from './ksa/boards';
|
|
340
|
+
|
|
341
|
+
// List existing boards
|
|
342
|
+
const boards = await listBoards();
|
|
343
|
+
|
|
344
|
+
// Add and run a card
|
|
345
|
+
const cardId = await addCard(boardId, 'task-001', 'Analyze Nike', { autoRun: true });
|
|
346
|
+
\`\`\``,
|
|
347
|
+
|
|
348
|
+
brandscan: `### Brand Scan KSA (\`./ksa/brandscan\`) - Brand intelligence scanning
|
|
349
|
+
\`\`\`typescript
|
|
350
|
+
import { startScan, getScanStatus, waitForScan, getBrandData, listBrands, getBrandByDomain } from './ksa/brandscan';
|
|
351
|
+
|
|
352
|
+
// Start a brand scan by domain
|
|
353
|
+
const scanId = await startScan('example.com');
|
|
354
|
+
console.log('Scan started:', scanId);
|
|
355
|
+
|
|
356
|
+
// Wait for scan to complete
|
|
357
|
+
const result = await waitForScan(scanId, 120000); // 2 min timeout
|
|
358
|
+
console.log('Scan complete:', result);
|
|
359
|
+
|
|
360
|
+
// Get detailed brand data
|
|
361
|
+
const brand = await getBrandData(result.brandId);
|
|
362
|
+
console.log('Brand:', brand.name, brand.industry);
|
|
363
|
+
|
|
364
|
+
// Find existing brand by domain
|
|
365
|
+
const existing = await getBrandByDomain('competitor.com');
|
|
366
|
+
if (existing) {
|
|
367
|
+
console.log('Found brand:', existing.name);
|
|
368
|
+
}
|
|
369
|
+
\`\`\``,
|
|
370
|
+
|
|
371
|
+
workspaces: `### Workspaces KSA (\`./ksa/workspaces\`) - Design workspace management
|
|
372
|
+
\`\`\`typescript
|
|
373
|
+
import { listWorkspaces, createWorkspace, getCanvas, saveCanvas, addCanvasElement, saveDesign } from './ksa/workspaces';
|
|
374
|
+
|
|
375
|
+
// List workspaces
|
|
376
|
+
const workspaces = await listWorkspaces();
|
|
377
|
+
console.log('Workspaces:', workspaces.map(w => w.name));
|
|
378
|
+
|
|
379
|
+
// Create a new workspace
|
|
380
|
+
const workspaceId = await createWorkspace({ name: 'Campaign Assets' });
|
|
381
|
+
|
|
382
|
+
// Add elements to canvas
|
|
383
|
+
await addCanvasElement(workspaceId, {
|
|
384
|
+
type: 'image',
|
|
385
|
+
url: 'https://example.com/logo.png',
|
|
386
|
+
x: 100, y: 100, width: 200, height: 200
|
|
387
|
+
});
|
|
388
|
+
|
|
389
|
+
// Save a design
|
|
390
|
+
await saveDesign(workspaceId, {
|
|
391
|
+
name: 'Hero Banner',
|
|
392
|
+
format: 'png',
|
|
393
|
+
width: 1200, height: 630
|
|
394
|
+
});
|
|
395
|
+
\`\`\``,
|
|
396
|
+
|
|
397
|
+
frames: `### Frames KSA (\`./ksa/frames\`) - Visual frame generation
|
|
398
|
+
\`\`\`typescript
|
|
399
|
+
import { createFrame, generateFrame, listFrames, getFrame, updateFrame, getTemplates } from './ksa/frames';
|
|
400
|
+
|
|
401
|
+
// Generate a frame using AI
|
|
402
|
+
const frame = await generateFrame({
|
|
403
|
+
prompt: 'Create a landing page hero section for a SaaS product',
|
|
404
|
+
style: 'modern',
|
|
405
|
+
colors: ['#3B82F6', '#1F2937']
|
|
406
|
+
});
|
|
407
|
+
console.log('Generated frame:', frame.id);
|
|
408
|
+
|
|
409
|
+
// Get available templates
|
|
410
|
+
const templates = await getTemplates();
|
|
411
|
+
console.log('Templates:', templates.map(t => t.name));
|
|
412
|
+
|
|
413
|
+
// Create frame from template
|
|
414
|
+
const newFrame = await createFrame({
|
|
415
|
+
templateId: 'hero-section',
|
|
416
|
+
variables: {
|
|
417
|
+
headline: 'Build Better Products',
|
|
418
|
+
subheadline: 'AI-powered development tools'
|
|
419
|
+
}
|
|
420
|
+
});
|
|
421
|
+
|
|
422
|
+
// Update frame content
|
|
423
|
+
await updateFrame(newFrame.id, {
|
|
424
|
+
html: '<div class="hero">Updated content</div>'
|
|
425
|
+
});
|
|
426
|
+
\`\`\``,
|
|
427
|
+
};
|
|
428
|
+
|
|
429
|
+
/**
|
|
430
|
+
* Generate KSA documentation section for allowed KSAs only
|
|
431
|
+
*/
|
|
432
|
+
function generateKSADocumentation(allowedKSAs?: string[]): string {
|
|
433
|
+
// Determine which KSAs to include
|
|
434
|
+
const ksasToInclude = allowedKSAs
|
|
435
|
+
? [...CORE_KSAS, ...allowedKSAs.filter(k => !CORE_KSAS.includes(k))]
|
|
436
|
+
: ALL_KSA_NAMES;
|
|
437
|
+
|
|
438
|
+
const sections: string[] = [];
|
|
439
|
+
|
|
440
|
+
// Add examples for each available KSA
|
|
441
|
+
for (const ksaName of ksasToInclude) {
|
|
442
|
+
if (KSA_EXAMPLES[ksaName]) {
|
|
443
|
+
sections.push(KSA_EXAMPLES[ksaName]);
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
// Add note about unavailable KSAs
|
|
448
|
+
if (allowedKSAs) {
|
|
449
|
+
const unavailable = ALL_KSA_NAMES.filter(
|
|
450
|
+
k => !CORE_KSAS.includes(k) && !allowedKSAs.includes(k)
|
|
451
|
+
);
|
|
452
|
+
if (unavailable.length > 0) {
|
|
453
|
+
sections.push(`\n> **⚠️ NOT AVAILABLE for this task:** ${unavailable.join(", ")}. Do not attempt to import these KSAs.`);
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
return sections.join("\n\n");
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
/**
|
|
461
|
+
* Base system prompt (without KSA documentation)
|
|
462
|
+
*/
|
|
463
|
+
const CODE_EXEC_BASE_PROMPT = `You are an expert software engineer working in a sandboxed development environment.
|
|
464
|
+
|
|
465
|
+
## 🚨 CRITICAL: YOU MUST EXECUTE CODE 🚨
|
|
466
|
+
|
|
467
|
+
**On your FIRST response, you MUST provide code to execute.** You cannot complete any task by just describing what you would do - you MUST actually run code.
|
|
468
|
+
|
|
469
|
+
⚠️ FAILURE MODE TO AVOID:
|
|
470
|
+
- ❌ WRONG: Responding with "I have created the deliverable" without executing code
|
|
471
|
+
- ❌ WRONG: Providing \`response\` on the first turn
|
|
472
|
+
- ❌ WRONG: Setting \`code: ""\` on the first turn
|
|
473
|
+
- ✅ CORRECT: Providing \`code\` with actual TypeScript to execute, \`response: ""\`
|
|
474
|
+
|
|
475
|
+
## Response Format (JSON)
|
|
476
|
+
|
|
477
|
+
You MUST respond with a JSON object containing exactly these fields:
|
|
478
|
+
- **thinking** (string): Your reasoning about what to do next
|
|
479
|
+
- **code** (string): TypeScript code to execute. MUST be non-empty on first turn!
|
|
480
|
+
- **response** (string): Final response. MUST be "" until you've executed code and verified results.
|
|
481
|
+
|
|
482
|
+
### Step 1 - Execute code (REQUIRED FIRST):
|
|
483
|
+
\`\`\`json
|
|
484
|
+
{
|
|
485
|
+
"thinking": "I need to search the web and save a deliverable",
|
|
486
|
+
"code": "import { search } from './ksa/web'; const r = await search('AI news'); console.log(r);",
|
|
487
|
+
"response": ""
|
|
488
|
+
}
|
|
489
|
+
\`\`\`
|
|
490
|
+
|
|
491
|
+
### Step 2+ - After seeing execution output, continue or finish:
|
|
492
|
+
\`\`\`json
|
|
493
|
+
{
|
|
494
|
+
"thinking": "Code executed successfully, I can now summarize",
|
|
495
|
+
"code": "",
|
|
496
|
+
"response": "Here is what I found: [summary based on ACTUAL execution output]"
|
|
497
|
+
}
|
|
498
|
+
\`\`\`
|
|
499
|
+
|
|
500
|
+
## Rules
|
|
501
|
+
1. **FIRST RESPONSE MUST HAVE CODE** - Never skip code execution
|
|
502
|
+
2. **response MUST be ""** until code has run and you've seen the output
|
|
503
|
+
3. Only put \`response\` on the FINAL turn after verifying code ran successfully
|
|
504
|
+
4. Import from \`./ksa/*\` for all capabilities
|
|
505
|
+
5. Use \`console.log()\` to see results from your code
|
|
506
|
+
|
|
507
|
+
## How You Work
|
|
508
|
+
|
|
509
|
+
You complete tasks by providing code in the "code" field. You have access to **KSAs** (Knowledge, Skills, and Abilities) - TypeScript modules that provide various capabilities.
|
|
510
|
+
|
|
511
|
+
**Your workflow:**
|
|
512
|
+
1. Analyze the task, provide thinking and code
|
|
513
|
+
2. Review the execution output
|
|
514
|
+
3. Continue providing code until the task is complete
|
|
515
|
+
4. When done, provide a non-empty response (with code as "")
|
|
516
|
+
|
|
517
|
+
## Available KSAs
|
|
518
|
+
|
|
519
|
+
KSAs are in \`/home/user/ksa/\`. Import and use them like any TypeScript module.
|
|
520
|
+
|
|
521
|
+
{{KSA_DOCUMENTATION}}
|
|
522
|
+
|
|
523
|
+
## Working Directories
|
|
524
|
+
|
|
525
|
+
- \`/home/user/workspace/\` - Your working directory for code and files
|
|
526
|
+
- \`/home/user/artifacts/\` - For persistent outputs that should be saved
|
|
527
|
+
- \`/home/user/ksa/\` - KSA modules (read-only)
|
|
528
|
+
|
|
529
|
+
## Guidelines
|
|
530
|
+
|
|
531
|
+
1. **Start with beads planning** - Create tasks for your work plan FIRST
|
|
532
|
+
2. **Always use console.log()** to output results you need to see
|
|
533
|
+
3. **Import from ./ksa/** for capabilities (don't try to use fetch or fs directly)
|
|
534
|
+
4. **Handle errors** gracefully - if something fails, try a different approach
|
|
535
|
+
5. **Be incremental** - don't try to do everything in one code block
|
|
536
|
+
6. **Verify results** - check that operations succeeded before continuing
|
|
537
|
+
7. **Track progress** - Update beads status as you complete each step
|
|
538
|
+
|
|
539
|
+
## Required Workflow
|
|
540
|
+
|
|
541
|
+
**FIRST CODE BLOCK MUST:**
|
|
542
|
+
1. Import beads: \`import { create, update, close } from './ksa/beads';\`
|
|
543
|
+
2. Create tasks for each deliverable/step
|
|
544
|
+
3. Then proceed with actual work
|
|
545
|
+
|
|
546
|
+
This enables proper tracking and retry handling.
|
|
547
|
+
|
|
548
|
+
## Example: Research Task with Deliverable
|
|
549
|
+
|
|
550
|
+
**Task**: "Find recent news about AI and save a summary document"
|
|
551
|
+
|
|
552
|
+
**Turn 1** - Create work plan with beads:
|
|
553
|
+
\`\`\`json
|
|
554
|
+
{
|
|
555
|
+
"thinking": "I need to plan my work using beads, then search for AI news and save results",
|
|
556
|
+
"code": "import { create, update, close } from './ksa/beads';\\n\\n// Create work plan (create returns { success, id })\\nconst searchTask = await create({ title: 'Search for AI news', type: 'task', priority: 1 });\\nconst summaryTask = await create({ title: 'Create summary document', type: 'task', priority: 2 });\\nconsole.log('Created tasks:', searchTask.id, summaryTask.id);\\n\\n// Start first task - use .id for updates\\nawait update(searchTask.id, { status: 'in_progress' });",
|
|
557
|
+
"response": ""
|
|
558
|
+
}
|
|
559
|
+
\`\`\`
|
|
560
|
+
|
|
561
|
+
**Turn 2** - Execute search and save:
|
|
562
|
+
\`\`\`json
|
|
563
|
+
{
|
|
564
|
+
"thinking": "Work plan created. Now searching for AI news and saving results.",
|
|
565
|
+
"code": "import { search } from './ksa/web';\\nimport { saveArtifact } from './ksa/artifacts';\\nimport { close } from './ksa/beads';\\n\\nconst results = await search('AI news 2026');\\nconsole.log('Found', results.length, 'results');\\nconst searchTask = 'task-from-turn-1';\\nawait close(searchTask, \`Found \${results.length} articles\`);\\n\\nconst summary = results.slice(0, 5).map(r => \`- \${r.title}\\n \${r.url}\`).join('\\n');\\nawait saveArtifact({ name: 'ai-news-summary.md', type: 'markdown', content: \`# AI News Summary\\n\\n\${summary}\` });\\nconst summaryTask = 'task-from-turn-1';\\nawait close(summaryTask, 'Saved summary document');\\nconsole.log('All tasks complete');",
|
|
566
|
+
"response": ""
|
|
567
|
+
}
|
|
568
|
+
\`\`\`
|
|
569
|
+
|
|
570
|
+
**Turn 3** - After seeing "All tasks complete" in output:
|
|
571
|
+
\`\`\`json
|
|
572
|
+
{
|
|
573
|
+
"thinking": "All beads tasks closed, deliverable saved successfully",
|
|
574
|
+
"code": "",
|
|
575
|
+
"response": "I found 5 AI news articles and saved a summary document as ai-news-summary.md"
|
|
576
|
+
}
|
|
577
|
+
\`\`\`
|
|
578
|
+
`;
|
|
579
|
+
|
|
580
|
+
// ============================================================================
|
|
581
|
+
// Intent Schema Types (mirrored from cloud - no Node.js imports in Convex)
|
|
582
|
+
// ============================================================================
|
|
583
|
+
|
|
584
|
+
interface IntentGoal {
|
|
585
|
+
id: string;
|
|
586
|
+
text: string;
|
|
587
|
+
importance: "critical" | "important" | "nice-to-have";
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
interface IntentDeliverable {
|
|
591
|
+
id: string;
|
|
592
|
+
type: string;
|
|
593
|
+
name: string;
|
|
594
|
+
description: string;
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
interface IntentSchema {
|
|
598
|
+
intent: {
|
|
599
|
+
summary: string;
|
|
600
|
+
objective: string;
|
|
601
|
+
context: string[];
|
|
602
|
+
domain?: string;
|
|
603
|
+
};
|
|
604
|
+
ksas: {
|
|
605
|
+
priority: string[];
|
|
606
|
+
secondary: string[];
|
|
607
|
+
notNeeded: string[];
|
|
608
|
+
reasoning: string;
|
|
609
|
+
};
|
|
610
|
+
plan: {
|
|
611
|
+
goals: IntentGoal[];
|
|
612
|
+
deliverables: IntentDeliverable[];
|
|
613
|
+
steps: string[];
|
|
614
|
+
};
|
|
615
|
+
policy: {
|
|
616
|
+
enabledKSAs: string[];
|
|
617
|
+
disabledKSAs: string[];
|
|
618
|
+
allowExternalCalls: boolean;
|
|
619
|
+
requireApprovalFor?: string[];
|
|
620
|
+
};
|
|
621
|
+
meta: {
|
|
622
|
+
model: string;
|
|
623
|
+
generatedAt: number;
|
|
624
|
+
confidence: "high" | "medium" | "low";
|
|
625
|
+
latencyMs?: number;
|
|
626
|
+
};
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
/**
|
|
630
|
+
* Generate intent schema guidance section for the system prompt.
|
|
631
|
+
* This provides structured guidance based on pre-analysis of the user request.
|
|
632
|
+
*/
|
|
633
|
+
function generateIntentSchemaGuidance(schema: IntentSchema): string {
|
|
634
|
+
const lines: string[] = [
|
|
635
|
+
"## 🎯 Pre-Analyzed Intent (Use This as Your Guide)",
|
|
636
|
+
"",
|
|
637
|
+
`**Objective:** ${schema.intent.objective}`,
|
|
638
|
+
"",
|
|
639
|
+
];
|
|
640
|
+
|
|
641
|
+
// Context elements
|
|
642
|
+
if (schema.intent.context.length > 0) {
|
|
643
|
+
lines.push("**Key Context:**");
|
|
644
|
+
for (const ctx of schema.intent.context) {
|
|
645
|
+
lines.push(`- ${ctx}`);
|
|
646
|
+
}
|
|
647
|
+
lines.push("");
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
// Priority KSAs
|
|
651
|
+
if (schema.ksas.priority.length > 0) {
|
|
652
|
+
lines.push(
|
|
653
|
+
`**Priority KSAs (Import First):** ${schema.ksas.priority.join(", ")}`
|
|
654
|
+
);
|
|
655
|
+
lines.push(`> *${schema.ksas.reasoning}*`);
|
|
656
|
+
lines.push("");
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
// Goals
|
|
660
|
+
if (schema.plan.goals.length > 0) {
|
|
661
|
+
lines.push("**Goals to Accomplish:**");
|
|
662
|
+
for (const goal of schema.plan.goals) {
|
|
663
|
+
const importance =
|
|
664
|
+
goal.importance === "critical"
|
|
665
|
+
? "🔴"
|
|
666
|
+
: goal.importance === "important"
|
|
667
|
+
? "🟡"
|
|
668
|
+
: "🟢";
|
|
669
|
+
lines.push(`${importance} ${goal.text}`);
|
|
670
|
+
}
|
|
671
|
+
lines.push("");
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
// Deliverables
|
|
675
|
+
if (schema.plan.deliverables.length > 0) {
|
|
676
|
+
lines.push("**Expected Deliverables:**");
|
|
677
|
+
for (const d of schema.plan.deliverables) {
|
|
678
|
+
lines.push(`- **${d.name}** (${d.type}): ${d.description}`);
|
|
679
|
+
}
|
|
680
|
+
lines.push("");
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
// Suggested steps
|
|
684
|
+
if (schema.plan.steps.length > 0) {
|
|
685
|
+
lines.push("**Suggested Approach:**");
|
|
686
|
+
schema.plan.steps.forEach((step, i) => {
|
|
687
|
+
lines.push(`${i + 1}. ${step}`);
|
|
688
|
+
});
|
|
689
|
+
lines.push("");
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
// Policy notes
|
|
693
|
+
if (schema.policy.disabledKSAs.length > 0) {
|
|
694
|
+
lines.push(
|
|
695
|
+
`> ⚠️ **Blocked KSAs (do not use):** ${schema.policy.disabledKSAs.join(", ")}`
|
|
696
|
+
);
|
|
697
|
+
}
|
|
698
|
+
if (schema.policy.requireApprovalFor?.length) {
|
|
699
|
+
lines.push(
|
|
700
|
+
`> ℹ️ **Requires approval:** ${schema.policy.requireApprovalFor.join(", ")}`
|
|
701
|
+
);
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
return lines.join("\n");
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
/**
|
|
708
|
+
* Get the system prompt with dynamic KSA documentation
|
|
709
|
+
* @param options.allowedKSAs - If provided, only include documentation for these KSAs (core always included)
|
|
710
|
+
* @param options.additions - Additional context to append
|
|
711
|
+
* @param options.intentSchema - Pre-analyzed intent schema for structured guidance
|
|
712
|
+
*/
|
|
713
|
+
export function getCodeExecSystemPrompt(options?: {
|
|
714
|
+
allowedKSAs?: string[];
|
|
715
|
+
additions?: string;
|
|
716
|
+
intentSchema?: IntentSchema;
|
|
717
|
+
}): string {
|
|
718
|
+
// Generate dynamic KSA documentation based on what's allowed
|
|
719
|
+
const ksaDocumentation = generateKSADocumentation(options?.allowedKSAs);
|
|
720
|
+
|
|
721
|
+
// Replace the placeholder with dynamic content
|
|
722
|
+
let prompt = CODE_EXEC_BASE_PROMPT.replace("{{KSA_DOCUMENTATION}}", ksaDocumentation);
|
|
723
|
+
|
|
724
|
+
// Add intent schema guidance FIRST (high priority)
|
|
725
|
+
if (options?.intentSchema) {
|
|
726
|
+
const intentGuidance = generateIntentSchemaGuidance(options.intentSchema);
|
|
727
|
+
prompt += `\n\n${intentGuidance}`;
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
// Add any additional context
|
|
731
|
+
if (options?.additions) {
|
|
732
|
+
prompt += `\n\n## Additional Context\n\n${options.additions}`;
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
return prompt;
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
// For backwards compatibility - the full prompt with all KSAs
|
|
739
|
+
export const CODE_EXEC_SYSTEM_PROMPT = getCodeExecSystemPrompt();
|
|
740
|
+
|
|
741
|
+
// ============================================================================
|
|
742
|
+
// KSA Instructions Generation
|
|
743
|
+
// ============================================================================
|
|
744
|
+
|
|
745
|
+
/** Display names for KSAs */
|
|
746
|
+
const KSA_DISPLAY_NAMES: Record<string, string> = {
|
|
747
|
+
web: "Web Research",
|
|
748
|
+
news: "News Monitoring",
|
|
749
|
+
social: "Social Media",
|
|
750
|
+
ads: "Ad Library Search",
|
|
751
|
+
companies: "Company Intelligence",
|
|
752
|
+
browser: "Browser Automation",
|
|
753
|
+
pdf: "PDF Generation",
|
|
754
|
+
email: "Email",
|
|
755
|
+
file: "File Operations",
|
|
756
|
+
artifacts: "Artifacts",
|
|
757
|
+
context: "Context",
|
|
758
|
+
beads: "Task Tracking",
|
|
759
|
+
};
|
|
760
|
+
|
|
761
|
+
/**
|
|
762
|
+
* Generate system prompt additions from skill configurations.
|
|
763
|
+
* This embeds user-specific instructions and config settings into the system prompt
|
|
764
|
+
* so the agent knows how to use each KSA according to user preferences.
|
|
765
|
+
*
|
|
766
|
+
* @param skillConfigs - Map of KSA name to user config (e.g., { web: { depth: 'thorough', instructions: '...' } })
|
|
767
|
+
* @returns String to add to system prompt, or empty string if no configs
|
|
768
|
+
*/
|
|
769
|
+
export function generateKSAInstructions(
|
|
770
|
+
skillConfigs: Record<string, Record<string, unknown>>
|
|
771
|
+
): string {
|
|
772
|
+
const sections: string[] = [];
|
|
773
|
+
|
|
774
|
+
for (const [ksaName, config] of Object.entries(skillConfigs)) {
|
|
775
|
+
// Skip if no meaningful config (only _isPreset/_baseKSA markers or empty)
|
|
776
|
+
const meaningfulKeys = Object.keys(config).filter(
|
|
777
|
+
(k) => !k.startsWith("_")
|
|
778
|
+
);
|
|
779
|
+
if (meaningfulKeys.length === 0) continue;
|
|
780
|
+
|
|
781
|
+
// Skip if only has instructions that's empty
|
|
782
|
+
if (
|
|
783
|
+
meaningfulKeys.length === 1 &&
|
|
784
|
+
meaningfulKeys[0] === "instructions" &&
|
|
785
|
+
!config.instructions
|
|
786
|
+
) {
|
|
787
|
+
continue;
|
|
788
|
+
}
|
|
789
|
+
|
|
790
|
+
const displayName = KSA_DISPLAY_NAMES[ksaName] || ksaName;
|
|
791
|
+
const lines: string[] = [`### ${displayName} Configuration`];
|
|
792
|
+
lines.push(`When using the ${ksaName} KSA:`);
|
|
793
|
+
|
|
794
|
+
// Add user instructions first (most important)
|
|
795
|
+
if (config.instructions && typeof config.instructions === "string") {
|
|
796
|
+
lines.push(`- **User Instructions:** ${config.instructions}`);
|
|
797
|
+
}
|
|
798
|
+
|
|
799
|
+
// Add relevant config settings
|
|
800
|
+
if (config.depth) {
|
|
801
|
+
lines.push(`- Research depth: ${config.depth}`);
|
|
802
|
+
}
|
|
803
|
+
if (config.searchType) {
|
|
804
|
+
lines.push(`- Search type: ${config.searchType}`);
|
|
805
|
+
}
|
|
806
|
+
if (config.fastMode !== undefined) {
|
|
807
|
+
lines.push(`- Fast mode: ${config.fastMode ? "enabled" : "disabled"}`);
|
|
808
|
+
}
|
|
809
|
+
if (Array.isArray(config.platforms) && config.platforms.length > 0) {
|
|
810
|
+
lines.push(`- Platforms: ${config.platforms.join(", ")}`);
|
|
811
|
+
}
|
|
812
|
+
if (Array.isArray(config.contentTypes) && config.contentTypes.length > 0) {
|
|
813
|
+
lines.push(`- Content types: ${config.contentTypes.join(", ")}`);
|
|
814
|
+
}
|
|
815
|
+
if (config.postsLimit) {
|
|
816
|
+
lines.push(`- Posts limit: ${config.postsLimit}`);
|
|
817
|
+
}
|
|
818
|
+
if (config.enrichmentLevel) {
|
|
819
|
+
lines.push(`- Enrichment level: ${config.enrichmentLevel}`);
|
|
820
|
+
}
|
|
821
|
+
if (config.includeTechStack !== undefined) {
|
|
822
|
+
lines.push(
|
|
823
|
+
`- Include tech stack: ${config.includeTechStack ? "yes" : "no"}`
|
|
824
|
+
);
|
|
825
|
+
}
|
|
826
|
+
if (config.template) {
|
|
827
|
+
lines.push(`- Template: ${config.template}`);
|
|
828
|
+
}
|
|
829
|
+
if (config.pageSize) {
|
|
830
|
+
lines.push(`- Page size: ${config.pageSize}`);
|
|
831
|
+
}
|
|
832
|
+
if (config.sandboxMode !== undefined) {
|
|
833
|
+
lines.push(
|
|
834
|
+
`- Sandbox mode: ${config.sandboxMode ? "enabled (test only)" : "disabled (live)"}`
|
|
835
|
+
);
|
|
836
|
+
}
|
|
837
|
+
if (Array.isArray(config.includeSources) && config.includeSources.length > 0) {
|
|
838
|
+
lines.push(`- Include sources: ${config.includeSources.join(", ")}`);
|
|
839
|
+
}
|
|
840
|
+
if (Array.isArray(config.excludeSources) && config.excludeSources.length > 0) {
|
|
841
|
+
lines.push(`- Exclude sources: ${config.excludeSources.join(", ")}`);
|
|
842
|
+
}
|
|
843
|
+
|
|
844
|
+
sections.push(lines.join("\n"));
|
|
845
|
+
}
|
|
846
|
+
|
|
847
|
+
if (sections.length === 0) {
|
|
848
|
+
return "";
|
|
849
|
+
}
|
|
850
|
+
|
|
851
|
+
return `## Skill Configurations\n\nThe following KSAs have been configured with specific settings for this task:\n\n${sections.join("\n\n")}`;
|
|
852
|
+
}
|