@blocklet/pages-kit-agents 0.5.41 → 0.5.43

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.
Files changed (30) hide show
  1. package/lib/cjs/agents/template-designer.d.ts +13 -0
  2. package/lib/cjs/agents/template-designer.js +67 -0
  3. package/lib/cjs/agents/template-generator.d.ts +18 -0
  4. package/lib/cjs/agents/template-generator.js +186 -0
  5. package/lib/cjs/tsconfig.tsbuildinfo +1 -1
  6. package/lib/cjs/utils/component-tuils.d.ts +12 -0
  7. package/lib/cjs/utils/component-tuils.js +141 -0
  8. package/lib/cjs/utils/file-utils.d.ts +23 -0
  9. package/lib/cjs/utils/file-utils.js +77 -0
  10. package/lib/cjs/workflow-agents/reflection-agent.d.ts +16 -0
  11. package/lib/cjs/workflow-agents/reflection-agent.js +38 -0
  12. package/lib/esm/agents/template-designer.d.ts +13 -0
  13. package/lib/esm/agents/template-designer.js +61 -0
  14. package/lib/esm/agents/template-generator.d.ts +18 -0
  15. package/lib/esm/agents/template-generator.js +180 -0
  16. package/lib/esm/tsconfig.tsbuildinfo +1 -1
  17. package/lib/esm/utils/component-tuils.d.ts +12 -0
  18. package/lib/esm/utils/component-tuils.js +136 -0
  19. package/lib/esm/utils/file-utils.d.ts +23 -0
  20. package/lib/esm/utils/file-utils.js +74 -0
  21. package/lib/esm/workflow-agents/reflection-agent.d.ts +16 -0
  22. package/lib/esm/workflow-agents/reflection-agent.js +34 -0
  23. package/lib/types/agents/template-designer.d.ts +13 -0
  24. package/lib/types/agents/template-generator.d.ts +18 -0
  25. package/lib/types/tsconfig.tsbuildinfo +1 -1
  26. package/lib/types/utils/component-tuils.d.ts +12 -0
  27. package/lib/types/utils/file-utils.d.ts +23 -0
  28. package/lib/types/workflow-agents/reflection-agent.d.ts +16 -0
  29. package/package.json +5 -2
  30. package/workflow-cli.ts +132 -0
