process-gpt-agent-sdk 0.2.3__tar.gz → 0.2.5__tar.gz
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.
- {process_gpt_agent_sdk-0.2.3/process_gpt_agent_sdk.egg-info → process_gpt_agent_sdk-0.2.5}/PKG-INFO +1 -1
- {process_gpt_agent_sdk-0.2.3 → process_gpt_agent_sdk-0.2.5/process_gpt_agent_sdk.egg-info}/PKG-INFO +1 -1
- {process_gpt_agent_sdk-0.2.3 → process_gpt_agent_sdk-0.2.5}/processgpt_agent_sdk/core/database.py +2 -12
- {process_gpt_agent_sdk-0.2.3 → process_gpt_agent_sdk-0.2.5}/processgpt_agent_sdk/server.py +21 -5
- {process_gpt_agent_sdk-0.2.3 → process_gpt_agent_sdk-0.2.5}/processgpt_agent_sdk/utils/event_handler.py +32 -26
- {process_gpt_agent_sdk-0.2.3 → process_gpt_agent_sdk-0.2.5}/pyproject.toml +1 -1
- {process_gpt_agent_sdk-0.2.3 → process_gpt_agent_sdk-0.2.5}/MANIFEST.in +0 -0
- {process_gpt_agent_sdk-0.2.3 → process_gpt_agent_sdk-0.2.5}/README.md +0 -0
- {process_gpt_agent_sdk-0.2.3 → process_gpt_agent_sdk-0.2.5}/function.sql +0 -0
- {process_gpt_agent_sdk-0.2.3 → process_gpt_agent_sdk-0.2.5}/process_gpt_agent_sdk.egg-info/SOURCES.txt +0 -0
- {process_gpt_agent_sdk-0.2.3 → process_gpt_agent_sdk-0.2.5}/process_gpt_agent_sdk.egg-info/dependency_links.txt +0 -0
- {process_gpt_agent_sdk-0.2.3 → process_gpt_agent_sdk-0.2.5}/process_gpt_agent_sdk.egg-info/requires.txt +0 -0
- {process_gpt_agent_sdk-0.2.3 → process_gpt_agent_sdk-0.2.5}/process_gpt_agent_sdk.egg-info/top_level.txt +0 -0
- {process_gpt_agent_sdk-0.2.3 → process_gpt_agent_sdk-0.2.5}/processgpt_agent_sdk/__init__.py +0 -0
- {process_gpt_agent_sdk-0.2.3 → process_gpt_agent_sdk-0.2.5}/processgpt_agent_sdk/core/__init__.py +0 -0
- {process_gpt_agent_sdk-0.2.3 → process_gpt_agent_sdk-0.2.5}/processgpt_agent_sdk/tools/__init__.py +0 -0
- {process_gpt_agent_sdk-0.2.3 → process_gpt_agent_sdk-0.2.5}/processgpt_agent_sdk/tools/human_query_tool.py +0 -0
- {process_gpt_agent_sdk-0.2.3 → process_gpt_agent_sdk-0.2.5}/processgpt_agent_sdk/tools/knowledge_tools.py +0 -0
- {process_gpt_agent_sdk-0.2.3 → process_gpt_agent_sdk-0.2.5}/processgpt_agent_sdk/tools/safe_tool_loader.py +0 -0
- {process_gpt_agent_sdk-0.2.3 → process_gpt_agent_sdk-0.2.5}/processgpt_agent_sdk/utils/__init__.py +0 -0
- {process_gpt_agent_sdk-0.2.3 → process_gpt_agent_sdk-0.2.5}/processgpt_agent_sdk/utils/context_manager.py +0 -0
- {process_gpt_agent_sdk-0.2.3 → process_gpt_agent_sdk-0.2.5}/processgpt_agent_sdk/utils/crewai_event_listener.py +0 -0
- {process_gpt_agent_sdk-0.2.3 → process_gpt_agent_sdk-0.2.5}/processgpt_agent_sdk/utils/logger.py +0 -0
- {process_gpt_agent_sdk-0.2.3 → process_gpt_agent_sdk-0.2.5}/processgpt_agent_sdk/utils/summarizer.py +0 -0
- {process_gpt_agent_sdk-0.2.3 → process_gpt_agent_sdk-0.2.5}/setup.cfg +0 -0
{process_gpt_agent_sdk-0.2.3 → process_gpt_agent_sdk-0.2.5}/processgpt_agent_sdk/core/database.py
RENAMED
|
@@ -359,20 +359,10 @@ async def fetch_human_users_by_proc_inst_id(proc_inst_id: str) -> str:
|
|
|
359
359
|
# 데이터 저장
|
|
360
360
|
# 설명: 이벤트/알림/작업 결과 저장
|
|
361
361
|
# ============================================================================
|
|
362
|
-
async def record_event(
|
|
363
|
-
"""UI용 events 테이블에 이벤트 기록"""
|
|
362
|
+
async def record_event(payload: Dict[str, Any]) -> None:
|
|
363
|
+
"""UI용 events 테이블에 이벤트 기록 (전달된 payload 그대로 저장)"""
|
|
364
364
|
def _call():
|
|
365
365
|
client = get_db_client()
|
|
366
|
-
payload: Dict[str, Any] = {
|
|
367
|
-
"id": str(uuid.uuid4()),
|
|
368
|
-
"job_id": todo.get("proc_inst_id") or str(todo.get("id")),
|
|
369
|
-
"todo_id": str(todo.get("id")),
|
|
370
|
-
"proc_inst_id": todo.get("proc_inst_id"),
|
|
371
|
-
"crew_type": todo.get("agent_orch"),
|
|
372
|
-
"data": data,
|
|
373
|
-
}
|
|
374
|
-
if event_type is not None:
|
|
375
|
-
payload["event_type"] = event_type
|
|
376
366
|
return client.table("events").insert(payload).execute()
|
|
377
367
|
|
|
378
368
|
resp = await _async_retry(_call, name="record_event", fallback=lambda: None)
|
|
@@ -132,7 +132,8 @@ class ProcessGPTAgentServer:
|
|
|
132
132
|
executor = self._executor
|
|
133
133
|
|
|
134
134
|
context = ProcessGPTRequestContext(prepared_data)
|
|
135
|
-
|
|
135
|
+
loop = asyncio.get_running_loop()
|
|
136
|
+
event_queue = ProcessGPTEventQueue(task_record, loop=loop)
|
|
136
137
|
|
|
137
138
|
try:
|
|
138
139
|
set_context(
|
|
@@ -234,9 +235,10 @@ class ProcessGPTRequestContext(RequestContext):
|
|
|
234
235
|
# 설명: 실행기 이벤트를 내부 큐에 넣고, 비동기 처리 태스크를 생성해 저장 로직 호출
|
|
235
236
|
# =============================================================================
|
|
236
237
|
class ProcessGPTEventQueue(EventQueue):
|
|
237
|
-
def __init__(self, task_record: Dict[str, Any]):
|
|
238
|
+
def __init__(self, task_record: Dict[str, Any], loop: asyncio.AbstractEventLoop | None = None):
|
|
238
239
|
"""현재 처리 중인 작업 레코드를 보관한다."""
|
|
239
240
|
self.todo = task_record
|
|
241
|
+
self._loop = loop
|
|
240
242
|
super().__init__()
|
|
241
243
|
|
|
242
244
|
def enqueue_event(self, event: Event):
|
|
@@ -263,13 +265,27 @@ class ProcessGPTEventQueue(EventQueue):
|
|
|
263
265
|
pass
|
|
264
266
|
|
|
265
267
|
def _create_bg_task(self, coro: Any, label: str) -> None:
|
|
266
|
-
"""백그라운드 태스크 생성 및 완료 콜백으로 예외 로깅.
|
|
268
|
+
"""백그라운드 태스크 생성 및 완료 콜백으로 예외 로깅.
|
|
269
|
+
|
|
270
|
+
- 실행 중인 이벤트 루프가 없을 때도 전달된 루프에 안전하게 예약한다.
|
|
271
|
+
"""
|
|
267
272
|
try:
|
|
268
|
-
|
|
273
|
+
loop = self._loop
|
|
274
|
+
if loop is None:
|
|
275
|
+
try:
|
|
276
|
+
loop = asyncio.get_running_loop()
|
|
277
|
+
except RuntimeError:
|
|
278
|
+
raise
|
|
279
|
+
|
|
269
280
|
def _cb(t: asyncio.Task):
|
|
270
281
|
exc = t.exception()
|
|
271
282
|
if exc:
|
|
272
283
|
handle_application_error(f"백그라운드 태스크 오류({label})", exc, raise_error=False)
|
|
273
|
-
|
|
284
|
+
|
|
285
|
+
def _schedule():
|
|
286
|
+
task = loop.create_task(coro)
|
|
287
|
+
task.add_done_callback(_cb)
|
|
288
|
+
|
|
289
|
+
loop.call_soon_threadsafe(_schedule)
|
|
274
290
|
except Exception as e:
|
|
275
291
|
handle_application_error(f"백그라운드 태스크 생성 실패({label})", e, raise_error=False)
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
import json
|
|
4
|
-
import uuid
|
|
5
|
-
from datetime import datetime, timezone
|
|
6
3
|
from typing import Any, Dict
|
|
4
|
+
import uuid
|
|
7
5
|
|
|
8
6
|
from a2a.server.events import Event
|
|
9
7
|
from .logger import handle_application_error, write_log_message
|
|
@@ -11,35 +9,42 @@ from ..core.database import record_event, save_task_result
|
|
|
11
9
|
from ..tools.safe_tool_loader import SafeToolLoader
|
|
12
10
|
|
|
13
11
|
|
|
12
|
+
# =============================================================================
|
|
13
|
+
# 이벤트 변환: Event 또는 dict를 표준 dict로 통일
|
|
14
|
+
# =============================================================================
|
|
15
|
+
|
|
14
16
|
def convert_event_to_dictionary(event: Event) -> Dict[str, Any]:
|
|
17
|
+
"""Event/dict를 표준 dict로 변환한다."""
|
|
15
18
|
try:
|
|
19
|
+
# 이미 dict로 전달된 경우 그대로 사용
|
|
20
|
+
if isinstance(event, dict):
|
|
21
|
+
return event
|
|
22
|
+
# Event 객체면 공개 필드만 추출
|
|
16
23
|
if hasattr(event, "__dict__"):
|
|
17
24
|
return {k: v for k, v in event.__dict__.items() if not k.startswith("_")}
|
|
18
|
-
|
|
25
|
+
# 알 수 없는 타입은 문자열로 보존
|
|
26
|
+
return {"type": "event", "data": str(event)}
|
|
19
27
|
except Exception as e:
|
|
20
28
|
handle_application_error("event dict 변환 실패", e, raise_error=False)
|
|
21
|
-
return {"event": str(event)}
|
|
29
|
+
return {"type": "event", "data": str(event)}
|
|
22
30
|
|
|
23
31
|
|
|
24
|
-
|
|
25
|
-
|
|
32
|
+
# =============================================================================
|
|
33
|
+
# 이벤트 처리: type에 따라 저장 위치 분기
|
|
34
|
+
# =============================================================================
|
|
26
35
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
- "done": 실행 종료 신호 → 이벤트 기록 후 MCP 리소스 정리
|
|
30
|
-
"""
|
|
36
|
+
async def process_event_message(todo: Dict[str, Any], event: Event) -> None:
|
|
37
|
+
"""이벤트 타입별로 todolist/events에 저장하거나 리소스 정리."""
|
|
31
38
|
try:
|
|
32
39
|
data = convert_event_to_dictionary(event)
|
|
33
40
|
evt_type = str(data.get("type") or data.get("event_type") or "").lower()
|
|
34
41
|
|
|
35
42
|
# done: 종료 이벤트 → 기록 후 MCP 정리
|
|
36
43
|
if evt_type == "done":
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
"
|
|
40
|
-
|
|
41
|
-
}
|
|
42
|
-
await record_event(todo, normalized, event_type="done")
|
|
44
|
+
payload = data.get("data") or {}
|
|
45
|
+
if isinstance(payload, dict) and "id" not in payload:
|
|
46
|
+
payload["id"] = str(uuid.uuid4())
|
|
47
|
+
await record_event(payload)
|
|
43
48
|
try:
|
|
44
49
|
SafeToolLoader.shutdown_all_adapters()
|
|
45
50
|
write_log_message("MCP 리소스 정리 완료")
|
|
@@ -49,18 +54,19 @@ async def process_event_message(todo: Dict[str, Any], event: Event) -> None:
|
|
|
49
54
|
|
|
50
55
|
# output: 결과 저장만 수행
|
|
51
56
|
if evt_type == "output":
|
|
52
|
-
payload = data.get("data") or
|
|
53
|
-
is_final = bool(payload.get("final") or payload.get("is_final"))
|
|
57
|
+
payload = data.get("data") or {}
|
|
58
|
+
is_final = bool(payload.get("final") or payload.get("is_final")) if isinstance(payload, dict) else False
|
|
54
59
|
content = payload.get("content") if isinstance(payload, dict) else payload
|
|
55
60
|
await save_task_result(str(todo.get("id")), content, final=is_final)
|
|
56
61
|
return
|
|
62
|
+
|
|
63
|
+
# event : 일반 이벤트 저장 (워커 데이터 그대로 보존)
|
|
64
|
+
if evt_type == "event":
|
|
65
|
+
payload = data.get("data") or {}
|
|
66
|
+
if isinstance(payload, dict) and "id" not in payload:
|
|
67
|
+
payload["id"] = str(uuid.uuid4())
|
|
68
|
+
await record_event(payload)
|
|
69
|
+
return
|
|
57
70
|
|
|
58
|
-
# event: 일반 이벤트 저장
|
|
59
|
-
normalized = {
|
|
60
|
-
"id": str(uuid.uuid4()),
|
|
61
|
-
"timestamp": datetime.now(timezone.utc).isoformat(),
|
|
62
|
-
**data,
|
|
63
|
-
}
|
|
64
|
-
await record_event(todo, normalized, event_type="event")
|
|
65
71
|
except Exception as e:
|
|
66
72
|
handle_application_error("process_event_message 처리 실패", e, raise_error=False)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{process_gpt_agent_sdk-0.2.3 → process_gpt_agent_sdk-0.2.5}/processgpt_agent_sdk/__init__.py
RENAMED
|
File without changes
|
{process_gpt_agent_sdk-0.2.3 → process_gpt_agent_sdk-0.2.5}/processgpt_agent_sdk/core/__init__.py
RENAMED
|
File without changes
|
{process_gpt_agent_sdk-0.2.3 → process_gpt_agent_sdk-0.2.5}/processgpt_agent_sdk/tools/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{process_gpt_agent_sdk-0.2.3 → process_gpt_agent_sdk-0.2.5}/processgpt_agent_sdk/utils/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{process_gpt_agent_sdk-0.2.3 → process_gpt_agent_sdk-0.2.5}/processgpt_agent_sdk/utils/logger.py
RENAMED
|
File without changes
|
{process_gpt_agent_sdk-0.2.3 → process_gpt_agent_sdk-0.2.5}/processgpt_agent_sdk/utils/summarizer.py
RENAMED
|
File without changes
|
|
File without changes
|