flock-core 0.5.0b65__py3-none-any.whl → 0.5.0b71__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 (56) hide show
  1. flock/cli.py +74 -2
  2. flock/engines/dspy_engine.py +41 -5
  3. flock/examples.py +4 -1
  4. flock/frontend/README.md +15 -1
  5. flock/frontend/package-lock.json +2 -2
  6. flock/frontend/package.json +1 -1
  7. flock/frontend/src/App.tsx +74 -6
  8. flock/frontend/src/__tests__/e2e/critical-scenarios.test.tsx +4 -5
  9. flock/frontend/src/__tests__/integration/filtering-e2e.test.tsx +7 -3
  10. flock/frontend/src/components/filters/ArtifactTypeFilter.tsx +21 -0
  11. flock/frontend/src/components/filters/FilterFlyout.module.css +104 -0
  12. flock/frontend/src/components/filters/FilterFlyout.tsx +80 -0
  13. flock/frontend/src/components/filters/FilterPills.module.css +186 -45
  14. flock/frontend/src/components/filters/FilterPills.test.tsx +115 -99
  15. flock/frontend/src/components/filters/FilterPills.tsx +120 -44
  16. flock/frontend/src/components/filters/ProducerFilter.tsx +21 -0
  17. flock/frontend/src/components/filters/SavedFiltersControl.module.css +60 -0
  18. flock/frontend/src/components/filters/SavedFiltersControl.test.tsx +158 -0
  19. flock/frontend/src/components/filters/SavedFiltersControl.tsx +159 -0
  20. flock/frontend/src/components/filters/TagFilter.tsx +21 -0
  21. flock/frontend/src/components/filters/TimeRangeFilter.module.css +24 -0
  22. flock/frontend/src/components/filters/TimeRangeFilter.tsx +6 -1
  23. flock/frontend/src/components/filters/VisibilityFilter.tsx +21 -0
  24. flock/frontend/src/components/graph/GraphCanvas.tsx +24 -0
  25. flock/frontend/src/components/layout/DashboardLayout.css +13 -0
  26. flock/frontend/src/components/layout/DashboardLayout.tsx +8 -24
  27. flock/frontend/src/components/modules/HistoricalArtifactsModule.module.css +288 -0
  28. flock/frontend/src/components/modules/HistoricalArtifactsModule.tsx +460 -0
  29. flock/frontend/src/components/modules/HistoricalArtifactsModuleWrapper.tsx +13 -0
  30. flock/frontend/src/components/modules/ModuleRegistry.ts +7 -1
  31. flock/frontend/src/components/modules/registerModules.ts +9 -10
  32. flock/frontend/src/hooks/useModules.ts +11 -1
  33. flock/frontend/src/services/api.ts +140 -0
  34. flock/frontend/src/services/indexeddb.ts +56 -2
  35. flock/frontend/src/services/websocket.ts +129 -0
  36. flock/frontend/src/store/filterStore.test.ts +105 -185
  37. flock/frontend/src/store/filterStore.ts +173 -26
  38. flock/frontend/src/store/graphStore.test.ts +19 -0
  39. flock/frontend/src/store/graphStore.ts +166 -27
  40. flock/frontend/src/types/filters.ts +34 -1
  41. flock/frontend/src/types/graph.ts +7 -0
  42. flock/frontend/src/utils/artifacts.ts +24 -0
  43. flock/orchestrator.py +23 -1
  44. flock/service.py +146 -9
  45. flock/store.py +971 -24
  46. {flock_core-0.5.0b65.dist-info → flock_core-0.5.0b71.dist-info}/METADATA +26 -1
  47. {flock_core-0.5.0b65.dist-info → flock_core-0.5.0b71.dist-info}/RECORD +50 -43
  48. flock/frontend/src/components/filters/FilterBar.module.css +0 -29
  49. flock/frontend/src/components/filters/FilterBar.test.tsx +0 -133
  50. flock/frontend/src/components/filters/FilterBar.tsx +0 -33
  51. flock/frontend/src/components/modules/EventLogModule.test.tsx +0 -401
  52. flock/frontend/src/components/modules/EventLogModule.tsx +0 -396
  53. flock/frontend/src/components/modules/EventLogModuleWrapper.tsx +0 -17
  54. {flock_core-0.5.0b65.dist-info → flock_core-0.5.0b71.dist-info}/WHEEL +0 -0
  55. {flock_core-0.5.0b65.dist-info → flock_core-0.5.0b71.dist-info}/entry_points.txt +0 -0
  56. {flock_core-0.5.0b65.dist-info → flock_core-0.5.0b71.dist-info}/licenses/LICENSE +0 -0
