@deepagents/orchestrator 6.1.0 → 7.0.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/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/lib/arxiv/arxiv.js +153 -0
- package/dist/lib/arxiv/arxiv.js.map +7 -0
- package/dist/lib/citation.js +120 -0
- package/dist/lib/citation.js.map +7 -0
- package/dist/lib/deepplan/demo.js +518 -0
- package/dist/lib/deepplan/demo.js.map +7 -0
- package/dist/lib/deepplan/executors/generic-executor.js +196 -0
- package/dist/lib/deepplan/executors/generic-executor.js.map +7 -0
- package/dist/lib/deepplan/executors/hackernews-executor.js +210 -0
- package/dist/lib/deepplan/executors/hackernews-executor.js.map +7 -0
- package/dist/lib/deepplan/executors/product-manager-executor.js +226 -0
- package/dist/lib/deepplan/executors/product-manager-executor.js.map +7 -0
- package/dist/lib/deepplan/executors/repo-search-executor.js +76 -0
- package/dist/lib/deepplan/executors/repo-search-executor.js.map +7 -0
- package/dist/lib/deepplan/executors/research-executor.js +196 -0
- package/dist/lib/deepplan/executors/research-executor.js.map +7 -0
- package/dist/lib/deepplan/next/plan.js +1 -0
- package/dist/lib/deepplan/next/plan.js.map +7 -0
- package/dist/lib/deepplan/plan-and-solve.js +826 -0
- package/dist/lib/deepplan/plan-and-solve.js.map +7 -0
- package/dist/lib/deepplan/planner-agent.js +416 -0
- package/dist/lib/deepplan/planner-agent.js.map +7 -0
- package/dist/lib/deepplan/replanner-agent.js +418 -0
- package/dist/lib/deepplan/replanner-agent.js.map +7 -0
- package/dist/lib/deepplan/synthesizer.js +75 -0
- package/dist/lib/deepplan/synthesizer.js.map +7 -0
- package/dist/lib/deepresearch.v0.js +297 -0
- package/dist/lib/deepresearch.v0.js.map +7 -0
- package/dist/lib/deepresearch.v1.js +260 -0
- package/dist/lib/deepresearch.v1.js.map +7 -0
- package/dist/lib/deepwiki/complete-wiki.js +319 -0
- package/dist/lib/deepwiki/complete-wiki.js.map +7 -0
- package/dist/lib/deepwiki/deepwiki.js +370 -0
- package/dist/lib/deepwiki/deepwiki.js.map +7 -0
- package/dist/lib/deepwiki/gitignore-agent.js +40 -0
- package/dist/lib/deepwiki/gitignore-agent.js.map +7 -0
- package/dist/lib/deepwiki/outline-agent.d.ts.map +1 -1
- package/dist/lib/deepwiki/outline-agent.js +186 -0
- package/dist/lib/deepwiki/outline-agent.js.map +7 -0
- package/dist/lib/deepwiki/wiki-writer.js +242 -0
- package/dist/lib/deepwiki/wiki-writer.js.map +7 -0
- package/dist/lib/deepwiki/writer.js +407 -0
- package/dist/lib/deepwiki/writer.js.map +7 -0
- package/dist/lib/evolving.js +204 -0
- package/dist/lib/evolving.js.map +7 -0
- package/dist/lib/graph.js +12 -0
- package/dist/lib/graph.js.map +7 -0
- package/dist/lib/openai-deepresearch/clarrify-agent.js +67 -0
- package/dist/lib/openai-deepresearch/clarrify-agent.js.map +7 -0
- package/dist/lib/openai-deepresearch/lead-research.js +168 -0
- package/dist/lib/openai-deepresearch/lead-research.js.map +7 -0
- package/dist/lib/openai-deepresearch/openai-deepresearch.js +179 -0
- package/dist/lib/openai-deepresearch/openai-deepresearch.js.map +7 -0
- package/dist/lib/openai-deepresearch/reasearcher.js +62 -0
- package/dist/lib/openai-deepresearch/reasearcher.js.map +7 -0
- package/dist/lib/openai-deepresearch/research-brief.js +59 -0
- package/dist/lib/openai-deepresearch/research-brief.js.map +7 -0
- package/dist/lib/repo-context.js +11 -0
- package/dist/lib/repo-context.js.map +7 -0
- package/package.json +8 -8
|
@@ -0,0 +1,407 @@
|
|
|
1
|
+
// packages/orchestrator/src/lib/deepwiki/writer.ts
|
|
2
|
+
import { groq as groq2 } from "@ai-sdk/groq";
|
|
3
|
+
import { tool as tool2 } from "ai";
|
|
4
|
+
import { snakeCase } from "lodash-es";
|
|
5
|
+
import { readFile, writeFile } from "node:fs/promises";
|
|
6
|
+
import z2 from "zod";
|
|
7
|
+
import {
|
|
8
|
+
agent as agent2,
|
|
9
|
+
execute as execute2,
|
|
10
|
+
instructions as instructions2,
|
|
11
|
+
lmstudio,
|
|
12
|
+
printer,
|
|
13
|
+
toState,
|
|
14
|
+
user as user2
|
|
15
|
+
} from "@deepagents/agent";
|
|
16
|
+
import {
|
|
17
|
+
read_file_tool as read_file_tool2,
|
|
18
|
+
scratchpad_tool as scratchpad_tool2,
|
|
19
|
+
search_content_tool
|
|
20
|
+
} from "@deepagents/toolbox";
|
|
21
|
+
|
|
22
|
+
// packages/orchestrator/src/lib/graph.ts
|
|
23
|
+
async function fold(item, parent, write2, store) {
|
|
24
|
+
const sections = item.sections || [];
|
|
25
|
+
for (const section of sections) {
|
|
26
|
+
await fold(section, item, write2, store);
|
|
27
|
+
}
|
|
28
|
+
await store.set(item.title, await write2(item));
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// packages/orchestrator/src/lib/deepwiki/outline-agent.ts
|
|
32
|
+
import { groq } from "@ai-sdk/groq";
|
|
33
|
+
import { generateId, toUIMessageStream, tool } from "ai";
|
|
34
|
+
import z from "zod";
|
|
35
|
+
import {
|
|
36
|
+
agent,
|
|
37
|
+
execute,
|
|
38
|
+
generate,
|
|
39
|
+
instructions,
|
|
40
|
+
user
|
|
41
|
+
} from "@deepagents/agent";
|
|
42
|
+
import { read_file_tool, scratchpad_tool } from "@deepagents/toolbox";
|
|
43
|
+
var BaseOutlineItem = z.object({
|
|
44
|
+
title: z.string().trim().min(1, "Title is required")
|
|
45
|
+
});
|
|
46
|
+
var OutlineItemSchema = z.lazy(
|
|
47
|
+
() => BaseOutlineItem.extend({
|
|
48
|
+
sections: z.array(OutlineItemSchema).optional()
|
|
49
|
+
})
|
|
50
|
+
);
|
|
51
|
+
var OutlineSchema = z.array(OutlineItemSchema);
|
|
52
|
+
var outlineAgent = agent({
|
|
53
|
+
name: "Outline Agent",
|
|
54
|
+
model: groq("moonshotai/kimi-k2-instruct-0905"),
|
|
55
|
+
// model: lmstudio('qwen/qwen3-8b'),
|
|
56
|
+
// model: lmstudio('openai/gpt-oss-20b'),
|
|
57
|
+
// temperature: 0.1,
|
|
58
|
+
prompt: (context) => instructions({
|
|
59
|
+
purpose: [
|
|
60
|
+
"You are wiki architect, meticulously analyzing a repository's structure and content to automatically generate a comprehensive, intelligent, and perfectly structured outline, laying the bedrock for exceptional documentation.",
|
|
61
|
+
"\n",
|
|
62
|
+
"<RepositoryTree>",
|
|
63
|
+
context?.tree || "",
|
|
64
|
+
"</RepositoryTree>"
|
|
65
|
+
],
|
|
66
|
+
routine: []
|
|
67
|
+
// routine: [
|
|
68
|
+
// 'Your primary tool for memory is your `scratchpad`. After every action, you MUST summarize your findings and add them to the scratchpad using the `update_scratchpad` tool.',
|
|
69
|
+
// 'Systematically investigate key files and directories use `search_files`. For each finding add it as a new note to your scratchpad.',
|
|
70
|
+
// 'When you read a file like `README.md` or `package.json`, do not keep the whole content in your head. Instead, summarize the important parts (like headings, dependencies, or scripts) and add that summary to your scratchpad.',
|
|
71
|
+
// 'Continue this process of exploring, summarizing, and adding to your scratchpad until you are confident you have a full picture of the repository.',
|
|
72
|
+
// 'Once you believe you have gathered enough information, your second-to-last step is to review your entire scratchpad to synthesize a plan for the final outline.',
|
|
73
|
+
// 'Finally, based *only* on the information you have gathered in your scratchpad, generate the complete, detailed outline and store it using the `store_outline` tool. You must only call `store_outline` ONCE at the very end.',
|
|
74
|
+
// ],
|
|
75
|
+
}),
|
|
76
|
+
tools: {
|
|
77
|
+
read_file: read_file_tool,
|
|
78
|
+
// read_dir: read_dir_tool,
|
|
79
|
+
// search_files: search_files_tool,
|
|
80
|
+
// file_exists: file_exists_tool,
|
|
81
|
+
update_scratchpad: scratchpad_tool,
|
|
82
|
+
store_outline: tool({
|
|
83
|
+
description: `Use this tool to store the generated outline.
|
|
84
|
+
The outline should be a detailed hierarchical structure representing the sections and subsections of the repository documentation. In thory you can nest sections as deep as you want, but try to keep it to 4 levels deep maximum.
|
|
85
|
+
|
|
86
|
+
## Example outline
|
|
87
|
+
[
|
|
88
|
+
{
|
|
89
|
+
"title": "xxxx",
|
|
90
|
+
"sections": [
|
|
91
|
+
{
|
|
92
|
+
"title": "yyyy",
|
|
93
|
+
sections: [
|
|
94
|
+
{
|
|
95
|
+
"title": "vvvv",
|
|
96
|
+
"sections": [...],
|
|
97
|
+
}
|
|
98
|
+
]
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
"title": "gggg",
|
|
102
|
+
"sections": [...],
|
|
103
|
+
}
|
|
104
|
+
]
|
|
105
|
+
},
|
|
106
|
+
]
|
|
107
|
+
`,
|
|
108
|
+
inputSchema: z.object({
|
|
109
|
+
outline: OutlineSchema
|
|
110
|
+
})
|
|
111
|
+
// execute: ({ outline }, options) => {
|
|
112
|
+
// const context = toState<OutlineAgentContext>(options);
|
|
113
|
+
// // Store the outline in a file or database
|
|
114
|
+
// console.log('Generated Outline:\n', outline);
|
|
115
|
+
// context.outline = outline;
|
|
116
|
+
// return 'Outline stored successfully.';
|
|
117
|
+
// },
|
|
118
|
+
})
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
var outlineCondensedAgent = agent({
|
|
122
|
+
name: "Outline Condensed Agent",
|
|
123
|
+
model: groq("moonshotai/kimi-k2-instruct-0905"),
|
|
124
|
+
prompt: instructions({
|
|
125
|
+
purpose: [
|
|
126
|
+
"To intelligently condense and optimize an existing outline by merging redundant sections, removing overly granular subdivisions, and creating a more streamlined, maintainable documentation structure.",
|
|
127
|
+
"Your goal is to reduce complexity while preserving all essential information and maintaining logical hierarchy."
|
|
128
|
+
],
|
|
129
|
+
routine: [
|
|
130
|
+
"Examine the current outline structure stored in the context. Use your scratchpad to track your analysis.",
|
|
131
|
+
"Identify sections that are too granular (e.g., sections with only 1-2 subsections that could be merged with their parent).",
|
|
132
|
+
"Look for redundant or overlapping sections that cover similar topics and can be consolidated.",
|
|
133
|
+
"Note sections with excessive nesting depth (more than 3-4 levels) that could be flattened.",
|
|
134
|
+
'Identify sections with very similar titles that could be merged (e.g., "API Overview" and "API Introduction").',
|
|
135
|
+
"For each potential consolidation, add a note to your scratchpad explaining the rationale.",
|
|
136
|
+
"Create a condensed version of the outline that:",
|
|
137
|
+
" - Merges related subsections into broader topics",
|
|
138
|
+
" - Reduces nesting depth where appropriate",
|
|
139
|
+
" - Eliminates redundancy while keeping all unique content areas",
|
|
140
|
+
" - Maintains a maximum depth of 3 levels unless absolutely necessary",
|
|
141
|
+
" - Ensures each section has substantial content to document",
|
|
142
|
+
"Return the condensed outline as structured output."
|
|
143
|
+
]
|
|
144
|
+
}),
|
|
145
|
+
output: OutlineSchema
|
|
146
|
+
});
|
|
147
|
+
function slugify(text) {
|
|
148
|
+
return text.toLowerCase().replace(/[^a-z0-9\s-]/g, "").trim().replace(/\s+/g, "-").replace(/-+/g, "-");
|
|
149
|
+
}
|
|
150
|
+
function buildToc(items, baseDepth = 1, prefix = []) {
|
|
151
|
+
const lines = [];
|
|
152
|
+
for (const it of items) {
|
|
153
|
+
const path = [...prefix, it.title];
|
|
154
|
+
const indent = " ".repeat(Math.max(0, path.length - 1));
|
|
155
|
+
const anchor = slugify(it.title);
|
|
156
|
+
lines.push(`${indent}- [${it.title}](#${anchor})`);
|
|
157
|
+
if (it.sections?.length) {
|
|
158
|
+
lines.push(...buildToc(it.sections, baseDepth + 1, path));
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
return lines;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// packages/orchestrator/src/lib/deepwiki/writer.ts
|
|
165
|
+
var write_section_tool = tool2({
|
|
166
|
+
description: "Use this tool to return the final markdown content for the current section. You MUST use this tool to return your final output.",
|
|
167
|
+
inputSchema: z2.object({
|
|
168
|
+
sectionTitle: z2.string().describe(
|
|
169
|
+
'The title of the section being written. Prefer the FULL hierarchical path like "Parent > Child" to ensure uniqueness.'
|
|
170
|
+
),
|
|
171
|
+
sectionContent: z2.string().describe(
|
|
172
|
+
"The markdown content for the section excluding section heading."
|
|
173
|
+
)
|
|
174
|
+
}),
|
|
175
|
+
execute: async ({
|
|
176
|
+
sectionTitle,
|
|
177
|
+
sectionContent
|
|
178
|
+
}, options) => {
|
|
179
|
+
const context = toState(options);
|
|
180
|
+
const p = `./docs/section_${snakeCase(sectionTitle)}.md`;
|
|
181
|
+
await writeFile(p, sectionContent, "utf-8");
|
|
182
|
+
context.section_path[sectionTitle] = p;
|
|
183
|
+
return `Section "${sectionTitle}" written to file.`;
|
|
184
|
+
}
|
|
185
|
+
});
|
|
186
|
+
var writer = agent2({
|
|
187
|
+
name: "Wiki Writer",
|
|
188
|
+
model: lmstudio("qwen/qwen3-8b"),
|
|
189
|
+
// model: groq('openai/gpt-oss-120b'),
|
|
190
|
+
// model: groq('openai/gpt-oss-20b'),
|
|
191
|
+
prompt: instructions2({
|
|
192
|
+
purpose: [
|
|
193
|
+
"You write comprehensive, accurate, and actionable documentation sections for a repository wiki.",
|
|
194
|
+
"You can inspect files and directory structure using provided tools to ground your writing in the actual codebase."
|
|
195
|
+
],
|
|
196
|
+
routine: [
|
|
197
|
+
"Use the scratchpad to note findings from reading files or directories; keep it concise and relevant.",
|
|
198
|
+
"Clarify scope: write ONLY for the current section path you are working on; do not expand into subsections (those are handled separately).",
|
|
199
|
+
"Avoid references to unknown frameworks or generated folders; ground claims in actual repo contents when possible.",
|
|
200
|
+
"Make use of the `search_content` tool to find relevant information in the codebase. this tool can search the entire repository for keywords or topics. use it to find code examples, explanations, or relevant files.",
|
|
201
|
+
'When you return a section via write_section, set sectionTitle to the FULL hierarchical path of the section using ">" as a separator (e.g., "Parent > Child > Subchild").'
|
|
202
|
+
]
|
|
203
|
+
}),
|
|
204
|
+
tools: {
|
|
205
|
+
read_file: read_file_tool2,
|
|
206
|
+
// read_dir: read_dir_tool,
|
|
207
|
+
// search_files: search_files_tool,
|
|
208
|
+
write_section: write_section_tool,
|
|
209
|
+
search_content: search_content_tool,
|
|
210
|
+
update_scratchpad: scratchpad_tool2
|
|
211
|
+
}
|
|
212
|
+
});
|
|
213
|
+
function headingFor(level, title) {
|
|
214
|
+
const capped = Math.min(Math.max(level, 1), 6);
|
|
215
|
+
return `${"#".repeat(capped)} ${title}`;
|
|
216
|
+
}
|
|
217
|
+
async function generateWiki(options) {
|
|
218
|
+
const toc = buildToc(options.outline);
|
|
219
|
+
const state = {
|
|
220
|
+
repo_path: options.repo_path,
|
|
221
|
+
scratchpad: "## Scratchpad\n\n",
|
|
222
|
+
tree: options.tree,
|
|
223
|
+
toc,
|
|
224
|
+
section_path: {}
|
|
225
|
+
};
|
|
226
|
+
return "";
|
|
227
|
+
}
|
|
228
|
+
var sectionWriterAgent = agent2({
|
|
229
|
+
name: "Section Writer",
|
|
230
|
+
// model: lmstudio('qwen/qwen3-8b'),
|
|
231
|
+
model: groq2("openai/gpt-oss-20b"),
|
|
232
|
+
// temperature: 0.3,
|
|
233
|
+
tools: {
|
|
234
|
+
read_file: read_file_tool2,
|
|
235
|
+
search_content: search_content_tool
|
|
236
|
+
},
|
|
237
|
+
prompt: ""
|
|
238
|
+
});
|
|
239
|
+
var stitchAgent = agent2({
|
|
240
|
+
name: "Stitch Agent",
|
|
241
|
+
model: groq2("moonshotai/kimi-k2-instruct-0905"),
|
|
242
|
+
prompt: instructions2({
|
|
243
|
+
purpose: [
|
|
244
|
+
"You synthesize and stitch together child subsections into a cohesive parent section for a wiki.",
|
|
245
|
+
"Your role is to create an introduction and transitions that bind child sections together while maintaining clarity and flow."
|
|
246
|
+
],
|
|
247
|
+
routine: [
|
|
248
|
+
"Review all child section contents provided to understand their focus and relationships.",
|
|
249
|
+
"Create a cohesive parent section that introduces the topic and smoothly connects to the child sections.",
|
|
250
|
+
"Add transitions and context that help readers understand how child sections relate to each other.",
|
|
251
|
+
"Do NOT duplicate content from child sections; reference and introduce them instead.",
|
|
252
|
+
"Keep your writing clear, concise, and focused on synthesis rather than repetition."
|
|
253
|
+
]
|
|
254
|
+
})
|
|
255
|
+
});
|
|
256
|
+
async function write(state, item) {
|
|
257
|
+
console.log(buildToc([item]));
|
|
258
|
+
return await execute2(
|
|
259
|
+
sectionWriterAgent,
|
|
260
|
+
[
|
|
261
|
+
user2(
|
|
262
|
+
`
|
|
263
|
+
You are part of a team writing a comprehensive wiki for a code repository. Your specific task is to write the following section of the wiki:
|
|
264
|
+
|
|
265
|
+
<SectionTitle>
|
|
266
|
+
${item.title}
|
|
267
|
+
</SectionTitle>
|
|
268
|
+
<ActiveSectionWiki>
|
|
269
|
+
${buildToc([item])}
|
|
270
|
+
</ActiveSectionWiki>
|
|
271
|
+
|
|
272
|
+
The complete wiki outline is as follows:
|
|
273
|
+
<WikiOutline>
|
|
274
|
+
${state.toc}
|
|
275
|
+
</WikiOutline>
|
|
276
|
+
|
|
277
|
+
The repository structure is as follows:
|
|
278
|
+
|
|
279
|
+
<RepositoryTree>
|
|
280
|
+
${state.tree}
|
|
281
|
+
</RepositoryTree>
|
|
282
|
+
|
|
283
|
+
You should:
|
|
284
|
+
|
|
285
|
+
1. Understand the section title and its place in the overall structure.
|
|
286
|
+
2. Use the provided tools to inspect relevant files and directories in the repository to gather information for that section.
|
|
287
|
+
3. Write clear, concise, and informative markdown content for the section, including code examples where appropriate.
|
|
288
|
+
4. Ensure that the section is self-contained and provides value to someone reading the wiki.
|
|
289
|
+
|
|
290
|
+
Remember to keep your writing clear, concise, and focused on the current section topic. Do not include information about other sections or subsections.
|
|
291
|
+
`
|
|
292
|
+
)
|
|
293
|
+
],
|
|
294
|
+
state
|
|
295
|
+
);
|
|
296
|
+
}
|
|
297
|
+
async function stitch(state, item, childSections) {
|
|
298
|
+
const childSectionsList = childSections.map(
|
|
299
|
+
(child) => `
|
|
300
|
+
### ${child.title}
|
|
301
|
+
${child.content}
|
|
302
|
+
`
|
|
303
|
+
).join("\n");
|
|
304
|
+
return await execute2(
|
|
305
|
+
stitchAgent,
|
|
306
|
+
[
|
|
307
|
+
user2(
|
|
308
|
+
`
|
|
309
|
+
You are stitching together child subsections into a cohesive parent section for a wiki. Your task is to create an introduction and transitions that bind the following child sections together.
|
|
310
|
+
|
|
311
|
+
<ParentSectionTitle>
|
|
312
|
+
${item.title}
|
|
313
|
+
</ParentSectionTitle>
|
|
314
|
+
|
|
315
|
+
<ChildSections>
|
|
316
|
+
${childSectionsList}
|
|
317
|
+
</ChildSections>
|
|
318
|
+
|
|
319
|
+
The complete wiki outline is as follows:
|
|
320
|
+
<WikiOutline>
|
|
321
|
+
${state.toc}
|
|
322
|
+
</WikiOutline>
|
|
323
|
+
|
|
324
|
+
The repository structure is as follows:
|
|
325
|
+
|
|
326
|
+
<RepositoryTree>
|
|
327
|
+
${state.tree}
|
|
328
|
+
</RepositoryTree>
|
|
329
|
+
|
|
330
|
+
Your task is to:
|
|
331
|
+
|
|
332
|
+
1. Create an introduction to the parent section that sets the context for the child sections.
|
|
333
|
+
2. Add smooth transitions between child sections that explain their relationships.
|
|
334
|
+
3. Synthesize the content into a cohesive narrative rather than just concatenating the children.
|
|
335
|
+
4. Do NOT duplicate the full content of child sections - assume readers will see them in context.
|
|
336
|
+
5. Focus on creating connections and providing high-level overview.
|
|
337
|
+
|
|
338
|
+
`
|
|
339
|
+
)
|
|
340
|
+
],
|
|
341
|
+
state
|
|
342
|
+
);
|
|
343
|
+
}
|
|
344
|
+
function assembleDocument(items, local, depth) {
|
|
345
|
+
let output = "";
|
|
346
|
+
for (const item of items) {
|
|
347
|
+
const content = local[item.title];
|
|
348
|
+
output += `${headingFor(depth, item.title)}
|
|
349
|
+
|
|
350
|
+
`;
|
|
351
|
+
if (content) {
|
|
352
|
+
output += `${content}
|
|
353
|
+
|
|
354
|
+
`;
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
return output;
|
|
358
|
+
}
|
|
359
|
+
async function singlePageWiki(state) {
|
|
360
|
+
const root = state.outline[0];
|
|
361
|
+
const local = {};
|
|
362
|
+
const store = {
|
|
363
|
+
async set(key, value) {
|
|
364
|
+
await writeFile(`./docs/section_${snakeCase(key)}.md`, value, "utf-8");
|
|
365
|
+
local[key] = value;
|
|
366
|
+
}
|
|
367
|
+
};
|
|
368
|
+
await fold(
|
|
369
|
+
root,
|
|
370
|
+
{ title: root.title },
|
|
371
|
+
async (item) => {
|
|
372
|
+
if (!item.sections || item.sections.length === 0) {
|
|
373
|
+
const result = await write(
|
|
374
|
+
{
|
|
375
|
+
repo_path: state.repo_path,
|
|
376
|
+
tree: state.tree,
|
|
377
|
+
scratchpad: "## Scratchpad\n\n",
|
|
378
|
+
toc: buildToc(state.outline)
|
|
379
|
+
},
|
|
380
|
+
item
|
|
381
|
+
);
|
|
382
|
+
return result.text;
|
|
383
|
+
} else {
|
|
384
|
+
const stitchResult = await stitch(
|
|
385
|
+
{
|
|
386
|
+
repo_path: state.repo_path,
|
|
387
|
+
tree: state.tree,
|
|
388
|
+
scratchpad: "## Scratchpad\n\n",
|
|
389
|
+
toc: buildToc(state.outline)
|
|
390
|
+
},
|
|
391
|
+
item,
|
|
392
|
+
Object.entries(local).filter(([k]) => item.sections.some((key) => key.title === k)).map(([title, content]) => ({ title, content }))
|
|
393
|
+
);
|
|
394
|
+
console.log("=== STITCH RESULT ===");
|
|
395
|
+
await printer.stdout(stitchResult);
|
|
396
|
+
return stitchResult.text;
|
|
397
|
+
}
|
|
398
|
+
},
|
|
399
|
+
store
|
|
400
|
+
);
|
|
401
|
+
return assembleDocument(state.outline, local, 1);
|
|
402
|
+
}
|
|
403
|
+
export {
|
|
404
|
+
generateWiki,
|
|
405
|
+
singlePageWiki
|
|
406
|
+
};
|
|
407
|
+
//# sourceMappingURL=writer.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/lib/deepwiki/writer.ts", "../../../src/lib/graph.ts", "../../../src/lib/deepwiki/outline-agent.ts"],
|
|
4
|
+
"sourcesContent": ["import { groq } from '@ai-sdk/groq';\nimport { type ToolExecutionOptions, tool } from 'ai';\nimport { snakeCase } from 'lodash-es';\nimport { readFile, writeFile } from 'node:fs/promises';\nimport z from 'zod';\n\nimport {\n agent,\n execute,\n instructions,\n lmstudio,\n printer,\n toState,\n user,\n} from '@deepagents/agent';\nimport {\n read_file_tool,\n scratchpad_tool,\n search_content_tool,\n} from '@deepagents/toolbox';\n\nimport { fold } from '../graph.ts';\nimport { type Outline, buildToc } from './outline-agent.ts';\n\ntype SectionAgentContext = {\n repo_path: string;\n scratchpad: string;\n tree: string;\n toc: string[];\n section_path: Record<string, string>;\n};\n\n// Define tool outside agent to help TypeScript with type inference\nconst write_section_tool = tool({\n description:\n 'Use this tool to return the final markdown content for the current section. You MUST use this tool to return your final output.',\n inputSchema: z.object({\n sectionTitle: z\n .string()\n .describe(\n 'The title of the section being written. Prefer the FULL hierarchical path like \"Parent > Child\" to ensure uniqueness.',\n ),\n sectionContent: z\n .string()\n .describe(\n 'The markdown content for the section excluding section heading.',\n ),\n }),\n execute: async (\n {\n sectionTitle,\n sectionContent,\n }: { sectionTitle: string; sectionContent: string },\n options: ToolExecutionOptions<any>,\n ) => {\n const context = toState<SectionAgentContext>(options);\n const p = `./docs/section_${snakeCase(sectionTitle)}.md`;\n await writeFile(p, sectionContent, 'utf-8');\n context.section_path[sectionTitle] = p;\n return `Section \"${sectionTitle}\" written to file.`;\n },\n});\n\nconst writer = agent<SectionAgentContext>({\n name: 'Wiki Writer',\n model: lmstudio('qwen/qwen3-8b'),\n // model: groq('openai/gpt-oss-120b'),\n // model: groq('openai/gpt-oss-20b'),\n prompt: instructions({\n purpose: [\n 'You write comprehensive, accurate, and actionable documentation sections for a repository wiki.',\n 'You can inspect files and directory structure using provided tools to ground your writing in the actual codebase.',\n ],\n routine: [\n 'Use the scratchpad to note findings from reading files or directories; keep it concise and relevant.',\n 'Clarify scope: write ONLY for the current section path you are working on; do not expand into subsections (those are handled separately).',\n 'Avoid references to unknown frameworks or generated folders; ground claims in actual repo contents when possible.',\n 'Make use of the `search_content` tool to find relevant information in the codebase. this tool can search the entire repository for keywords or topics. use it to find code examples, explanations, or relevant files.',\n 'When you return a section via write_section, set sectionTitle to the FULL hierarchical path of the section using \">\" as a separator (e.g., \"Parent > Child > Subchild\").',\n ],\n }),\n tools: {\n read_file: read_file_tool,\n // read_dir: read_dir_tool,\n // search_files: search_files_tool,\n write_section: write_section_tool,\n search_content: search_content_tool,\n update_scratchpad: scratchpad_tool,\n },\n});\n\nfunction headingFor(level: number, title: string) {\n const capped = Math.min(Math.max(level, 1), 6);\n return `${'#'.repeat(capped)} ${title}`;\n}\n\nasync function readIfExists(path: string): Promise<string | undefined> {\n try {\n return await readFile(path, 'utf-8');\n } catch {\n return undefined;\n }\n}\n\nasync function aggregateSections(\n items: Outline,\n depth: number,\n state: SectionAgentContext,\n path: string[] = [],\n): Promise<string> {\n let out = '';\n for (const item of items) {\n const currentPath = [...path, item.title];\n const pathKey = currentPath.join(' > ');\n const directKey = item.title;\n\n // Prefer mapped file based on full path, fall back to title, then inferred filename(s)\n const mappedPath =\n state.section_path[pathKey] || state.section_path[directKey];\n const inferredCandidates = [\n `./section_${snakeCase(pathKey)}.md`,\n `./section_${snakeCase(directKey)}.md`,\n ];\n\n let content: string | undefined;\n if (mappedPath) {\n content = await readIfExists(mappedPath);\n }\n if (!content) {\n for (const p of inferredCandidates) {\n content = await readIfExists(p);\n if (content) break;\n }\n }\n\n out += `\\n\\n${headingFor(depth, item.title)}\\n\\n`;\n if (content) out += `${content}\\n`;\n\n if (item.sections?.length) {\n out += await aggregateSections(\n item.sections,\n depth + 1,\n state,\n currentPath,\n );\n }\n }\n return out;\n}\n\nexport async function generateWiki(options: {\n repo_path: string;\n outline: Outline;\n tree: string;\n}) {\n const toc = buildToc(options.outline);\n const state: SectionAgentContext = {\n repo_path: options.repo_path,\n scratchpad: '## Scratchpad\\n\\n',\n tree: options.tree,\n toc: toc,\n section_path: {},\n };\n\n // await execute(\n // writer,\n // [\n // user(`You are tasked with writing a comprehensive wiki for a code repository. The wiki will be structured according to the provided outline, which details the sections and subsections to be covered.\n\n // <RepositoryTree>\n // ${options.tree}\n // </RepositoryTree>\n\n // <WikiOutline>\n // ${toc}\n // </WikiOutline>\n\n // Your job is to write each section of the wiki based on this outline. For each section, you should:\n\n // 1. Understand the section title and its place in the overall structure.\n // 2. Use the provided tools to inspect relevant files and directories in the repository to gather information for that section.\n // 3. Write clear, concise, and informative markdown content for the section, including code examples where appropriate.\n // 4. Ensure that each section is self-contained and provides value to someone reading the wiki.\n\n // Begin by writing the top-level sections of the outline. For each section, if there are subsections, you will handle those separately after completing the parent section.\n\n // Important: When calling write_section, set sectionTitle to the FULL hierarchical path (e.g., \"Parent > Child > Subchild\").\n\n // ],\n // state,\n // ).text;\n\n // const header = ['# Project Wiki', '', '## Table of Contents', ...toc].join(\n // '\\n',\n // );\n\n // const body = await aggregateSections(options.outline, 1, state);\n // return `${header}\\n\\n${body}\\n`;\n return '';\n}\n\ntype IsolatedSectionAgentContext = {\n repo_path: string;\n scratchpad: string;\n tree: string;\n toc: string[];\n};\nconst sectionWriterAgent = agent<IsolatedSectionAgentContext>({\n name: 'Section Writer',\n // model: lmstudio('qwen/qwen3-8b'),\n model: groq('openai/gpt-oss-20b'),\n // temperature: 0.3,\n tools: {\n read_file: read_file_tool,\n search_content: search_content_tool,\n },\n prompt: '',\n});\n\ntype StitchAgentContext = {\n repo_path: string;\n scratchpad: string;\n tree: string;\n toc: string[];\n};\nconst stitchAgent = agent<StitchAgentContext>({\n name: 'Stitch Agent',\n model: groq('moonshotai/kimi-k2-instruct-0905'),\n prompt: instructions({\n purpose: [\n 'You synthesize and stitch together child subsections into a cohesive parent section for a wiki.',\n 'Your role is to create an introduction and transitions that bind child sections together while maintaining clarity and flow.',\n ],\n routine: [\n 'Review all child section contents provided to understand their focus and relationships.',\n 'Create a cohesive parent section that introduces the topic and smoothly connects to the child sections.',\n 'Add transitions and context that help readers understand how child sections relate to each other.',\n 'Do NOT duplicate content from child sections; reference and introduce them instead.',\n 'Keep your writing clear, concise, and focused on synthesis rather than repetition.',\n ],\n }),\n});\n\nasync function write(\n state: IsolatedSectionAgentContext,\n item: Outline[number],\n) {\n console.log(buildToc([item]));\n return await execute(\n sectionWriterAgent,\n [\n user(\n `\n You are part of a team writing a comprehensive wiki for a code repository. Your specific task is to write the following section of the wiki:\n\n<SectionTitle>\n ${item.title}\n</SectionTitle>\n<ActiveSectionWiki>\n ${buildToc([item])}\n</ActiveSectionWiki>\n\nThe complete wiki outline is as follows:\n<WikiOutline>\n${state.toc}\n</WikiOutline>\n\nThe repository structure is as follows:\n\n<RepositoryTree>\n${state.tree}\n</RepositoryTree>\n\nYou should:\n\n1. Understand the section title and its place in the overall structure.\n2. Use the provided tools to inspect relevant files and directories in the repository to gather information for that section.\n3. Write clear, concise, and informative markdown content for the section, including code examples where appropriate.\n4. Ensure that the section is self-contained and provides value to someone reading the wiki.\n\nRemember to keep your writing clear, concise, and focused on the current section topic. Do not include information about other sections or subsections.\n`,\n ),\n ],\n state,\n );\n}\n\nasync function stitch(\n state: StitchAgentContext,\n item: Outline[number],\n childSections: Array<{ title: string; content: string }>,\n) {\n const childSectionsList = childSections\n .map(\n (child) => `\n### ${child.title}\n${child.content}\n`,\n )\n .join('\\n');\n\n return await execute(\n stitchAgent,\n [\n user(\n `\n You are stitching together child subsections into a cohesive parent section for a wiki. Your task is to create an introduction and transitions that bind the following child sections together.\n\n<ParentSectionTitle>\n ${item.title}\n</ParentSectionTitle>\n\n<ChildSections>\n${childSectionsList}\n</ChildSections>\n\nThe complete wiki outline is as follows:\n<WikiOutline>\n${state.toc}\n</WikiOutline>\n\nThe repository structure is as follows:\n\n<RepositoryTree>\n${state.tree}\n</RepositoryTree>\n\nYour task is to:\n\n1. Create an introduction to the parent section that sets the context for the child sections.\n2. Add smooth transitions between child sections that explain their relationships.\n3. Synthesize the content into a cohesive narrative rather than just concatenating the children.\n4. Do NOT duplicate the full content of child sections - assume readers will see them in context.\n5. Focus on creating connections and providing high-level overview.\n\n`,\n ),\n ],\n state,\n );\n}\n\nfunction assembleDocument(\n items: Outline,\n local: Record<string, string>,\n depth: number,\n): string {\n let output = '';\n\n for (const item of items) {\n const content = local[item.title];\n\n // Add heading for this section\n output += `${headingFor(depth, item.title)}\\n\\n`;\n\n // Add the content - if this is a parent section,\n // the stitched content already includes all children inline\n if (content) {\n output += `${content}\\n\\n`;\n }\n }\n\n return output;\n}\n\nexport async function singlePageWiki(state: {\n repo_path: string;\n outline: Outline;\n tree: string;\n}) {\n const root = state.outline[0];\n const local: Record<string, string> = {};\n const store = {\n async set(key: string, value: string) {\n await writeFile(`./docs/section_${snakeCase(key)}.md`, value, 'utf-8');\n local[key] = value;\n },\n };\n await fold(\n root,\n { title: root.title },\n async (item) => {\n if (!item.sections || item.sections.length === 0) {\n const result = await write(\n {\n repo_path: state.repo_path,\n tree: state.tree,\n scratchpad: '## Scratchpad\\n\\n',\n toc: buildToc(state.outline),\n },\n item,\n );\n // await printer.stdout(result);\n return result.text;\n } else {\n // Stitch the parent section from child sections\n const stitchResult = await stitch(\n {\n repo_path: state.repo_path,\n tree: state.tree,\n scratchpad: '## Scratchpad\\n\\n',\n toc: buildToc(state.outline),\n },\n item,\n Object.entries(local)\n .filter(([k]) => item.sections!.some((key) => key.title === k))\n .map(([title, content]) => ({ title, content })),\n );\n console.log('=== STITCH RESULT ===');\n await printer.stdout(stitchResult);\n return stitchResult.text;\n }\n },\n store,\n );\n\n // Assemble the final document from all processed sections\n return assembleDocument(state.outline, local, 1);\n}\n", "import type { Outline } from './deepwiki/outline-agent.ts';\n\ntype WithParent = {\n title: string;\n parent?: WithParent;\n sections?: WithParent[];\n};\n\nfunction flat(item: WithParent) {\n const paths: string[][] = [];\n if (!item.sections || item.sections.length === 0) {\n let current: WithParent | undefined = item;\n const path: string[] = [];\n while (current.parent) {\n current = current.parent;\n path.unshift(current.title);\n }\n path.push(item.title);\n paths.push(path);\n return paths;\n }\n for (const section of item.sections) {\n paths.push(...flat({ ...section, parent: item }));\n }\n return paths;\n}\n\nexport async function fold(\n item: Outline[number],\n parent: Outline[number],\n write: (section: Outline[number]) => Promise<string>,\n store: {\n set: (key: string, value: string) => Promise<void>;\n },\n) {\n const sections = item.sections || [];\n for (const section of sections) {\n await fold(section, item, write, store);\n }\n await store.set(item.title, await write(item));\n}\n", "import { groq } from '@ai-sdk/groq';\nimport { type UIMessage, generateId, toUIMessageStream, tool } from 'ai';\nimport z from 'zod';\n\nimport {\n agent,\n execute,\n generate,\n instructions,\n user,\n} from '@deepagents/agent';\nimport { read_file_tool, scratchpad_tool } from '@deepagents/toolbox';\n\nconst BaseOutlineItem = z.object({\n title: z.string().trim().min(1, 'Title is required'),\n});\ntype OutlineItem = z.output<typeof BaseOutlineItem> & {\n sections?: z.output<typeof OutlineItemSchema>[];\n};\nconst OutlineItemSchema: z.ZodType<OutlineItem> = z.lazy(() =>\n BaseOutlineItem.extend({\n sections: z.array(OutlineItemSchema).optional(),\n }),\n);\nconst OutlineSchema = z.array(OutlineItemSchema);\nexport type Outline = z.output<typeof OutlineSchema>;\nexport type OutlineAgentContext = {\n repo_path: string;\n outline: z.output<typeof OutlineSchema>;\n scratchpad: string;\n tree: string;\n};\n\nexport const outlineAgent = agent<unknown, OutlineAgentContext>({\n name: 'Outline Agent',\n model: groq('moonshotai/kimi-k2-instruct-0905'),\n // model: lmstudio('qwen/qwen3-8b'),\n // model: lmstudio('openai/gpt-oss-20b'),\n\n // temperature: 0.1,\n prompt: (context) =>\n instructions({\n purpose: [\n \"You are wiki architect, meticulously analyzing a repository's structure and content to automatically generate a comprehensive, intelligent, and perfectly structured outline, laying the bedrock for exceptional documentation.\",\n '\\n',\n '<RepositoryTree>',\n context?.tree || '',\n '</RepositoryTree>',\n ],\n routine: [],\n // routine: [\n // 'Your primary tool for memory is your `scratchpad`. After every action, you MUST summarize your findings and add them to the scratchpad using the `update_scratchpad` tool.',\n // 'Systematically investigate key files and directories use `search_files`. For each finding add it as a new note to your scratchpad.',\n // 'When you read a file like `README.md` or `package.json`, do not keep the whole content in your head. Instead, summarize the important parts (like headings, dependencies, or scripts) and add that summary to your scratchpad.',\n // 'Continue this process of exploring, summarizing, and adding to your scratchpad until you are confident you have a full picture of the repository.',\n // 'Once you believe you have gathered enough information, your second-to-last step is to review your entire scratchpad to synthesize a plan for the final outline.',\n // 'Finally, based *only* on the information you have gathered in your scratchpad, generate the complete, detailed outline and store it using the `store_outline` tool. You must only call `store_outline` ONCE at the very end.',\n // ],\n }),\n tools: {\n read_file: read_file_tool,\n // read_dir: read_dir_tool,\n // search_files: search_files_tool,\n // file_exists: file_exists_tool,\n update_scratchpad: scratchpad_tool,\n store_outline: tool({\n description: `Use this tool to store the generated outline.\n\t\tThe outline should be a detailed hierarchical structure representing the sections and subsections of the repository documentation. In thory you can nest sections as deep as you want, but try to keep it to 4 levels deep maximum.\n\n\t\t## Example outline\n\t\t[\n\t\t\t{\n\t\t\t\t\"title\": \"xxxx\",\n\t\t\t\t\"sections\": [\n\t\t\t\t\t{\n\t\t\t\t\t\t\"title\": \"yyyy\",\n\t\t\t\t\t\tsections: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"title\": \"vvvv\",\n\t\t\t\t\t\t\t\t\"sections\": [...],\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t]\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t\"title\": \"gggg\",\n\t\t\t\t\t\t\"sections\": [...],\n\t\t\t\t\t}\n\t\t\t\t]\n\t\t\t},\n\t\t]\n\t\t\t`,\n inputSchema: z.object({\n outline: OutlineSchema,\n }),\n // execute: ({ outline }, options) => {\n // const context = toState<OutlineAgentContext>(options);\n // // Store the outline in a file or database\n // console.log('Generated Outline:\\n', outline);\n // context.outline = outline;\n // return 'Outline stored successfully.';\n // },\n }),\n },\n});\n\nexport const outlineCondensedAgent = agent<unknown, OutlineAgentContext>({\n name: 'Outline Condensed Agent',\n model: groq('moonshotai/kimi-k2-instruct-0905'),\n prompt: instructions({\n purpose: [\n 'To intelligently condense and optimize an existing outline by merging redundant sections, removing overly granular subdivisions, and creating a more streamlined, maintainable documentation structure.',\n 'Your goal is to reduce complexity while preserving all essential information and maintaining logical hierarchy.',\n ],\n routine: [\n 'Examine the current outline structure stored in the context. Use your scratchpad to track your analysis.',\n 'Identify sections that are too granular (e.g., sections with only 1-2 subsections that could be merged with their parent).',\n 'Look for redundant or overlapping sections that cover similar topics and can be consolidated.',\n 'Note sections with excessive nesting depth (more than 3-4 levels) that could be flattened.',\n 'Identify sections with very similar titles that could be merged (e.g., \"API Overview\" and \"API Introduction\").',\n 'For each potential consolidation, add a note to your scratchpad explaining the rationale.',\n 'Create a condensed version of the outline that:',\n ' - Merges related subsections into broader topics',\n ' - Reduces nesting depth where appropriate',\n ' - Eliminates redundancy while keeping all unique content areas',\n ' - Maintains a maximum depth of 3 levels unless absolutely necessary',\n ' - Ensures each section has substantial content to document',\n 'Return the condensed outline as structured output.',\n ],\n }),\n output: OutlineSchema,\n});\n\nexport async function generateOutline(state: OutlineAgentContext) {\n const messages: UIMessage[] = [\n user(\n 'Walk through the repository and generate a detailed outline. Make sure to avoid looking into framework generated files and folders. when outline is complete, call the store_outline tool.',\n ),\n ];\n const max_iterations = 3;\n let current_iteration = 0;\n while (current_iteration < max_iterations) {\n console.log(`\\n=== Outline Iteration ${current_iteration + 1} ===\\n`);\n const result = await execute(outlineAgent, messages, state);\n await Array.fromAsync(\n toUIMessageStream({\n stream: result.stream,\n tools: outlineAgent.toToolset(),\n generateMessageId: generateId,\n originalMessages: messages,\n onEnd: async ({ responseMessage }: { responseMessage: UIMessage }) => {\n messages.push(responseMessage);\n },\n }),\n );\n await result.consumeStream();\n const calls = await result.toolCalls;\n const outlineCall = calls.find(\n (t: { toolName: string }) => t.toolName === 'store_outline',\n );\n if (outlineCall) {\n console.log('\\n=== Outline Generation Complete ===\\n');\n state.outline = outlineCall.input.outline;\n break;\n }\n current_iteration++;\n }\n if (!state.outline.length) {\n throw new Error('Outline generation failed.');\n }\n return generate(\n outlineCondensedAgent,\n `Condense and optimize the following outline:\\n\\n${buildToc(state.outline)}`,\n state,\n ).then(({ output }) => output);\n}\n\nfunction slugify(text: string) {\n return text\n .toLowerCase()\n .replace(/[^a-z0-9\\s-]/g, '')\n .trim()\n .replace(/\\s+/g, '-')\n .replace(/-+/g, '-');\n}\n\nexport function buildToc(\n items: OutlineItem[],\n baseDepth = 1,\n prefix: string[] = [],\n) {\n const lines: string[] = [];\n for (const it of items) {\n const path = [...prefix, it.title];\n const indent = ' '.repeat(Math.max(0, path.length - 1));\n const anchor = slugify(it.title);\n lines.push(`${indent}- [${it.title}](#${anchor})`);\n if (it.sections?.length) {\n lines.push(...buildToc(it.sections, baseDepth + 1, path));\n }\n }\n return lines;\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["groq", "tool", "z", "agent", "execute", "instructions", "user", "read_file_tool", "scratchpad_tool", "write", "tool", "z", "agent", "instructions", "read_file_tool", "scratchpad_tool", "agent", "groq", "read_file_tool", "instructions", "execute", "user"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
// packages/orchestrator/src/lib/evolving.ts
|
|
2
|
+
import { groq } from "@ai-sdk/groq";
|
|
3
|
+
import { toUIMessageStream, tool } from "ai";
|
|
4
|
+
import dedent from "dedent";
|
|
5
|
+
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
6
|
+
import { dirname, extname, join } from "node:path";
|
|
7
|
+
import z from "zod";
|
|
8
|
+
import { agent, generate, stream, user } from "@deepagents/agent";
|
|
9
|
+
var defaultPrompt = dedent`
|
|
10
|
+
|
|
11
|
+
<SystemContext>
|
|
12
|
+
You are a code execution agent that writes and runs TypeScript code to accomplish user requests.
|
|
13
|
+
|
|
14
|
+
<Identity>
|
|
15
|
+
Your role is to translate user instructions into executable TypeScript code that produces results.
|
|
16
|
+
You excel at:
|
|
17
|
+
- Breaking down requests into simple, executable code
|
|
18
|
+
- Choosing appropriate Node.js APIs for the task
|
|
19
|
+
- Writing clear, correct TypeScript with proper imports
|
|
20
|
+
- Analyzing errors and adjusting approach when needed
|
|
21
|
+
</Identity>
|
|
22
|
+
|
|
23
|
+
<ExecutionEnvironment>
|
|
24
|
+
Runtime: Node.js with ES module support
|
|
25
|
+
Execution Model: Files are dynamically imported after creation
|
|
26
|
+
Project Root: Accessible via process.cwd()
|
|
27
|
+
</ExecutionEnvironment>
|
|
28
|
+
|
|
29
|
+
<Tools>
|
|
30
|
+
write_content(fileName: string, content: string)
|
|
31
|
+
- Creates or overwrites a .ts file in .evolving/ directory
|
|
32
|
+
- Only .ts extensions permitted
|
|
33
|
+
- Parent directories created automatically
|
|
34
|
+
|
|
35
|
+
run_code(fileName: string)
|
|
36
|
+
- Executes a TypeScript file via dynamic import()
|
|
37
|
+
- File must exist before execution (write first, then run)
|
|
38
|
+
- Returns module exports object
|
|
39
|
+
</Tools>
|
|
40
|
+
|
|
41
|
+
<Methodology>
|
|
42
|
+
Phase 1: Analysis
|
|
43
|
+
- Understand what data or result the user needs
|
|
44
|
+
- Identify which Node.js APIs are appropriate (fs, path, etc.)
|
|
45
|
+
|
|
46
|
+
Phase 2: Implementation
|
|
47
|
+
- Write TypeScript code using appropriate imports
|
|
48
|
+
- Use process.cwd() for project root references
|
|
49
|
+
- Include console.log statements for output visibility
|
|
50
|
+
- Export data if needed for further processing
|
|
51
|
+
|
|
52
|
+
Phase 3: Execution
|
|
53
|
+
- Run the code file
|
|
54
|
+
- Observe results and determine if goal is achieved
|
|
55
|
+
</Methodology>
|
|
56
|
+
|
|
57
|
+
<Principles>
|
|
58
|
+
Code Approach:
|
|
59
|
+
✓ Start with synchronous operations (readdirSync, readFileSync)
|
|
60
|
+
✓ Use ES module imports (import { x } from 'module')
|
|
61
|
+
✓ Reference project root with process.cwd()
|
|
62
|
+
✓ Write self-contained code with clear variable names
|
|
63
|
+
✗ Avoid async callbacks when synchronous versions exist
|
|
64
|
+
✗ Avoid complex path manipulations when simple ones suffice
|
|
65
|
+
✗ Avoid mixing CommonJS (require) with ES modules (import)
|
|
66
|
+
|
|
67
|
+
Error Handling:
|
|
68
|
+
✓ Read error messages carefully to understand root cause
|
|
69
|
+
✓ Check if the issue is environmental, syntactic, or logical
|
|
70
|
+
✓ Adjust approach based on specific error, not generic retries
|
|
71
|
+
✗ Avoid repeating the same approach if it failed
|
|
72
|
+
✗ Avoid trying multiple variations without understanding why previous attempts failed
|
|
73
|
+
|
|
74
|
+
Iteration Management:
|
|
75
|
+
✓ Attempt a straightforward solution first
|
|
76
|
+
✓ If first attempt fails, analyze the error and make ONE targeted fix
|
|
77
|
+
✓ If second attempt fails, reconsider the approach entirely
|
|
78
|
+
✗ Stop after 3 failed attempts and report the issue
|
|
79
|
+
✗ Avoid trial-and-error loops without clear reasoning
|
|
80
|
+
</Principles>
|
|
81
|
+
|
|
82
|
+
<CriticalInstructions>
|
|
83
|
+
- Maximum 3 retry attempts per task before reporting the issue
|
|
84
|
+
- Each file write should be purposeful, not exploratory
|
|
85
|
+
- run_code must only be called on files that were written via write_content
|
|
86
|
+
- Follow the user's instructions precisely and deliver the requested results
|
|
87
|
+
</CriticalInstructions>
|
|
88
|
+
|
|
89
|
+
</SystemContext>
|
|
90
|
+
|
|
91
|
+
`;
|
|
92
|
+
var PROMPT_FILE_PATH = join(
|
|
93
|
+
process.cwd(),
|
|
94
|
+
".evolving",
|
|
95
|
+
"executor-prompt.txt"
|
|
96
|
+
);
|
|
97
|
+
var prompt = await readFile(PROMPT_FILE_PATH, "utf-8").catch(() => defaultPrompt) || defaultPrompt;
|
|
98
|
+
async function savePrompt(promptText) {
|
|
99
|
+
await mkdir(dirname(PROMPT_FILE_PATH), { recursive: true });
|
|
100
|
+
await writeFile(PROMPT_FILE_PATH, promptText, "utf-8");
|
|
101
|
+
console.log("Saved revised prompt to file");
|
|
102
|
+
}
|
|
103
|
+
var write_content_tool = tool({
|
|
104
|
+
description: "Writes content based on given instructions.",
|
|
105
|
+
inputSchema: z.object({
|
|
106
|
+
fileName: z.string().describe("The name of the file to write to."),
|
|
107
|
+
content: z.string().describe("The content to be written.")
|
|
108
|
+
}),
|
|
109
|
+
execute: async ({ fileName, content }, _options) => {
|
|
110
|
+
if (extname(fileName) !== ".ts") {
|
|
111
|
+
return "Error: Can only write .ts files.";
|
|
112
|
+
}
|
|
113
|
+
await mkdir(dirname(join(process.cwd(), ".evolving", fileName)), {
|
|
114
|
+
recursive: true
|
|
115
|
+
});
|
|
116
|
+
await writeFile(
|
|
117
|
+
join(process.cwd(), ".evolving", fileName),
|
|
118
|
+
content,
|
|
119
|
+
"utf-8"
|
|
120
|
+
);
|
|
121
|
+
return `File written: ${fileName}`;
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
var run_code_tool = tool({
|
|
125
|
+
description: "Executes provided code snippets and returns the output.",
|
|
126
|
+
inputSchema: z.object({
|
|
127
|
+
fileName: z.string().describe("The name of the file containing the code to run.")
|
|
128
|
+
}),
|
|
129
|
+
execute: async ({ fileName }, _options) => {
|
|
130
|
+
return await import(join(process.cwd(), ".evolving", fileName));
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
var executorTools = {
|
|
134
|
+
write_content: write_content_tool,
|
|
135
|
+
run_code: run_code_tool
|
|
136
|
+
};
|
|
137
|
+
var adaptingAgent = agent({
|
|
138
|
+
model: groq("openai/gpt-oss-20b"),
|
|
139
|
+
name: "adapting_agent",
|
|
140
|
+
prompt: dedent`
|
|
141
|
+
You are an adapting agent that update other agents system prompt and behavior based on execution results.
|
|
142
|
+
Your job is to analyze execution results and refine the executor agent's prompt to improve future performance.
|
|
143
|
+
Consider what changes to the system context, identity, methodology, principles, or critical instructions could help the executor succeed.
|
|
144
|
+
Provide a revised prompt that addresses any shortcomings revealed by the execution results.
|
|
145
|
+
`,
|
|
146
|
+
output: z.object({
|
|
147
|
+
revisedPrompt: z.string().describe("The revised system prompt for the executor.")
|
|
148
|
+
})
|
|
149
|
+
});
|
|
150
|
+
var USER_TASK = `Using typescript compiler, count how many times the agent function have been invoked. use tsconfig.base.json as project configuration.`;
|
|
151
|
+
var MAX_REFINEMENTS = 3;
|
|
152
|
+
async function runAdaptationCycle() {
|
|
153
|
+
let currentPrompt = prompt;
|
|
154
|
+
for (let iteration = 1; iteration <= MAX_REFINEMENTS; iteration++) {
|
|
155
|
+
console.log(
|
|
156
|
+
`
|
|
157
|
+
========== Iteration ${iteration}/${MAX_REFINEMENTS} ==========`
|
|
158
|
+
);
|
|
159
|
+
const executor = agent({
|
|
160
|
+
name: "executor_agent",
|
|
161
|
+
model: groq("openai/gpt-oss-120b"),
|
|
162
|
+
prompt: currentPrompt,
|
|
163
|
+
tools: executorTools
|
|
164
|
+
});
|
|
165
|
+
const result$ = await stream(executor, [user(USER_TASK)], {});
|
|
166
|
+
const messages = await Array.fromAsync(
|
|
167
|
+
toUIMessageStream({
|
|
168
|
+
stream: result$.stream,
|
|
169
|
+
tools: executor.toToolset()
|
|
170
|
+
})
|
|
171
|
+
);
|
|
172
|
+
await result$.consumeStream();
|
|
173
|
+
const reasoning = messages.filter((it) => it.type === "reasoning-delta").map((it) => it.delta).join("");
|
|
174
|
+
const text = messages.filter((it) => it.type === "text-delta").map((it) => it.delta).join("");
|
|
175
|
+
console.log("Final Result Text:", text);
|
|
176
|
+
const { output } = await generate(
|
|
177
|
+
adaptingAgent,
|
|
178
|
+
[
|
|
179
|
+
user(
|
|
180
|
+
`
|
|
181
|
+
<ExecutionResults>
|
|
182
|
+
${text}
|
|
183
|
+
</ExecutionResults>
|
|
184
|
+
|
|
185
|
+
<AgentReasoning>
|
|
186
|
+
${reasoning}
|
|
187
|
+
</AgentReasoning>
|
|
188
|
+
|
|
189
|
+
<AgentPrompt>
|
|
190
|
+
${currentPrompt}
|
|
191
|
+
</AgentPrompt>
|
|
192
|
+
`
|
|
193
|
+
)
|
|
194
|
+
],
|
|
195
|
+
{}
|
|
196
|
+
);
|
|
197
|
+
const { revisedPrompt } = output;
|
|
198
|
+
await savePrompt(revisedPrompt);
|
|
199
|
+
currentPrompt = revisedPrompt;
|
|
200
|
+
}
|
|
201
|
+
console.log("\n========== Adaptation Complete ==========");
|
|
202
|
+
}
|
|
203
|
+
runAdaptationCycle();
|
|
204
|
+
//# sourceMappingURL=evolving.js.map
|