@@ -0,0 +1,12 @@
1
+ import { z } from 'zod';
2
+ export declare function getSchemaByComponentIds(sections: {
3
+ componentId: string;
4
+ componentName: string;
5
+ sectionName: string;
6
+ }[]): z.ZodObject<Record<string, any>, "strip", z.ZodTypeAny, {
7
+ [x: string]: any;
8
+ }, {
9
+ [x: string]: any;
10
+ }>;
11
+ export declare function getComponentsSimpleMetadata(): string;
12
+ export declare function getComponentsMetadata(): string;
@@ -0,0 +1,136 @@
1
+ import { zodSchemaToJsonSchema } from '@blocklet/pages-kit-block-studio/zod-utils';
2
+ import { z } from 'zod';
3
+ const componentList = [
4
+ {
5
+ name: 'HeroV2',
6
+ id: '1',
7
+ description: 'Hero 区域,展示核心价值主张,主 CTA',
8
+ properties: z.object({
9
+ title: z.string().describe('主标题'),
10
+ description: z.string().describe('描述'),
11
+ image: z.string().describe('图片'),
12
+ buttons: z
13
+ .array(z.object({
14
+ text: z.string().describe('按钮文本'),
15
+ link: z.string().describe('按钮链接'),
16
+ }))
17
+ .describe('按钮列表'),
18
+ }),
19
+ },
20
+ {
21
+ name: 'ContentCards',
22
+ id: '2',
23
+ description: 'Hero、Features 、 Benefits、How it Works、',
24
+ properties: z.object({
25
+ title: z.string().describe('标题'),
26
+ description: z.string().describe('描述'),
27
+ list: z
28
+ .array(z.object({
29
+ title: z.string().describe('标题'),
30
+ description: z.string().describe('描述'),
31
+ image: z.string().describe('图片'),
32
+ }))
33
+ .describe('列表'),
34
+ }),
35
+ },
36
+ {
37
+ name: 'FAQ',
38
+ id: '3',
39
+ description: 'FAQ 区域,展示常见问题及答案',
40
+ properties: z.object({
41
+ title: z.string().describe('标题'),
42
+ list: z
43
+ .array(z.object({
44
+ question: z.string().describe('问题'),
45
+ answer: z.string().describe('答案'),
46
+ }))
47
+ .describe('列表'),
48
+ }),
49
+ },
50
+ {
51
+ name: 'Pricing',
52
+ id: '4',
53
+ description: 'Pricing 区域,展示价格方案',
54
+ properties: z.object({
55
+ title: z.string().describe('标题'),
56
+ list: z
57
+ .array(z.object({
58
+ title: z.string().describe('标题'),
59
+ description: z.string().describe('描述'),
60
+ price: z.string().describe('价格'),
61
+ }))
62
+ .describe('列表'),
63
+ }),
64
+ },
65
+ {
66
+ name: 'CTA',
67
+ id: '5',
68
+ description: 'CTA 区域,展示最终行动召唤',
69
+ properties: z.object({
70
+ title: z.string().describe('标题'),
71
+ description: z.string().describe('描述'),
72
+ buttons: z
73
+ .array(z.object({
74
+ text: z.string().describe('按钮文本'),
75
+ link: z.string().describe('按钮链接'),
76
+ }))
77
+ .describe('按钮列表'),
78
+ }),
79
+ },
80
+ {
81
+ name: 'Logo List',
82
+ id: '6',
83
+ description: 'Logo 列表,展示合作伙伴',
84
+ properties: z.object({
85
+ title: z.string().describe('标题'),
86
+ list: z
87
+ .array(z.object({
88
+ image: z.string().describe('图片'),
89
+ name: z.string().describe('名称'),
90
+ link: z.string().describe('链接'),
91
+ }))
92
+ .describe('列表'),
93
+ }),
94
+ },
95
+ ];
96
+ export function getSchemaByComponentIds(sections) {
97
+ const schemaObject = {};
98
+ sections.forEach((section) => {
99
+ const component = componentList.find((comp) => comp.id === section.componentId);
100
+ if (component) {
101
+ schemaObject[section.sectionName] = component.properties;
102
+ }
103
+ });
104
+ return z.object(schemaObject);
105
+ }
106
+ export function getComponentsSimpleMetadata() {
107
+ return componentList
108
+ .map((component) => {
109
+ const context = `
110
+ ------------------------------------------------------------
111
+ 组件名称:${component.name}
112
+ 组件Id:${component.id}
113
+ 组件描述(适用场景):${component.description}
114
+ ------------------------------------------------------------
115
+ `;
116
+ return context;
117
+ })
118
+ .filter(Boolean)
119
+ .join('\n');
120
+ }
121
+ export function getComponentsMetadata() {
122
+ return componentList
123
+ .map((component) => {
124
+ const context = `
125
+ ------------------------------------------------------------
126
+ 组件名称:${component.name}
127
+ 组件Id:${component.id}
128
+ 组件描述(适用场景):${component.description}
129
+ 组件属性结构:${JSON.stringify(zodSchemaToJsonSchema(component.properties))}
130
+ ------------------------------------------------------------
131
+ `;
132
+ return context;
133
+ })
134
+ .filter(Boolean)
135
+ .join('\n');
136
+ }
@@ -3,3 +3,26 @@
3
3
  * and generating a list of all HTML files in each subfolder
4
4
  */
5
5
  export declare function updateFileList(): Promise<void>;