@@ -17,6 +17,7 @@ import MessageFlowEdge from './MessageFlowEdge';
17
17
  import TransformEdge from './TransformEdge';
18
18
  import MiniMap from './MiniMap';
19
19
  import { useGraphStore } from '../../store/graphStore';
20
+ import { useFilterStore } from '../../store/filterStore';
20
21
  import { useUIStore } from '../../store/uiStore';
21
22
  import { useModuleStore } from '../../store/moduleStore';
22
23
  import { useSettingsStore } from '../../store/settingsStore';
@@ -44,6 +45,14 @@ const GraphCanvas: React.FC = () => {
44
45
  const generateBlackboardViewGraph = useGraphStore((state) => state.generateBlackboardViewGraph);
45
46
  const updateNodePosition = useGraphStore((state) => state.updateNodePosition);
46
47
  const addModule = useModuleStore((state) => state.addModule);
48
+ const applyFilters = useGraphStore((state) => state.applyFilters);
49
+
50
+ const correlationId = useFilterStore((state) => state.correlationId);
51
+ const timeRange = useFilterStore((state) => state.timeRange);
52
+ const selectedArtifactTypes = useFilterStore((state) => state.selectedArtifactTypes);
53
+ const selectedProducers = useFilterStore((state) => state.selectedProducers);
54
+ const selectedTags = useFilterStore((state) => state.selectedTags);
55
+ const selectedVisibility = useFilterStore((state) => state.selectedVisibility);
47
56
 
48
57
  // Graph settings from settings store
49
58
  const edgeType = useSettingsStore((state) => state.graph.edgeType);
@@ -93,6 +102,21 @@ const GraphCanvas: React.FC = () => {
93
102
  }
94
103
  }, [edgeType, edgeStrokeWidth, edgeAnimation, mode, generateAgentViewGraph, generateBlackboardViewGraph]);
95
104
 
