Skip to content

Commit 4a0e74f

Browse files
committed
Merge branch 'main' of https://github.com/kaiban-ai/KaibanJS into workflow-driven-agent
2 parents 5549df5 + 17bf1ab commit 4a0e74f

File tree

4 files changed

+308
-14
lines changed

4 files changed

+308
-14
lines changed

playground/react/package-lock.json

Lines changed: 35 additions & 14 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

playground/react/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
"langchain": "^0.3.33",
2929
"mathjs": "^13.0.3",
3030
"octokit": "^4.0.2",
31+
"openai": "^6.9.0",
3132
"react": "^18.2.0",
3233
"react-dom": "^18.2.0",
3334
"react-markdown": "^10.1.0"
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import AgentsBoardDebugger from '../AgentsBoardDebugger';
2+
import teamOpenAI from '../teams/conference_analysis/openai';
3+
import '../index.css';
4+
5+
// More on how to set up stories at: https://storybook.js.org/docs/writing-stories#default-export
6+
export default {
7+
title: 'Teams/Conference Analysis Team',
8+
component: AgentsBoardDebugger,
9+
};
10+
11+
// More on writing stories with args: https://storybook.js.org/docs/writing-stories/args
12+
export const withOpenAI = {
13+
args: {
14+
team: teamOpenAI,
15+
title: 'Conference Analysis with OpenAI Whisper',
16+
},
17+
};
Lines changed: 255 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,255 @@
1+
import { Agent, Task, Team } from 'kaibanjs';
2+
import { z } from 'zod';
3+
import OpenAI from 'openai';
4+
5+
// ──── Custom Tool: Audio Transcription ────────────────────────────────
6+
/**
7+
* Custom tool for transcribing audio files using OpenAI Whisper API
8+
* Downloads audio from URL and transcribes it client-side
9+
*/
10+
class AudioTranscriptionTool {
11+
name = 'audio_transcription';
12+
13+
description =
14+
'Downloads an audio file from a URL and transcribes it using OpenAI Whisper API. Returns the full transcription text.';
15+
16+
schema = z.object({
17+
audioUrl: z.string().describe('URL of the audio file to transcribe'),
18+
});
19+
20+
openaiClient = null;
21+
22+
constructor(apiKey) {
23+
if (!apiKey) {
24+
throw new Error('API key is required');
25+
}
26+
this.openaiClient = new OpenAI({
27+
apiKey,
28+
dangerouslyAllowBrowser: true, // Required for browser usage
29+
});
30+
}
31+
32+
async invoke(input) {
33+
const { audioUrl } = input;
34+
35+
try {
36+
// Download audio file from URL
37+
const response = await fetch(audioUrl);
38+
if (!response.ok) {
39+
throw new Error(`Failed to download audio: ${response.statusText}`);
40+
}
41+
42+
const audioBlob = await response.blob();
43+
44+
// Convert blob to File object for OpenAI API
45+
const audioFile = new File([audioBlob], 'audio.mp3', {
46+
type: audioBlob.type || 'audio/mpeg',
47+
});
48+
49+
// Transcribe using OpenAI Whisper
50+
const transcription = await this.openaiClient.audio.transcriptions.create(
51+
{
52+
file: audioFile,
53+
model: 'gpt-4o-mini-transcribe',
54+
response_format: 'text',
55+
// model: 'gpt-4o-transcribe-diarize',
56+
// response_format: 'diarized_json',
57+
// chunking_strategy: 'auto',
58+
}
59+
);
60+
console.log('transcription', transcription);
61+
62+
return typeof transcription === 'string'
63+
? transcription
64+
: JSON.stringify(transcription);
65+
} catch (error) {
66+
return JSON.stringify({
67+
status: 'ERROR',
68+
message: `Failed to transcribe audio: ${
69+
error instanceof Error ? error.message : 'Unknown error'
70+
}`,
71+
});
72+
}
73+
}
74+
}
75+
76+
// Initialize transcription tool with API key from environment
77+
const transcriptionTool = new AudioTranscriptionTool(
78+
import.meta.env.VITE_OPENAI_API_KEY
79+
);
80+
81+
// ──── Agents ───────────────────────────────────────────────────────────
82+
83+
/**
84+
* Transcription Agent
85+
* Handles audio transcription using the custom tool
86+
*/
87+
const transcriber = new Agent({
88+
name: 'Transcriber',
89+
role: 'Audio Transcription Specialist',
90+
goal: 'Transcribe audio recordings to accurate text ',
91+
background: 'Expert in audio processing and speech-to-text conversion.',
92+
type: 'ReactChampionAgent',
93+
tools: [transcriptionTool],
94+
});
95+
96+
/**
97+
* Content Analyst Agent
98+
* Analyzes transcription to extract topics, context, participants, and generate summary
99+
* This agent handles multiple related analysis tasks
100+
*/
101+
const contentAnalyst = new Agent({
102+
name: 'Analyst',
103+
role: 'Content Analysis Specialist',
104+
goal: 'Analyze conference content to identify topics, context, participants, and create summaries.',
105+
background:
106+
'Expert in content analysis, information extraction, and summarization with experience in meeting analysis.',
107+
type: 'ReactChampionAgent',
108+
tools: [],
109+
});
110+
111+
/**
112+
* Information Extractor Agent
113+
* Extracts action items and relevant notes from the transcription
114+
*/
115+
const informationExtractor = new Agent({
116+
name: 'Extractor',
117+
role: 'Information Extraction Specialist',
118+
goal: 'Extract actionable items, responsibilities, and key notes from conference discussions.',
119+
background:
120+
'Specialist in identifying action items, tracking responsibilities, and extracting key insights from conversations.',
121+
type: 'ReactChampionAgent',
122+
tools: [],
123+
});
124+
125+
/**
126+
* Document Consolidator Agent
127+
* Consolidates all analysis into a final markdown document
128+
*/
129+
const consolidator = new Agent({
130+
name: 'Consolidator',
131+
role: 'Document Consolidation Specialist',
132+
goal: 'Consolidate all conference analysis into a comprehensive, well-structured markdown document.',
133+
background:
134+
'Expert in document creation and information synthesis, creating professional meeting notes and reports.',
135+
type: 'ReactChampionAgent',
136+
tools: [],
137+
});
138+
139+
// ──── Tasks ─────────────────────────────────────────────────────────────
140+
141+
/**
142+
* Task 1: Transcribe audio
143+
*/
144+
const transcriptionTask = new Task({
145+
description: `Transcribe the audio file from the provided URL: {audioUrl}`,
146+
expectedOutput:
147+
'Complete transcription of the conference audio in plain text format.',
148+
agent: transcriber,
149+
});
150+
151+
/**
152+
* Task 2: Analyze topics and context
153+
* Uses contentAnalyst agent
154+
*/
155+
const topicContextTask = new Task({
156+
description: `Analyze the transcription to identify the main topics discussed and the overall context of the conference.
157+
Provide a clear overview of what the conference was about and the key themes.`,
158+
expectedOutput:
159+
'Detailed analysis of main topics and context of the conference.',
160+
agent: contentAnalyst,
161+
});
162+
163+
/**
164+
* Task 3: Extract participants
165+
* Uses contentAnalyst agent
166+
*/
167+
const participantsTask = new Task({
168+
description: `Identify all participants mentioned in the transcription.
169+
Extract their names, roles, titles, and any other relevant information about them.`,
170+
expectedOutput:
171+
'Complete list of participants with their details (names, roles, titles, etc.).',
172+
agent: contentAnalyst,
173+
});
174+
175+
/**
176+
* Task 4: Generate summary
177+
* Uses contentAnalyst agent
178+
*/
179+
const summaryTask = new Task({
180+
description: `Create a concise and comprehensive summary of the conference based on the transcription.
181+
Highlight the main points, decisions made, and important discussions.`,
182+
expectedOutput:
183+
'A well-structured summary of the conference covering main points and decisions.',
184+
agent: contentAnalyst,
185+
});
186+
187+
/**
188+
* Task 5: Extract action items
189+
* Uses informationExtractor agent
190+
*/
191+
const actionItemsTask = new Task({
192+
description: `Identify all action items mentioned in the conference.
193+
For each action item, extract the task description and the person responsible (if mentioned).`,
194+
expectedOutput:
195+
'List of action items with descriptions and assigned responsible parties.',
196+
agent: informationExtractor,
197+
});
198+
199+
/**
200+
* Task 6: Extract relevant notes
201+
* Uses informationExtractor agent
202+
*/
203+
const notesTask = new Task({
204+
description: `Extract and organize all relevant notes, insights, and important information from the conference.
205+
Focus on key takeaways, decisions, and valuable insights that should be documented.`,
206+
expectedOutput:
207+
'Organized collection of relevant notes, insights, and key takeaways from the conference.',
208+
agent: informationExtractor,
209+
});
210+
211+
/**
212+
* Task 7: Consolidate final document
213+
* Uses consolidator agent - This is the deliverable
214+
*/
215+
const consolidationTask = new Task({
216+
description: `Consolidate all the analysis results into a comprehensive markdown document.
217+
Include:
218+
- Conference Summary
219+
- Topics & Context
220+
- Participants (with details)
221+
- Action Items (with responsible parties)
222+
- Key Notes & Insights
223+
224+
Format everything in a clear, professional markdown structure suitable for meeting notes.`,
225+
expectedOutput:
226+
'A complete, well-formatted markdown document containing all conference analysis results.',
227+
isDeliverable: true,
228+
agent: consolidator,
229+
});
230+
231+
// ──── Team ──────────────────────────────────────────────────────────────
232+
233+
// Create the team
234+
const team = new Team({
235+
name: 'Conference Analysis Team',
236+
agents: [transcriber, contentAnalyst, informationExtractor, consolidator],
237+
tasks: [
238+
transcriptionTask,
239+
topicContextTask,
240+
participantsTask,
241+
summaryTask,
242+
actionItemsTask,
243+
notesTask,
244+
consolidationTask,
245+
],
246+
inputs: {
247+
audioUrl:
248+
'https://raw.githubusercontent.com/ringcentral/ringcentral-api-docs/main/resources/RC_Conversation_Sample.mp3',
249+
},
250+
env: {
251+
OPENAI_API_KEY: import.meta.env.VITE_OPENAI_API_KEY,
252+
},
253+
});
254+
255+
export default team;

0 commit comments

Comments
 (0)