flock-core 0.4.0b34__py3-none-any.whl → 0.4.0b36__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 flock-core might be problematic. Click here for more details.

Files changed (63) hide show
  1. flock/__init__.py +53 -8
  2. flock/cli/loaded_flock_cli.py +38 -18
  3. flock/core/api/main.py +138 -39
  4. flock/core/flock.py +48 -3
  5. flock/themes/alabaster.toml +43 -43
  6. flock/themes/guezwhoz.toml +43 -43
  7. flock/themes/wildcherry.toml +43 -43
  8. flock/themes/wombat.toml +43 -43
  9. flock/themes/zenburn.toml +43 -43
  10. flock/webapp/__init__.py +1 -0
  11. flock/webapp/app/__init__.py +0 -0
  12. flock/webapp/app/api/__init__.py +0 -0
  13. flock/webapp/app/api/agent_management.py +270 -0
  14. flock/webapp/app/api/execution.py +173 -0
  15. flock/webapp/app/api/flock_management.py +102 -0
  16. flock/webapp/app/api/registry_viewer.py +30 -0
  17. flock/webapp/app/config.py +87 -0
  18. flock/webapp/app/main.py +1074 -0
  19. flock/webapp/app/models_ui.py +7 -0
  20. flock/webapp/app/services/__init__.py +0 -0
  21. flock/webapp/app/services/flock_service.py +291 -0
  22. flock/webapp/app/templates/theme_mapper.html +326 -0
  23. flock/webapp/app/theme_mapper.py +812 -0
  24. flock/webapp/app/utils.py +85 -0
  25. flock/webapp/run.py +132 -0
  26. flock/webapp/static/css/custom.css +612 -0
  27. flock/webapp/templates/base.html +105 -0
  28. flock/webapp/templates/flock_editor.html +17 -0
  29. flock/webapp/templates/index.html +12 -0
  30. flock/webapp/templates/partials/_agent_detail_form.html +98 -0
  31. flock/webapp/templates/partials/_agent_list.html +19 -0
  32. flock/webapp/templates/partials/_agent_manager_view.html +53 -0
  33. flock/webapp/templates/partials/_agent_manager_view_old.html +19 -0
  34. flock/webapp/templates/partials/_agent_tools_checklist.html +14 -0
  35. flock/webapp/templates/partials/_create_flock_form.html +52 -0
  36. flock/webapp/templates/partials/_dashboard_flock_detail.html +18 -0
  37. flock/webapp/templates/partials/_dashboard_flock_file_list.html +17 -0
  38. flock/webapp/templates/partials/_dashboard_flock_properties_preview.html +29 -0
  39. flock/webapp/templates/partials/_dashboard_upload_flock_form.html +17 -0
  40. flock/webapp/templates/partials/_dynamic_input_form_content.html +22 -0
  41. flock/webapp/templates/partials/_env_vars_table.html +25 -0
  42. flock/webapp/templates/partials/_execution_form.html +48 -0
  43. flock/webapp/templates/partials/_execution_view_container.html +20 -0
  44. flock/webapp/templates/partials/_flock_file_list.html +24 -0
  45. flock/webapp/templates/partials/_flock_properties_form.html +52 -0
  46. flock/webapp/templates/partials/_flock_upload_form.html +17 -0
  47. flock/webapp/templates/partials/_header_flock_status.html +5 -0
  48. flock/webapp/templates/partials/_load_manager_view.html +50 -0
  49. flock/webapp/templates/partials/_registry_table.html +25 -0
  50. flock/webapp/templates/partials/_registry_viewer_content.html +47 -0
  51. flock/webapp/templates/partials/_results_display.html +35 -0
  52. flock/webapp/templates/partials/_settings_env_content.html +10 -0
  53. flock/webapp/templates/partials/_settings_theme_content.html +15 -0
  54. flock/webapp/templates/partials/_settings_view.html +36 -0
  55. flock/webapp/templates/partials/_sidebar.html +70 -0
  56. flock/webapp/templates/partials/_structured_data_view.html +40 -0
  57. flock/webapp/templates/partials/_theme_preview.html +23 -0
  58. flock/webapp/templates/registry_viewer.html +84 -0
  59. {flock_core-0.4.0b34.dist-info → flock_core-0.4.0b36.dist-info}/METADATA +1 -1
  60. {flock_core-0.4.0b34.dist-info → flock_core-0.4.0b36.dist-info}/RECORD +63 -14
  61. {flock_core-0.4.0b34.dist-info → flock_core-0.4.0b36.dist-info}/WHEEL +0 -0
  62. {flock_core-0.4.0b34.dist-info → flock_core-0.4.0b36.dist-info}/entry_points.txt +0 -0
  63. {flock_core-0.4.0b34.dist-info → flock_core-0.4.0b36.dist-info}/licenses/LICENSE +0 -0