6
+ /**
7
+ * File content information interface
8
+ */
9
+ export interface FileContent {
10
+ filePath: string;
11
+ fileName: string;
12
+ content: string;
13
+ }
14
+ /**
15
+ * Recursively reads files matching a pattern from a directory and its subdirectories
16
+ * @param dirPath - The directory path to search in
17
+ * @param pattern - String or RegExp pattern to match file names
18
+ * @param options - Optional configuration
19
+ * @returns Promise<FileContent[]> - Array of file content objects
20
+ */
21
+ export declare function readFilesByPattern(dirPath: string, pattern: string | RegExp, options?: {
22
+ recursive?: boolean;
23
+ }): Promise<FileContent[]>;
24
+ export declare function readFileByPath(filePath: string): Promise<string>;
25
+ /**
26
+ * Save content to a file, creating directories if needed
27
+ */
28
+ export declare function saveFileByPath(filePath: string, content: string): Promise<void>;
@@ -103,3 +103,77 @@ const FILE_LIST_DATA = [];`);
103
103
  console.error('Error updating file list:', error);
104
104
  }
105
105
  }
106
+ /**
107
+ * Recursively reads files matching a pattern from a directory and its subdirectories
108
+ * @param dirPath - The directory path to search in
109
+ * @param pattern - String or RegExp pattern to match file names
110
+ * @param options - Optional configuration
111
+ * @returns Promise<FileContent[]> - Array of file content objects
112
+ */
113
+ export async function readFilesByPattern(dirPath, pattern, options = { recursive: true }) {
114
+ const results = [];
115
+ // Convert string pattern to RegExp if needed
116
+ const regex = typeof pattern === 'string' ? new RegExp(pattern) : pattern;
117
+ /**
118
+ * Recursively process directory
119
+ */
120
+ async function processDirectory(currentPath) {
121
+ try {
122
+ const entries = await fs.readdir(currentPath, { withFileTypes: true });
123
+ for (const entry of entries) {
124
+ const fullPath = path.join(currentPath, entry.name);
125
+ if (entry.isDirectory() && options.recursive) {
126
+ // Recursively process subdirectory
127
+ await processDirectory(fullPath);
128
+ }
129
+ else if (entry.isFile() && regex.test(entry.name)) {
130
+ // Read file content if it matches the pattern
131
+ try {
132
+ const content = await fs.readFile(fullPath, 'utf8');
133
+ results.push({
134
+ filePath: fullPath,
135
+ fileName: entry.name,
136
+ content,
137
+ });
138
+ }
139
+ catch (fileError) {
140
+ // Ignore individual file read errors and continue
141
+ console.warn(`Warning: Failed to read file ${fullPath}:`, fileError);
142
+ }
143
+ }
144
+ }
145
+ }
146
+ catch (dirError) {
147
+ // Ignore directory read errors and continue
148
+ console.warn(`Warning: Failed to read directory ${currentPath}:`, dirError);
149
+ }
150
+ }
151
+ // Check if the directory exists before processing
152
+ if (!existsSync(dirPath)) {
153
+ console.warn(`Warning: Directory ${dirPath} does not exist`);
154
+ return results;
155
+ }
156
+ await processDirectory(dirPath);
157
+ return results;
158
+ }
159
+ // 读取文件内容
160
+ export async function readFileByPath(filePath) {
161
+ try {
162
+ const absolutePath = path.resolve(process.cwd(), filePath);
163
+ const content = await fs.readFile(absolutePath, 'utf-8');
164
+ return content;
165
+ }
166
+ catch (error) {
167
+ throw new Error(`无法读取文件 "${filePath}": ${error instanceof Error ? error.message : String(error)}`);
168
+ }
169
+ }
170
+ /**
171
+ * Save content to a file, creating directories if needed
172
+ */
173
+ export async function saveFileByPath(filePath, content) {
174
+ const pathModule = await import('path');
175
+ const fsModule = await import('fs/promises');
176
+ const dir = pathModule.dirname(filePath);
177
+ await fsModule.mkdir(dir, { recursive: true });
178
+ await fsModule.writeFile(filePath, content, 'utf8');
179
+ }
@@ -0,0 +1,16 @@
1
+ import { Agent, type AgentInvokeOptions, type AgentOptions, type AgentProcessResult, type Message } from '@aigne/core';
2
+ import type { PromiseOrValue } from '@aigne/core/utils/type-utils.js';
3
+ export interface ReflectionAgentOptions<I extends Message = Message, RO extends Message = Message> extends AgentOptions<I, I> {
4
+ editor: Agent<I, I>;
5
+ reviewer: Agent<I, RO>;
6
+ isApproved?: (result: RO) => PromiseOrValue<boolean>;
7
+ maxIterations?: number;
8
+ }
9
+ export declare class ReflectionAgent<I extends Message = Message, RO extends Message = Message> extends Agent<I, I> {
10
+ constructor(options: ReflectionAgentOptions<I, RO>);
11
+ editor: Agent<I, I>;
12
+ reviewer: Agent<I, RO>;
13
+ isApproved?: (result: RO) => PromiseOrValue<boolean>;
14
+ maxIterations: number;
15
+ process(input: I, options: AgentInvokeOptions): Promise<AgentProcessResult<I>>;
16
+ }
@@ -0,0 +1,34 @@
1
+ import { Agent } from '@aigne/core';
2
+ const DEFAULT_MAX_ITERATIONS = 3;
3
+ export class ReflectionAgent extends Agent {
4
+ constructor(options) {
5
+ super(options);
6
+ this.editor = options.editor;
7
+ this.reviewer = options.reviewer;
8
+ this.isApproved = options.isApproved;
9
+ this.maxIterations = options.maxIterations ?? DEFAULT_MAX_ITERATIONS;
10
+ }
11
+ editor;
12
+ reviewer;
13
+ isApproved;
14
+ maxIterations;
15
+ async process(input, options) {
16
+ let previousResult = input;
17
+ let reviewResult;
18
+ let iterations = 0;
19
+ // 先执行一次 editor,确保有结果
20
+ previousResult = await options.context.invoke(this.editor, previousResult);
21
+ do {
22
+ reviewResult = await options.context.invoke(this.reviewer, previousResult);
23
+ const isApproved = await this.isApproved?.(reviewResult);
24
+ if (isApproved === true) {
25
+ return previousResult;
26
+ }
27
+ previousResult = await options.context.invoke(this.editor, {
28
+ ...previousResult,
29
+ ...reviewResult,
30
+ });
31
+ } while (++iterations < this.maxIterations);
32
+ return previousResult;
33
+ }
34
+ }
@@ -0,0 +1,13 @@
1
+ import { AIAgent } from '@aigne/core';
2
+ /**
3
+ * 用于设计页面结构的 workflow
4
+ * 1. AI 根据拿到的 collectorResult 和 componentList,生成一个页面设计模板,需要用 ASCII 图画出来,给到用户确认
5
+ * 2. 用户确认后,AI 保存页面设计模板,并返回页面设计模板
6
+ */
7
+ export declare const designerAgent: AIAgent<{
8
+ collectResult: string;
9
+ }, {
10
+ ascii: string;
11
+ $message: string;
12
+ filteredComponentList: string[];
13
+ }>;
@@ -0,0 +1,18 @@
1
+ import { FunctionAgent } from '@aigne/core';
2
+ import { ReflectionAgent } from '../workflow-agents/reflection-agent.js';
3
+ export declare const generatorAgentWithReflection: ReflectionAgent<{
4
+ ascii: string;
5
+ collectResult: string;
6
+ $message: string;
7
+ filteredComponentList: string[];
8
+ feedback?: string | null | undefined;
9
+ }, {
10
+ isApproved: boolean;
11
+ feedback: string;
12
+ }>;
13
+ export declare const saveYamlAgent: FunctionAgent<{
14
+ $message: string;
15
+ yaml: string;
16
+ }, {
17
+ $message: string;
18
+ } & import("@aigne/core").Message>;