hdsp-jupyter-extension 2.0.2__py3-none-any.whl → 2.0.4__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.
Files changed (47) hide show
  1. agent_server/langchain/agent.py +44 -37
  2. agent_server/routers/langchain_agent.py +44 -9
  3. hdsp_agent_core/models/common.py +8 -1
  4. {hdsp_jupyter_extension-2.0.2.data → hdsp_jupyter_extension-2.0.4.data}/data/share/jupyter/labextensions/hdsp-agent/build_log.json +1 -1
  5. {hdsp_jupyter_extension-2.0.2.data → hdsp_jupyter_extension-2.0.4.data}/data/share/jupyter/labextensions/hdsp-agent/package.json +2 -2
  6. hdsp_jupyter_extension-2.0.2.data/data/share/jupyter/labextensions/hdsp-agent/static/frontend_styles_index_js.634cf0ae0f3592d0882f.js → hdsp_jupyter_extension-2.0.4.data/data/share/jupyter/labextensions/hdsp-agent/static/frontend_styles_index_js.4105453345c170c1d6e6.js +20 -2
  7. hdsp_jupyter_extension-2.0.4.data/data/share/jupyter/labextensions/hdsp-agent/static/frontend_styles_index_js.4105453345c170c1d6e6.js.map +1 -0
  8. hdsp_jupyter_extension-2.0.2.data/data/share/jupyter/labextensions/hdsp-agent/static/lib_index_js.1366019c413f1d68467f.js → hdsp_jupyter_extension-2.0.4.data/data/share/jupyter/labextensions/hdsp-agent/static/lib_index_js.a223ea20056954479ae9.js +53 -5
  9. hdsp_jupyter_extension-2.0.4.data/data/share/jupyter/labextensions/hdsp-agent/static/lib_index_js.a223ea20056954479ae9.js.map +1 -0
  10. hdsp_jupyter_extension-2.0.2.data/data/share/jupyter/labextensions/hdsp-agent/static/remoteEntry.3379c4b222c042de2b01.js → hdsp_jupyter_extension-2.0.4.data/data/share/jupyter/labextensions/hdsp-agent/static/remoteEntry.f9bcbb6529a2bf9261a2.js +3 -3
  11. hdsp_jupyter_extension-2.0.2.data/data/share/jupyter/labextensions/hdsp-agent/static/remoteEntry.3379c4b222c042de2b01.js.map → hdsp_jupyter_extension-2.0.4.data/data/share/jupyter/labextensions/hdsp-agent/static/remoteEntry.f9bcbb6529a2bf9261a2.js.map +1 -1
  12. {hdsp_jupyter_extension-2.0.2.dist-info → hdsp_jupyter_extension-2.0.4.dist-info}/METADATA +6 -1
  13. {hdsp_jupyter_extension-2.0.2.dist-info → hdsp_jupyter_extension-2.0.4.dist-info}/RECORD +43 -43
  14. jupyter_ext/_version.py +1 -1
  15. jupyter_ext/labextension/build_log.json +1 -1
  16. jupyter_ext/labextension/package.json +2 -2
  17. jupyter_ext/labextension/static/{frontend_styles_index_js.634cf0ae0f3592d0882f.js → frontend_styles_index_js.4105453345c170c1d6e6.js} +20 -2
  18. jupyter_ext/labextension/static/frontend_styles_index_js.4105453345c170c1d6e6.js.map +1 -0
  19. jupyter_ext/labextension/static/{lib_index_js.1366019c413f1d68467f.js → lib_index_js.a223ea20056954479ae9.js} +53 -5
  20. jupyter_ext/labextension/static/lib_index_js.a223ea20056954479ae9.js.map +1 -0
  21. jupyter_ext/labextension/static/{remoteEntry.3379c4b222c042de2b01.js → remoteEntry.f9bcbb6529a2bf9261a2.js} +3 -3
  22. jupyter_ext/labextension/static/{remoteEntry.3379c4b222c042de2b01.js.map → remoteEntry.f9bcbb6529a2bf9261a2.js.map} +1 -1
  23. hdsp_jupyter_extension-2.0.2.data/data/share/jupyter/labextensions/hdsp-agent/static/frontend_styles_index_js.634cf0ae0f3592d0882f.js.map +0 -1
  24. hdsp_jupyter_extension-2.0.2.data/data/share/jupyter/labextensions/hdsp-agent/static/lib_index_js.1366019c413f1d68467f.js.map +0 -1
  25. jupyter_ext/labextension/static/frontend_styles_index_js.634cf0ae0f3592d0882f.js.map +0 -1
  26. jupyter_ext/labextension/static/lib_index_js.1366019c413f1d68467f.js.map +0 -1
  27. {hdsp_jupyter_extension-2.0.2.data → hdsp_jupyter_extension-2.0.4.data}/data/etc/jupyter/jupyter_server_config.d/hdsp_jupyter_extension.json +0 -0
  28. {hdsp_jupyter_extension-2.0.2.data → hdsp_jupyter_extension-2.0.4.data}/data/share/jupyter/labextensions/hdsp-agent/install.json +0 -0
  29. {hdsp_jupyter_extension-2.0.2.data → hdsp_jupyter_extension-2.0.4.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
  30. {hdsp_jupyter_extension-2.0.2.data → hdsp_jupyter_extension-2.0.4.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
  31. {hdsp_jupyter_extension-2.0.2.data → hdsp_jupyter_extension-2.0.4.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
  32. {hdsp_jupyter_extension-2.0.2.data → hdsp_jupyter_extension-2.0.4.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
  33. {hdsp_jupyter_extension-2.0.2.data → hdsp_jupyter_extension-2.0.4.data}/data/share/jupyter/labextensions/hdsp-agent/static/style.js +0 -0
  34. {hdsp_jupyter_extension-2.0.2.data → hdsp_jupyter_extension-2.0.4.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
  35. {hdsp_jupyter_extension-2.0.2.data → hdsp_jupyter_extension-2.0.4.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
  36. {hdsp_jupyter_extension-2.0.2.data → hdsp_jupyter_extension-2.0.4.data}/data/share/jupyter/labextensions/hdsp-agent/static/vendors-node_modules_emotion_cache_dist_emotion-cache_browser_development_esm_js.24edcc52a1c014a8a5f0.js +0 -0
  37. {hdsp_jupyter_extension-2.0.2.data → hdsp_jupyter_extension-2.0.4.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
  38. {hdsp_jupyter_extension-2.0.2.data → hdsp_jupyter_extension-2.0.4.data}/data/share/jupyter/labextensions/hdsp-agent/static/vendors-node_modules_emotion_react_dist_emotion-react_browser_development_esm_js.19ecf6babe00caff6b8a.js +0 -0
  39. {hdsp_jupyter_extension-2.0.2.data → hdsp_jupyter_extension-2.0.4.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
  40. {hdsp_jupyter_extension-2.0.2.data → hdsp_jupyter_extension-2.0.4.data}/data/share/jupyter/labextensions/hdsp-agent/static/vendors-node_modules_emotion_styled_dist_emotion-styled_browser_development_esm_js.661fb5836f4978a7c6e1.js +0 -0
  41. {hdsp_jupyter_extension-2.0.2.data → hdsp_jupyter_extension-2.0.4.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
  42. {hdsp_jupyter_extension-2.0.2.data → hdsp_jupyter_extension-2.0.4.data}/data/share/jupyter/labextensions/hdsp-agent/static/vendors-node_modules_mui_material_index_js.985697e0162d8d088ca2.js +0 -0
  43. {hdsp_jupyter_extension-2.0.2.data → hdsp_jupyter_extension-2.0.4.data}/data/share/jupyter/labextensions/hdsp-agent/static/vendors-node_modules_mui_material_index_js.985697e0162d8d088ca2.js.map +0 -0
  44. {hdsp_jupyter_extension-2.0.2.data → hdsp_jupyter_extension-2.0.4.data}/data/share/jupyter/labextensions/hdsp-agent/static/vendors-node_modules_mui_material_utils_createSvgIcon_js.1f5038488cdfd8b3a85d.js +0 -0
  45. {hdsp_jupyter_extension-2.0.2.data → hdsp_jupyter_extension-2.0.4.data}/data/share/jupyter/labextensions/hdsp-agent/static/vendors-node_modules_mui_material_utils_createSvgIcon_js.1f5038488cdfd8b3a85d.js.map +0 -0
  46. {hdsp_jupyter_extension-2.0.2.dist-info → hdsp_jupyter_extension-2.0.4.dist-info}/WHEEL +0 -0
  47. {hdsp_jupyter_extension-2.0.2.dist-info → hdsp_jupyter_extension-2.0.4.dist-info}/licenses/LICENSE +0 -0
@@ -20,6 +20,43 @@ from agent_server.langchain.tools import (
20
20
 
21
21
  logger = logging.getLogger(__name__)
22
22
 
23
+ DEFAULT_SYSTEM_PROMPT = """You are an expert Python data scientist and Jupyter notebook assistant.
24
+ Your role is to help users with data analysis, visualization, and Python coding tasks in Jupyter notebooks.
25
+
26
+ ## ⚠️ CRITICAL RULE: NEVER produce an empty response
27
+
28
+ You MUST ALWAYS call a tool in every response. After any tool result, you MUST:
29
+ 1. Check your todo list - are there pending or in_progress items?
30
+ 2. If YES → call the next appropriate tool (jupyter_cell_tool, markdown_tool, etc.)
31
+ 3. If ALL todos are completed → call final_answer_tool with a summary
32
+
33
+ NEVER end your turn without calling a tool. NEVER produce an empty response.
34
+
35
+ ## Available Tools
36
+ 1. **jupyter_cell_tool**: Execute Python code in a new notebook cell
37
+ 2. **markdown_tool**: Add a markdown explanation cell
38
+ 3. **final_answer_tool**: Complete the task with a summary - REQUIRED when done
39
+ 4. **read_file_tool**: Read file contents
40
+ 5. **write_file_tool**: Write file contents
41
+ 6. **list_files_tool**: List directory contents
42
+ 7. **search_workspace_tool**: Search for patterns in workspace files
43
+ 8. **search_notebook_cells_tool**: Search for patterns in notebook cells
44
+ 9. **write_todos**: Create and update task list for complex multi-step tasks
45
+
46
+ ## Mandatory Workflow
47
+ 1. After EVERY tool result, immediately call the next tool
48
+ 2. Continue until ALL todos show status: "completed"
49
+ 3. ONLY THEN call final_answer_tool to summarize
50
+ 4. If `!pip install` fails, use `!pip3 install` instead
51
+ 5. For plots and charts, use English text only
52
+
53
+ ## ❌ FORBIDDEN (will break the workflow)
54
+ - Producing an empty response (no tool call, no content)
55
+ - Stopping after any tool without calling the next tool
56
+ - Ending without calling final_answer_tool
57
+ - Leaving todos in "in_progress" or "pending" state without continuing
58
+ """
59
+
23
60
 
24
61
  def _create_llm(llm_config: Dict[str, Any]):
25
62
  """Create LangChain LLM from config"""
@@ -107,6 +144,7 @@ def create_simple_chat_agent(
107
144
  enable_hitl: bool = True,
108
145
  enable_todo_list: bool = True,
109
146
  checkpointer: Optional[object] = None,
147
+ system_prompt_override: Optional[str] = None,
110
148
  ):
111
149
  """
112
150
  Create a simple chat agent using LangChain's create_agent with Human-in-the-Loop.
@@ -642,43 +680,12 @@ NEVER end your response after calling write_todos - always continue with the nex
642
680
  middleware.append(list_files_limit)
643
681
  logger.info("Added ToolCallLimitMiddleware for write_todos and list_files_tool")
644
682
 
645
- # System prompt for the agent
646
- system_prompt = """You are an expert Python data scientist and Jupyter notebook assistant.
647
- Your role is to help users with data analysis, visualization, and Python coding tasks in Jupyter notebooks.
648
-
649
- ## ⚠️ CRITICAL RULE: NEVER produce an empty response
650
-
651
- You MUST ALWAYS call a tool in every response. After any tool result, you MUST:
652
- 1. Check your todo list - are there pending or in_progress items?
653
- 2. If YES → call the next appropriate tool (jupyter_cell_tool, markdown_tool, etc.)
654
- 3. If ALL todos are completed → call final_answer_tool with a summary
655
-
656
- NEVER end your turn without calling a tool. NEVER produce an empty response.
657
-
658
- ## Available Tools
659
- 1. **jupyter_cell_tool**: Execute Python code in a new notebook cell
660
- 2. **markdown_tool**: Add a markdown explanation cell
661
- 3. **final_answer_tool**: Complete the task with a summary - REQUIRED when done
662
- 4. **read_file_tool**: Read file contents
663
- 5. **write_file_tool**: Write file contents
664
- 6. **list_files_tool**: List directory contents
665
- 7. **search_workspace_tool**: Search for patterns in workspace files
666
- 8. **search_notebook_cells_tool**: Search for patterns in notebook cells
667
- 9. **write_todos**: Create and update task list for complex multi-step tasks
668
-
669
- ## Mandatory Workflow
670
- 1. After EVERY tool result, immediately call the next tool
671
- 2. Continue until ALL todos show status: "completed"
672
- 3. ONLY THEN call final_answer_tool to summarize
673
- 4. If `!pip install` fails, use `!pip3 install` instead
674
- 5. For plots and charts, use English text only
675
-
676
- ## ❌ FORBIDDEN (will break the workflow)
677
- - Producing an empty response (no tool call, no content)
678
- - Stopping after any tool without calling the next tool
679
- - Ending without calling final_answer_tool
680
- - Leaving todos in "in_progress" or "pending" state without continuing
681
- """
683
+ # System prompt for the agent (override applies only to LangChain agent)
684
+ if system_prompt_override and system_prompt_override.strip():
685
+ system_prompt = system_prompt_override.strip()
686
+ logger.info("SimpleChatAgent using custom system prompt override")
687
+ else:
688
+ system_prompt = DEFAULT_SYSTEM_PROMPT
682
689
 
683
690
  logger.info("SimpleChatAgent system_prompt: %s", system_prompt)
684
691
 
@@ -33,10 +33,17 @@ router = APIRouter(prefix="/langchain", tags=["langchain-agent"])
33
33
  class LLMConfig(BaseModel):
34
34
  """LLM configuration"""
35
35
 
36
+ model_config = ConfigDict(populate_by_name=True)
37
+
36
38
  provider: str = Field(default="gemini", description="LLM provider")
37
39
  gemini: Optional[Dict[str, Any]] = Field(default=None)
38
40
  openai: Optional[Dict[str, Any]] = Field(default=None)
39
41
  vllm: Optional[Dict[str, Any]] = Field(default=None)
42
+ system_prompt: Optional[str] = Field(
43
+ default=None,
44
+ alias="systemPrompt",
45
+ description="Override system prompt for LangChain agent",
46
+ )
40
47
 
41
48
 
42
49
  class NotebookContext(BaseModel):
@@ -364,6 +371,9 @@ async def stream_agent(request: AgentRequest):
364
371
  config_dict["openai"] = request.llmConfig.openai
365
372
  if request.llmConfig.vllm:
366
373
  config_dict["vllm"] = request.llmConfig.vllm
374
+ system_prompt_override = (
375
+ request.llmConfig.system_prompt if request.llmConfig else None
376
+ )
367
377
 
368
378
  agent = create_simple_chat_agent(
369
379
  llm_config=config_dict,
@@ -372,6 +382,7 @@ async def stream_agent(request: AgentRequest):
372
382
  checkpointer=_simple_agent_checkpointers.setdefault(
373
383
  thread_id, InMemorySaver()
374
384
  ),
385
+ system_prompt_override=system_prompt_override,
375
386
  )
376
387
 
377
388
  # Prepare config with thread_id
@@ -392,7 +403,7 @@ async def stream_agent(request: AgentRequest):
392
403
  # Initial status: waiting for LLM
393
404
  yield {
394
405
  "event": "debug",
395
- "data": json.dumps({"status": "🤔 LLM 응답 대기 중..."}),
406
+ "data": json.dumps({"status": "🤔 LLM 응답 대기 "}),
396
407
  }
397
408
 
398
409
  for step in agent.stream(agent_input, config, stream_mode="values"):
@@ -406,7 +417,7 @@ async def stream_agent(request: AgentRequest):
406
417
 
407
418
  yield {
408
419
  "event": "debug",
409
- "data": json.dumps({"status": "⏸️ 사용자 승인 대기 중..."}),
420
+ "data": json.dumps({"status": "⏸️ 사용자 승인 대기 "}),
410
421
  }
411
422
 
412
423
  # Process interrupts
@@ -427,7 +438,8 @@ async def stream_agent(request: AgentRequest):
427
438
  normalized_actions
428
439
  )
429
440
 
430
- for action in normalized_actions:
441
+ total_actions = len(normalized_actions)
442
+ for idx, action in enumerate(normalized_actions):
431
443
  yield {
432
444
  "event": "interrupt",
433
445
  "data": json.dumps(
@@ -436,6 +448,8 @@ async def stream_agent(request: AgentRequest):
436
448
  "action": action.get("name", "unknown"),
437
449
  "args": action.get("arguments", {}),
438
450
  "description": action.get("description", ""),
451
+ "action_index": idx,
452
+ "total_actions": total_actions,
439
453
  }
440
454
  ),
441
455
  }
@@ -873,7 +887,7 @@ async def stream_agent(request: AgentRequest):
873
887
  yield {
874
888
  "event": "debug",
875
889
  "data": json.dumps(
876
- {"status": "🔄 Jupyter Cell로 변환 중..."}
890
+ {"status": "🔄 Jupyter Cell로 변환 "}
877
891
  ),
878
892
  }
879
893
  yield {
@@ -973,6 +987,9 @@ async def resume_agent(request: ResumeRequest):
973
987
  config_dict["openai"] = request.llmConfig.openai
974
988
  if request.llmConfig.vllm:
975
989
  config_dict["vllm"] = request.llmConfig.vllm
990
+ system_prompt_override = (
991
+ request.llmConfig.system_prompt if request.llmConfig else None
992
+ )
976
993
 
977
994
  # Create agent (will use same checkpointer)
978
995
  agent = create_simple_chat_agent(
@@ -982,16 +999,31 @@ async def resume_agent(request: ResumeRequest):
982
999
  checkpointer=_simple_agent_checkpointers.setdefault(
983
1000
  request.threadId, InMemorySaver()
984
1001
  ),
1002
+ system_prompt_override=system_prompt_override,
985
1003
  )
986
1004
 
987
1005
  # Prepare config with thread_id
988
1006
  config = {"configurable": {"thread_id": request.threadId}}
989
1007
 
990
1008
  pending_actions = _simple_agent_pending_actions.get(request.threadId, [])
1009
+ num_pending = len(pending_actions)
1010
+ num_decisions = len(request.decisions)
1011
+
1012
+ # If user provides fewer decisions than pending actions,
1013
+ # apply the first decision to all remaining pending actions
1014
+ # This handles cases where the model returns multiple tool calls at once
1015
+ decisions_to_process = list(request.decisions)
1016
+ if num_decisions < num_pending and num_decisions > 0:
1017
+ logger.info(
1018
+ f"Expanding {num_decisions} decision(s) to match {num_pending} pending action(s)"
1019
+ )
1020
+ first_decision = request.decisions[0]
1021
+ while len(decisions_to_process) < num_pending:
1022
+ decisions_to_process.append(first_decision)
991
1023
 
992
1024
  # Convert decisions to LangChain format
993
1025
  langgraph_decisions = []
994
- for index, decision in enumerate(request.decisions):
1026
+ for index, decision in enumerate(decisions_to_process):
995
1027
  if decision.type == "approve":
996
1028
  langgraph_decisions.append({"type": "approve"})
997
1029
  elif decision.type == "edit":
@@ -1020,7 +1052,7 @@ async def resume_agent(request: ResumeRequest):
1020
1052
  # Resume execution
1021
1053
  yield {
1022
1054
  "event": "debug",
1023
- "data": json.dumps({"status": "▶️ 실행 재개 중..."}),
1055
+ "data": json.dumps({"status": "▶️ 실행 재개 "}),
1024
1056
  }
1025
1057
 
1026
1058
  _simple_agent_pending_actions.pop(request.threadId, None)
@@ -1035,7 +1067,7 @@ async def resume_agent(request: ResumeRequest):
1035
1067
  # Status: waiting for LLM response
1036
1068
  yield {
1037
1069
  "event": "debug",
1038
- "data": json.dumps({"status": "🤔 LLM 응답 대기 중..."}),
1070
+ "data": json.dumps({"status": "🤔 LLM 응답 대기 "}),
1039
1071
  }
1040
1072
 
1041
1073
  step_count = 0
@@ -1059,7 +1091,7 @@ async def resume_agent(request: ResumeRequest):
1059
1091
 
1060
1092
  yield {
1061
1093
  "event": "debug",
1062
- "data": json.dumps({"status": "⏸️ 사용자 승인 대기 중..."}),
1094
+ "data": json.dumps({"status": "⏸️ 사용자 승인 대기 "}),
1063
1095
  }
1064
1096
 
1065
1097
  for interrupt in interrupts:
@@ -1077,7 +1109,8 @@ async def resume_agent(request: ResumeRequest):
1077
1109
  normalized_actions
1078
1110
  )
1079
1111
 
1080
- for action in normalized_actions:
1112
+ total_actions = len(normalized_actions)
1113
+ for idx, action in enumerate(normalized_actions):
1081
1114
  yield {
1082
1115
  "event": "interrupt",
1083
1116
  "data": json.dumps(
@@ -1086,6 +1119,8 @@ async def resume_agent(request: ResumeRequest):
1086
1119
  "action": action.get("name", "unknown"),
1087
1120
  "args": action.get("arguments", {}),
1088
1121
  "description": action.get("description", ""),
1122
+ "action_index": idx,
1123
+ "total_actions": total_actions,
1089
1124
  }
1090
1125
  ),
1091
1126
  }
@@ -6,7 +6,7 @@ Shared data models used across all agent services.
6
6
 
7
7
  from typing import Any, Dict, List, Optional
8
8
 
9
- from pydantic import BaseModel, Field
9
+ from pydantic import BaseModel, ConfigDict, Field
10
10
 
11
11
 
12
12
  class ToolCall(BaseModel):
@@ -87,9 +87,16 @@ class LLMConfig(BaseModel):
87
87
  API keys are managed client-side and passed with each request.
88
88
  """
89
89
 
90
+ model_config = ConfigDict(populate_by_name=True)
91
+
90
92
  provider: str = Field(
91
93
  default="gemini", description="LLM provider (gemini, openai, vllm)"
92
94
  )
93
95
  gemini: Optional[GeminiConfig] = Field(default=None, description="Gemini config")
94
96
  openai: Optional[OpenAIConfig] = Field(default=None, description="OpenAI config")
95
97
  vllm: Optional[VLLMConfig] = Field(default=None, description="vLLM config")
98
+ system_prompt: Optional[str] = Field(
99
+ default=None,
100
+ alias="systemPrompt",
101
+ description="LangChain system prompt override",
102
+ )
@@ -722,7 +722,7 @@
722
722
  "@mui/material": {},
723
723
  "react-markdown": {},
724
724
  "hdsp-agent": {
725
- "version": "2.0.2",
725
+ "version": "2.0.4",
726
726
  "singleton": true,
727
727
  "import": "/Users/a421721/Desktop/hdsp/hdsp_agent/extensions/jupyter/lib/index.js"
728
728
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hdsp-agent",
3
- "version": "2.0.2",
3
+ "version": "2.0.4",
4
4
  "description": "HDSP Agent JupyterLab Extension - Thin client for Agent Server",
5
5
  "keywords": [
6
6
  "jupyter",
@@ -126,7 +126,7 @@
126
126
  }
127
127
  },
128
128
  "_build": {
129
- "load": "static/remoteEntry.3379c4b222c042de2b01.js",
129
+ "load": "static/remoteEntry.f9bcbb6529a2bf9261a2.js",
130
130
  "extension": "./extension",
131
131
  "style": "./style"
132
132
  }
@@ -4008,6 +4008,13 @@ ___CSS_LOADER_EXPORT___.push([module.id, `/**
4008
4008
  font-family: var(--jp-ui-font-family);
4009
4009
  }
4010
4010
 
4011
+ .jp-agent-settings-textarea {
4012
+ min-height: 140px;
4013
+ resize: vertical;
4014
+ font-family: var(--jp-code-font-family);
4015
+ line-height: 1.4;
4016
+ }
4017
+
4011
4018
  .jp-agent-settings-input:focus,
4012
4019
  .jp-agent-settings-select:focus {
4013
4020
  outline: none;
@@ -4071,6 +4078,17 @@ ___CSS_LOADER_EXPORT___.push([module.id, `/**
4071
4078
  background-color: var(--jp-layout-color3);
4072
4079
  }
4073
4080
 
4081
+ .jp-agent-settings-inline-actions {
4082
+ display: flex;
4083
+ justify-content: flex-end;
4084
+ margin-top: 6px;
4085
+ }
4086
+
4087
+ .jp-agent-settings-button-compact {
4088
+ padding: 6px 10px;
4089
+ font-size: 12px;
4090
+ }
4091
+
4074
4092
  .jp-agent-settings-button-test {
4075
4093
  background-color: var(--jp-warn-color1);
4076
4094
  color: white;
@@ -4311,7 +4329,7 @@ ___CSS_LOADER_EXPORT___.push([module.id, `/**
4311
4329
  padding-top: 8px;
4312
4330
  border-top: 1px solid var(--jp-border-color2);
4313
4331
  }
4314
- `, "",{"version":3,"sources":["webpack://./frontend/styles/settings-panel.css"],"names":[],"mappings":"AAAA;;EAEE;;AAEF,YAAY;AACZ;EACE,eAAe;EACf,MAAM;EACN,OAAO;EACP,QAAQ;EACR,SAAS;EACT,oCAAoC;EACpC,aAAa;EACb,mBAAmB;EACnB,uBAAuB;EACvB,cAAc;AAChB;;AAEA,WAAW;AACX;EACE,yCAAyC;EACzC,kBAAkB;EAClB,yCAAyC;EACzC,UAAU;EACV,gBAAgB;EAChB,gBAAgB;EAChB,aAAa;EACb,sBAAsB;AACxB;;AAEA,WAAW;AACX;EACE,aAAa;EACb,8BAA8B;EAC9B,mBAAmB;EACnB,kBAAkB;EAClB,gDAAgD;AAClD;;AAEA;EACE,SAAS;EACT,eAAe;EACf,gBAAgB;EAChB,+BAA+B;AACjC;;AAEA;EACE,gBAAgB;EAChB,YAAY;EACZ,eAAe;EACf,+BAA+B;EAC/B,eAAe;EACf,UAAU;EACV,WAAW;EACX,YAAY;EACZ,aAAa;EACb,mBAAmB;EACnB,uBAAuB;EACvB,kBAAkB;EAClB,iCAAiC;AACnC;;AAEA;EACE,yCAAyC;EACzC,+BAA+B;AACjC;;AAEA,YAAY;AACZ;EACE,aAAa;EACb,gBAAgB;EAChB,OAAO;AACT;;AAEA;EACE,mBAAmB;AACrB;;AAEA;EACE,cAAc;EACd,kBAAkB;EAClB,eAAe;EACf,gBAAgB;EAChB,+BAA+B;AACjC;;AAEA;;EAEE,WAAW;EACX,iBAAiB;EACjB,eAAe;EACf,yCAAyC;EACzC,kBAAkB;EAClB,yCAAyC;EACzC,+BAA+B;EAC/B,qCAAqC;AACvC;;AAEA;;EAEE,aAAa;EACb,oCAAoC;EACpC,4CAA4C;AAC9C;;AAEA;EACE,+BAA+B;AACjC;;AAEA;EACE,gBAAgB;AAClB;;AAEA;EACE,kBAAkB;EAClB,eAAe;EACf,gBAAgB;EAChB,+BAA+B;AACjC;;AAEA,gBAAgB;AAChB;EACE,mBAAmB;EACnB,aAAa;EACb,kBAAkB;EAClB,eAAe;EACf,yCAAyC;EACzC,yCAAyC;EACzC,+BAA+B;EAC/B,uCAAuC;AACzC;;AAEA,WAAW;AACX;EACE,aAAa;EACb,yBAAyB;EACzB,QAAQ;EACR,kBAAkB;EAClB,6CAA6C;AAC/C;;AAEA;EACE,iBAAiB;EACjB,eAAe;EACf,gBAAgB;EAChB,kBAAkB;EAClB,YAAY;EACZ,eAAe;EACf,oBAAoB;EACpB,qCAAqC;AACvC;;AAEA;EACE,yCAAyC;EACzC,+BAA+B;AACjC;;AAEA;EACE,yCAAyC;AAC3C;;AAEA;EACE,uCAAuC;EACvC,YAAY;AACd;;AAEA;EACE,uCAAuC;AACzC;;AAEA;EACE,YAAY;EACZ,mBAAmB;AACrB;;AAEA;EACE,wCAAwC;EACxC,YAAY;AACd;;AAEA;EACE,wCAAwC;AAC1C;;AAEA;EACE,0BAA0B;AAC5B;;AAEA;EACE,YAAY;EACZ,mBAAmB;AACrB;;AAEA,yBAAyB;AACzB;EACE,iBAAiB;EACjB,eAAe;AACjB;;AAEA,2BAA2B;AAC3B;EACE,wCAAwC;EACxC,YAAY;AACd;;AAEA;EACE,wCAAwC;AAC1C;;AAEA;EACE,YAAY;EACZ,mBAAmB;AACrB;;AAEA,oCAAoC;AACpC;EACE,6BAA6B;EAC7B,wCAAwC;EACxC,6BAA6B;AAC/B;;AAEA;EACE,wCAAwC;AAC1C;;AAEA,gDAAgD;;AAEhD;EACE,gBAAgB;EAChB,aAAa;EACb,yCAAyC;EACzC,kBAAkB;EAClB,yCAAyC;AAC3C;;AAEA;EACE,aAAa;EACb,8BAA8B;EAC9B,mBAAmB;EACnB,mBAAmB;AACrB;;AAEA;EACE,SAAS;EACT,eAAe;EACf,gBAAgB;EAChB,+BAA+B;AACjC;;AAEA;EACE,eAAe;EACf,+BAA+B;EAC/B,yCAAyC;EACzC,gBAAgB;EAChB,mBAAmB;AACrB;;AAEA;EACE,aAAa;EACb,8BAA8B;EAC9B,mBAAmB;EACnB,iBAAiB;EACjB,mBAAmB;EACnB,wCAAwC;EACxC,kBAAkB;EAClB,6BAA6B;EAC7B,eAAe;AACjB;;AAEA;EACE,gBAAgB;EAChB,YAAY;EACZ,eAAe;EACf,eAAe;EACf,6BAA6B;EAC7B,cAAc;AAChB;;AAEA;EACE,YAAY;AACd;;AAEA;EACE,iBAAiB;EACjB,gBAAgB;EAChB,mBAAmB;AACrB;;AAEA;EACE,kBAAkB;EAClB,kBAAkB;EAClB,+BAA+B;EAC/B,eAAe;EACf,yCAAyC;EACzC,kBAAkB;EAClB,0CAA0C;AAC5C;;AAEA;EACE,aAAa;EACb,8BAA8B;EAC9B,mBAAmB;EACnB,kBAAkB;EAClB,kBAAkB;EAClB,kBAAkB;EAClB,yCAAyC;EACzC,yCAAyC;EACzC,oDAAoD;AACtD;;AAEA;EACE,gBAAgB;AAClB;;AAEA;EACE,qCAAqC;AACvC;;AAEA;EACE,oCAAoC;EACpC,wCAAwC;AAC1C;;AAEA;EACE,aAAa;EACb,mBAAmB;EACnB,QAAQ;EACR,eAAe;AACjB;;AAEA;EACE,uCAAuC;EACvC,eAAe;EACf,+BAA+B;EAC/B,yCAAyC;EACzC,gBAAgB;EAChB,kBAAkB;AACpB;;AAEA;EACE,gBAAgB;EAChB,mBAAmB;EACnB,eAAe;EACf,gBAAgB;AAClB;;AAEA;EACE,0CAA0C;EAC1C,+BAA+B;AACjC;;AAEA;EACE,uCAAuC;EACvC,4BAA4B;AAC9B;;AAEA;EACE,yCAAyC;EACzC,+BAA+B;AACjC;;AAEA;EACE,gBAAgB;EAChB,mBAAmB;EACnB,eAAe;EACf,gBAAgB;EAChB,wCAAwC;EACxC,YAAY;EACZ,yBAAyB;EACzB,qBAAqB;AACvB;;AAEA;EACE,aAAa;EACb,QAAQ;AACV;;AAEA;EACE,aAAa;EACb,QAAQ;EACR,mBAAmB;AACrB;;AAEA;EACE,OAAO;EACP,YAAY;AACd;;AAEA;EACE,cAAc;EACd,mBAAmB;AACrB;;AAEA;EACE,+BAA+B;EAC/B,eAAe;EACf,kBAAkB;EAClB,gBAAgB;EAChB,gBAAgB;EAChB,6CAA6C;AAC/C","sourcesContent":["/**\n * Settings Panel Styles\n */\n\n/* Overlay */\n.jp-agent-settings-overlay {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background-color: rgba(0, 0, 0, 0.5);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 10000;\n}\n\n/* Dialog */\n.jp-agent-settings-dialog {\n background-color: var(--jp-layout-color1);\n border-radius: 8px;\n box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);\n width: 90%;\n max-width: 500px;\n max-height: 80vh;\n display: flex;\n flex-direction: column;\n}\n\n/* Header */\n.jp-agent-settings-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 16px 20px;\n border-bottom: 1px solid var(--jp-border-color1);\n}\n\n.jp-agent-settings-header h2 {\n margin: 0;\n font-size: 18px;\n font-weight: 600;\n color: var(--jp-ui-font-color1);\n}\n\n.jp-agent-settings-close {\n background: none;\n border: none;\n font-size: 24px;\n color: var(--jp-ui-font-color2);\n cursor: pointer;\n padding: 0;\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 4px;\n transition: background-color 0.2s;\n}\n\n.jp-agent-settings-close:hover {\n background-color: var(--jp-layout-color2);\n color: var(--jp-ui-font-color1);\n}\n\n/* Content */\n.jp-agent-settings-content {\n padding: 20px;\n overflow-y: auto;\n flex: 1;\n}\n\n.jp-agent-settings-group {\n margin-bottom: 16px;\n}\n\n.jp-agent-settings-label {\n display: block;\n margin-bottom: 6px;\n font-size: 13px;\n font-weight: 500;\n color: var(--jp-ui-font-color1);\n}\n\n.jp-agent-settings-input,\n.jp-agent-settings-select {\n width: 100%;\n padding: 8px 12px;\n font-size: 13px;\n border: 1px solid var(--jp-border-color2);\n border-radius: 4px;\n background-color: var(--jp-layout-color1);\n color: var(--jp-ui-font-color1);\n font-family: var(--jp-ui-font-family);\n}\n\n.jp-agent-settings-input:focus,\n.jp-agent-settings-select:focus {\n outline: none;\n border-color: var(--jp-brand-color1);\n box-shadow: 0 0 0 1px var(--jp-brand-color1);\n}\n\n.jp-agent-settings-input::placeholder {\n color: var(--jp-ui-font-color3);\n}\n\n.jp-agent-settings-provider {\n margin-top: 20px;\n}\n\n.jp-agent-settings-provider h3 {\n margin: 0 0 16px 0;\n font-size: 15px;\n font-weight: 600;\n color: var(--jp-ui-font-color1);\n}\n\n/* Test Result */\n.jp-agent-settings-test-result {\n margin: 16px 20px 0;\n padding: 12px;\n border-radius: 4px;\n font-size: 13px;\n background-color: var(--jp-layout-color2);\n border: 1px solid var(--jp-border-color2);\n color: var(--jp-ui-font-color1);\n font-family: var(--jp-code-font-family);\n}\n\n/* Footer */\n.jp-agent-settings-footer {\n display: flex;\n justify-content: flex-end;\n gap: 8px;\n padding: 16px 20px;\n border-top: 1px solid var(--jp-border-color1);\n}\n\n.jp-agent-settings-button {\n padding: 8px 16px;\n font-size: 13px;\n font-weight: 500;\n border-radius: 4px;\n border: none;\n cursor: pointer;\n transition: all 0.2s;\n font-family: var(--jp-ui-font-family);\n}\n\n.jp-agent-settings-button-secondary {\n background-color: var(--jp-layout-color2);\n color: var(--jp-ui-font-color1);\n}\n\n.jp-agent-settings-button-secondary:hover {\n background-color: var(--jp-layout-color3);\n}\n\n.jp-agent-settings-button-test {\n background-color: var(--jp-warn-color1);\n color: white;\n}\n\n.jp-agent-settings-button-test:hover:not(:disabled) {\n background-color: var(--jp-warn-color0);\n}\n\n.jp-agent-settings-button-test:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.jp-agent-settings-button-primary {\n background-color: var(--jp-brand-color1);\n color: white;\n}\n\n.jp-agent-settings-button-primary:hover {\n background-color: var(--jp-brand-color0);\n}\n\n.jp-agent-settings-button:active {\n transform: translateY(1px);\n}\n\n.jp-agent-settings-button-primary:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n/* Small Button Variant */\n.jp-agent-settings-button-small {\n padding: 4px 10px;\n font-size: 11px;\n}\n\n/* Danger Button (Delete) */\n.jp-agent-settings-button-danger {\n background-color: var(--jp-error-color1);\n color: white;\n}\n\n.jp-agent-settings-button-danger:hover:not(:disabled) {\n background-color: var(--jp-error-color0);\n}\n\n.jp-agent-settings-button-danger:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n/* Outline Button (Inactive state) */\n.jp-agent-settings-button-outline {\n background-color: transparent;\n border: 1px solid var(--jp-brand-color1);\n color: var(--jp-brand-color1);\n}\n\n.jp-agent-settings-button-outline:hover {\n background-color: var(--jp-brand-color3);\n}\n\n/* ========== API Keys Panel Styles ========== */\n\n.jp-agent-keys-panel {\n margin-top: 20px;\n padding: 16px;\n border: 1px solid var(--jp-border-color2);\n border-radius: 6px;\n background-color: var(--jp-layout-color0);\n}\n\n.jp-agent-keys-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 12px;\n}\n\n.jp-agent-keys-header h4 {\n margin: 0;\n font-size: 14px;\n font-weight: 600;\n color: var(--jp-ui-font-color1);\n}\n\n.jp-agent-keys-count {\n font-size: 12px;\n color: var(--jp-ui-font-color2);\n background-color: var(--jp-layout-color2);\n padding: 2px 8px;\n border-radius: 10px;\n}\n\n.jp-agent-keys-error {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 8px 12px;\n margin-bottom: 12px;\n background-color: var(--jp-error-color3);\n border-radius: 4px;\n color: var(--jp-error-color1);\n font-size: 13px;\n}\n\n.jp-agent-keys-error button {\n background: none;\n border: none;\n cursor: pointer;\n font-size: 16px;\n color: var(--jp-error-color1);\n padding: 0 4px;\n}\n\n.jp-agent-keys-error button:hover {\n opacity: 0.8;\n}\n\n.jp-agent-keys-list {\n max-height: 200px;\n overflow-y: auto;\n margin-bottom: 12px;\n}\n\n.jp-agent-keys-empty {\n padding: 24px 20px;\n text-align: center;\n color: var(--jp-ui-font-color2);\n font-size: 13px;\n background-color: var(--jp-layout-color1);\n border-radius: 4px;\n border: 1px dashed var(--jp-border-color2);\n}\n\n.jp-agent-key-item {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 10px 12px;\n margin-bottom: 6px;\n border-radius: 4px;\n background-color: var(--jp-layout-color1);\n border: 1px solid var(--jp-border-color2);\n transition: border-color 0.2s, background-color 0.2s;\n}\n\n.jp-agent-key-item:last-child {\n margin-bottom: 0;\n}\n\n.jp-agent-key-item:hover {\n border-color: var(--jp-border-color1);\n}\n\n.jp-agent-key-item-active {\n border-color: var(--jp-brand-color1);\n background-color: var(--jp-brand-color3);\n}\n\n.jp-agent-key-info {\n display: flex;\n align-items: center;\n gap: 8px;\n flex-wrap: wrap;\n}\n\n.jp-agent-key-masked {\n font-family: var(--jp-code-font-family);\n font-size: 12px;\n color: var(--jp-ui-font-color1);\n background-color: var(--jp-layout-color2);\n padding: 2px 6px;\n border-radius: 3px;\n}\n\n.jp-agent-key-status {\n padding: 2px 8px;\n border-radius: 10px;\n font-size: 11px;\n font-weight: 500;\n}\n\n.jp-agent-key-status-active {\n background-color: var(--jp-success-color3);\n color: var(--jp-success-color1);\n}\n\n.jp-agent-key-status-cooldown {\n background-color: var(--jp-warn-color3);\n color: var(--jp-warn-color1);\n}\n\n.jp-agent-key-status-disabled {\n background-color: var(--jp-layout-color2);\n color: var(--jp-ui-font-color2);\n}\n\n.jp-agent-key-current {\n padding: 2px 8px;\n border-radius: 10px;\n font-size: 10px;\n font-weight: 600;\n background-color: var(--jp-brand-color1);\n color: white;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.jp-agent-key-actions {\n display: flex;\n gap: 6px;\n}\n\n.jp-agent-keys-add {\n display: flex;\n gap: 8px;\n margin-bottom: 12px;\n}\n\n.jp-agent-keys-add input {\n flex: 1;\n min-width: 0;\n}\n\n.jp-agent-keys-add button {\n flex-shrink: 0;\n white-space: nowrap;\n}\n\n.jp-agent-keys-info-text {\n color: var(--jp-ui-font-color2);\n font-size: 11px;\n text-align: center;\n line-height: 1.5;\n padding-top: 8px;\n border-top: 1px solid var(--jp-border-color2);\n}\n"],"sourceRoot":""}]);
4332
+ `, "",{"version":3,"sources":["webpack://./frontend/styles/settings-panel.css"],"names":[],"mappings":"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","sourcesContent":["/**\n * Settings Panel Styles\n */\n\n/* Overlay */\n.jp-agent-settings-overlay {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background-color: rgba(0, 0, 0, 0.5);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 10000;\n}\n\n/* Dialog */\n.jp-agent-settings-dialog {\n background-color: var(--jp-layout-color1);\n border-radius: 8px;\n box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);\n width: 90%;\n max-width: 500px;\n max-height: 80vh;\n display: flex;\n flex-direction: column;\n}\n\n/* Header */\n.jp-agent-settings-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 16px 20px;\n border-bottom: 1px solid var(--jp-border-color1);\n}\n\n.jp-agent-settings-header h2 {\n margin: 0;\n font-size: 18px;\n font-weight: 600;\n color: var(--jp-ui-font-color1);\n}\n\n.jp-agent-settings-close {\n background: none;\n border: none;\n font-size: 24px;\n color: var(--jp-ui-font-color2);\n cursor: pointer;\n padding: 0;\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 4px;\n transition: background-color 0.2s;\n}\n\n.jp-agent-settings-close:hover {\n background-color: var(--jp-layout-color2);\n color: var(--jp-ui-font-color1);\n}\n\n/* Content */\n.jp-agent-settings-content {\n padding: 20px;\n overflow-y: auto;\n flex: 1;\n}\n\n.jp-agent-settings-group {\n margin-bottom: 16px;\n}\n\n.jp-agent-settings-label {\n display: block;\n margin-bottom: 6px;\n font-size: 13px;\n font-weight: 500;\n color: var(--jp-ui-font-color1);\n}\n\n.jp-agent-settings-input,\n.jp-agent-settings-select {\n width: 100%;\n padding: 8px 12px;\n font-size: 13px;\n border: 1px solid var(--jp-border-color2);\n border-radius: 4px;\n background-color: var(--jp-layout-color1);\n color: var(--jp-ui-font-color1);\n font-family: var(--jp-ui-font-family);\n}\n\n.jp-agent-settings-textarea {\n min-height: 140px;\n resize: vertical;\n font-family: var(--jp-code-font-family);\n line-height: 1.4;\n}\n\n.jp-agent-settings-input:focus,\n.jp-agent-settings-select:focus {\n outline: none;\n border-color: var(--jp-brand-color1);\n box-shadow: 0 0 0 1px var(--jp-brand-color1);\n}\n\n.jp-agent-settings-input::placeholder {\n color: var(--jp-ui-font-color3);\n}\n\n.jp-agent-settings-provider {\n margin-top: 20px;\n}\n\n.jp-agent-settings-provider h3 {\n margin: 0 0 16px 0;\n font-size: 15px;\n font-weight: 600;\n color: var(--jp-ui-font-color1);\n}\n\n/* Test Result */\n.jp-agent-settings-test-result {\n margin: 16px 20px 0;\n padding: 12px;\n border-radius: 4px;\n font-size: 13px;\n background-color: var(--jp-layout-color2);\n border: 1px solid var(--jp-border-color2);\n color: var(--jp-ui-font-color1);\n font-family: var(--jp-code-font-family);\n}\n\n/* Footer */\n.jp-agent-settings-footer {\n display: flex;\n justify-content: flex-end;\n gap: 8px;\n padding: 16px 20px;\n border-top: 1px solid var(--jp-border-color1);\n}\n\n.jp-agent-settings-button {\n padding: 8px 16px;\n font-size: 13px;\n font-weight: 500;\n border-radius: 4px;\n border: none;\n cursor: pointer;\n transition: all 0.2s;\n font-family: var(--jp-ui-font-family);\n}\n\n.jp-agent-settings-button-secondary {\n background-color: var(--jp-layout-color2);\n color: var(--jp-ui-font-color1);\n}\n\n.jp-agent-settings-button-secondary:hover {\n background-color: var(--jp-layout-color3);\n}\n\n.jp-agent-settings-inline-actions {\n display: flex;\n justify-content: flex-end;\n margin-top: 6px;\n}\n\n.jp-agent-settings-button-compact {\n padding: 6px 10px;\n font-size: 12px;\n}\n\n.jp-agent-settings-button-test {\n background-color: var(--jp-warn-color1);\n color: white;\n}\n\n.jp-agent-settings-button-test:hover:not(:disabled) {\n background-color: var(--jp-warn-color0);\n}\n\n.jp-agent-settings-button-test:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.jp-agent-settings-button-primary {\n background-color: var(--jp-brand-color1);\n color: white;\n}\n\n.jp-agent-settings-button-primary:hover {\n background-color: var(--jp-brand-color0);\n}\n\n.jp-agent-settings-button:active {\n transform: translateY(1px);\n}\n\n.jp-agent-settings-button-primary:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n/* Small Button Variant */\n.jp-agent-settings-button-small {\n padding: 4px 10px;\n font-size: 11px;\n}\n\n/* Danger Button (Delete) */\n.jp-agent-settings-button-danger {\n background-color: var(--jp-error-color1);\n color: white;\n}\n\n.jp-agent-settings-button-danger:hover:not(:disabled) {\n background-color: var(--jp-error-color0);\n}\n\n.jp-agent-settings-button-danger:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n/* Outline Button (Inactive state) */\n.jp-agent-settings-button-outline {\n background-color: transparent;\n border: 1px solid var(--jp-brand-color1);\n color: var(--jp-brand-color1);\n}\n\n.jp-agent-settings-button-outline:hover {\n background-color: var(--jp-brand-color3);\n}\n\n/* ========== API Keys Panel Styles ========== */\n\n.jp-agent-keys-panel {\n margin-top: 20px;\n padding: 16px;\n border: 1px solid var(--jp-border-color2);\n border-radius: 6px;\n background-color: var(--jp-layout-color0);\n}\n\n.jp-agent-keys-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 12px;\n}\n\n.jp-agent-keys-header h4 {\n margin: 0;\n font-size: 14px;\n font-weight: 600;\n color: var(--jp-ui-font-color1);\n}\n\n.jp-agent-keys-count {\n font-size: 12px;\n color: var(--jp-ui-font-color2);\n background-color: var(--jp-layout-color2);\n padding: 2px 8px;\n border-radius: 10px;\n}\n\n.jp-agent-keys-error {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 8px 12px;\n margin-bottom: 12px;\n background-color: var(--jp-error-color3);\n border-radius: 4px;\n color: var(--jp-error-color1);\n font-size: 13px;\n}\n\n.jp-agent-keys-error button {\n background: none;\n border: none;\n cursor: pointer;\n font-size: 16px;\n color: var(--jp-error-color1);\n padding: 0 4px;\n}\n\n.jp-agent-keys-error button:hover {\n opacity: 0.8;\n}\n\n.jp-agent-keys-list {\n max-height: 200px;\n overflow-y: auto;\n margin-bottom: 12px;\n}\n\n.jp-agent-keys-empty {\n padding: 24px 20px;\n text-align: center;\n color: var(--jp-ui-font-color2);\n font-size: 13px;\n background-color: var(--jp-layout-color1);\n border-radius: 4px;\n border: 1px dashed var(--jp-border-color2);\n}\n\n.jp-agent-key-item {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 10px 12px;\n margin-bottom: 6px;\n border-radius: 4px;\n background-color: var(--jp-layout-color1);\n border: 1px solid var(--jp-border-color2);\n transition: border-color 0.2s, background-color 0.2s;\n}\n\n.jp-agent-key-item:last-child {\n margin-bottom: 0;\n}\n\n.jp-agent-key-item:hover {\n border-color: var(--jp-border-color1);\n}\n\n.jp-agent-key-item-active {\n border-color: var(--jp-brand-color1);\n background-color: var(--jp-brand-color3);\n}\n\n.jp-agent-key-info {\n display: flex;\n align-items: center;\n gap: 8px;\n flex-wrap: wrap;\n}\n\n.jp-agent-key-masked {\n font-family: var(--jp-code-font-family);\n font-size: 12px;\n color: var(--jp-ui-font-color1);\n background-color: var(--jp-layout-color2);\n padding: 2px 6px;\n border-radius: 3px;\n}\n\n.jp-agent-key-status {\n padding: 2px 8px;\n border-radius: 10px;\n font-size: 11px;\n font-weight: 500;\n}\n\n.jp-agent-key-status-active {\n background-color: var(--jp-success-color3);\n color: var(--jp-success-color1);\n}\n\n.jp-agent-key-status-cooldown {\n background-color: var(--jp-warn-color3);\n color: var(--jp-warn-color1);\n}\n\n.jp-agent-key-status-disabled {\n background-color: var(--jp-layout-color2);\n color: var(--jp-ui-font-color2);\n}\n\n.jp-agent-key-current {\n padding: 2px 8px;\n border-radius: 10px;\n font-size: 10px;\n font-weight: 600;\n background-color: var(--jp-brand-color1);\n color: white;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.jp-agent-key-actions {\n display: flex;\n gap: 6px;\n}\n\n.jp-agent-keys-add {\n display: flex;\n gap: 8px;\n margin-bottom: 12px;\n}\n\n.jp-agent-keys-add input {\n flex: 1;\n min-width: 0;\n}\n\n.jp-agent-keys-add button {\n flex-shrink: 0;\n white-space: nowrap;\n}\n\n.jp-agent-keys-info-text {\n color: var(--jp-ui-font-color2);\n font-size: 11px;\n text-align: center;\n line-height: 1.5;\n padding-top: 8px;\n border-top: 1px solid var(--jp-border-color2);\n}\n"],"sourceRoot":""}]);
4315
4333
  // Exports
4316
4334
  /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);
4317
4335
 
@@ -4770,4 +4788,4 @@ module.exports = "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYi
4770
4788
  /***/ }
4771
4789
 
4772
4790
  }]);
4773
- //# sourceMappingURL=frontend_styles_index_js.634cf0ae0f3592d0882f.js.map
4791
+ //# sourceMappingURL=frontend_styles_index_js.4105453345c170c1d6e6.js.map