@@ -2,28 +2,28 @@
2
2
  panel_style = "on #1f1726"
3
3
  table_header_style = "bold #e4ffff on #002831"
4
4
  table_title_style = "bold #dafaff"
5
- table_border_style = "#308cba"
6
- panel_border_style = "#308cba"
5
+ table_border_style = " #308cba"
6
+ panel_border_style = " #308cba"
7
7
  column_output = "bold #dafaff"
8
- column_value = "#dafaff"
9
- bright_black = "#009cc9"
10
- bright_blue = "#308cba"
11
- bright_cyan = "#ff919d"
12
- bright_green = "#f4dca5"
13
- bright_magenta = "#ae636b"
14
- bright_red = "#da6bac"
15
- bright_white = "#e4838d"
16
- bright_yellow = "#eac066"
17
- normal_black = "#000507"
18
- normal_blue = "#883cdc"
19
- normal_cyan = "#c1b8b7"
20
- normal_green = "#2ab250"
21
- normal_magenta = "#ececec"
22
- normal_red = "#d94085"
23
- normal_white = "#fff8de"
24
- normal_yellow = "#ffd16f"
25
- cursor_cursor = "#dd00ff"
26
- cursor_text = "#ff00fe"
8
+ column_value = " #dafaff"
9
+ bright_black = " #009cc9"
10
+ bright_blue = " #308cba"
11
+ bright_cyan = " #ff919d"
12
+ bright_green = " #f4dca5"
13
+ bright_magenta = " #ae636b"
14
+ bright_red = " #da6bac"
15
+ bright_white = " #e4838d"
16
+ bright_yellow = " #eac066"
17
+ normal_black = " #000507"
18
+ normal_blue = " #883cdc"
19
+ normal_cyan = " #c1b8b7"
20
+ normal_green = " #2ab250"
21
+ normal_magenta = " #ececec"
22
+ normal_red = " #d94085"
23
+ normal_white = " #fff8de"
24
+ normal_yellow = " #ffd16f"
25
+ cursor_cursor = " #dd00ff"
26
+ cursor_text = " #ff00fe"
27
27
  table_show_lines = false
28
28
  table_box = "DOUBLE_EDGE"
29
29
  panel_padding = [ 1, 2,]
@@ -45,33 +45,33 @@ table_caption_justify = "center"
45
45
  table_highlight = false
46
46
 
47
47
  [colors.bright]
48
- black = "#009cc9"
49
- blue = "#308cba"
50
- cyan = "#ff919d"
51
- green = "#f4dca5"
52
- magenta = "#ae636b"
53
- red = "#da6bac"
54
- white = "#e4838d"
55
- yellow = "#eac066"
48
+ black = " #009cc9"
49
+ blue = " #308cba"
50
+ cyan = " #ff919d"
51
+ green = " #f4dca5"
52
+ magenta = " #ae636b"
53
+ red = " #da6bac"
54
+ white = " #e4838d"
55
+ yellow = " #eac066"
56
56
 
57
57
  [colors.cursor]
58
- cursor = "#dd00ff"
59
- text = "#ff00fe"
58
+ cursor = " #dd00ff"
59
+ text = " #ff00fe"
60
60
 