105
+ // Apply filters whenever filter store state changes
106
+ useEffect(() => {
107
+ applyFilters();
108
+ }, [
109
+ applyFilters,
110
+ correlationId,
111
+ timeRange.preset,
112
+ timeRange.start,
113
+ timeRange.end,
114
+ selectedArtifactTypes.join('|'),
115
+ selectedProducers.join('|'),
116
+ selectedTags.join('|'),
117
+ selectedVisibility.join('|'),
118
+ ]);
119
+
96
120
  const onNodesChange = useCallback(
97
121
  (changes: NodeChange[]) => {
98
122
  const updatedNodes = applyNodeChanges(changes, nodes);
@@ -29,6 +29,19 @@
29
29
  z-index: 100;
30
30
  }
31
31
 
32
+ .filter-pills-bar {
33
+ position: relative;
34
+ padding: var(--spacing-1-5) var(--space-layout-md);
35
+ background: color-mix(in srgb, var(--color-bg-overlay) 65%, transparent);
36
+ border-bottom: var(--border-subtle);
37
+ backdrop-filter: blur(var(--blur-sm));
38
+ min-height: 0;
39
+ display: flex;
40
+ align-items: center;
41
+ gap: var(--gap-md);
42
+ z-index: 90;
43
+ }
44
+
32
45
  .dashboard-title {
33
46
  margin: 0;
34
47
  font-size: var(--font-size-h3);
@@ -2,7 +2,8 @@ import React, { useState } from 'react';
2
2
  import { ReactFlowProvider } from '@xyflow/react';
3
3
  import GraphCanvas from '../graph/GraphCanvas';
4
4
  import DetailWindowContainer from '../details/DetailWindowContainer';
5
- import FilterBar from '../filters/FilterBar';
5
+ import FilterFlyout from '../filters/FilterFlyout';
6
+ import FilterPills from '../filters/FilterPills';
6
7
  import PublishControl from '../controls/PublishControl';
7
8
  import ModuleWindow from '../modules/ModuleWindow';
8
9
  import SettingsPanel from '../settings/SettingsPanel';
@@ -169,27 +170,6 @@ const DashboardLayout: React.FC = () => {
169
170
  <span>Agent Details</span>
170
171
  </button>
171
172
 
172
- {/* Filter */}
173
- <button
174
- type="button"
175
- onClick={() => setShowFilters(!showFilters)}
176
- className={`controls-toggle ${showFilters ? 'active' : ''}`}
177
- title={`${showFilters ? 'Hide' : 'Show'} filter panel (Ctrl+Shift+F)`}
178
- aria-pressed={showFilters ? 'true' : 'false'}
179
- aria-label={showFilters ? 'Filters shown' : 'Filters hidden'}
180
- >
181
- <svg width="16" height="16" viewBox="0 0 16 16" fill="none">
182
- <path
183
- d="M2.667 2.667h10.666L9.333 7v4.667l-2.666 1.333V7L2.667 2.667z"
184
- stroke="currentColor"
185
- strokeWidth="1.5"
186
- strokeLinecap="round"
187
- strokeLinejoin="round"
188
- />
189
- </svg>
190
- <span>Filter</span>
191
- </button>
192
-
193
173
  {/* Settings */}
194
174
  <button
195
175
  type="button"
@@ -261,8 +241,12 @@ const DashboardLayout: React.FC = () => {
261
241
  </div>
262
242
  </header>
263
243
 
264
- {/* Filter Bar - Collapsible */}
265
- {showFilters && <FilterBar />}
244
+ <div className="filter-pills-bar">
245
+ <FilterPills />
246
+ </div>
247
+
248
+ {/* Filter Flyout */}
249
+ {showFilters && <FilterFlyout onClose={() => setShowFilters(false)} />}
266
250
 
267
251
  {/* Main Content */}
268
252
  <div className="dashboard-main">
@@ -0,0 +1,288 @@
1
+ .container {
2
+ display: flex;
3
+ flex-direction: column;
4
+ gap: var(--space-layout-sm);
5
+ height: 100%;
6
+ padding: var(--space-layout-sm);
7
+ background: var(--color-bg-surface);
8
+ }
9
+
10
+ .header {
11
+ display: flex;
12
+ align-items: center;
13
+ justify-content: space-between;
14
+ gap: var(--gap-sm);
15
+ }
16
+
17
+ .metrics {
18
+ display: flex;
19
+ gap: var(--gap-lg);
20
+ flex-wrap: wrap;
21
+ }
22
+
23
+ .metricLabel {
24
+ display: block;
25
+ font-size: var(--font-size-overline);
26
+ color: var(--color-text-tertiary);
27
+ text-transform: uppercase;
28
+ letter-spacing: var(--letter-spacing-wider);
29
+ }
30
+
31
+ .metricValue {
32
+ font-size: var(--font-size-body-md);
33
+ font-weight: var(--font-weight-semibold);
34
+ color: var(--color-text-primary);
35
+ }
36
+
37
+ .actions {
38
+ display: flex;
39
+ gap: var(--gap-sm);
40
+ }
41
+
42
+ .actions button {
43
+ padding: var(--spacing-1) var(--spacing-3);
44
+ border-radius: var(--radius-sm);
45
+ border: none;
46
+ cursor: pointer;
47
+ background: rgba(99, 102, 241, 0.25);
48
+ color: var(--color-text-primary);
49
+ transition: background-color var(--duration-fast) ease;
50
+ }
51
+
52
+ .actions button:disabled {
53
+ opacity: 0.5;
54
+ cursor: not-allowed;
55
+ }
56
+
57
+ .actions button:hover:not(:disabled) {
58
+ background: rgba(99, 102, 241, 0.45);
59
+ }
60
+
61
+ .tableContainer {
62
+ display: flex;
63
+ flex-direction: column;
64
+ background: rgba(15, 23, 42, 0.6);
65
+ border: 1px solid rgba(148, 163, 184, 0.1);
66
+ border-radius: var(--radius-md);
67
+ overflow: hidden;
68
+ flex: 2 1 0;
69
+ min-height: 0;
70
+ }
71
+
72
+ .contentArea {
73
+ display: flex;
74
+ gap: var(--space-layout-sm);
75
+ flex: 1;
76
+ min-height: 0;
77
+ }
78
+
79
+ .detailPanel {
80
+ flex: 1 1 0;
81
+ background: rgba(15, 23, 42, 0.5);
82
+ border: 1px solid rgba(148, 163, 184, 0.15);
83
+ border-radius: var(--radius-md);
84
+ padding: var(--spacing-3);
85
+ display: flex;
86
+ flex-direction: column;
87
+ gap: var(--gap-md);
88
+ max-height: 100%;
89
+ overflow-y: auto;
90
+ }
91
+
92
+ .headerRow,
93
+ .dataRow {
94
+ display: grid;
95
+ grid-template-columns: 200px 140px 160px 180px 160px 120px 100px;
96
+ gap: var(--gap-sm);
97
+ padding: var(--spacing-2) var(--spacing-3);
98
+ font-size: var(--font-size-body-xs);
99
+ align-items: center;
100
+ }
101
+
102
+ .headerRow {
103
+ background: rgba(148, 163, 184, 0.1);
104
+ font-weight: var(--font-weight-semibold);
105
+ text-transform: uppercase;
106
+ letter-spacing: var(--letter-spacing-wide);
107
+ }
108
+
109
+ .dataRow {
110
+ border-bottom: 1px solid rgba(148, 163, 184, 0.08);
111
+ }
112
+
113
+ .virtualViewport {
114
+ overflow-y: auto;
115
+ }
116
+
117
+ .dataRowStripe {
118
+ background: rgba(148, 163, 184, 0.05);
119
+ }
120
+
121
+ .dataRow {
122
+ cursor: pointer;
123
+ transition: background-color var(--duration-fast) ease;
124
+ }
125
+
126
+ .dataRow:focus-visible {
127
+ outline: 2px solid var(--color-primary-400);
128
+ outline-offset: 2px;
129
+ }
130
+
131
+ .dataRowSelected {
132
+ background: rgba(99, 102, 241, 0.25);
133
+ border-left: 3px solid var(--color-primary-400);
134
+ }
135
+
136
+ .dataRowSelected span {
137
+ color: var(--color-text-primary);
138
+ }
139
+
140
+ .emptyState,
141
+ .loading,
142
+ .error {
143
+ padding: var(--spacing-4);
144
+ text-align: center;
145
+ color: var(--color-text-secondary);
146
+ }
147
+
148
+ .error {
149
+ color: var(--color-error);
150
+ }
151
+
152
+ .retentionBanner {
153
+ display: flex;
154
+ flex-direction: column;
155
+ gap: var(--gap-xs);
156
+ background: rgba(148, 163, 184, 0.08);
157
+ border: 1px solid rgba(148, 163, 184, 0.15);
158
+ border-radius: var(--radius-sm);
159
+ padding: var(--spacing-2) var(--spacing-3);
160
+ font-size: var(--font-size-body-xs);
161
+ color: var(--color-text-secondary);
162
+ }
163
+
164
+ .retentionBanner strong {
165
+ color: var(--color-text-primary);
166
+ font-weight: var(--font-weight-semibold);
167
+ }
168
+
169
+ @media (max-width: 1280px) {
170
+ .contentArea {
171
+ flex-direction: column;
172
+ }
173
+
174
+ .detailPanel {
175
+ max-height: none;
176
+ }
177
+ }
178
+
179
+ .detailHeader {
180
+ display: flex;
181
+ align-items: flex-start;
182
+ justify-content: space-between;
183
+ gap: var(--gap-sm);
184
+ }
185
+
186
+ .detailHeader h3 {
187
+ margin: 0;
188
+ font-size: var(--font-size-body-lg);
189
+ color: var(--color-text-primary);
190
+ }
191
+
192
+ .detailHeader p {
193
+ margin: 0;
194
+ font-size: var(--font-size-body-xs);
195
+ color: var(--color-text-secondary);
196
+ }
197
+
198
+ .detailHeader button {
199
+ padding: var(--spacing-1) var(--spacing-3);
200
+ border-radius: var(--radius-sm);
201
+ border: none;
202
+ cursor: pointer;
203
+ background: rgba(99, 102, 241, 0.2);
204
+ color: var(--color-primary-50);
205
+ font-size: var(--font-size-body-xs);
206
+ text-transform: uppercase;
207
+ letter-spacing: var(--letter-spacing-wide);
208
+ }
209
+
210
+ .detailHeader button:hover {
211
+ background: rgba(99, 102, 241, 0.35);
212
+ }
213
+
214
+ .detailSection {
215
+ display: flex;
216
+ flex-direction: column;
217
+ gap: var(--gap-sm);
218
+ }
219
+
220
+ .detailSection h4 {
221
+ margin: 0;
222
+ font-size: var(--font-size-body-sm);
223
+ color: var(--color-text-secondary);
224
+ text-transform: uppercase;
225
+ letter-spacing: var(--letter-spacing-wide);
226
+ }
227
+
228
+ .detailList {
229
+ display: grid;
230
+ grid-template-columns: minmax(110px, 0.45fr) 1fr;
231
+ gap: var(--gap-xs) var(--gap-sm);
232
+ font-size: var(--font-size-body-xs);
233
+ }
234
+
235
+ .detailList dt {
236
+ color: var(--color-text-tertiary);
237
+ font-weight: var(--font-weight-semibold);
238
+ }
239
+
240
+ .detailList dd {
241
+ margin: 0;
242
+ color: var(--color-text-primary);
243
+ word-break: break-word;
244
+ }
245
+
246
+ .consumptionList {
247
+ list-style: none;
248
+ padding: 0;
249
+ margin: 0;
250
+ display: flex;
251
+ flex-direction: column;
252
+ gap: var(--gap-xs);
253
+ }
254
+
255
+ .consumptionList li {
256
+ display: flex;
257
+ flex-direction: column;
258
+ gap: 2px;
259
+ padding: var(--spacing-2);
260
+ border: 1px solid rgba(148, 163, 184, 0.18);
261
+ border-radius: var(--radius-sm);
262
+ background: rgba(30, 41, 59, 0.55);
263
+ }
264
+
265
+ .consumerName {
266
+ font-weight: var(--font-weight-semibold);
267
+ color: var(--color-text-primary);
268
+ }
269
+
270
+ .runBadge {
271
+ display: inline-flex;
272
+ align-items: center;
273
+ justify-content: center;
274
+ align-self: flex-start;
275
+ padding: 2px 6px;
276
+ border-radius: var(--radius-xs);
277
+ font-size: var(--font-size-caption);
278
+ background: rgba(99, 102, 241, 0.25);
279
+ color: var(--color-primary-100);
280
+ margin-top: 2px;
281
+ }
282
+
283
+ .emptyDetail,
284
+ .emptyConsumption {
285
+ font-size: var(--font-size-body-sm);
286
+ color: var(--color-text-secondary);
287
+ margin: 0;
288
+ }