process-gpt-agent-sdk 0.2.11__py3-none-any.whl → 0.3.3__py3-none-any.whl

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.

Potentially problematic release.


This version of process-gpt-agent-sdk might be problematic. Click here for more details.

@@ -1,1026 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: process-gpt-agent-sdk
3
- Version: 0.2.11
4
- Summary: Supabase 기반 이벤트/작업 폴링으로 A2A AgentExecutor를 실행하는 SDK
5
- License: MIT
6
- Project-URL: Homepage, https://github.com/your-org/process-gpt-agent-sdk
7
- Project-URL: Issues, https://github.com/your-org/process-gpt-agent-sdk/issues
8
- Keywords: agent,a2a,supabase,workflow,sdk,processgpt
9
- Classifier: Programming Language :: Python :: 3
10
- Classifier: Programming Language :: Python :: 3 :: Only
11
- Classifier: License :: OSI Approved :: MIT License
12
- Classifier: Operating System :: OS Independent
13
- Requires-Python: >=3.9
14
- Description-Content-Type: text/markdown
15
- Requires-Dist: supabase>=2.0.0
16
- Requires-Dist: python-dotenv>=1.0.0
17
- Requires-Dist: click>=8.0.0
18
- Requires-Dist: asyncio-mqtt>=0.13.0
19
- Requires-Dist: jsonschema>=4.0.0
20
- Requires-Dist: structlog>=23.0.0
21
- Requires-Dist: typing-extensions>=4.0.0
22
- Requires-Dist: python-dateutil>=2.8.0
23
- Requires-Dist: openai>=1.40.0
24
- Requires-Dist: a2a-sdk==0.2.4
25
- Requires-Dist: requests>=2.31.0
26
- Requires-Dist: anyio>=4.4.0
27
- Requires-Dist: pydantic>=2.7.0
28
- Requires-Dist: crewai>=0.51.0
29
- Requires-Dist: crewai-tools>=0.8.2
30
- Requires-Dist: mem0ai>=0.1.0
31
- Requires-Dist: mcp>=1.0.0
32
-
33
- 배포: ./release.sh 0.2.8 (버전은 pyproject.toml에서 확인 후 진행) 조금이라도 수정을 했다면, 버전은 계속 올려가면서 진행해야합니다.
34
-
35
- # ProcessGPT Agent Framework
36
-
37
- Google A2A SDK의 인터페이스를 활용하면서 웹소켓 대신 Supabase 실시간 DB를 사용하는 에이전트 실행 프레임워크입니다.
38
-
39
- ## 🏗️ 아키텍처 개요
40
-
41
- 이 프레임워크는 기존의 Google A2A SDK의 `AgentExecutor`와 `RequestContext` 인터페이스를 그대로 활용하되, 웹소켓 기반 통신 대신 Supabase 데이터베이스를 중간 매개체로 사용합니다.
42
-
43
- ### 핵심 구성 요소
44
-
45
- 1. **Supabase Database Tables**
46
- - `todolist`: 에이전트가 처리해야 할 작업들을 저장
47
- - `events`: 각 태스크의 실행 상태와 진행 과정을 추적
48
-
49
- 2. **ProcessGPT Server**
50
- - Supabase `todolist` 테이블을 폴링하여 대기 중인 작업을 감지
51
- - Google A2A SDK의 `AgentExecutor.execute()` 메서드를 호출
52
- - 커스터마이즈된 `EventQueue`를 통해 이벤트를 Supabase에 저장
53
-
54
- 3. **Custom Classes**
55
- - `ProcessGPTRequestContext`: todolist 데이터를 기반으로 한 RequestContext 구현
56
- - `ProcessGPTEventQueue`: Supabase events 테이블에 이벤트를 저장하는 EventQueue 구현
57
-
58
- ## 🚀 빠른 시작 가이드
59
-
60
- ### 1. AgentExecutor 구현
61
-
62
- 먼저 비즈니스 로직을 처리할 사용자 정의 AgentExecutor를 구현합니다:
63
-
64
- ```python
65
- import asyncio
66
- from typing import Any, Dict
67
- from a2a.server.agent_execution import AgentExecutor, RequestContext
68
- from a2a.server.events import EventQueue, Event
69
-
70
- class MyBusinessAgentExecutor(AgentExecutor):
71
- """비즈니스 로직을 처리하는 사용자 정의 AgentExecutor"""
72
-
73
- def __init__(self, config: Dict[str, Any] = None):
74
- self.config = config or {}
75
- self.is_cancelled = False
76
-
77
- async def execute(self, context: RequestContext, event_queue: EventQueue) -> None:
78
- """메인 실행 로직"""
79
- # 1. 사용자 입력 가져오기
80
- user_input = context.get_user_input()
81
- context_data = context.get_context_data()
82
-
83
- # 2. 시작 이벤트 발송
84
- start_event = Event(
85
- type="task_started",
86
- data={
87
- "message": f"작업 시작: {user_input}",
88
- "user_input": user_input,
89
- "agent_type": "MyBusinessAgent"
90
- }
91
- )
92
- event_queue.enqueue_event(start_event)
93
-
94
- try:
95
- # 3. 작업 단계별 처리
96
- await self._process_business_logic(user_input, context_data, event_queue)
97
-
98
- # 4. 성공 완료 이벤트
99
- if not self.is_cancelled:
100
- success_event = Event(
101
- type="done",
102
- data={
103
- "message": "작업이 성공적으로 완료되었습니다",
104
- "success": True
105
- }
106
- )
107
- event_queue.enqueue_event(success_event)
108
-
109
- except Exception as e:
110
- # 5. 오류 이벤트
111
- error_event = Event(
112
- type="error",
113
- data={
114
- "message": f"작업 처리 중 오류 발생: {str(e)}",
115
- "error": str(e)
116
- }
117
- )
118
- event_queue.enqueue_event(error_event)
119
- raise
120
-
121
- async def cancel(self, context: RequestContext, event_queue: EventQueue) -> None:
122
- """작업 취소 처리"""
123
- self.is_cancelled = True
124
-
125
- cancel_event = Event(
126
- type="cancelled",
127
- data={
128
- "message": "작업이 취소되었습니다",
129
- "cancelled_by": "user_request"
130
- }
131
- )
132
- event_queue.enqueue_event(cancel_event)
133
-
134
- async def _process_business_logic(self, user_input: str, context_data: Dict[str, Any], event_queue: EventQueue):
135
- """실제 비즈니스 로직 처리"""
136
- steps = [
137
- ("분석", "사용자 요청을 분석하고 있습니다..."),
138
- ("계획", "처리 계획을 수립하고 있습니다..."),
139
- ("실행", "작업을 실행하고 있습니다..."),
140
- ("검증", "결과를 검증하고 있습니다..."),
141
- ("완료", "최종 결과를 준비하고 있습니다...")
142
- ]
143
-
144
- for i, (step_name, step_message) in enumerate(steps, 1):
145
- if self.is_cancelled:
146
- break
147
-
148
- # 진행 상황 이벤트
149
- progress_event = Event(
150
- type="progress",
151
- data={
152
- "step": i,
153
- "total_steps": len(steps),
154
- "step_name": step_name,
155
- "message": step_message,
156
- "progress_percentage": (i / len(steps)) * 100
157
- }
158
- )
159
- event_queue.enqueue_event(progress_event)
160
-
161
- # 실제 작업 수행 (여기에 AI 모델 호출, 데이터 처리 등)
162
- await asyncio.sleep(1.0) # 시뮬레이션용 지연
163
-
164
- # 최종 결과 출력
165
- if not self.is_cancelled:
166
- result = await self._generate_final_result(user_input, context_data)
167
-
168
- output_event = Event(
169
- type="output",
170
- data={
171
- "content": result,
172
- "final": True
173
- }
174
- )
175
- event_queue.enqueue_event(output_event)
176
-
177
- async def _generate_final_result(self, user_input: str, context_data: Dict[str, Any]) -> Dict[str, Any]:
178
- """최종 결과 생성"""
179
- return {
180
- "input": user_input,
181
- "result": f"'{user_input}' 요청이 성공적으로 처리되었습니다.",
182
- "processed_at": "2024-01-15T10:30:45Z",
183
- "agent_type": "MyBusinessAgent",
184
- "status": "completed"
185
- }
186
- ```
187
-
188
- ### 2. ProcessGPTAgentServer 생성 및 시작
189
-
190
- AgentExecutor를 사용하여 ProcessGPT 서버를 생성하고 실행합니다:
191
-
192
- ```python
193
- import asyncio
194
- import os
195
- from processgpt_agent_sdk import ProcessGPTAgentServer
196
- from my_custom_executor import MyBusinessAgentExecutor
197
-
198
- async def main():
199
- """ProcessGPT 서버 메인 함수"""
200
-
201
- # 1. 환경변수 확인
202
- if not os.getenv("SUPABASE_URL") or not os.getenv("SUPABASE_ANON_KEY"):
203
- print("오류: SUPABASE_URL과 SUPABASE_ANON_KEY 환경변수가 필요합니다.")
204
- return
205
-
206
- # 2. 사용자 정의 실행기 생성
207
- executor = MyBusinessAgentExecutor(config={"timeout": 30})
208
-
209
- # 3. ProcessGPT 서버 생성
210
- server = ProcessGPTAgentServer(
211
- executor=executor,
212
- polling_interval=5, # 5초마다 폴링
213
- agent_orch="my_business_agent" # 에이전트 타입 식별자
214
- )
215
-
216
- print("ProcessGPT 서버 시작...")
217
- print(f"에이전트 타입: my_business_agent")
218
- print(f"폴링 간격: 5초")
219
- print("Ctrl+C로 서버를 중지할 수 있습니다.")
220
-
221
- try:
222
- # 4. 서버 실행 (무한 루프)
223
- await server.run()
224
- except KeyboardInterrupt:
225
- print("\n서버 중지 요청...")
226
- server.stop()
227
- print("서버가 정상적으로 중지되었습니다.")
228
-
229
- if __name__ == "__main__":
230
- asyncio.run(main())
231
- ```
232
-
233
- 실행하기:
234
-
235
- ```bash
236
- # 서버 실행
237
- python my_server.py
238
- ```
239
-
240
- ### 3. Supabase 구성
241
-
242
- #### 3.1 Supabase 프로젝트 설정
243
-
244
- 1. [Supabase](https://supabase.com) 에서 새 프로젝트 생성
245
- 2. 프로젝트 설정에서 API 키 복사
246
- 3. 환경변수 설정:
247
-
248
- ```bash
249
- # .env 파일 생성
250
- echo "SUPABASE_URL=https://your-project.supabase.co" >> .env
251
- echo "SUPABASE_ANON_KEY=your-anon-key-here" >> .env
252
- ```
253
-
254
- #### 3.2 데이터베이스 스키마 생성
255
-
256
- Supabase SQL Editor에서 다음 스키마를 실행:
257
-
258
- ```sql
259
- -- 1. 테이블 타입 정의
260
- CREATE TYPE todo_status AS ENUM (
261
- 'PENDING', 'IN_PROGRESS', 'DONE', 'CANCELLED', 'SUBMITTED'
262
- );
263
-
264
- CREATE TYPE agent_mode AS ENUM (
265
- 'DRAFT', 'COMPLETE'
266
- );
267
-
268
- CREATE TYPE agent_orch AS ENUM (
269
- 'my_business_agent', 'data_analyst', 'customer_service', 'project_manager'
270
- );
271
-
272
- CREATE TYPE draft_status AS ENUM (
273
- 'STARTED', 'COMPLETED', 'FB_REQUESTED'
274
- );
275
-
276
- -- 2. TodoList 테이블 생성
277
- CREATE TABLE IF NOT EXISTS todolist (
278
- id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
279
- user_id TEXT NOT NULL,
280
- proc_inst_id TEXT,
281
- proc_def_id TEXT,
282
- activity_id TEXT,
283
- activity_name TEXT NOT NULL,
284
- start_date TIMESTAMP DEFAULT NOW(),
285
- end_date TIMESTAMP,
286
- description TEXT NOT NULL,
287
- tool TEXT,
288
- due_date TIMESTAMP,
289
- tenant_id TEXT NOT NULL,
290
- reference_ids TEXT[],
291
- adhoc BOOLEAN DEFAULT FALSE,
292
- assignees JSONB,
293
- duration INTEGER,
294
- output JSONB,
295
- retry INTEGER DEFAULT 0,
296
- consumer TEXT,
297
- log TEXT,
298
- draft JSONB,
299
- project_id UUID,
300
- feedback JSONB,
301
- updated_at TIMESTAMPTZ DEFAULT NOW(),
302
- username TEXT,
303
- status todo_status DEFAULT 'PENDING',
304
- agent_mode agent_mode DEFAULT 'COMPLETE',
305
- agent_orch agent_orch DEFAULT 'my_business_agent',
306
- temp_feedback TEXT,
307
- draft_status draft_status
308
- );
309
-
310
- -- 3. Events 테이블 생성
311
- CREATE TABLE IF NOT EXISTS events (
312
- id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
313
- todolist_id UUID NOT NULL REFERENCES todolist(id),
314
- event_type VARCHAR(50) NOT NULL,
315
- event_data JSONB NOT NULL,
316
- context_id VARCHAR(255),
317
- task_id VARCHAR(255),
318
- message TEXT,
319
- created_at TIMESTAMPTZ DEFAULT NOW()
320
- );
321
-
322
- -- 4. 인덱스 생성
323
- CREATE INDEX IF NOT EXISTS idx_todolist_status_agent ON todolist(status, agent_orch);
324
- CREATE INDEX IF NOT EXISTS idx_todolist_proc_inst ON todolist(proc_inst_id);
325
- CREATE INDEX IF NOT EXISTS idx_events_todolist_id ON events(todolist_id);
326
- CREATE INDEX IF NOT EXISTS idx_events_created_at ON events(created_at);
327
- ```
328
-
329
- #### 3.3 필수 함수 생성
330
-
331
- 프로젝트에 포함된 `function.sql` 파일을 Supabase에서 실행:
332
-
333
- ```bash
334
- # SQL 파일 내용을 Supabase SQL Editor에 복사하여 실행
335
- cat function.sql
336
- ```
337
-
338
- ### 4. SQL Insert로 테스트
339
-
340
- #### 4.1 직접 SQL 테스트
341
-
342
- Supabase SQL Editor에서 테스트 작업 생성:
343
-
344
- ```sql
345
- -- 테스트 작업 삽입
346
- INSERT INTO todolist (
347
- user_id,
348
- proc_inst_id,
349
- activity_name,
350
- description,
351
- tenant_id,
352
- agent_orch,
353
- status
354
- ) VALUES (
355
- 'test-user-001',
356
- 'proc-inst-' || gen_random_uuid()::text,
357
- 'data_analysis_task',
358
- '월별 매출 데이터를 분석하고 트렌드를 파악해주세요',
359
- 'test-tenant-001',
360
- 'my_business_agent',
361
- 'IN_PROGRESS'
362
- );
363
-
364
- -- 삽입된 작업 확인
365
- SELECT id, description, status, agent_orch, created_at
366
- FROM todolist
367
- ORDER BY created_at DESC
368
- LIMIT 5;
369
- ```
370
-
371
- #### 4.2 Python 클라이언트로 테스트
372
-
373
- ```python
374
- import os
375
- from supabase import create_client, Client
376
-
377
- # Supabase 클라이언트 초기화
378
- supabase: Client = create_client(
379
- os.getenv("SUPABASE_URL"),
380
- os.getenv("SUPABASE_ANON_KEY")
381
- )
382
-
383
- def create_test_task(description: str, agent_type: str = "my_business_agent"):
384
- """테스트 작업 생성"""
385
-
386
- task_data = {
387
- "user_id": "test-user-001",
388
- "proc_inst_id": f"proc-inst-{os.urandom(8).hex()}",
389
- "activity_name": "test_task",
390
- "description": description,
391
- "tenant_id": "test-tenant-001",
392
- "agent_orch": agent_type,
393
- "status": "IN_PROGRESS"
394
- }
395
-
396
- try:
397
- result = supabase.table("todolist").insert(task_data).execute()
398
- task_id = result.data[0]["id"]
399
- print(f"✅ 작업 생성 성공: {task_id}")
400
- print(f"📝 설명: {description}")
401
- return task_id
402
- except Exception as e:
403
- print(f"❌ 작업 생성 실패: {e}")
404
- return None
405
-
406
- def monitor_task_progress(task_id: str):
407
- """작업 진행상황 모니터링"""
408
-
409
- print(f"\n📊 작업 진행상황 모니터링: {task_id}")
410
-
411
- try:
412
- # 작업 상태 조회
413
- task_result = supabase.table("todolist").select("*").eq("id", task_id).execute()
414
- if task_result.data:
415
- task = task_result.data[0]
416
- print(f"상태: {task['status']}")
417
- print(f"Draft 상태: {task.get('draft_status', 'None')}")
418
-
419
- # 관련 이벤트 조회
420
- events_result = supabase.table("events").select("*").eq("todolist_id", task_id).order("created_at").execute()
421
-
422
- print(f"\n📋 이벤트 히스토리 ({len(events_result.data)}개):")
423
- for event in events_result.data:
424
- print(f" [{event['created_at']}] {event['event_type']}: {event.get('message', 'N/A')}")
425
-
426
- except Exception as e:
427
- print(f"❌ 모니터링 실패: {e}")
428
-
429
- if __name__ == "__main__":
430
- # 테스트 시나리오
431
- test_cases = [
432
- "월별 매출 데이터를 분석해주세요",
433
- "고객 만족도 조사 보고서를 작성해주세요",
434
- "고객 문의에 대한 응답을 준비해주세요",
435
- "신제품 출시 프로젝트 계획을 수립해주세요"
436
- ]
437
-
438
- print("🚀 ProcessGPT 테스트 시작\n")
439
-
440
- for i, description in enumerate(test_cases, 1):
441
- print(f"--- 테스트 {i} ---")
442
- task_id = create_test_task(description)
443
-
444
- if task_id:
445
- # 잠시 대기 후 진행상황 확인
446
- import time
447
- time.sleep(2)
448
- monitor_task_progress(task_id)
449
-
450
- print("\n" + "="*50 + "\n")
451
- ```
452
-
453
- 실행하기:
454
-
455
- ```bash
456
- python test_client.py
457
- ```
458
-
459
- #### 4.3 실시간 모니터링
460
-
461
- 작업 진행상황을 실시간으로 모니터링:
462
-
463
- ```python
464
- import asyncio
465
- from supabase import create_client
466
-
467
- async def real_time_monitor():
468
- """실시간 이벤트 모니터링"""
469
-
470
- supabase = create_client(
471
- os.getenv("SUPABASE_URL"),
472
- os.getenv("SUPABASE_ANON_KEY")
473
- )
474
-
475
- print("📡 실시간 모니터링 시작...")
476
-
477
- while True:
478
- try:
479
- # 최근 이벤트 조회
480
- events = supabase.table("events")\
481
- .select("*, todolist!inner(description)")\
482
- .order("created_at", desc=True)\
483
- .limit(5)\
484
- .execute()
485
-
486
- for event in events.data:
487
- task_desc = event['todolist']['description'][:50] + "..."
488
- print(f"[{event['created_at']}] {event['event_type']}: {task_desc}")
489
-
490
- await asyncio.sleep(5) # 5초마다 체크
491
-
492
- except KeyboardInterrupt:
493
- print("\n모니터링 중지")
494
- break
495
- except Exception as e:
496
- print(f"모니터링 오류: {e}")
497
- await asyncio.sleep(5)
498
-
499
- # 실행
500
- asyncio.run(real_time_monitor())
501
- ```
502
-
503
- ---
504
-
505
- ## 🎮 ProcessGPT Agent Simulator
506
-
507
- **데이터베이스 연결 없이** ProcessGPT 에이전트를 시뮬레이션할 수 있는 완전한 툴킷이 제공됩니다. 개발, 테스트, 데모 목적으로 사용할 수 있습니다.
508
-
509
- ### 🚀 빠른 시작
510
-
511
- #### 독립적인 시뮬레이터 (추천)
512
-
513
- ```bash
514
- # 기본 시뮬레이션 실행
515
- python3 simulate_standalone.py "데이터를 분석해주세요"
516
-
517
- # 빠른 실행 (지연 시간 단축)
518
- python3 simulate_standalone.py "보고서를 작성해주세요" --delay 0.3
519
-
520
- # 상세 로그와 함께
521
- python3 simulate_standalone.py "고객 문의를 처리해주세요" --verbose
522
-
523
- # 도움말 보기
524
- python3 simulate_standalone.py --help
525
- ```
526
-
527
- #### 의존성이 있는 시뮬레이터
528
-
529
- ```bash
530
- # 간단한 시뮬레이션 실행
531
- python processgpt_simulator_cli.py "데이터를 분석해주세요"
532
-
533
- # 또는 shell script 사용
534
- ./simulate.sh "보고서를 작성해주세요"
535
-
536
- # 고급 옵션
537
- python processgpt_simulator_cli.py "프로젝트를 계획해주세요" --steps 8 --delay 0.5
538
- ```
539
-
540
- ### 🎯 주요 특징
541
-
542
- - **데이터베이스 불필요**: Supabase 연결 없이 완전한 독립 실행
543
- - **스마트 프로세스 선택**: 프롬프트 분석으로 자동 프로세스 결정
544
- - **실시간 이벤트 출력**: JSON 형태로 진행상태를 stdout에 출력
545
- - **사용자 정의 가능**: 자체 실행기 구현 지원
546
- - **다양한 시뮬레이션 모드**: 단계별 진행, 지연 시간 조정 등
547
-
548
- ### 🧠 지원하는 프로세스 타입
549
-
550
- 시뮬레이터는 프롬프트를 분석하여 자동으로 적절한 프로세스를 선택합니다:
551
-
552
- - **데이터 분석**: 데이터 수집 → 정제 → 분석 → 결과 생성 → 시각화
553
- - **보고서 작성**: 요구사항 분석 → 구조 설계 → 내용 작성 → 검토
554
- - **고객 서비스**: 문의 분석 → 솔루션 검색 → 응답 준비
555
- - **프로젝트 관리**: 분석 → 계획 → 리소스 할당 → 위험 평가
556
- - **일반 작업**: 작업 분석 → 처리 수행 → 결과 생성
557
-
558
- ### 📊 출력 형태
559
-
560
- 시뮬레이터는 각 이벤트를 JSON 형태로 stdout에 출력합니다:
561
-
562
- ```json
563
- [EVENT] {
564
- "timestamp": "2024-01-15T10:30:45.123456Z",
565
- "task_id": "550e8400-e29b-41d4-a716-446655440000",
566
- "proc_inst_id": "550e8400-e29b-41d4-a716-446655440001",
567
- "event": {
568
- "type": "progress",
569
- "data": {
570
- "step": 2,
571
- "total_steps": 5,
572
- "step_name": "데이터 정제",
573
- "message": "데이터를 정제하고 전처리하고 있습니다...",
574
- "progress_percentage": 40.0,
575
- "process_type": "데이터 분석"
576
- }
577
- }
578
- }
579
- ```
580
-
581
- #### 이벤트 타입
582
-
583
- - `task_started`: 작업 시작
584
- - `progress`: 진행 상황 업데이트
585
- - `output`: 중간/최종 결과 출력
586
- - `done`: 작업 완료
587
- - `cancelled`: 작업 취소
588
- - `error`: 오류 발생
589
-
590
- ### 📋 CLI 옵션
591
-
592
- | 옵션 | 설명 | 기본값 |
593
- |------|------|--------|
594
- | `prompt` | 에이전트가 처리할 프롬프트 메시지 | (필수) |
595
- | `--agent-orch` | 에이전트 오케스트레이션 타입 | `simulator` |
596
- | `--activity-name` | 활동 이름 | `simulation_task` |
597
- | `--user-id` | 사용자 ID | 자동 생성 |
598
- | `--tenant-id` | 테넌트 ID | 자동 생성 |
599
- | `--tool` | 사용할 도구 | `default` |
600
- | `--feedback` | 피드백 메시지 | (빈 문자열) |
601
- | `--steps` | 시뮬레이션 단계 수 | `5` (프로세스별 자동 결정) |
602
- | `--delay` | 각 단계별 대기 시간(초) | `1.0` |
603
- | `--verbose` | 상세한 로그 출력 | `false` |
604
-
605
- ### 시뮬레이터에서 사용자 정의 실행기 사용
606
-
607
- ```python
608
- # 시뮬레이터에서 사용자 정의 실행기 사용 예제
609
- from processgpt_agent_sdk.simulator import ProcessGPTAgentSimulator
610
- from my_custom_executor import MyBusinessAgentExecutor
611
-
612
- async def main():
613
- # 사용자 정의 실행기 생성
614
- executor = MyBusinessAgentExecutor(config={"timeout": 30})
615
-
616
- # 시뮬레이터 생성
617
- simulator = ProcessGPTAgentSimulator(
618
- executor=executor,
619
- agent_orch="my_business_agent"
620
- )
621
-
622
- # 시뮬레이션 실행
623
- await simulator.run_simulation(
624
- prompt="월별 매출 보고서를 작성해주세요",
625
- activity_name="report_generation",
626
- user_id="user123",
627
- tenant_id="tenant456"
628
- )
629
-
630
- # 실행
631
- if __name__ == "__main__":
632
- asyncio.run(main())
633
- ```
634
-
635
- ### 📁 실제 사용 예제
636
-
637
- #### 데이터 분석 시뮬레이션
638
-
639
- ```bash
640
- # 독립적 시뮬레이터 사용
641
- python3 simulate_standalone.py "월별 매출 데이터를 분석하고 트렌드를 파악해주세요" \
642
- --agent-orch "data_analyst" \
643
- --delay 0.5 \
644
- --verbose
645
-
646
- # 의존성 있는 시뮬레이터 사용
647
- python processgpt_simulator_cli.py "고객 행동 패턴을 분석해주세요" \
648
- --steps 6 \
649
- --delay 2.0
650
- ```
651
-
652
- #### 고객 서비스 시뮬레이션
653
-
654
- ```bash
655
- python3 simulate_standalone.py "제품 반품 문의에 대한 응답을 준비해주세요" \
656
- --agent-orch "customer_service" \
657
- --activity-name "return_inquiry" \
658
- --feedback "고객은 배송 지연을 이유로 반품을 요청했습니다"
659
- ```
660
-
661
- #### 프로젝트 관리 시뮬레이션
662
-
663
- ```bash
664
- python3 simulate_standalone.py "신제품 출시를 위한 프로젝트 계획을 수립해주세요" \
665
- --agent-orch "project_manager" \
666
- --delay 1.5
667
- ```
668
-
669
- ### 🔍 로그 및 디버깅
670
-
671
- #### 이벤트 필터링
672
-
673
- ```bash
674
- # 진행 상황 이벤트만 출력
675
- python3 simulate_standalone.py "테스트" | grep '\[EVENT\]' | jq '.event | select(.type == "progress")'
676
-
677
- # 최종 결과만 출력
678
- python3 simulate_standalone.py "테스트" | grep '\[EVENT\]' | jq '.event | select(.type == "output")'
679
-
680
- # 특정 프로세스 타입만 필터링
681
- python3 simulate_standalone.py "데이터 분석" | grep "데이터 분석"
682
- ```
683
-
684
- #### CI/CD 통합
685
-
686
- ```yaml
687
- # .github/workflows/test.yml
688
- name: Agent Simulation Tests
689
- on: [push, pull_request]
690
-
691
- jobs:
692
- test:
693
- runs-on: ubuntu-latest
694
- steps:
695
- - uses: actions/checkout@v2
696
- - name: Set up Python
697
- uses: actions/setup-python@v2
698
- with:
699
- python-version: '3.9'
700
-
701
- - name: Run Agent Simulation Tests
702
- run: |
703
- python3 simulate_standalone.py "테스트 시나리오 1" --delay 0.1
704
- python3 simulate_standalone.py "테스트 시나리오 2" --delay 0.1
705
- python3 simulate_standalone.py "테스트 시나리오 3" --delay 0.1
706
- ```
707
-
708
- ## 🔄 워크플로우
709
-
710
- ### 시퀀스 다이어그램
711
-
712
- ```mermaid
713
- sequenceDiagram
714
- participant Client as Client Application
715
- participant DB as Supabase Database
716
- participant TodoTable as TodoList Table
717
- participant EventTable as Events Table
718
- participant Server as ProcessGPT Agent Server
719
- participant Executor as Agent Executor
720
- participant AI as CrewAI/Langgraph/OpenAI
721
-
722
- Note over Client, AI: ProcessGPT Agent Framework Workflow
723
-
724
- %% Task Submission
725
- Client->>DB: Submit new task
726
- Client->>TodoTable: INSERT INTO todolist<br/>(agent_orch, description, status='IN_PROGRESS')
727
- TodoTable-->>Client: Return todolist_id
728
-
729
- %% Server Polling Loop
730
- loop Every 5 seconds (configurable)
731
- Server->>TodoTable: SELECT * FROM todolist<br/>WHERE status='IN_PROGRESS'<br/>AND agent_orch='{configured_type}'
732
- TodoTable-->>Server: Return pending tasks
733
-
734
- alt Tasks found
735
- Server->>TodoTable: UPDATE todolist<br/>SET draft_status='STARTED',<br/>consumer='{server_id}'
736
-
737
- %% Event Logging - Task Started
738
- Server->>EventTable: INSERT INTO events<br/>(todolist_id, event_type='task_started')
739
-
740
- %% Create Request Context
741
- Server->>Server: Create ProcessGPTRequestContext<br/>from todolist data
742
-
743
- %% Create Event Queue
744
- Server->>Server: Create ProcessGPTEventQueue<br/>with Supabase connection
745
-
746
- %% Execute Agent
747
- Server->>Executor: execute(context, event_queue)
748
-
749
- %% Agent Processing with AI Frameworks
750
- Executor->>AI: Use AI frameworks<br/>(CrewAI, Langgraph, OpenAI)<br/>with A2A interfaces
751
-
752
- loop During Agent Execution
753
- AI->>Executor: Progress events/status updates
754
- Executor->>Server: Forward events to ProcessGPTEventQueue
755
- Server->>EventTable: INSERT INTO events<br/>(todolist_id, event_type, event_data)
756
- end
757
-
758
- alt Agent Success
759
- AI-->>Executor: Task completed successfully
760
- Executor-->>Server: Task completion
761
- Server->>EventTable: INSERT INTO events<br/>(event_type='done')
762
- Server->>TodoTable: UPDATE todolist<br/>SET status='SUBMITTED',<br/>draft_status='COMPLETED'
763
- else Agent Failure
764
- AI-->>Executor: Task failed with error
765
- Executor-->>Server: Task failure
766
- Server->>EventTable: INSERT INTO events<br/>(event_type='error')
767
- Server->>TodoTable: UPDATE todolist<br/>SET status='CANCELLED'
768
- end
769
- else No tasks
770
- Note over Server: Wait for next polling cycle
771
- end
772
- end
773
-
774
- %% Client Status Monitoring
775
- loop Client Monitoring
776
- Client->>TodoTable: SELECT * FROM todolist<br/>WHERE id='{todolist_id}'
777
- TodoTable-->>Client: Return task status
778
-
779
- Client->>EventTable: SELECT * FROM events<br/>WHERE todolist_id='{todolist_id}'<br/>ORDER BY created_at
780
- EventTable-->>Client: Return event history
781
-
782
- alt Task Completed
783
- Note over Client: Process final result
784
- else Task Still Running
785
- Note over Client: Continue monitoring
786
- end
787
- end
788
- ```
789
-
790
- ### 워크플로우 단계
791
-
792
- 1. **태스크 제출**: 클라이언트가 `todolist` 테이블에 새로운 작업을 INSERT
793
- 2. **폴링**: ProcessGPT Agent Server가 주기적으로 `IN_PROGRESS` 상태의 작업들을 조회
794
- 3. **상태 업데이트**: 발견된 작업의 상태를 `STARTED`로 변경
795
- 4. **컨텍스트 생성**: todolist 데이터를 기반으로 `ProcessGPTRequestContext` 생성
796
- 5. **이벤트 큐 생성**: Supabase 연동 `ProcessGPTEventQueue` 생성
797
- 6. **에이전트 실행**: Google A2A SDK 인터페이스를 통해 AI 프레임워크(CrewAI, Langgraph, OpenAI) 호출
798
- 7. **이벤트 로깅**: 실행 과정의 모든 이벤트가 `events` 테이블에 저장
799
- 8. **완료 처리**: 최종 결과가 `todolist`의 `output` 또는 `draft`에 저장
800
-
801
- ## 🛠️ 커스터마이제이션
802
-
803
- ### CrewAI 통합 예제
804
-
805
- ```python
806
- from crewai import Agent, Task, Crew
807
- import asyncio
808
-
809
- class CrewAIAgentExecutor(AgentExecutor):
810
- """CrewAI를 활용한 AgentExecutor"""
811
-
812
- def __init__(self):
813
- self.is_cancelled = False
814
-
815
- # CrewAI 에이전트 설정
816
- self.researcher = Agent(
817
- role='Senior Researcher',
818
- goal='Conduct thorough research and provide accurate information',
819
- backstory='An experienced researcher with attention to detail',
820
- verbose=True
821
- )
822
-
823
- self.analyst = Agent(
824
- role='Data Analyst',
825
- goal='Analyze data and extract meaningful insights',
826
- backstory='A skilled analyst with expertise in data interpretation',
827
- verbose=True
828
- )
829
-
830
- async def execute(self, context: RequestContext, event_queue: EventQueue) -> None:
831
- user_input = context.get_user_input()
832
-
833
- # 시작 이벤트
834
- start_event = Event(
835
- type="task_started",
836
- data={"message": f"CrewAI 에이전트 시작: {user_input}"}
837
- )
838
- event_queue.enqueue_event(start_event)
839
-
840
- try:
841
- # CrewAI 태스크 생성
842
- research_task = Task(
843
- description=f"Research the following topic: {user_input}",
844
- agent=self.researcher,
845
- expected_output="Comprehensive research findings"
846
- )
847
-
848
- analysis_task = Task(
849
- description="Analyze the research findings and provide insights",
850
- agent=self.analyst,
851
- expected_output="Detailed analysis with actionable insights"
852
- )
853
-
854
- # Crew 생성 및 실행
855
- crew = Crew(
856
- agents=[self.researcher, self.analyst],
857
- tasks=[research_task, analysis_task],
858
- verbose=True
859
- )
860
-
861
- # 진행 상황 이벤트
862
- progress_event = Event(
863
- type="progress",
864
- data={"message": "CrewAI 에이전트들이 작업을 수행하고 있습니다..."}
865
- )
866
- event_queue.enqueue_event(progress_event)
867
-
868
- # 비동기 실행
869
- result = await asyncio.to_thread(crew.kickoff)
870
-
871
- # 결과 이벤트
872
- output_event = Event(
873
- type="output",
874
- data={
875
- "content": {
876
- "crew_result": str(result),
877
- "agents_used": ["Senior Researcher", "Data Analyst"]
878
- },
879
- "final": True
880
- }
881
- )
882
- event_queue.enqueue_event(output_event)
883
-
884
- # 완료 이벤트
885
- done_event = Event(
886
- type="done",
887
- data={"message": "CrewAI 작업 완료", "success": True}
888
- )
889
- event_queue.enqueue_event(done_event)
890
-
891
- except Exception as e:
892
- error_event = Event(
893
- type="error",
894
- data={"message": f"CrewAI 실행 오류: {str(e)}"}
895
- )
896
- event_queue.enqueue_event(error_event)
897
- raise
898
-
899
- async def cancel(self, context: RequestContext, event_queue: EventQueue) -> None:
900
- self.is_cancelled = True
901
- # CrewAI 취소 로직 구현
902
- ```
903
-
904
- ## 📊 모니터링
905
-
906
- 시스템 상태를 모니터링하기 위한 유틸리티:
907
-
908
- ```python
909
- from processgpt_utils import ProcessGPTMonitor
910
-
911
- monitor = ProcessGPTMonitor(supabase)
912
-
913
- # 시스템 통계 조회
914
- stats = await monitor.get_system_stats()
915
- print(f"Total tasks: {stats['total_tasks']}")
916
- print(f"Pending: {stats['pending_tasks']}")
917
- print(f"Completed: {stats['completed_tasks']}")
918
-
919
- # 최근 이벤트 조회
920
- recent_events = await monitor.get_recent_events(limit=10)
921
- ```
922
-
923
- ## 🔧 설정 옵션
924
-
925
- ### 환경변수
926
-
927
- ```bash
928
- # Supabase 설정
929
- SUPABASE_URL=https://your-project.supabase.co
930
- SUPABASE_ANON_KEY=your-anon-key-here
931
-
932
- # 에이전트 설정
933
- DEFAULT_AGENT_TYPE=my_business_agent
934
- DEFAULT_POLLING_INTERVAL=5
935
-
936
- # 로깅
937
- LOG_LEVEL=INFO
938
- ```
939
-
940
- ### 서버 옵션
941
-
942
- ```bash
943
- # 폴링 간격 설정 (초)
944
- python server.py --polling-interval 10
945
-
946
- # 특정 에이전트 타입만 처리
947
- python server.py --agent-type my-custom-agent
948
- ```
949
-
950
- ## 🐛 트러블슈팅
951
-
952
- ### 시뮬레이터 관련
953
-
954
- 1. **Import 오류**
955
- - Python 경로가 올바르게 설정되었는지 확인
956
- - 필요한 의존성이 설치되었는지 확인: `pip install -r requirements.txt`
957
-
958
- 2. **Permission 오류**
959
- - 스크립트 실행 권한 부여: `chmod +x simulate_standalone.py`
960
- - 헬퍼 스크립트 권한 부여: `chmod +x simulate.sh`
961
-
962
- 3. **시뮬레이션이 느리게 실행됨**
963
- - `--delay` 옵션으로 단계별 지연 시간 단축: `--delay 0.1`
964
- - `--steps` 옵션으로 단계 수 줄이기: `--steps 3`
965
-
966
- ### 실제 서버 관련
967
-
968
- 1. **Supabase 연결 실패**
969
- - 환경변수 `SUPABASE_URL`과 `SUPABASE_ANON_KEY` 확인
970
- - 네트워크 연결 상태 확인
971
- - Supabase 프로젝트가 활성화되어 있는지 확인
972
-
973
- 2. **폴링이 작동하지 않음**
974
- - 데이터베이스 테이블이 올바르게 생성되었는지 확인
975
- - `agent_orch`이 정확히 매칭되는지 확인
976
- - 폴링 간격 설정 확인
977
-
978
- 3. **이벤트가 저장되지 않음**
979
- - Supabase RLS (Row Level Security) 정책 확인
980
- - 테이블 권한 설정 확인
981
- - API 키 권한 확인
982
-
983
- ### 로그 확인
984
-
985
- ```bash
986
- # 시뮬레이터 디버그 모드
987
- python3 simulate_standalone.py "테스트" --verbose
988
-
989
- # 실제 서버 디버그 모드
990
- LOG_LEVEL=DEBUG python server.py
991
-
992
- # 로그 간격 조정
993
- LOG_SPACED=0 python3 simulate_standalone.py "테스트"
994
- ```
995
-
996
- ### 성능 최적화
997
-
998
- ```bash
999
- # 빠른 테스트를 위한 설정
1000
- python3 simulate_standalone.py "테스트" --delay 0.1 --steps 2
1001
-
1002
- # 배치 테스트
1003
- for prompt in "분석" "보고서" "고객서비스"; do
1004
- python3 simulate_standalone.py "$prompt 작업" --delay 0.1
1005
- done
1006
- ```
1007
-
1008
- ## 🤝 기여
1009
-
1010
- 1. Fork the repository
1011
- 2. Create a feature branch
1012
- 3. Commit your changes
1013
- 4. Push to the branch
1014
- 5. Create a Pull Request
1015
-
1016
- ## 📄 라이선스
1017
-
1018
- MIT License - 자세한 내용은 LICENSE 파일을 참조하세요.
1019
-
1020
- ## 🔗 관련 링크
1021
-
1022
- - [Google A2A SDK Documentation](https://developers.google.com/a2a)
1023
- - [Supabase Documentation](https://supabase.com/docs)
1024
- - [CrewAI Documentation](https://docs.crewai.com/)
1025
- - [LangGraph Documentation](https://langchain-ai.github.io/langgraph/)
1026
- - [ProcessGPT Framework Issues](https://github.com/your-repo/issues)