61
61
  [colors.normal]
62
- black = "#000507"
63
- blue = "#883cdc"
64
- cyan = "#c1b8b7"
65
- green = "#2ab250"
66
- magenta = "#ececec"
67
- red = "#d94085"
68
- white = "#fff8de"
69
- yellow = "#ffd16f"
62
+ black = " #000507"
63
+ blue = " #883cdc"
64
+ cyan = " #c1b8b7"
65
+ green = " #2ab250"
66
+ magenta = " #ececec"
67
+ red = " #d94085"
68
+ white = " #fff8de"
69
+ yellow = " #ffd16f"
70
70
 
71
71
  [colors.primary]
72
- background = "#1f1726"
73
- foreground = "#dafaff"
72
+ background = " #1f1726"
73
+ foreground = " #dafaff"
74
74
 
75
75
  [colors.selection]
76
- background = "#002831"
77
- text = "#e4ffff"
76
+ background = " #002831"
77
+ text = " #e4ffff"
flock/themes/wombat.toml CHANGED
@@ -2,28 +2,28 @@
2
2
  panel_style = "on #171717"
3
3
  table_header_style = "bold #b6bbc0 on #453b39"
4
4
  table_title_style = "bold #dedacf"
5
- table_border_style = "#a5c7ff"
6
- panel_border_style = "#a5c7ff"
5
+ table_border_style = " #a5c7ff"
6
+ panel_border_style = " #a5c7ff"
7
7
  column_output = "bold #dedacf"
8
- column_value = "#dedacf"
9
- bright_black = "#313131"
10
- bright_blue = "#a5c7ff"
11
- bright_cyan = "#b7fff9"
12
- bright_green = "#ddf88f"
13
- bright_magenta = "#ddaaff"
14
- bright_red = "#f58c80"
15
- bright_white = "#ffffff"
16
- bright_yellow = "#eee5b2"
17
- normal_black = "#000000"
18
- normal_blue = "#5da9f6"
19
- normal_cyan = "#82fff7"
20
- normal_green = "#b1e969"
21
- normal_magenta = "#e86aff"
22
- normal_red = "#ff615a"
23
- normal_white = "#dedacf"
24
- normal_yellow = "#ebd99c"
25
- cursor_cursor = "#bbbbbb"
26
- cursor_text = "#ffffff"
8
+ column_value = " #dedacf"
9
+ bright_black = " #313131"
10
+ bright_blue = " #a5c7ff"
11
+ bright_cyan = " #b7fff9"
12
+ bright_green = " #ddf88f"
13
+ bright_magenta = " #ddaaff"
14
+ bright_red = " #f58c80"
15
+ bright_white = " #ffffff"
16
+ bright_yellow = " #eee5b2"
17
+ normal_black = " #000000"
18
+ normal_blue = " #5da9f6"
19
+ normal_cyan = " #82fff7"
20
+ normal_green = " #b1e969"
21
+ normal_magenta = " #e86aff"
22
+ normal_red = " #ff615a"
23
+ normal_white = " #dedacf"
24
+ normal_yellow = " #ebd99c"
25
+ cursor_cursor = " #bbbbbb"
26
+ cursor_text = " #ffffff"
27
27
  table_show_lines = true
28
28
  table_box = "SIMPLE"
29
29
  panel_padding = [ 1, 1,]
@@ -45,33 +45,33 @@ table_caption_justify = "center"
45
45
  table_highlight = false
46
46
 
47
47
  [colors.bright]
48
- black = "#313131"
49
- blue = "#a5c7ff"
50
- cyan = "#b7fff9"
51
- green = "#ddf88f"
52
- magenta = "#ddaaff"
53
- red = "#f58c80"
54
- white = "#ffffff"
55
- yellow = "#eee5b2"
48
+ black = " #313131"
49
+ blue = " #a5c7ff"
50
+ cyan = " #b7fff9"
51
+ green = " #ddf88f"
52
+ magenta = " #ddaaff"
53
+ red = " #f58c80"
54
+ white = " #ffffff"
55
+ yellow = " #eee5b2"
56
56
 
