flock-core 0.4.510__py3-none-any.whl → 0.4.512__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 (43) hide show
  1. flock/core/config/flock_agent_config.py +11 -0
  2. flock/core/config/scheduled_agent_config.py +40 -0
  3. flock/core/flock_agent.py +6 -0
  4. flock/core/flock_factory.py +44 -0
  5. flock/core/flock_scheduler.py +166 -0
  6. flock/webapp/app/main.py +66 -11
  7. flock/webapp/app/services/sharing_store.py +173 -0
  8. flock/webapp/run.py +3 -1
  9. flock/webapp/static/css/two-pane.css +48 -0
  10. flock/webapp/templates/base.html +10 -10
  11. flock/webapp/templates/chat.html +7 -10
  12. flock/webapp/templates/chat_settings.html +3 -4
  13. flock/webapp/templates/flock_editor.html +1 -2
  14. flock/webapp/templates/index.html +1 -1
  15. flock/webapp/templates/partials/_agent_detail_form.html +7 -13
  16. flock/webapp/templates/partials/_agent_list.html +1 -2
  17. flock/webapp/templates/partials/_agent_manager_view.html +2 -3
  18. flock/webapp/templates/partials/_chat_container.html +2 -2
  19. flock/webapp/templates/partials/_chat_settings_form.html +6 -8
  20. flock/webapp/templates/partials/_create_flock_form.html +2 -4
  21. flock/webapp/templates/partials/_dashboard_flock_detail.html +2 -3
  22. flock/webapp/templates/partials/_dashboard_flock_file_list.html +1 -2
  23. flock/webapp/templates/partials/_dashboard_flock_properties_preview.html +2 -3
  24. flock/webapp/templates/partials/_dashboard_upload_flock_form.html +1 -2
  25. flock/webapp/templates/partials/_env_vars_table.html +2 -4
  26. flock/webapp/templates/partials/_execution_form.html +12 -10
  27. flock/webapp/templates/partials/_execution_view_container.html +14 -6
  28. flock/webapp/templates/partials/_flock_file_list.html +2 -3
  29. flock/webapp/templates/partials/_flock_properties_form.html +2 -2
  30. flock/webapp/templates/partials/_flock_upload_form.html +1 -2
  31. flock/webapp/templates/partials/_load_manager_view.html +2 -3
  32. flock/webapp/templates/partials/_registry_viewer_content.html +4 -5
  33. flock/webapp/templates/partials/_settings_env_content.html +2 -3
  34. flock/webapp/templates/partials/_settings_theme_content.html +2 -2
  35. flock/webapp/templates/partials/_settings_view.html +2 -2
  36. flock/webapp/templates/partials/_sidebar.html +27 -39
  37. flock/webapp/templates/registry_viewer.html +7 -10
  38. flock/webapp/templates/shared_run_page.html +7 -10
  39. {flock_core-0.4.510.dist-info → flock_core-0.4.512.dist-info}/METADATA +3 -1
  40. {flock_core-0.4.510.dist-info → flock_core-0.4.512.dist-info}/RECORD +43 -39
  41. {flock_core-0.4.510.dist-info → flock_core-0.4.512.dist-info}/WHEEL +0 -0
  42. {flock_core-0.4.510.dist-info → flock_core-0.4.512.dist-info}/entry_points.txt +0 -0
  43. {flock_core-0.4.510.dist-info → flock_core-0.4.512.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,48 @@
1
+ /* ========================================================================
2
+ two-pane.css — Styles for the two-pane layout used in execution view
3
+ ======================================================================== */
4
+
5
+ /* Two pane container */
6
+ .two-pane-flex-container {
7
+ display: flex;
8
+ width: 100%;
9
+ }
10
+
11
+ /* Collapsed left pane */
12
+ .left-pane-collapsed {
13
+ width: 40px;
14
+ display: flex;
15
+ align-items: center;
16
+ justify-content: center;
17
+ background-color: var(--pico-muted-border-color);
18
+ border-radius: 0 4px 4px 0;
19
+ writing-mode: vertical-lr;
20
+ transform: rotate(180deg);
21
+ margin-right: 10px;
22
+ transition: background-color 0.2s;
23
+ }
24
+
25
+ .left-pane-collapsed:hover {
26
+ background-color: var(--pico-primary-hover);
27
+ }
28
+
29
+ /* Toggle links styling */
30
+ .pane-toggle {
31
+ text-decoration: none;
32
+ color: var(--pico-primary);
33
+ font-size: 0.875rem;
34
+ font-weight: 500;
35
+ padding: 5px 10px;
36
+ border-radius: 4px;
37
+ transition: all 0.2s;
38
+ }
39
+
40
+ .pane-toggle:hover {
41
+ background-color: var(--pico-primary-hover);
42
+ color: var(--pico-primary-inverse);
43
+ }
44
+
45
+ /* Ensure right pane takes full width when left is collapsed */
46
+ #execution-right-pane {
47
+ transition: flex 0.3s, padding-left 0.3s;
48
+ }
@@ -7,11 +7,14 @@
7
7
  <title>{% block title %}Flock UI{% endblock %}</title>
8
8
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.min.css" />
9
9
  <!-- Split modular CSS files -->
