hdsp-jupyter-extension 2.0.26__py3-none-any.whl → 2.0.28__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.
- agent_server/context_providers/__init__.py +4 -2
- agent_server/context_providers/actions.py +73 -7
- agent_server/context_providers/file.py +23 -23
- agent_server/langchain/__init__.py +2 -2
- agent_server/langchain/agent.py +18 -251
- agent_server/langchain/agent_factory.py +26 -4
- agent_server/langchain/agent_prompts/planner_prompt.py +22 -35
- agent_server/langchain/custom_middleware.py +278 -43
- agent_server/langchain/llm_factory.py +102 -54
- agent_server/langchain/logging_utils.py +1 -1
- agent_server/langchain/middleware/__init__.py +5 -0
- agent_server/langchain/middleware/code_history_middleware.py +126 -37
- agent_server/langchain/middleware/content_injection_middleware.py +110 -0
- agent_server/langchain/middleware/subagent_events.py +88 -9
- agent_server/langchain/middleware/subagent_middleware.py +518 -240
- agent_server/langchain/prompts.py +5 -22
- agent_server/langchain/state_schema.py +44 -0
- agent_server/langchain/tools/jupyter_tools.py +4 -5
- agent_server/langchain/tools/tool_registry.py +6 -0
- agent_server/routers/chat.py +305 -2
- agent_server/routers/config.py +193 -8
- agent_server/routers/config_schema.py +254 -0
- agent_server/routers/context.py +31 -8
- agent_server/routers/langchain_agent.py +310 -153
- hdsp_agent_core/managers/config_manager.py +100 -1
- {hdsp_jupyter_extension-2.0.26.data → hdsp_jupyter_extension-2.0.28.data}/data/share/jupyter/labextensions/hdsp-agent/build_log.json +1 -1
- {hdsp_jupyter_extension-2.0.26.data → hdsp_jupyter_extension-2.0.28.data}/data/share/jupyter/labextensions/hdsp-agent/package.json +2 -2
- hdsp_jupyter_extension-2.0.26.data/data/share/jupyter/labextensions/hdsp-agent/static/frontend_styles_index_js.b5e4416b4e07ec087aad.js → hdsp_jupyter_extension-2.0.28.data/data/share/jupyter/labextensions/hdsp-agent/static/frontend_styles_index_js.55727265b00191e68d9a.js +479 -15
- hdsp_jupyter_extension-2.0.28.data/data/share/jupyter/labextensions/hdsp-agent/static/frontend_styles_index_js.55727265b00191e68d9a.js.map +1 -0
- jupyter_ext/labextension/static/lib_index_js.67505497667f9c0a763d.js → hdsp_jupyter_extension-2.0.28.data/data/share/jupyter/labextensions/hdsp-agent/static/lib_index_js.df05d90f366bfd5fa023.js +1287 -190
- hdsp_jupyter_extension-2.0.28.data/data/share/jupyter/labextensions/hdsp-agent/static/lib_index_js.df05d90f366bfd5fa023.js.map +1 -0
- hdsp_jupyter_extension-2.0.26.data/data/share/jupyter/labextensions/hdsp-agent/static/remoteEntry.0fe2dcbbd176ee0efceb.js → hdsp_jupyter_extension-2.0.28.data/data/share/jupyter/labextensions/hdsp-agent/static/remoteEntry.08fce819ee32e9d25175.js +3 -3
- jupyter_ext/labextension/static/remoteEntry.0fe2dcbbd176ee0efceb.js.map → hdsp_jupyter_extension-2.0.28.data/data/share/jupyter/labextensions/hdsp-agent/static/remoteEntry.08fce819ee32e9d25175.js.map +1 -1
- {hdsp_jupyter_extension-2.0.26.dist-info → hdsp_jupyter_extension-2.0.28.dist-info}/METADATA +1 -1
- {hdsp_jupyter_extension-2.0.26.dist-info → hdsp_jupyter_extension-2.0.28.dist-info}/RECORD +66 -64
- jupyter_ext/_version.py +1 -1
- jupyter_ext/handlers.py +41 -0
- jupyter_ext/labextension/build_log.json +1 -1
- jupyter_ext/labextension/package.json +2 -2
- jupyter_ext/labextension/static/{frontend_styles_index_js.b5e4416b4e07ec087aad.js → frontend_styles_index_js.55727265b00191e68d9a.js} +479 -15
- jupyter_ext/labextension/static/frontend_styles_index_js.55727265b00191e68d9a.js.map +1 -0
- hdsp_jupyter_extension-2.0.26.data/data/share/jupyter/labextensions/hdsp-agent/static/lib_index_js.67505497667f9c0a763d.js → jupyter_ext/labextension/static/lib_index_js.df05d90f366bfd5fa023.js +1287 -190
- jupyter_ext/labextension/static/lib_index_js.df05d90f366bfd5fa023.js.map +1 -0
- jupyter_ext/labextension/static/{remoteEntry.0fe2dcbbd176ee0efceb.js → remoteEntry.08fce819ee32e9d25175.js} +3 -3
- hdsp_jupyter_extension-2.0.26.data/data/share/jupyter/labextensions/hdsp-agent/static/remoteEntry.0fe2dcbbd176ee0efceb.js.map → jupyter_ext/labextension/static/remoteEntry.08fce819ee32e9d25175.js.map +1 -1
- agent_server/langchain/middleware/description_injector.py +0 -150
- hdsp_jupyter_extension-2.0.26.data/data/share/jupyter/labextensions/hdsp-agent/static/frontend_styles_index_js.b5e4416b4e07ec087aad.js.map +0 -1
- hdsp_jupyter_extension-2.0.26.data/data/share/jupyter/labextensions/hdsp-agent/static/lib_index_js.67505497667f9c0a763d.js.map +0 -1
- jupyter_ext/labextension/static/frontend_styles_index_js.b5e4416b4e07ec087aad.js.map +0 -1
- jupyter_ext/labextension/static/lib_index_js.67505497667f9c0a763d.js.map +0 -1
- {hdsp_jupyter_extension-2.0.26.data → hdsp_jupyter_extension-2.0.28.data}/data/etc/jupyter/jupyter_server_config.d/hdsp_jupyter_extension.json +0 -0
- {hdsp_jupyter_extension-2.0.26.data → hdsp_jupyter_extension-2.0.28.data}/data/share/jupyter/labextensions/hdsp-agent/install.json +0 -0
- {hdsp_jupyter_extension-2.0.26.data → hdsp_jupyter_extension-2.0.28.data}/data/share/jupyter/labextensions/hdsp-agent/static/node_modules_emotion_use-insertion-effect-with-fallbacks_dist_emotion-use-insertion-effect-wi-3ba6b80.c095373419d05e6f141a.js +0 -0
- {hdsp_jupyter_extension-2.0.26.data → hdsp_jupyter_extension-2.0.28.data}/data/share/jupyter/labextensions/hdsp-agent/static/node_modules_emotion_use-insertion-effect-with-fallbacks_dist_emotion-use-insertion-effect-wi-3ba6b80.c095373419d05e6f141a.js.map +0 -0
- {hdsp_jupyter_extension-2.0.26.data → hdsp_jupyter_extension-2.0.28.data}/data/share/jupyter/labextensions/hdsp-agent/static/node_modules_emotion_use-insertion-effect-with-fallbacks_dist_emotion-use-insertion-effect-wi-3ba6b81.61e75fb98ecff46cf836.js +0 -0
- {hdsp_jupyter_extension-2.0.26.data → hdsp_jupyter_extension-2.0.28.data}/data/share/jupyter/labextensions/hdsp-agent/static/node_modules_emotion_use-insertion-effect-with-fallbacks_dist_emotion-use-insertion-effect-wi-3ba6b81.61e75fb98ecff46cf836.js.map +0 -0
- {hdsp_jupyter_extension-2.0.26.data → hdsp_jupyter_extension-2.0.28.data}/data/share/jupyter/labextensions/hdsp-agent/static/style.js +0 -0
- {hdsp_jupyter_extension-2.0.26.data → hdsp_jupyter_extension-2.0.28.data}/data/share/jupyter/labextensions/hdsp-agent/static/vendors-node_modules_babel_runtime_helpers_esm_extends_js-node_modules_emotion_serialize_dist-051195.e2553aab0c3963b83dd7.js +0 -0
- {hdsp_jupyter_extension-2.0.26.data → hdsp_jupyter_extension-2.0.28.data}/data/share/jupyter/labextensions/hdsp-agent/static/vendors-node_modules_babel_runtime_helpers_esm_extends_js-node_modules_emotion_serialize_dist-051195.e2553aab0c3963b83dd7.js.map +0 -0
- {hdsp_jupyter_extension-2.0.26.data → hdsp_jupyter_extension-2.0.28.data}/data/share/jupyter/labextensions/hdsp-agent/static/vendors-node_modules_emotion_cache_dist_emotion-cache_browser_development_esm_js.24edcc52a1c014a8a5f0.js +0 -0
- {hdsp_jupyter_extension-2.0.26.data → hdsp_jupyter_extension-2.0.28.data}/data/share/jupyter/labextensions/hdsp-agent/static/vendors-node_modules_emotion_cache_dist_emotion-cache_browser_development_esm_js.24edcc52a1c014a8a5f0.js.map +0 -0
- {hdsp_jupyter_extension-2.0.26.data → hdsp_jupyter_extension-2.0.28.data}/data/share/jupyter/labextensions/hdsp-agent/static/vendors-node_modules_emotion_react_dist_emotion-react_browser_development_esm_js.19ecf6babe00caff6b8a.js +0 -0
- {hdsp_jupyter_extension-2.0.26.data → hdsp_jupyter_extension-2.0.28.data}/data/share/jupyter/labextensions/hdsp-agent/static/vendors-node_modules_emotion_react_dist_emotion-react_browser_development_esm_js.19ecf6babe00caff6b8a.js.map +0 -0
- {hdsp_jupyter_extension-2.0.26.data → hdsp_jupyter_extension-2.0.28.data}/data/share/jupyter/labextensions/hdsp-agent/static/vendors-node_modules_emotion_styled_dist_emotion-styled_browser_development_esm_js.661fb5836f4978a7c6e1.js +0 -0
- {hdsp_jupyter_extension-2.0.26.data → hdsp_jupyter_extension-2.0.28.data}/data/share/jupyter/labextensions/hdsp-agent/static/vendors-node_modules_emotion_styled_dist_emotion-styled_browser_development_esm_js.661fb5836f4978a7c6e1.js.map +0 -0
- {hdsp_jupyter_extension-2.0.26.data → hdsp_jupyter_extension-2.0.28.data}/data/share/jupyter/labextensions/hdsp-agent/static/vendors-node_modules_mui_material_index_js.985697e0162d8d088ca2.js +0 -0
- {hdsp_jupyter_extension-2.0.26.data → hdsp_jupyter_extension-2.0.28.data}/data/share/jupyter/labextensions/hdsp-agent/static/vendors-node_modules_mui_material_index_js.985697e0162d8d088ca2.js.map +0 -0
- {hdsp_jupyter_extension-2.0.26.data → hdsp_jupyter_extension-2.0.28.data}/data/share/jupyter/labextensions/hdsp-agent/static/vendors-node_modules_mui_material_utils_createSvgIcon_js.1f5038488cdfd8b3a85d.js +0 -0
- {hdsp_jupyter_extension-2.0.26.data → hdsp_jupyter_extension-2.0.28.data}/data/share/jupyter/labextensions/hdsp-agent/static/vendors-node_modules_mui_material_utils_createSvgIcon_js.1f5038488cdfd8b3a85d.js.map +0 -0
- {hdsp_jupyter_extension-2.0.26.dist-info → hdsp_jupyter_extension-2.0.28.dist-info}/WHEEL +0 -0
- {hdsp_jupyter_extension-2.0.26.dist-info → hdsp_jupyter_extension-2.0.28.dist-info}/licenses/LICENSE +0 -0
|
@@ -42,35 +42,38 @@ class SubagentEvent:
|
|
|
42
42
|
"""Convert to debug message for UI display (legacy, for logging)."""
|
|
43
43
|
if self.event_type == "subagent_start":
|
|
44
44
|
desc_preview = self.description[:80] + "..." if self.description and len(self.description) > 80 else self.description
|
|
45
|
-
return f"Subagent
|
|
45
|
+
return f"Subagent-{self.subagent_name} 작업 시작: {desc_preview}"
|
|
46
46
|
elif self.event_type == "subagent_tool_call":
|
|
47
|
-
return f"Subagent
|
|
47
|
+
return f"Subagent-{self.subagent_name} Tool 실행: {self.tool_name}"
|
|
48
48
|
elif self.event_type == "subagent_complete":
|
|
49
|
-
return f"Subagent
|
|
49
|
+
return f"Subagent-{self.subagent_name} 완료"
|
|
50
50
|
else:
|
|
51
|
-
return f"Subagent
|
|
51
|
+
return f"Subagent-{self.subagent_name} {self.event_type}"
|
|
52
52
|
|
|
53
53
|
def to_status_dict(self) -> Dict[str, Any]:
|
|
54
54
|
"""Convert to status dict with icon for SSE streaming."""
|
|
55
55
|
if self.event_type == "subagent_start":
|
|
56
56
|
desc_preview = self.description[:80] + "..." if self.description and len(self.description) > 80 else self.description
|
|
57
|
+
full_status = f"Subagent-{self.subagent_name} 작업 시작: {self.description}"
|
|
57
58
|
return {
|
|
58
|
-
"status": f"Subagent
|
|
59
|
-
"icon": "subagentStart"
|
|
59
|
+
"status": f"Subagent-{self.subagent_name} 작업 시작: {desc_preview}",
|
|
60
|
+
"icon": "subagentStart",
|
|
61
|
+
"expandable": bool(self.description and len(self.description) > 80),
|
|
62
|
+
"full_text": full_status,
|
|
60
63
|
}
|
|
61
64
|
elif self.event_type == "subagent_tool_call":
|
|
62
65
|
return {
|
|
63
|
-
"status": f"Subagent
|
|
66
|
+
"status": f"Subagent-{self.subagent_name} Tool 실행: {self.tool_name}",
|
|
64
67
|
"icon": "tool"
|
|
65
68
|
}
|
|
66
69
|
elif self.event_type == "subagent_complete":
|
|
67
70
|
return {
|
|
68
|
-
"status": f"Subagent
|
|
71
|
+
"status": f"Subagent-{self.subagent_name} 완료",
|
|
69
72
|
"icon": "subagentComplete"
|
|
70
73
|
}
|
|
71
74
|
else:
|
|
72
75
|
return {
|
|
73
|
-
"status": f"Subagent
|
|
76
|
+
"status": f"Subagent-{self.subagent_name} {self.event_type}",
|
|
74
77
|
"icon": "info"
|
|
75
78
|
}
|
|
76
79
|
|
|
@@ -169,3 +172,79 @@ def drain_subagent_events() -> List[SubagentEvent]:
|
|
|
169
172
|
def get_pending_event_count() -> int:
|
|
170
173
|
"""Get the number of pending events in the queue."""
|
|
171
174
|
return _event_queue.qsize()
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
178
|
+
# Summarization Events - For context compression status display
|
|
179
|
+
# ═══════════════════════════════════════════════════════════════════════════
|
|
180
|
+
|
|
181
|
+
@dataclass
|
|
182
|
+
class SummarizationEvent:
|
|
183
|
+
"""Represents a summarization event for UI display."""
|
|
184
|
+
|
|
185
|
+
event_type: str # summarization_start, summarization_complete
|
|
186
|
+
message_count_before: Optional[int] = None
|
|
187
|
+
message_count_after: Optional[int] = None
|
|
188
|
+
timestamp: datetime = field(default_factory=datetime.now)
|
|
189
|
+
|
|
190
|
+
def to_status_dict(self) -> Dict[str, Any]:
|
|
191
|
+
"""Convert to status dict with icon for SSE streaming."""
|
|
192
|
+
if self.event_type == "summarization_start":
|
|
193
|
+
return {
|
|
194
|
+
"status": "대화 컨텍스트 요약 중...",
|
|
195
|
+
"icon": "thinking"
|
|
196
|
+
}
|
|
197
|
+
elif self.event_type == "summarization_complete":
|
|
198
|
+
if self.message_count_before and self.message_count_after:
|
|
199
|
+
return {
|
|
200
|
+
"status": f"대화가 자동으로 압축되었습니다. ({self.message_count_before} → {self.message_count_after} 메시지)",
|
|
201
|
+
"icon": "check"
|
|
202
|
+
}
|
|
203
|
+
return {
|
|
204
|
+
"status": "대화가 자동으로 압축되었습니다.",
|
|
205
|
+
"icon": "check"
|
|
206
|
+
}
|
|
207
|
+
else:
|
|
208
|
+
return {
|
|
209
|
+
"status": f"Summarization {self.event_type}",
|
|
210
|
+
"icon": "info"
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
# Separate queue for summarization events (to avoid mixing with subagent events)
|
|
215
|
+
_summarization_queue: Queue = Queue()
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
def emit_summarization_start() -> None:
|
|
219
|
+
"""Emit a summarization start event."""
|
|
220
|
+
event = SummarizationEvent(event_type="summarization_start")
|
|
221
|
+
_summarization_queue.put(event)
|
|
222
|
+
logger.info("Summarization event: starting context compression")
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
def emit_summarization_complete(before_count: int = 0, after_count: int = 0) -> None:
|
|
226
|
+
"""Emit a summarization complete event."""
|
|
227
|
+
event = SummarizationEvent(
|
|
228
|
+
event_type="summarization_complete",
|
|
229
|
+
message_count_before=before_count,
|
|
230
|
+
message_count_after=after_count,
|
|
231
|
+
)
|
|
232
|
+
_summarization_queue.put(event)
|
|
233
|
+
logger.info(f"Summarization event: complete ({before_count} → {after_count} messages)")
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
def drain_summarization_events() -> List[SummarizationEvent]:
|
|
237
|
+
"""
|
|
238
|
+
Drain all pending summarization events from the queue.
|
|
239
|
+
|
|
240
|
+
Returns:
|
|
241
|
+
List of SummarizationEvent objects
|
|
242
|
+
"""
|
|
243
|
+
events = []
|
|
244
|
+
while True:
|
|
245
|
+
try:
|
|
246
|
+
event = _summarization_queue.get_nowait()
|
|
247
|
+
events.append(event)
|
|
248
|
+
except Empty:
|
|
249
|
+
break
|
|
250
|
+
return events
|