57
57
  [colors.cursor]
58
- cursor = "#bbbbbb"
59
- text = "#ffffff"
58
+ cursor = " #bbbbbb"
59
+ text = " #ffffff"
60
60
 
61
61
  [colors.normal]
62
- black = "#000000"
63
- blue = "#5da9f6"
64
- cyan = "#82fff7"
65
- green = "#b1e969"
66
- magenta = "#e86aff"
67
- red = "#ff615a"
68
- white = "#dedacf"
69
- yellow = "#ebd99c"
62
+ black = " #000000"
63
+ blue = " #5da9f6"
64
+ cyan = " #82fff7"
65
+ green = " #b1e969"
66
+ magenta = " #e86aff"
67
+ red = " #ff615a"
68
+ white = " #dedacf"
69
+ yellow = " #ebd99c"
70
70
 
71
71
  [colors.primary]
72
- background = "#171717"
73
- foreground = "#dedacf"
72
+ background = " #171717"
73
+ foreground = " #dedacf"
74
74
 
75
75
  [colors.selection]
76
- background = "#453b39"
77
- text = "#b6bbc0"
76
+ background = " #453b39"
77
+ text = " #b6bbc0"
flock/themes/zenburn.toml CHANGED
@@ -2,28 +2,28 @@
2
2
  panel_style = "on #3f3f3f"
3
3
  table_header_style = "bold #c2d87a on #21322f"
4
4
  table_title_style = "bold #dcdccc"
5
- table_border_style = "#94bff3"
6
- panel_border_style = "#94bff3"
5
+ table_border_style = " #94bff3"
6
+ panel_border_style = " #94bff3"
7
7
  column_output = "bold #dcdccc"
8
- column_value = "#dcdccc"
9
- bright_black = "#709080"
10
- bright_blue = "#94bff3"
11
- bright_cyan = "#93e0e3"
12
- bright_green = "#c3bf9f"
13
- bright_magenta = "#ec93d3"
14
- bright_red = "#dca3a3"
15
- bright_white = "#ffffff"
16
- bright_yellow = "#e0cf9f"
17
- normal_black = "#4d4d4d"
18
- normal_blue = "#506070"
19
- normal_cyan = "#8cd0d3"
20
- normal_green = "#60b48a"
21
- normal_magenta = "#dc8cc3"
22
- normal_red = "#705050"
23
- normal_white = "#dcdccc"
24
- normal_yellow = "#f0dfaf"
25
- cursor_cursor = "#73635a"
26
- cursor_text = "#000000"
8
+ column_value = " #dcdccc"
9
+ bright_black = " #709080"
10
+ bright_blue = " #94bff3"
11
+ bright_cyan = " #93e0e3"
12
+ bright_green = " #c3bf9f"
13
+ bright_magenta = " #ec93d3"
14
+ bright_red = " #dca3a3"
15
+ bright_white = " #ffffff"
16
+ bright_yellow = " #e0cf9f"
17
+ normal_black = " #4d4d4d"
18
+ normal_blue = " #506070"
19
+ normal_cyan = " #8cd0d3"
20
+ normal_green = " #60b48a"
21
+ normal_magenta = " #dc8cc3"
22
+ normal_red = " #705050"
23
+ normal_white = " #dcdccc"
24
+ normal_yellow = " #f0dfaf"
25
+ cursor_cursor = " #73635a"
26
+ cursor_text = " #000000"
27
27
  table_show_lines = false
28
28
  table_box = "HEAVY"
29
29
  panel_padding = [ 1, 2,]
@@ -45,33 +45,33 @@ table_caption_justify = "center"
45
45
  table_highlight = false
46
46
 
47
47
  [colors.bright]
