process-gpt-agent-sdk 0.3.20__py3-none-any.whl → 0.4.0__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.
- process_gpt_agent_sdk-0.4.0.dist-info/METADATA +177 -0
- process_gpt_agent_sdk-0.4.0.dist-info/RECORD +8 -0
- processgpt_agent_sdk/__init__.py +42 -42
- processgpt_agent_sdk/database.py +391 -382
- processgpt_agent_sdk/processgpt_agent_framework.py +516 -515
- processgpt_agent_sdk/utils.py +76 -58
- process_gpt_agent_sdk-0.3.20.dist-info/METADATA +0 -663
- process_gpt_agent_sdk-0.3.20.dist-info/RECORD +0 -8
- {process_gpt_agent_sdk-0.3.20.dist-info → process_gpt_agent_sdk-0.4.0.dist-info}/WHEEL +0 -0
- {process_gpt_agent_sdk-0.3.20.dist-info → process_gpt_agent_sdk-0.4.0.dist-info}/top_level.txt +0 -0
processgpt_agent_sdk/utils.py
CHANGED
|
@@ -2,64 +2,91 @@ import os
|
|
|
2
2
|
import logging
|
|
3
3
|
import traceback
|
|
4
4
|
from typing import Any, Dict, Optional, List
|
|
5
|
-
from
|
|
6
|
-
from openai import AsyncOpenAI
|
|
5
|
+
from llm_factory import create_llm
|
|
7
6
|
|
|
8
7
|
|
|
9
8
|
logger = logging.getLogger(__name__)
|
|
10
9
|
|
|
11
10
|
|
|
12
11
|
# ─────────────────────────────
|
|
13
|
-
# Lazy Singleton
|
|
12
|
+
# Lazy Singleton LLM Client
|
|
14
13
|
# ─────────────────────────────
|
|
15
|
-
_client
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
14
|
+
_client = None
|
|
15
|
+
_global_agent_model = None
|
|
16
|
+
|
|
17
|
+
def set_agent_model(agent: Optional[Dict[str, Any]]) -> None:
|
|
18
|
+
"""첫 번째 에이전트의 모델을 글로벌 변수에 설정합니다."""
|
|
19
|
+
global _global_agent_model
|
|
20
|
+
|
|
21
|
+
if agent:
|
|
22
|
+
model = agent.get("model")
|
|
23
|
+
if model:
|
|
24
|
+
# "openai/gpt-4o" 형식을 파싱하여 provider와 model 분리
|
|
25
|
+
if "/" in model:
|
|
26
|
+
provider, model_name = model.split("/", 1)
|
|
27
|
+
_global_agent_model = {"provider": provider, "model": model_name}
|
|
28
|
+
logger.info("🤖 글로벌 에이전트 모델 설정: %s/%s", provider, model_name)
|
|
29
|
+
else:
|
|
30
|
+
# 벤더사명이 없으면 모델명만 저장
|
|
31
|
+
_global_agent_model = {"provider": None, "model": model}
|
|
32
|
+
logger.info("🤖 글로벌 에이전트 모델 설정: %s", model)
|
|
33
|
+
else:
|
|
34
|
+
_global_agent_model = None
|
|
35
|
+
logger.info("🤖 에이전트에 모델 정보가 없음")
|
|
36
|
+
else:
|
|
37
|
+
_global_agent_model = None
|
|
38
|
+
logger.info("🤖 에이전트가 없음")
|
|
39
|
+
|
|
40
|
+
def get_agent_model() -> Optional[str]:
|
|
41
|
+
"""글로벌 에이전트 모델 정보를 반환합니다."""
|
|
42
|
+
return _global_agent_model
|
|
43
|
+
|
|
44
|
+
def get_client():
|
|
24
45
|
global _client
|
|
25
46
|
if _client is not None:
|
|
26
47
|
return _client
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
48
|
+
|
|
49
|
+
# 글로벌 에이전트 모델로 클라이언트 생성
|
|
50
|
+
agent_model = get_agent_model()
|
|
51
|
+
if agent_model:
|
|
52
|
+
provider = agent_model["provider"]
|
|
53
|
+
model_name = agent_model["model"]
|
|
54
|
+
|
|
55
|
+
if provider:
|
|
56
|
+
# 벤더사가 있으면 provider와 model 모두 전달
|
|
57
|
+
_client = create_llm(provider=provider, model=model_name, temperature=0)
|
|
58
|
+
logger.info("🤖 글로벌 에이전트 모델로 LLM 클라이언트 초기화: %s/%s", provider, model_name)
|
|
59
|
+
else:
|
|
60
|
+
# 벤더사가 없으면 model만 전달
|
|
61
|
+
_client = create_llm(model=model_name, temperature=0)
|
|
62
|
+
logger.info("🤖 글로벌 에이전트 모델로 LLM 클라이언트 초기화: %s", model_name)
|
|
63
|
+
else:
|
|
64
|
+
_client = create_llm(model="gpt-4.1-mini", temperature=0)
|
|
65
|
+
logger.info("🔧 기본 모델로 LLM 클라이언트 초기화: gpt-4.1-mini")
|
|
32
66
|
return _client
|
|
33
67
|
|
|
34
68
|
# ─────────────────────────────
|
|
35
69
|
# 공통 LLM 호출 유틸
|
|
36
70
|
# ─────────────────────────────
|
|
37
|
-
async def _llm_request(system: str, user: str
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
#
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
text =
|
|
55
|
-
|
|
56
|
-
text = None
|
|
57
|
-
|
|
58
|
-
if not text and hasattr(resp, "choices") and resp.choices: # 구 구조 호환
|
|
59
|
-
choice0 = resp.choices[0]
|
|
60
|
-
text = getattr(getattr(choice0, "message", None), "content", None)
|
|
61
|
-
|
|
62
|
-
if not text:
|
|
71
|
+
async def _llm_request(system: str, user: str) -> str:
|
|
72
|
+
logger.info("📡 LLM 요청 전송")
|
|
73
|
+
|
|
74
|
+
model = get_client()
|
|
75
|
+
|
|
76
|
+
# llm_factory를 사용한 LLM 호출
|
|
77
|
+
messages = [
|
|
78
|
+
{"role": "system", "content": system},
|
|
79
|
+
{"role": "user", "content": user},
|
|
80
|
+
]
|
|
81
|
+
|
|
82
|
+
response = await model.ainvoke(messages)
|
|
83
|
+
|
|
84
|
+
# 응답에서 텍스트 추출
|
|
85
|
+
if hasattr(response, 'content'):
|
|
86
|
+
text = response.content
|
|
87
|
+
elif isinstance(response, str):
|
|
88
|
+
text = response
|
|
89
|
+
else:
|
|
63
90
|
raise RuntimeError("No text in LLM response")
|
|
64
91
|
|
|
65
92
|
return text.strip()
|
|
@@ -68,12 +95,8 @@ async def _llm_request(system: str, user: str, model_env: str, default_model: st
|
|
|
68
95
|
# 공개 API
|
|
69
96
|
# ─────────────────────────────
|
|
70
97
|
async def summarize_error_to_user(exc: Exception, meta: Dict[str, Any]) -> str:
|
|
71
|
-
"""
|
|
72
|
-
|
|
73
|
-
- 모델: gpt-4.1-nano (환경변수 ERROR_SUMMARY_MODEL로 재정의 가능)
|
|
74
|
-
- 폴백: 없음 (LLM 실패 시 예외를 상위로 전파)
|
|
75
|
-
"""
|
|
76
|
-
logger.info("🔍 오류 컨텍스트 분석 시작")
|
|
98
|
+
"""예외 정보를 바탕으로 사용자 친화적인 5줄 요약을 생성."""
|
|
99
|
+
logger.info("\n\n🔍 오류 컨텍스트 분석 시작")
|
|
77
100
|
|
|
78
101
|
err_text = f"{type(exc).__name__}: {str(exc)}"
|
|
79
102
|
|
|
@@ -109,20 +132,15 @@ async def summarize_error_to_user(exc: Exception, meta: Dict[str, Any]) -> str:
|
|
|
109
132
|
)
|
|
110
133
|
|
|
111
134
|
try:
|
|
112
|
-
text = await _llm_request(system, user
|
|
135
|
+
text = await _llm_request(system, user)
|
|
113
136
|
logger.info("✅ LLM 오류 요약 생성 완료")
|
|
114
137
|
return text
|
|
115
138
|
except Exception as e:
|
|
116
139
|
logger.warning("⚠️ LLM 오류 요약 생성 실패: %s", e, exc_info=True)
|
|
117
|
-
# 폴백 없이 상위 전파
|
|
118
140
|
raise
|
|
119
141
|
|
|
120
142
|
async def summarize_feedback(feedback_data: List[dict], content_data: dict = {}) -> str:
|
|
121
|
-
"""
|
|
122
|
-
피드백과 결과물을 바탕으로 통합된 피드백 요약을 생성.
|
|
123
|
-
- 모델: gpt-4.1-nano (환경변수 FEEDBACK_SUMMARY_MODEL로 재정의 가능)
|
|
124
|
-
- 폴백: 없음 (LLM 실패 시 예외를 상위로 전파)
|
|
125
|
-
"""
|
|
143
|
+
"""피드백과 결과물을 바탕으로 통합된 피드백 요약을 생성."""
|
|
126
144
|
logger.info(
|
|
127
145
|
"🔍 피드백 요약 처리 시작 | 피드백: %s, 결과물: %s자",
|
|
128
146
|
feedback_data, content_data)
|
|
@@ -131,12 +149,11 @@ async def summarize_feedback(feedback_data: List[dict], content_data: dict = {})
|
|
|
131
149
|
user_prompt = _create_feedback_summary_prompt(feedback_data, content_data)
|
|
132
150
|
|
|
133
151
|
try:
|
|
134
|
-
text = await _llm_request(system_prompt, user_prompt
|
|
152
|
+
text = await _llm_request(system_prompt, user_prompt)
|
|
135
153
|
logger.info("✅ LLM 피드백 요약 생성 완료")
|
|
136
154
|
return text
|
|
137
155
|
except Exception as e:
|
|
138
156
|
logger.error("❌ LLM 피드백 요약 생성 실패: %s", e, exc_info=True)
|
|
139
|
-
# 폴백 없이 상위 전파
|
|
140
157
|
raise
|
|
141
158
|
|
|
142
159
|
# ─────────────────────────────
|
|
@@ -166,6 +183,7 @@ def _create_feedback_summary_prompt(feedback_data: List[dict], content_data: dic
|
|
|
166
183
|
- 구체적이고 실행 가능한 개선사항 제시
|
|
167
184
|
- **자연스럽고 통합된 하나의 완전한 피드백으로 작성**
|
|
168
185
|
- 최대 1000자까지 허용하여 상세히 작성
|
|
186
|
+
- 만약 전달된 피드백 내용이 1000자 미만일 경우 요약하지 않고 하나의 문맥으로 그대로 반환
|
|
169
187
|
|
|
170
188
|
**중요한 상황별 처리:**
|
|
171
189
|
- 결과물 품질에 대한 불만 → **품질 개선** 요구
|