@aigne/example-workflow-group-chat 1.2.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.
@@ -0,0 +1,5 @@
1
+ # Change the name of this file to .env.local and fill in the following values
2
+
3
+ DEBUG=aigne:mcp
4
+
5
+ OPENAI_API_KEY="" # Your OpenAI API key
package/README.md ADDED
@@ -0,0 +1,79 @@
1
+ # Workflow Group Chat Demo
2
+
3
+ This is a demonstration of using [AIGNE Framework](https://github.com/AIGNE-io/aigne-framework) to build a group chat workflow.
4
+
5
+ ```mermaid
6
+ flowchart LR
7
+
8
+ manager(Group Manager)
9
+ user(User)
10
+ writer(Writer)
11
+ editor(Editor)
12
+ illustrator(Illustrator)
13
+
14
+ manager ==2 request to speak==> writer
15
+ manager --4 request to speak--> illustrator
16
+
17
+ writer -.3 group message.-> manager
18
+ writer -..-> editor
19
+ writer -..-> illustrator
20
+ writer -..-> user
21
+
22
+
23
+ classDef inputOutput fill:#f9f0ed,stroke:#debbae,stroke-width:2px,color:#b35b39,font-weight:bolder;
24
+ classDef processing fill:#F0F4EB,stroke:#C2D7A7,stroke-width:2px,color:#6B8F3C,font-weight:bolder;
25
+
26
+ class manager inputOutput
27
+ class user processing
28
+ class writer processing
29
+ class editor processing
30
+ class illustrator processing
31
+ ```
32
+
33
+ ## Prerequisites
34
+
35
+ - [Node.js](https://nodejs.org) and npm installed on your machine
36
+ - [OpenAI API key](https://platform.openai.com/api-keys) used to interact with OpenAI API
37
+ - [Pnpm](https://pnpm.io) [Optional] if you want to run the example from source code
38
+
39
+ ## Try without Installation
40
+
41
+ ```bash
42
+ export OPENAI_API_KEY=YOUR_OPENAI_API_KEY # setup your OpenAI API key
43
+
44
+ npx -y @aigne/example-workflow-group-chat # run the example
45
+ ```
46
+
47
+ ## Installation
48
+
49
+ ### Clone the Repository
50
+
51
+ ```bash
52
+ git clone https://github.com/AIGNE-io/aigne-framework
53
+ ```
54
+
55
+ ### Install Dependencies
56
+
57
+ ```bash
58
+ cd aigne-framework/examples/workflow-group-chat
59
+
60
+ pnpm install
61
+ ```
62
+
63
+ ### Setup Environment Variables
64
+
65
+ Setup your OpenAI API key in the `.env.local` file:
66
+
67
+ ```bash
68
+ OPENAI_API_KEY="" # setup your OpenAI API key here
69
+ ```
70
+
71
+ ### Run the Example
72
+
73
+ ```bash
74
+ pnpm start
75
+ ```
76
+
77
+ ## License
78
+
79
+ This project is licensed under the MIT License.
package/index.ts ADDED
@@ -0,0 +1,158 @@
1
+ #!/usr/bin/env npx -y bun
2
+
3
+ import assert from "node:assert";
4
+ import { randomUUID } from "node:crypto";
5
+ import {
6
+ AIAgent,
7
+ ExecutionEngine,
8
+ FunctionAgent,
9
+ OpenAIChatModel,
10
+ PromptTemplate,
11
+ UserAgent,
12
+ createMessage,
13
+ getMessage,
14
+ logger,
15
+ } from "@aigne/core";
16
+ import inquirer from "inquirer";
17
+ import { z } from "zod";
18
+
19
+ const { OPENAI_API_KEY } = process.env;
20
+ assert(OPENAI_API_KEY, "Please set the OPENAI_API_KEY environment variable");
21
+
22
+ const gpt = new OpenAIChatModel({
23
+ apiKey: OPENAI_API_KEY,
24
+ model: "gpt-4o",
25
+ });
26
+
27
+ const DEFAULT_TOPIC = "DEFAULT_TOPIC";
28
+
29
+ const writer = AIAgent.from({
30
+ name: "writer",
31
+ description: "Writer for creating any text content",
32
+ publishTopic: DEFAULT_TOPIC,
33
+ memory: { subscribeTopic: DEFAULT_TOPIC },
34
+ instructions: "You are a Writer. You produce good work.",
35
+ });
36
+
37
+ const editor = AIAgent.from({
38
+ name: "editor",
39
+ description: "Editor for planning and reviewing the content",
40
+ publishTopic: DEFAULT_TOPIC,
41
+ memory: { subscribeTopic: DEFAULT_TOPIC },
42
+ instructions: `\
43
+ You are an Editor. Plan and guide the task given by the user.
44
+ Provide critical feedbacks to the draft and illustration produced by Writer and Illustrator.
45
+ Approve if the task is completed and the draft and illustration meets user's requirements.`,
46
+ });
47
+
48
+ const generateImage = FunctionAgent.from({
49
+ name: "generate_image",
50
+ description: "Generate an image",
51
+ inputSchema: z.object({
52
+ character_appearance: z.string(),
53
+ style_attributes: z.string(),
54
+ worn_and_carried: z.string(),
55
+ scenario: z.string(),
56
+ }),
57
+ fn: (input) => {
58
+ return { ...input, url: `https://example.com/${randomUUID()}.jpg` };
59
+ },
60
+ });
61
+
62
+ const illustrator = AIAgent.from({
63
+ name: "illustrator",
64
+ description: "An illustrator for creating images",
65
+ publishTopic: DEFAULT_TOPIC,
66
+ memory: { subscribeTopic: DEFAULT_TOPIC },
67
+ instructions: `\
68
+ You are an Illustrator. You use the generate_image tool to create images given user's requirement.
69
+ Make sure the images have consistent characters and style.`,
70
+ tools: [generateImage],
71
+ toolChoice: "auto",
72
+ outputSchema: z.object({
73
+ images: z
74
+ .array(
75
+ z.object({
76
+ url: z.string().describe("The URL of the image"),
77
+ }),
78
+ )
79
+ .describe("The images created by the illustrator"),
80
+ }),
81
+ });
82
+
83
+ let isFirstQuestion = true;
84
+
85
+ const user = UserAgent.from({
86
+ name: "user",
87
+ description: "User for providing final approval",
88
+ publishTopic: DEFAULT_TOPIC,
89
+ memory: { subscribeTopic: DEFAULT_TOPIC },
90
+ async process() {
91
+ logger.globalSpinner.stop();
92
+ const { question } = await inquirer.prompt([
93
+ {
94
+ type: "input",
95
+ name: "question",
96
+ message: "💬",
97
+ required: true,
98
+ default: isFirstQuestion
99
+ ? "Please write a short story about the gingerbread man with up to 3 photo-realistic illustrations."
100
+ : undefined,
101
+ },
102
+ ]);
103
+ isFirstQuestion = false;
104
+ logger.globalSpinner.start();
105
+ return createMessage(question);
106
+ },
107
+ });
108
+
109
+ const roles = [writer, editor, illustrator, user];
110
+
111
+ const manager = AIAgent.from({
112
+ name: "manager",
113
+ subscribeTopic: DEFAULT_TOPIC,
114
+ publishTopic: (output) => output.role,
115
+ memory: { subscribeTopic: DEFAULT_TOPIC },
116
+ instructions: PromptTemplate.from(`\
117
+ You are participating in a role-playing game. The available roles are:
118
+
119
+ <roles>
120
+ {{roles}}
121
+ </roles>
122
+
123
+ Instructions:
124
+ 1. Read the following conversation history
125
+ 2. Identify the last speaking role in the conversation.
126
+ 3. If the last role is **not** "user," respond as "user" to approve and continue.
127
+ 4. Otherwise, select the next role **logically** based on the context of the conversation (do not repeat the same role unless necessary).
128
+ 5. Make sure responses align with the role’s personality and purpose in the game.
129
+ `).format({
130
+ roles: roles.map((i) => `${i.topic}: ${i.description}`).join("\n"),
131
+ }),
132
+ outputSchema: z.object({
133
+ role: z
134
+ .union(assertZodUnionArray(roles.map((i) => z.literal(i.topic))))
135
+ .describe("The next role to play"),
136
+ }),
137
+ });
138
+
139
+ const engine = new ExecutionEngine({
140
+ model: gpt,
141
+ agents: [user, manager, writer, editor, illustrator],
142
+ });
143
+
144
+ engine.subscribe(DEFAULT_TOPIC, (message) => {
145
+ console.log(
146
+ "------------- Received message -------------\n",
147
+ `${message.source}:`,
148
+ getMessage(message.message) || message.message,
149
+ "\n--------------------------------------------",
150
+ );
151
+ });
152
+
153
+ await engine.call(user, {});
154
+
155
+ function assertZodUnionArray<T extends z.ZodType>(union: T[]): [T, T, ...T[]] {
156
+ if (!(union.length >= 2)) throw new Error("Union must have at least 2 items");
157
+ return union as [T, T, ...T[]];
158
+ }
package/package.json ADDED
@@ -0,0 +1,27 @@
1
+ {
2
+ "name": "@aigne/example-workflow-group-chat",
3
+ "version": "1.2.0",
4
+ "description": "A demonstration of using AIGNE Framework to build a group chat workflow",
5
+ "author": "Arcblock <blocklet@arcblock.io> https://github.com/blocklet",
6
+ "homepage": "https://github.com/AIGNE-io/aigne-framework/tree/main/examples/workflow-group-chat",
7
+ "license": "ISC",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/AIGNE-io/aigne-framework"
11
+ },
12
+ "bin": "index.ts",
13
+ "files": [
14
+ ".env.local.example",
15
+ "*.ts",
16
+ "README.md"
17
+ ],
18
+ "dependencies": {
19
+ "openai": "^4.89.0",
20
+ "zod": "^3.24.2",
21
+ "@aigne/core": "^1.3.0"
22
+ },
23
+ "scripts": {
24
+ "start": "npx -y bun run index.ts",
25
+ "lint": "tsc --noEmit"
26
+ }
27
+ }