48
- black = "#709080"
49
- blue = "#94bff3"
50
- cyan = "#93e0e3"
51
- green = "#c3bf9f"
52
- magenta = "#ec93d3"
53
- red = "#dca3a3"
54
- white = "#ffffff"
55
- yellow = "#e0cf9f"
48
+ black = " #709080"
49
+ blue = " #94bff3"
50
+ cyan = " #93e0e3"
51
+ green = " #c3bf9f"
52
+ magenta = " #ec93d3"
53
+ red = " #dca3a3"
54
+ white = " #ffffff"
55
+ yellow = " #e0cf9f"
56
56
 
57
57
  [colors.cursor]
58
- cursor = "#73635a"
59
- text = "#000000"
58
+ cursor = " #73635a"
59
+ text = " #000000"
60
60
 
61
61
  [colors.normal]
62
- black = "#4d4d4d"
63
- blue = "#506070"
64
- cyan = "#8cd0d3"
65
- green = "#60b48a"
66
- magenta = "#dc8cc3"
67
- red = "#705050"
68
- white = "#dcdccc"
69
- yellow = "#f0dfaf"
62
+ black = " #4d4d4d"
63
+ blue = " #506070"
64
+ cyan = " #8cd0d3"
65
+ green = " #60b48a"
66
+ magenta = " #dc8cc3"
67
+ red = " #705050"
68
+ white = " #dcdccc"
69
+ yellow = " #f0dfaf"
70
70
 
71
71
  [colors.primary]
72
- background = "#3f3f3f"
73
- foreground = "#dcdccc"
72
+ background = " #3f3f3f"
73
+ foreground = " #dcdccc"
74
74
 
75
75
  [colors.selection]