10
- <link rel="stylesheet" href="/static/css/layout.css">
11
- <link rel="stylesheet" href="/static/css/header.css">
12
- <link rel="stylesheet" href="/static/css/sidebar.css">
13
- <link rel="stylesheet" href="/static/css/components.css">
14
- <link rel="stylesheet" href="/static/css/chat.css">
10
+ <link rel="stylesheet"
11
+ href="{{ url_for('static', path='css/layout.css') }}">
12
+ <link rel="stylesheet"
13
+ href="{{ url_for('static', path='css/header.css') }}">
14
+ <link rel="stylesheet" href="{{ url_for('static', path='css/sidebar.css') }}">
15
+ <link rel="stylesheet" href="{{ url_for('static', path='css/components.css') }}">
16
+ <link rel="stylesheet" href="{{ url_for('static', path='css/chat.css') }}">
17
+ <link rel="stylesheet" href="{{ url_for('static', path='css/two-pane.css') }}">
15
18
  <!-- Font Awesome for icons -->
16
19
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css">
17
20
  <!-- Prism.js CSS for syntax highlighting (okaidia theme) -->
@@ -41,14 +44,11 @@
41
44
  </div>
42
45
 
43
46
  <header class="top-header">
44
- <span><strong>🐧 Flock Playground 🐤</strong></span>
45
- <span id="header-flock-status-container" hx-get="/ui/htmx/header-flock-status?ui_mode={{ ui_mode }}"
47
+ <span><strong>🐧 Flock Playground 🐤</strong></span> <span id="header-flock-status-container" hx-get="{{ url_for('htmx_get_header_flock_status') }}?ui_mode={{ ui_mode }}"
46
48
  hx-trigger="load, flockLoaded from:body, flockCleared from:body" hx-swap="innerHTML">