76
- background = "#21322f"
77
- text = "#c2d87a"
76
+ background = " #21322f"
77
+ text = " #c2d87a"
@@ -0,0 +1 @@
1
+ """Flock Web Application Package."""
File without changes
File without changes
@@ -0,0 +1,270 @@
1
+ from pathlib import Path
2
+
3
+ from fastapi import APIRouter, Form, Request
4
+ from fastapi.responses import HTMLResponse
5
+ from fastapi.templating import Jinja2Templates
6
+
7
+ from flock.webapp.app.services.flock_service import (
8
+ add_agent_to_current_flock_service,
9
+ get_current_flock_instance,
10
+ get_registered_items_service,
11
+ remove_agent_from_current_flock_service,
12
+ update_agent_in_current_flock_service,
13
+ )
14
+
15
+ router = APIRouter()
16
+ BASE_DIR = Path(__file__).resolve().parent.parent.parent
17
+ templates = Jinja2Templates(directory=str(BASE_DIR / "templates"))
18
+
19
+
20
+ @router.get("/htmx/agent-list", response_class=HTMLResponse)
21
+ async def htmx_get_agent_list(
22
+ request: Request, message: str = None, success: bool = None
23
+ ):
24
+ flock = get_current_flock_instance()
25
+ if not flock:
26
+ return HTMLResponse("<p class='error'>No Flock loaded.</p>")
27
+ return templates.TemplateResponse(
28
+ "partials/_agent_list.html",
29
+ {
30
+ "request": request,
31
+ "flock": flock,
32
+ "message": message,
33
+ "success": success,
34
+ },
35
+ )
36
+
37
+
38
+ @router.get(
39
+ "/htmx/agents/{agent_name}/details-form", response_class=HTMLResponse
40
+ )
41
+ async def htmx_get_agent_details_form(request: Request, agent_name: str):
42
+ flock = get_current_flock_instance()
43
+ if not flock:
44
+ return HTMLResponse("<p class='error'>No Flock loaded.</p>")
45
+ agent = flock.agents.get(agent_name)
46
+ if not agent:
47
+ return HTMLResponse(
48
+ f"<p class='error'>Agent '{agent_name}' not found.</p>"
49
+ )
50
+
51
+ registered_tools = get_registered_items_service("tool")
52
+ current_tools = (
53
+ [tool.__name__ for tool in agent.tools] if agent.tools else []
54
+ )
55
+
56
+ return templates.TemplateResponse(
57
+ "partials/_agent_detail_form.html",
58
+ {
59
+ "request": request,
60
+ "agent": agent,
61
+ "is_new": False,
62
+ "registered_tools": registered_tools,
63
+ "current_tools": current_tools,
64
+ },
65
+ )
66
+
67
+
68
+ @router.get("/htmx/agents/new-agent-form", response_class=HTMLResponse)
69
+ async def htmx_get_new_agent_form(request: Request):
70
+ flock = get_current_flock_instance()
71
+ if not flock:
72
+ return HTMLResponse("<p class='error'>No Flock loaded.</p>")
73
+ registered_tools = get_registered_items_service("tool")
74
+ return templates.TemplateResponse(
75
+ "partials/_agent_detail_form.html",
76
+ {
77
+ "request": request,
78
+ "agent": None, # For new agent
79
+ "is_new": True,
80
+ "registered_tools": registered_tools,
81
+ "current_tools": [],
82
+ },
83
+ )
84
+
85
+
86
+ @router.post(
87
+ "/htmx/agents", response_class=HTMLResponse
88
+ ) # For creating new agent
89
+ async def htmx_create_agent(
90
+ request: Request,
91
+ agent_name: str = Form(...),
92
+ agent_description: str = Form(""),
93
+ agent_model: str = Form(None), # Can be empty to use Flock default
94
+ input_signature: str = Form(...),
95
+ output_signature: str = Form(...),
96
+ tools: list[str] = Form([]),
97
+ ): # FastAPI handles list from multiple form fields with same name
98
+ flock = get_current_flock_instance()
99
+ if not flock:
100
+ return HTMLResponse("<p class='error'>No Flock loaded.</p>")
101
+
102
+ if (
103
+ not agent_name.strip()
104
+ or not input_signature.strip()
105
+ or not output_signature.strip()
106
+ ):
107
+ # Render form again with error (or use a different target for error message)
108
+ registered_tools = get_registered_items_service("tool")
109
+ return templates.TemplateResponse(
110
+ "partials/_agent_detail_form.html",
111
+ {
112
+ "request": request,
113
+ "agent": None,
114
+ "is_new": True,
115
+ "error_message": "Name, Input Signature, and Output Signature are required.",
116
+ "registered_tools": registered_tools,
117
+ "current_tools": tools, # Pass back selected tools
118
+ },
119
+ )
120
+
121
+ agent_config = {
122
+ "name": agent_name,
123
+ "description": agent_description,
124
+ "model": agent_model
125
+ if agent_model
126
+ else None, # Pass None if empty string for FlockFactory
127
+ "input": input_signature,
128
+ "output": output_signature,
129
+ "tools_names": tools, # Pass tool names
130
+ }
131
+ success = add_agent_to_current_flock_service(agent_config)
132
+
133
+ # After action, re-render the agent list and clear the detail form
134
+ # Set headers for HTMX to trigger multiple target updates
135
+ response_headers = {}
136
+ if success:
137
+ response_headers["HX-Trigger"] = (
138
+ "agentListChanged" # Custom event to refresh list
139
+ )
140
+
141
+ # Render an empty detail form or a success message for the detail panel
142
+ empty_detail_form = templates.TemplateResponse(
143
+ "partials/_agent_detail_form.html",
144
+ {
145
+ "request": request,
146
+ "agent": None,
147
+ "is_new": True,
148
+ "registered_tools": get_registered_items_service("tool"),
149
+ "form_message": "Agent created successfully!"
150
+ if success
151
+ else "Failed to create agent.",
152
+ "success": success,
153
+ },
154
+ ).body.decode()
155
+
156
+ return HTMLResponse(content=empty_detail_form, headers=response_headers)
157
+
158
+
159
+ @router.put(
160
+ "/htmx/agents/{original_agent_name}", response_class=HTMLResponse
161
+ ) # For updating existing agent
162
+ async def htmx_update_agent(
163
+ request: Request,
164
+ original_agent_name: str,
165
+ agent_name: str = Form(...),
166
+ agent_description: str = Form(""),
167
+ agent_model: str = Form(None),
168
+ input_signature: str = Form(...),
169
+ output_signature: str = Form(...),
170
+ tools: list[str] = Form([]),
171
+ ):
172
+ flock = get_current_flock_instance()
173
+ if not flock:
174
+ return HTMLResponse("<p class='error'>No Flock loaded.</p>")
175
+
176
+ agent_config = {
177
+ "name": agent_name,
178
+ "description": agent_description,
179
+ "model": agent_model if agent_model else None,
180
+ "input": input_signature,
181
+ "output": output_signature,
182
+ "tools_names": tools,
183
+ }
184
+ success = update_agent_in_current_flock_service(
185
+ original_agent_name, agent_config
186
+ )
187
+
188
+ response_headers = {}
189
+ if success:
190
+ response_headers["HX-Trigger"] = "agentListChanged"
191
+
192
+ # Re-render the form with update message
193
+ updated_agent = flock.agents.get(
194
+ agent_name
195
+ ) # Get the potentially renamed agent
196
+ registered_tools = get_registered_items_service("tool")
197
+ current_tools = (
198
+ [tool.__name__ for tool in updated_agent.tools]
199
+ if updated_agent and updated_agent.tools
200
+ else []
201
+ )
202
+
203
+ updated_form = templates.TemplateResponse(
204
+ "partials/_agent_detail_form.html",
205
+ {
206
+ "request": request,
207
+ "agent": updated_agent, # Pass the updated agent
208
+ "is_new": False,
209
+ "form_message": "Agent updated successfully!"
210
+ if success
211
+ else "Failed to update agent.",
212
+ "success": success,
213
+ "registered_tools": registered_tools,
214
+ "current_tools": current_tools,
215
+ },
216
+ ).body.decode()
217
+ return HTMLResponse(content=updated_form, headers=response_headers)
218
+
219
+
220
+ @router.delete("/htmx/agents/{agent_name}", response_class=HTMLResponse)
221
+ async def htmx_delete_agent(request: Request, agent_name: str):
222
+ flock = get_current_flock_instance()
223
+ if not flock:
224
+ return HTMLResponse("") # Return empty to clear detail view
225
+
226
+ success = remove_agent_from_current_flock_service(agent_name)
227
+
228
+ response_headers = {}
229
+ if success:
230
+ response_headers["HX-Trigger"] = "agentListChanged"
231
+ # Return an empty agent detail form to clear the panel
232
+ # Also, the agent list will re-render due to HX-Trigger
233
+ return HTMLResponse(
234
+ templates.TemplateResponse(
235
+ "partials/_agent_detail_form.html",
236
+ {
237
+ "request": request,
238
+ "agent": None,
239
+ "is_new": True,
240
+ "form_message": f"Agent '{agent_name}' removed.",
241
+ "success": True,
242
+ "registered_tools": get_registered_items_service("tool"),
243
+ },
244
+ ).body.decode(),
245
+ headers=response_headers,
246
+ )
247
+ else:
248
+ # If deletion fails, re-render the agent detail form with an error
249
+ # This scenario should be rare unless the agent was already removed
250
+ agent = flock.agents.get(
251
+ agent_name
252
+ ) # Should still exist if delete failed
253
+ registered_tools = get_registered_items_service("tool")
254
+ current_tools = (
255
+ [tool.__name__ for tool in agent.tools]
256
+ if agent and agent.tools
257
+ else []
258
+ )
259
+ return templates.TemplateResponse(
260
+ "partials/_agent_detail_form.html",
261
+ {
262
+ "request": request,
263
+ "agent": agent,
264
+ "is_new": False,
265
+ "form_message": f"Failed to remove agent '{agent_name}'.",
266
+ "success": False,
267
+ "registered_tools": registered_tools,
268
+ "current_tools": current_tools,
269
+ },
270
+ )