47
49
  <small>Loading status...</small> {# Placeholder while loading #}
48
50
  </span>
49
- </header>
50
-
51
- <aside class="sidebar" hx-get="/ui/htmx/sidebar?ui_mode={{ ui_mode }}"
51
+ </header> <aside class="sidebar" hx-get="{{ url_for('htmx_get_sidebar') }}?ui_mode={{ ui_mode }}"
52
52
  hx-trigger="load, flockLoaded from:body, flockListChanged from:body" hx-swap="innerHTML">
53
53
  <p>Loading navigation...</p><progress></progress>
54
54
  </aside>
@@ -5,7 +5,7 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
6
  <title>Flock Chat</title>
7
7
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.min.css" />
8
- <link rel="stylesheet" href="/static/css/chat.css">
8
+ <link rel="stylesheet" href="{{ url_for('static', path='css/chat.css') }}">
9
9
  {# Prism.js CSS for syntax highlighting (okaidia theme) #}
10
10
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/themes/prism-okaidia.min.css" referrerpolicy="no-referrer" />
11
11
  {# Inject active theme variables #}
@@ -34,25 +34,22 @@
34
34
  <hgroup>
35
35
  <h2>Flock Chat</h2>
36
36
  <h3>{{ chat_subtitle }}</h3>
37
- </hgroup>
38
- {% if not is_shared_chat %}
39
- <button class="secondary outline" hx-get="/chat/settings-standalone" hx-target="#chat-content-area" hx-swap="innerHTML" style="min-width:auto;">Settings</button>
37
+ </hgroup> {% if not is_shared_chat %}
38
+ <button class="secondary outline" hx-get="{{ url_for('chat_settings_standalone') }}" hx-target="#chat-content-area" hx-swap="innerHTML" style="min-width:auto;">Settings</button>
40
39
  {% else %}
41
40
  {# Optionally, could show a disabled settings button or some other indicator #}
42
41
  <span style="font-size: 0.8rem; color: var(--pico-muted-color);">Settings frozen for shared session.</span>
43
42
  {% endif %}
44
43
  </div>
45
44
 
46
- <div id="chat-content-area">
47
- <div id="chat-log"
48
- hx-get="{% if is_shared_chat %}/chat/messages-shared/{{ share_id }}{% else %}/chat/messages{% endif %}"
45
+ <div id="chat-content-area"> <div id="chat-log"
46
+ hx-get="{% if is_shared_chat %}{{ url_for('chat_history_shared_partial', share_id=share_id) }}{% else %}{{ url_for('chat_history_partial') }}{% endif %}"
49
47
  hx-trigger="load" {# Polling removed #}
50
48
  hx-swap="innerHTML">
51
49
  <p><em>Loading chat…</em></p>
52
50
  </div>
53
-
54
- <form id="chat-form-standalone"
55
- hx-post="{% if is_shared_chat %}/chat/send-shared{% else %}/chat/send{% endif %}"
51
+ <form id="chat-form-standalone"
52
+ hx-post="{% if is_shared_chat %}{{ url_for('chat_send_shared') }}{% else %}{{ url_for('chat_send') }}{% endif %}"
56
53
  hx-target="#chat-log"
57
54
  hx-swap="innerHTML"
58
55
  hx-disabled-elt="input[name='message'], button[type='submit']"
@@ -4,9 +4,8 @@
4
4
  <meta charset="UTF-8">
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
6
  <title>Chat Settings</title>
7
- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.min.css" />
8
- <link rel="stylesheet" href="/static/css/chat.css">
9
- <link rel="stylesheet" href="/static/css/header.css">
7
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.min.css" /> <link rel="stylesheet" href="{{ url_for('static', path='css/chat.css') }}">
8
+ <link rel="stylesheet" href="{{ url_for('static', path='css/header.css') }}">
10
9
  {# Active theme CSS #}
11
10
  {% if theme_css %}<style>{{ theme_css | safe }}</style>{% endif %}
12
11
  <script src="https://unpkg.com/htmx.org@1.9.10" crossorigin="anonymous"></script>
@@ -14,7 +13,7 @@
14
13
  <body class="chat-page">
15
14
  <main style="max-width: 700px; margin: 2rem auto;">
16
15
  {% include 'partials/_chat_settings_form.html' %}
17
- <p style="text-align:center; margin-top: 1rem;"><a href="/chat">← Back to Chat</a></p>
16
+ <p style="text-align:center; margin-top: 1rem;"><a href="{{ url_for('chat_page') }}">← Back to Chat</a></p>
18
17
  </main>
19
18
  </body>
20
19
  </html>
@@ -5,8 +5,7 @@
5
5
  {% block content %}
6
6
  {# Main content area is now loaded dynamically based on sidebar clicks #}
7
7
  {# We can load the properties form by default when this page is hit #}
8
- <div id="editor-main-content"
9
- hx-get="/ui/api/flock/htmx/flock-properties-form"
8
+ <div id="editor-main-content" hx-get="{{ url_for('htmx_get_flock_properties_form') }}"
10
9
  hx-trigger="load"
11
10
  hx-swap="innerHTML">
12
11
  <article>
@@ -5,7 +5,7 @@
5
5
  {% block content %}
6
6
  {# This content will be loaded dynamically via HTMX from the sidebar #}
7
7
  {# We can load the 'load/manage' view by default #}
8
- <div id="dashboard-content" hx-get="/ui/htmx/load-flock-view" hx-trigger="load" hx-swap="innerHTML">
8
+ <div id="dashboard-content" hx-get="{{ url_for('htmx_get_load_flock_view') }}" hx-trigger="load" hx-swap="innerHTML">
9
9
  <p>Loading dashboard content...</p>
10
10
  <progress></progress>
11
11
  </div>
@@ -11,12 +11,9 @@
11
11
  x-transition:leave-end="opacity-0">
12
12
  {{ form_message }}
13
13
  </div>
14
- {% endif %}
15
-
16
- <form {% if is_new %}
17
- hx-post="/ui/api/flock/htmx/agents"
18
- {% else %}
19
- hx-put="/ui/api/flock/htmx/agents/{{ agent.name if agent else '' }}"
14
+ {% endif %} <form {% if is_new %} hx-post="{{ url_for('htmx_create_agent') }}"
15
+ {% else %}
16
+ hx-put="{{ url_for('htmx_update_agent', original_agent_name=agent.name if agent else '') }}"
20
17
  {% endif %}
21
18
  hx-target="#agent-detail-form-content"
22
19
  hx-swap="innerHTML"
@@ -75,18 +72,15 @@
75
72
  <button type="submit">
76
73
  {% if is_new %}Create Agent{% else %}Save Changes{% endif %}
77
74
  </button>
78
- {% if not is_new and agent %}
79
- <button type="button" role="button" class="secondary outline"
80
- hx-delete="/ui/api/flock/htmx/agents/{{ agent.name }}"
81
- hx-target="#agent-detail-form-content"
75
+ {% if not is_new and agent %} <button type="button" role="button" class="secondary outline" hx-delete="{{ url_for('htmx_delete_agent', agent_name=agent.name) }}"
76
+ hx-target="#agent-detail-form-content"
82
77
  hx-confirm="Are you sure you want to delete agent '{{ agent.name }}'?"
83
78
  hx-indicator="#agent-detail-loading-indicator">
84
79
  Delete Agent
85
80
  </button>
86
81
  {% endif %}
87
- <button type="button" class="outline"
88
- hx-get="/ui/api/flock/htmx/agents/new-agent-form"
89
- hx-target="#agent-detail-panel"
82
+ <button type="button" class="outline" hx-get="{{ url_for('htmx_get_new_agent_form') }}"
83
+ hx-target="#agent-detail-panel"
90
84
  hx-swap="innerHTML"
91
85
  hx-indicator="#agent-detail-loading-indicator">
92
86
  Cancel / New Form
@@ -5,8 +5,7 @@
5
5
  {% endif %}
6
6
  {% if flock.agents %}
7
7
  <ul class="item-list">
8
- {% for agent_name, agent in flock.agents.items() %}
9
- <li hx-get="/ui/api/flock/htmx/agents/{{ agent.name }}/details-form" hx-target="#agent-detail-panel" hx-swap="innerHTML" hx-indicator="#agent-detail-loading" onclick="this.closest('ul').querySelectorAll('li').forEach(li => li.classList.remove('selected-item')); this.classList.add('selected-item');">
8
+ {% for agent_name, agent in flock.agents.items() %} <li hx-get="{{ url_for('htmx_get_agent_details_form', agent_name=agent.name) }}" hx-target="#agent-detail-panel" hx-swap="innerHTML" hx-indicator="#agent-detail-loading" onclick="this.closest('ul').querySelectorAll('li').forEach(li => li.classList.remove('selected-item')); this.classList.add('selected-item');">
10
9
  <strong>{{ agent.name }}</strong><br>
11
10
  <small>{{ agent.resolved_description|truncate(80) if agent.resolved_description else 'No description' }}</small>
12
11
  </li>
@@ -20,14 +20,13 @@
20
20
  <header class="grid">
21
21
  <h2>Agents ({{ flock.agents|length }}) </h2>
22
22
  <div style="text-align: right;">
23
- <button role="button" class="outline" hx-get="/ui/api/flock/htmx/agents/new-agent-form" hx-target="#agent-detail-panel" hx-swap="innerHTML">Add New Agent</button>
23
+ <button role="button" class="outline" hx-get="{{ url_for('htmx_get_new_agent_form') }}" hx-target="#agent-detail-panel" hx-swap="innerHTML">Add New Agent</button>
24
24
  </div>
25
25
 
26
26
  </header>
27
27
 
28
28
  {# Content of the left pane now goes into this article #}
29
- <div style="padding: var(--pico-block-spacing-vertical) var(--pico-block-spacing-horizontal); flex-grow: 1; display: flex; flex-direction: column;">
30
- <div hx-get="/ui/api/flock/htmx/agent-list"
29
+ <div style="padding: var(--pico-block-spacing-vertical) var(--pico-block-spacing-horizontal); flex-grow: 1; display: flex; flex-direction: column;"> <div hx-get="{{ url_for('htmx_get_agent_list') }}"
31
30
  hx-trigger="load, agentListChanged from:body"
32
31
  hx-swap="innerHTML"
33
32
  id="agent-list-panel"
@@ -1,9 +1,9 @@
1
1
  <article id="chat-container" class="chat-container">
2
- <div id="chat-log" hx-get="/chat/messages" hx-trigger="load" hx-swap="innerHTML">
2
+ <div id="chat-log" hx-get="{{ url_for('chat_history_partial') }}" hx-trigger="load" hx-swap="innerHTML">
3
3
  <p><em>Loading chat…</em></p>
4
4
  </div>
5
5
  <form id="chat-form-embedded" class="chat-form"
6
- hx-post="/chat/send"
6
+ hx-post="{{ url_for('chat_send') }}"
7
7
  hx-target="#chat-log"
8
8
  hx-swap="innerHTML"
9
9
  hx-disabled-elt="input[name='message'], button[type='submit']"
@@ -1,12 +1,11 @@
1
- <form class="chat-settings-form" hx-post="/chat/settings" hx-target="this" hx-swap="outerHTML" hx-indicator="#chat-settings-saving" style="max-width: 500px; margin: 1rem auto;">
1
+ <form class="chat-settings-form" hx-post="{{ url_for('chat_settings_submit') }}" hx-target="this" hx-swap="outerHTML" hx-indicator="#chat-settings-saving" style="max-width: 500px; margin: 1rem auto;">
2
2
  <hgroup style="margin-bottom: 1rem;">
3
3
  <h3>Chat Settings</h3>
4
4
  <h4>Select agent & field mappings</h4>
5
5
  </hgroup>
6
6
 
7
- <label for="agent_name_field">Chat Agent</label>
8
- <select id="agent_name_field" name="agent_name"
9
- hx-get="/chat/htmx/settings-form"
7
+ <label for="agent_name_field">Chat Agent</label> <select id="agent_name_field" name="agent_name"
8
+ hx-get="{{ url_for('htmx_chat_settings_partial') }}"
10
9
  hx-target="closest form"
11
10
  hx-trigger="change"
12
11
  hx-include="[name=agent_name]">
@@ -57,9 +56,8 @@
57
56
  {% endif %}
58
57
 
59
58
  <div class="grid" style="margin-top: 1rem;">
60
- <button type="submit">Save Settings</button>
61
- <button type="reset" class="outline">Reset</button>
62
- <button type="button" class="secondary outline" hx-get="/chat/htmx/chat-view" hx-target="#chat-content-area" hx-swap="innerHTML">Cancel</button>
59
+ <button type="submit">Save Settings</button> <button type="reset" class="outline">Reset</button>
60
+ <button type="button" class="secondary outline" hx-get="{{ url_for('htmx_chat_view') }}" hx-target="#chat-content-area" hx-swap="innerHTML">Cancel</button>
63
61
  </div>
64
62
  <div id="chat-settings-saving" class="htmx-indicator" style="text-align:center; margin-top:0.5rem;"><progress indeterminate></progress></div>
65
63
 
@@ -69,7 +67,7 @@
69
67
  <p><small>Create a shareable link for this chat configuration. The current Flock and these chat settings will be frozen for the shared session.</small></p>
70
68
  <a href="#"
71
69
  id="shareChatHtmxLink"
72
- hx-post="/ui/htmx/share/chat/generate-link"
70
+ hx-post="{{ url_for('htmx_generate_share_link') }}"
73
71
  hx-target="#shareChatLinkDisplayArea"
74
72
  hx-swap="innerHTML"
75
73
  hx-indicator="#share-chat-loading-indicator"
@@ -15,8 +15,7 @@
15
15
  {% endif %}
16
16
 
17
17
  <section id="create-by-details-section">
18
- <h4>Define New Flock Properties</h4>
19
- <form hx-post="/ui/create-flock"
18
+ <h4>Define New Flock Properties</h4> <form hx-post="{{ url_for('create_flock') }}"
20
19
  hx-target="#main-content-area" {# On success, loads properties form into main area #}
21
20
  hx-swap="innerHTML"
22
21
  hx-indicator="#create-indicator-details">
@@ -37,8 +36,7 @@
37
36
  <hr>
38
37
 
39
38
  <section id="create-by-upload-section">
40
- <h4>Upload Existing Flock File</h4>
41
- <form hx-post="/ui/load-flock-action/by-upload"
39
+ <h4>Upload Existing Flock File</h4> <form hx-post="{{ url_for('load_flock_by_upload') }}"
42
40
  hx-target="#main-content-area" {# On success, loads properties form into main area #}
43
41
  hx-swap="innerHTML"
44
42
  hx-encoding="multipart/form-data"
@@ -2,8 +2,7 @@
2
2
  <header>
3
3
  <h5>Flock File: <code>{{ selected_filename }}</code></h5>
4
4
  </header>
5
- <p>Details for this Flock file (e.g., size, last modified) could be shown here if fetched.</p>
6
- <form hx-post="/ui/load-flock-action/by-name"
5
+ <p>Details for this Flock file (e.g., size, last modified) could be shown here if fetched.</p> <form hx-post="{{ url_for('ui_load_flock_by_name_action') }}"
7
6
  hx-target="#main-content-area" {# Target the main area to show editor on success #}
8
7
  hx-swap="innerHTML"
9
8
  hx-indicator="#dashboard-flock-detail-loading-indicator">
@@ -14,5 +13,5 @@
14
13
  <hr>
15
14
  <p><small>Or, you can use the form below to upload a different Flock file.</small></p>
16
15
  {# Include the upload form again or link back to it #}
17
- <div hx-get="/ui/htmx/dashboard-upload-flock-form" hx-trigger="load" hx-swap="innerHTML"></div>
16
+ <div hx-get="{{ url_for('htmx_get_dashboard_upload_flock_form') }}" hx-trigger="load" hx-swap="innerHTML"></div>
18
17
  </article>
@@ -1,7 +1,6 @@
1
1
  {% if flock_files %}
2
2
  <ul class="item-list">
3
- {% for file_name in flock_files %}
4
- <li hx-get="/ui/htmx/dashboard-flock-properties-preview/{{ file_name }}"
3
+ {% for file_name in flock_files %} <li hx-get="{{ url_for('htmx_get_dashboard_flock_properties_preview', filename=file_name) }}"
5
4
  hx-target="#flock-properties-or-action-content" {# Target the right pane #}
6
5
  hx-swap="innerHTML"
7
6
  hx-indicator="#flock-properties-or-action-content progress"
@@ -6,8 +6,7 @@
6
6
  <p><strong>Default Model:</strong> {{ preview_flock.model or 'Not set' }}</p>
7
7
  <p><strong>Description:</strong> {{ preview_flock.description or 'None' }}</p>
8
8
  <p><strong>Agents:</strong> {{ preview_flock.agents_count }}</p>
9
-
10
- <form hx-post="/ui/load-flock-action/by-name"
9
+ <form hx-post="{{ url_for('ui_load_flock_by_name_action') }}"
11
10
  hx-target="#main-content-area" {# This will load the full editor for this flock #}
12
11
  hx-swap="innerHTML"
13
12
  hx-indicator="#flock-preview-loading-indicator">
@@ -18,7 +17,7 @@
18
17
  {% else %}
19
18
  <p class="error">Could not load preview for <code>{{ selected_filename }}</code>. It might be corrupted or not a valid Flock file.</p>
20
19
  <p><small>You can still attempt to load it into the editor.</small></p>
21
- <form hx-post="/ui/load-flock-action/by-name" hx-target="#main-content-area" hx-swap="innerHTML">
20
+ <form hx-post="{{ url_for('ui_load_flock_by_name_action') }}" hx-target="#main-content-area" hx-swap="innerHTML">
22
21
  <input type="hidden" name="selected_flock_filename" value="{{ selected_filename }}">
23
22
  <button type="submit" class="secondary">Attempt to Load into Editor</button>
24
23
  </form>
@@ -1,8 +1,7 @@
1
1
  <article>
2
2
  <header>
3
3
  <h5>Upload New Flock File</h5>
4
- </header>
5
- <form hx-post="/ui/load-flock-action/by-upload"
4
+ </header> <form hx-post="{{ url_for('load_flock_by_upload') }}"
6
5
  hx-target="#main-content-area" {# Target the main area to show editor on success #}
7
6
  hx-swap="innerHTML"
8
7
  hx-encoding="multipart/form-data"
@@ -11,11 +11,9 @@
11
11
  {% for var in env_vars %}
12
12
  <tr>
13
13
  <td>{{ var.name }}</td>
14
- <td>{{ var.value }}</td>
15
- <td>
16
- <button class="secondary small outline" hx-post="/ui/htmx/env-edit" hx-vals='{"var_name": "{{ var.name }}"}'
14
+ <td>{{ var.value }}</td> <td> <button class="secondary small outline" hx-post="{{ url_for('htmx_env_edit') }}" hx-vals='{"var_name": "{{ var.name }}"}'
17
15
  hx-prompt="Enter new value for {{ var.name }}" hx-target="#env-vars-container" hx-swap="outerHTML">Edit</button>
18
- <button class="contrast small outline" hx-post="/ui/htmx/env-delete" hx-vals='{"var_name": "{{ var.name }}"}'
16
+ <button class="contrast small outline" hx-post="{{ url_for('htmx_env_delete') }}" hx-vals='{"var_name": "{{ var.name }}"}'
19
17
  hx-confirm="Delete {{ var.name }}?" hx-target="#env-vars-container" hx-swap="outerHTML" style="margin-left:0.25rem;">Delete</button>
20
18
  </td>
21
19
  </tr>
@@ -1,10 +1,14 @@
1
+ <script>
2
+ // Create URL template for agent input forms
3
+ window.agentInputFormUrlTemplate = '{{ url_for("htmx_get_agent_input_form", agent_name="AGENT_PLACEHOLDER") }}';
4
+ </script>
5
+
1
6
  <article id="execution-form-content">
2
7
  <header>
3
8
  <h2>Run Flock</h2>
4
9
  </header>
5
- {% if flock and flock.agents %}
6
- <form hx-post="/ui/api/flock/htmx/run"
7
- hx-target="#results-display"
10
+ {% if flock and flock.agents %} <form hx-post="{{ url_for('htmx_run_flock') }}"
11
+ hx-target="#results-display"
8
12
  hx-swap="innerHTML"
9
13
  hx-indicator="#run-loading-indicator"
10
14
  x-data="{ selectedAgentForInput: '' }">
@@ -12,11 +16,10 @@
12
16
  <label for="start_agent_name_select">Select Start Agent:</label>
13
17
  <select id="start_agent_name_select"
14
18
  name="start_agent_name"
15
- required
16
- x-model="selectedAgentForInput"
17
- @change="
19
+ required x-model="selectedAgentForInput" @change="
18
20
  if ($event.target.value) {
19
- htmx.ajax('GET', '/ui/api/flock/htmx/agents/' + $event.target.value + '/input-form', {target: '#dynamic-input-form-fields', swap: 'innerHTML', indicator: '#input-form-loading-indicator'});
21
+ const url = window.agentInputFormUrlTemplate.replace('AGENT_PLACEHOLDER', $event.target.value);
22
+ htmx.ajax('GET', url, {target: '#dynamic-input-form-fields', swap: 'innerHTML', indicator: '#input-form-loading-indicator'});
20
23
  } else {
21
24
  document.getElementById('dynamic-input-form-fields').innerHTML = '<p><small>Select an agent to see its input fields.</small></p>';
22
25
  }
@@ -37,10 +40,9 @@
37
40
 
38
41
  <button type="submit" {% if not flock.agents %}disabled{% endif %}>Run Flock</button>
39
42
 
40
- <div id="share-agent-link-container" style="margin-top: 0.5rem;">
41
- <a href="#"
43
+ <div id="share-agent-link-container" style="margin-top: 0.5rem;"> <a href="#"
42
44
  id="shareAgentHtmxLink"
43
- hx-post="/ui/htmx/share/generate-link"
45
+ hx-post="{{ url_for('htmx_generate_share_link') }}"
44
46
  hx-target="#shareLinkDisplayArea"
45
47
  hx-swap="innerHTML"
46
48
  hx-indicator="#share-loading-indicator"
@@ -1,14 +1,22 @@
1
- <article class="two-pane-flex-container">
2
- <section id="execution-left-pane" style="flex: 1; min-width: 300px;">
3
- {# The Execution Form will be loaded here #}
4
- <div id="execution-form-wrapper" hx-get="/ui/api/flock/htmx/execution-form-content" {# New endpoint for just the
5
- form #} hx-trigger="load" hx-swap="innerHTML">
1
+ <article class="two-pane-flex-container" x-data="{ showLeftPane: true }">
2
+ <!-- Left pane - collapsed state -->
3
+ <div class="left-pane-collapsed" x-show="!showLeftPane" style="display: none;">
4
+ <a href="#" class="pane-toggle" @click.prevent="showLeftPane = true" aria-label="Expand left pane">Show</a>
5
+ </div>
6
+
7
+ <!-- Left pane - expanded state -->
8
+ <section id="execution-left-pane" x-show="showLeftPane" style="flex: 1; min-width: 200px; max-width: 500px;">
9
+ <div class="pane-header" style="display: flex; justify-content: flex-end; margin-bottom: 10px;">
10
+ <a href="#" class="pane-toggle" @click.prevent="showLeftPane = false" aria-label="Hide left pane">Hide</a>
11
+ </div>
12
+ {# The Execution Form will be loaded here #} <div id="execution-form-wrapper" hx-get="{{ url_for('htmx_get_execution_form_content') }}"
13
+ hx-trigger="load" hx-swap="innerHTML">
6
14
  <p>Loading execution form...</p><progress indeterminate></progress>
7
15
  </div>
8
16
  </section>
9
17
 
10
18
  <section id="execution-right-pane" class="right-pane-framed"
11
- style="flex: 2; border-left: 1px solid var(--pico-muted-border-color); padding-left: 1.5rem;">
19
+ :style="showLeftPane ? 'flex: 2; border-left: 1px solid var(--pico-muted-border-color); padding-left: 1.5rem;' : 'flex: 1; border-left: none; padding-left: 0;'">
12
20
  {# The Results Display area, always present when this container is loaded #}
13
21
  <header style=" border-bottom: 1px solid var(--pico-muted-border-color); margin-bottom: 1rem;">
14
22
  <h5>Execution Results</h5>
@@ -1,7 +1,6 @@
1
1
  {% if flock_files %}
2
2
  <ul class="item-list">
3
- {% for file_name in flock_files %}
4
- <li hx-post="/ui/load-flock-action/by-name"
3
+ {% for file_name in flock_files %} <li hx-post="{{ url_for('ui_load_flock_by_name_action') }}"
5
4
  hx-vals='{"selected_flock_filename": "{{ file_name }}"}'
6
5
  {# After successful load, the main.py route for by-name will now return
7
6
  the flock properties form targeted to the main content area AND
@@ -13,7 +12,7 @@
13
12
  hx-target="#main-content-area" {# This will load the editor page content #}
14
13
  hx-swap="innerHTML"
15
14
  hx-indicator="#flock-file-list-loading-indicator"
16
- hx-push-url="/ui/editor/properties"> {# Push URL to editor after load #}
15
+ hx-push-url="{{ url_for('page_editor_section', ui_mode='properties') }}"> {# Push URL to editor after load #}
17
16
  {{ file_name }}
18
17
  </li>
19
18
  {% endfor %}
@@ -23,7 +23,7 @@
23
23
  </div>
24
24
  {% endif %}
25
25
 
26
- <form hx-post="/ui/api/flock/htmx/flock-properties" hx-target="#flock-properties-form-article" hx-swap="innerHTML" hx-indicator="#flock-props-loading">
26
+ <form hx-post="{{ url_for('htmx_update_flock_properties') }}" hx-target="#flock-properties-form-article" hx-swap="innerHTML" hx-indicator="#flock-props-loading">
27
27
  <label for="flock_name">Flock Name</label>
28
28
  <input type="text" id="flock_name" name="flock_name" value="{{ flock.name if flock else '' }}" required>
29
29
 
@@ -38,7 +38,7 @@
38
38
  </div>
39
39
  </form>
40
40
  <hr>
41
- <form hx-post="/ui/api/flock/htmx/save-flock" hx-target="#flock-properties-form-article" hx-swap="innerHTML" hx-indicator="#flock-save-loading">
41
+ <form hx-post="{{ url_for('htmx_save_flock') }}" hx-target="#flock-properties-form-article" hx-swap="innerHTML" hx-indicator="#flock-save-loading">
42
42
  <label for="save_filename">Save Flock As:</label>
43
43
  <input type="text" id="save_filename" name="save_filename"
44
44
  value="{{ current_filename if current_filename else (flock.name.replace(' ', '_').lower() + '.flock.yaml' if flock and flock.name else 'my_flock.flock.yaml') }}"
@@ -1,8 +1,7 @@
1
1
  <article>
2
2
  <header>
3
3
  <h5>Upload New Flock File</h5>
4
- </header>
5
- <form hx-post="/ui/load-flock-action/by-upload"
4
+ </header> <form hx-post="{{ url_for('load_flock_by_upload') }}"
6
5
  hx-target="#main-content-area" {# After upload, go to editor #}
7
6
  hx-swap="innerHTML"
8
7
  hx-encoding="multipart/form-data"
@@ -20,12 +20,11 @@
20
20
  <header class="grid">
21
21
  <h2>Load Flock</h2> {# Moved title here #}
22
22
  <div style="text-align: right;">
23
- <button role="button" class="outline" hx-get="/ui/htmx/create-flock-form?ui_mode={{ ui_mode }}" hx-target="#flock-properties-or-action-content" hx-swap="innerHTML">Add New Flock</button>
23
+ <button role="button" class="outline" hx-get="{{ url_for('htmx_get_create_flock_form') }}?ui_mode={{ ui_mode }}" hx-target="#flock-properties-or-action-content" hx-swap="innerHTML">Add New Flock</button>
24
24
  </div>
25
25
  </header>
26
26
  {# Content of the left pane now goes into this article #}
27
- <div style="padding: var(--pico-block-spacing-vertical) var(--pico-block-spacing-horizontal); flex-grow: 1; display: flex; flex-direction: column;">
28
- <div hx-get="/ui/htmx/dashboard-flock-file-list"
27
+ <div style="padding: var(--pico-block-spacing-vertical) var(--pico-block-spacing-horizontal); flex-grow: 1; display: flex; flex-direction: column;"> <div hx-get="{{ url_for('htmx_get_dashboard_flock_file_list_partial') }}"
29
28
  hx-trigger="load, flockFileListChanged from:body"
30
29
  hx-swap="innerHTML"
31
30
  id="dashboard-flock-file-list-target"
@@ -5,19 +5,18 @@
5
5
  </header>
6
6
 
7
7
  <nav>
8
- <ul role="group">
9
- <li>
10
- <button role="button" class="outline" hx-get="/ui/api/registry/htmx/type/table" hx-target="#registry-table-container" hx-indicator="#registry-loading" hx-on:click="setActiveButton(this)">
8
+ <ul role="group"> <li>
9
+ <button role="button" class="outline" hx-get="{{ url_for('htmx_get_registry_table', item_type='type') }}" hx-target="#registry-table-container" hx-indicator="#registry-loading" hx-on:click="setActiveButton(this)">
11
10
  View Types
12
11
  </button>
13
12
  </li>
14
13
  <li>
15
- <button role="button" class="outline" hx-get="/ui/api/registry/htmx/tool/table" hx-target="#registry-table-container" hx-indicator="#registry-loading" hx-on:click="setActiveButton(this)">
14
+ <button role="button" class="outline" hx-get="{{ url_for('htmx_get_registry_table', item_type='tool') }}" hx-target="#registry-table-container" hx-indicator="#registry-loading" hx-on:click="setActiveButton(this)">
16
15
  View Tools/Callables
17
16
  </button>
18
17
  </li>
19
18
  <li>
20
- <button role="button" class="outline" hx-get="/ui/api/registry/htmx/component/table" hx-target="#registry-table-container" hx-indicator="#registry-loading" hx-on:click="setActiveButton(this)">
19
+ <button role="button" class="outline" hx-get="{{ url_for('htmx_get_registry_table', item_type='component') }}" hx-target="#registry-table-container" hx-indicator="#registry-loading" hx-on:click="setActiveButton(this)">
21
20
  View Components
22
21
  </button>
23
22
  </li>
@@ -1,10 +1,9 @@
1
1
  <article>
2
2
  <h3>Environment Variables</h3>
3
- <div style="display:flex; gap:0.5rem; flex-wrap:wrap;">
4
- <button class="outline small" id="toggle-secrets-btn" hx-post="/ui/htmx/toggle-show-secrets" hx-target="#env-vars-container" hx-swap="outerHTML">
3
+ <div style="display:flex; gap:0.5rem; flex-wrap:wrap;"> <button class="outline small" id="toggle-secrets-btn" hx-post="{{ url_for('htmx_toggle_show_secrets') }}" hx-target="#env-vars-container" hx-swap="outerHTML">
5
4
  {% if show_secrets %}Hide Secrets{% else %}Show Secrets{% endif %}
6
5
  </button>
7
- <button class="outline small" hx-get="/ui/htmx/env-add-form" hx-target="#env-vars-container" hx-swap="afterbegin">Add Variable</button>
6
+ <button class="outline small" hx-get="{{ url_for('htmx_env_add_form') }}" hx-target="#env-vars-container" hx-swap="afterbegin">Add Variable</button>
8
7
  </div>
9
8
  {% include 'partials/_env_vars_table.html' %}
10
9
  </article>
@@ -2,12 +2,12 @@
2
2
  <h3>Theme Switcher</h3>
3
3
  <div style="display:flex; gap:0.5rem; flex-wrap:wrap; align-items:center;">
4
4
  <label for="theme-select" style="margin:0;">Select Theme:</label>
5
- <select id="theme-select" name="theme" hx-get="/ui/htmx/theme-preview" hx-target="#theme-preview" hx-trigger="load, change" hx-include="#theme-select">
5
+ <select id="theme-select" name="theme" hx-get="{{ url_for('htmx_theme_preview') }}" hx-target="#theme-preview" hx-trigger="load, change" hx-include="#theme-select">
6
6
  {% for t in themes %}
7
7
  <option value="{{ t }}" {% if t == current_theme %}selected{% endif %}>{{ t }}</option>
8
8
  {% endfor %}
9
9
  </select>
10
- <button class="small" hx-post="/ui/apply-theme" hx-target="body" hx-include="#theme-select" hx-swap="none">Apply</button>
10
+ <button class="small" hx-post="{{ url_for('apply_theme') }}" hx-target="body" hx-include="#theme-select" hx-swap="none">Apply</button>
11
11
  </div>
12
12
  <div id="theme-preview" style="margin-top:1rem;">
13
13
  <!-- Preview generated by theme-preview endpoint -->
@@ -6,10 +6,10 @@
6
6
  <nav>
7
7
  <ul role="group">
8
8
  <li>
9
- <button role="button" class="primary" hx-get="/ui/htmx/settings/env-vars" hx-target="#settings-content-container" hx-indicator="#settings-loading" hx-on:click="setActiveButton(this)">Environment</button>
9
+ <button role="button" class="primary" hx-get="{{ url_for('htmx_settings_env_vars') }}" hx-target="#settings-content-container" hx-indicator="#settings-loading" hx-on:click="setActiveButton(this)">Environment</button>
10
10
  </li>
11
11
  <li>
12
- <button role="button" class="outline" hx-get="/ui/htmx/settings/theme" hx-target="#settings-content-container" hx-indicator="#settings-loading" hx-on:click="setActiveButton(this)">Theme</button>
12
+ <button role="button" class="outline" hx-get="{{ url_for('htmx_settings_theme') }}" hx-target="#settings-content-container" hx-indicator="#settings-loading" hx-on:click="setActiveButton(this)">Theme</button>
13
13
  </li>
14
14
  </ul>
15
15
  </nav>