openwork 0.1.4 → 0.2.0
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.
package/README.md
CHANGED
|
@@ -44,7 +44,7 @@ Or configure them in-app via the settings panel.
|
|
|
44
44
|
| --------- | -------------------------------------------------------------------------------------- |
|
|
45
45
|
| Anthropic | Claude Opus 4.5, Claude Sonnet 4.5, Claude Haiku 4.5, Claude Opus 4.1, Claude Sonnet 4 |
|
|
46
46
|
| OpenAI | GPT-5.2, GPT-5.1, o3, o3 Mini, o4 Mini, o1, GPT-4.1, GPT-4o |
|
|
47
|
-
| Google | Gemini 3 Pro Preview, Gemini 2.5 Pro, Gemini 2.5 Flash, Gemini 2.5 Flash Lite
|
|
47
|
+
| Google | Gemini 3 Pro Preview, Gemini 3 Flash Preview, Gemini 2.5 Pro, Gemini 2.5 Flash, Gemini 2.5 Flash Lite |
|
|
48
48
|
|
|
49
49
|
## Contributing
|
|
50
50
|
|
|
@@ -541,6 +541,11 @@
|
|
|
541
541
|
display: inline-flex;
|
|
542
542
|
}
|
|
543
543
|
|
|
544
|
+
.size-1\.5 {
|
|
545
|
+
width: calc(var(--spacing) * 1.5);
|
|
546
|
+
height: calc(var(--spacing) * 1.5);
|
|
547
|
+
}
|
|
548
|
+
|
|
544
549
|
.size-2 {
|
|
545
550
|
width: calc(var(--spacing) * 2);
|
|
546
551
|
height: calc(var(--spacing) * 2);
|
|
@@ -760,6 +765,10 @@
|
|
|
760
765
|
width: 140px;
|
|
761
766
|
}
|
|
762
767
|
|
|
768
|
+
.w-\[200px\] {
|
|
769
|
+
width: 200px;
|
|
770
|
+
}
|
|
771
|
+
|
|
763
772
|
.w-\[420px\] {
|
|
764
773
|
width: 420px;
|
|
765
774
|
}
|
|
@@ -816,6 +825,14 @@
|
|
|
816
825
|
min-width: 8rem;
|
|
817
826
|
}
|
|
818
827
|
|
|
828
|
+
.min-w-\[200px\] {
|
|
829
|
+
min-width: 200px;
|
|
830
|
+
}
|
|
831
|
+
|
|
832
|
+
.min-w-max {
|
|
833
|
+
min-width: max-content;
|
|
834
|
+
}
|
|
835
|
+
|
|
819
836
|
.flex-1 {
|
|
820
837
|
flex: 1;
|
|
821
838
|
}
|
|
@@ -1043,6 +1060,11 @@
|
|
|
1043
1060
|
border-top-width: 1px;
|
|
1044
1061
|
}
|
|
1045
1062
|
|
|
1063
|
+
.border-t-2 {
|
|
1064
|
+
border-top-style: var(--tw-border-style);
|
|
1065
|
+
border-top-width: 2px;
|
|
1066
|
+
}
|
|
1067
|
+
|
|
1046
1068
|
.border-r {
|
|
1047
1069
|
border-right-style: var(--tw-border-style);
|
|
1048
1070
|
border-right-width: 1px;
|
|
@@ -1068,6 +1090,21 @@
|
|
|
1068
1090
|
border-left-width: 1px;
|
|
1069
1091
|
}
|
|
1070
1092
|
|
|
1093
|
+
.border-dashed {
|
|
1094
|
+
--tw-border-style: dashed;
|
|
1095
|
+
border-style: dashed;
|
|
1096
|
+
}
|
|
1097
|
+
|
|
1098
|
+
.\!border-amber-500\/50 {
|
|
1099
|
+
border-color: #f99c0080 !important;
|
|
1100
|
+
}
|
|
1101
|
+
|
|
1102
|
+
@supports (color: color-mix(in lab, red, red)) {
|
|
1103
|
+
.\!border-amber-500\/50 {
|
|
1104
|
+
border-color: color-mix(in oklab, var(--color-amber-500) 50%, transparent) !important;
|
|
1105
|
+
}
|
|
1106
|
+
}
|
|
1107
|
+
|
|
1071
1108
|
.border-amber-500\/20 {
|
|
1072
1109
|
border-color: #f99c0033;
|
|
1073
1110
|
}
|
|
@@ -1166,6 +1203,22 @@
|
|
|
1166
1203
|
border-color: #0000;
|
|
1167
1204
|
}
|
|
1168
1205
|
|
|
1206
|
+
.border-t-border {
|
|
1207
|
+
border-top-color: var(--border);
|
|
1208
|
+
}
|
|
1209
|
+
|
|
1210
|
+
.border-t-status-info {
|
|
1211
|
+
border-top-color: var(--status-info);
|
|
1212
|
+
}
|
|
1213
|
+
|
|
1214
|
+
.border-t-status-nominal {
|
|
1215
|
+
border-top-color: var(--status-nominal);
|
|
1216
|
+
}
|
|
1217
|
+
|
|
1218
|
+
.border-t-status-warning {
|
|
1219
|
+
border-top-color: var(--status-warning);
|
|
1220
|
+
}
|
|
1221
|
+
|
|
1169
1222
|
.border-t-transparent {
|
|
1170
1223
|
border-top-color: #0000;
|
|
1171
1224
|
}
|
|
@@ -1178,6 +1231,16 @@
|
|
|
1178
1231
|
border-left-color: #0000;
|
|
1179
1232
|
}
|
|
1180
1233
|
|
|
1234
|
+
.\!bg-amber-500\/5 {
|
|
1235
|
+
background-color: #f99c000d !important;
|
|
1236
|
+
}
|
|
1237
|
+
|
|
1238
|
+
@supports (color: color-mix(in lab, red, red)) {
|
|
1239
|
+
.\!bg-amber-500\/5 {
|
|
1240
|
+
background-color: color-mix(in oklab, var(--color-amber-500) 5%, transparent) !important;
|
|
1241
|
+
}
|
|
1242
|
+
}
|
|
1243
|
+
|
|
1181
1244
|
.bg-accent\/10 {
|
|
1182
1245
|
background-color: var(--accent);
|
|
1183
1246
|
}
|
|
@@ -1284,7 +1347,15 @@
|
|
|
1284
1347
|
}
|
|
1285
1348
|
}
|
|
1286
1349
|
|
|
1287
|
-
.bg-muted
|
|
1350
|
+
.bg-muted {
|
|
1351
|
+
background-color: var(--muted);
|
|
1352
|
+
}
|
|
1353
|
+
|
|
1354
|
+
.bg-muted-foreground {
|
|
1355
|
+
background-color: var(--muted-foreground);
|
|
1356
|
+
}
|
|
1357
|
+
|
|
1358
|
+
.bg-muted\/30 {
|
|
1288
1359
|
background-color: var(--muted);
|
|
1289
1360
|
}
|
|
1290
1361
|
|
|
@@ -1921,6 +1992,10 @@
|
|
|
1921
1992
|
opacity: 1;
|
|
1922
1993
|
}
|
|
1923
1994
|
|
|
1995
|
+
.opacity-\[0\.03\] {
|
|
1996
|
+
opacity: .03;
|
|
1997
|
+
}
|
|
1998
|
+
|
|
1924
1999
|
.shadow-lg {
|
|
1925
2000
|
--tw-shadow: 0 10px 15px -3px var(--tw-shadow-color, #0000001a), 0 4px 6px -4px var(--tw-shadow-color, #0000001a);
|
|
1926
2001
|
box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
|
|
@@ -2024,6 +2099,10 @@
|
|
|
2024
2099
|
}
|
|
2025
2100
|
|
|
2026
2101
|
@media (hover: hover) {
|
|
2102
|
+
.hover\:border-border-emphasis:hover {
|
|
2103
|
+
border-color: var(--border-emphasis);
|
|
2104
|
+
}
|
|
2105
|
+
|
|
2027
2106
|
.hover\:bg-accent\/50:hover {
|
|
2028
2107
|
background-color: var(--accent);
|
|
2029
2108
|
}
|
|
@@ -12755,6 +12755,12 @@ const Key = createLucideIcon("Key", [
|
|
|
12755
12755
|
["path", { d: "m21 2-9.6 9.6", key: "1j0ho8" }],
|
|
12756
12756
|
["circle", { cx: "7.5", cy: "15.5", r: "5.5", key: "yqb3hr" }]
|
|
12757
12757
|
]);
|
|
12758
|
+
const LayoutGrid = createLucideIcon("LayoutGrid", [
|
|
12759
|
+
["rect", { width: "7", height: "7", x: "3", y: "3", rx: "1", key: "1g98yp" }],
|
|
12760
|
+
["rect", { width: "7", height: "7", x: "14", y: "3", rx: "1", key: "6d4xhi" }],
|
|
12761
|
+
["rect", { width: "7", height: "7", x: "14", y: "14", rx: "1", key: "nxv5o0" }],
|
|
12762
|
+
["rect", { width: "7", height: "7", x: "3", y: "14", rx: "1", key: "1bb6yr" }]
|
|
12763
|
+
]);
|
|
12758
12764
|
const ListTodo = createLucideIcon("ListTodo", [
|
|
12759
12765
|
["rect", { x: "3", y: "5", width: "6", height: "6", rx: "1", key: "1defrl" }],
|
|
12760
12766
|
["path", { d: "m3 17 2 2 4-4", key: "1jhpwq" }],
|
|
@@ -16704,6 +16710,8 @@ const useAppStore = create$1((set, get) => ({
|
|
|
16704
16710
|
rightPanelTab: "todos",
|
|
16705
16711
|
settingsOpen: false,
|
|
16706
16712
|
sidebarCollapsed: false,
|
|
16713
|
+
showKanbanView: false,
|
|
16714
|
+
showSubagentsInKanban: true,
|
|
16707
16715
|
// Thread actions
|
|
16708
16716
|
loadThreads: async () => {
|
|
16709
16717
|
const threads = await window.api.threads.list();
|
|
@@ -16716,12 +16724,13 @@ const useAppStore = create$1((set, get) => ({
|
|
|
16716
16724
|
const thread = await window.api.threads.create(metadata);
|
|
16717
16725
|
set((state) => ({
|
|
16718
16726
|
threads: [thread, ...state.threads],
|
|
16719
|
-
currentThreadId: thread.thread_id
|
|
16727
|
+
currentThreadId: thread.thread_id,
|
|
16728
|
+
showKanbanView: false
|
|
16720
16729
|
}));
|
|
16721
16730
|
return thread;
|
|
16722
16731
|
},
|
|
16723
16732
|
selectThread: async (threadId) => {
|
|
16724
|
-
set({ currentThreadId: threadId });
|
|
16733
|
+
set({ currentThreadId: threadId, showKanbanView: false });
|
|
16725
16734
|
},
|
|
16726
16735
|
deleteThread: async (threadId) => {
|
|
16727
16736
|
console.log("[Store] Deleting thread:", threadId);
|
|
@@ -16796,6 +16805,17 @@ const useAppStore = create$1((set, get) => ({
|
|
|
16796
16805
|
},
|
|
16797
16806
|
setSidebarCollapsed: (collapsed) => {
|
|
16798
16807
|
set({ sidebarCollapsed: collapsed });
|
|
16808
|
+
},
|
|
16809
|
+
// Kanban actions
|
|
16810
|
+
setShowKanbanView: (show) => {
|
|
16811
|
+
if (show) {
|
|
16812
|
+
set({ showKanbanView: true, currentThreadId: null });
|
|
16813
|
+
} else {
|
|
16814
|
+
set({ showKanbanView: false });
|
|
16815
|
+
}
|
|
16816
|
+
},
|
|
16817
|
+
setShowSubagentsInKanban: (show) => {
|
|
16818
|
+
set({ showSubagentsInKanban: show });
|
|
16799
16819
|
}
|
|
16800
16820
|
}));
|
|
16801
16821
|
const CR = "\r".charCodeAt(0);
|
|
@@ -17944,6 +17964,13 @@ function convertToV1FromResponses(message) {
|
|
|
17944
17964
|
};
|
|
17945
17965
|
continue;
|
|
17946
17966
|
} else if (_isContentBlock(toolOutput, "image_generation_call")) {
|
|
17967
|
+
if (_isString(toolOutput.result)) yield {
|
|
17968
|
+
type: "image",
|
|
17969
|
+
mimeType: "image/png",
|
|
17970
|
+
data: toolOutput.result,
|
|
17971
|
+
id: _isString(toolOutput.id) ? toolOutput.id : void 0,
|
|
17972
|
+
metadata: { status: _isString(toolOutput.status) ? toolOutput.status : void 0 }
|
|
17973
|
+
};
|
|
17947
17974
|
yield {
|
|
17948
17975
|
type: "non_standard",
|
|
17949
17976
|
value: toolOutput
|
|
@@ -18187,8 +18214,8 @@ const DEFAULT_MERGE_IGNORE_KEYS = [
|
|
|
18187
18214
|
];
|
|
18188
18215
|
function _mergeDicts(left, right, options) {
|
|
18189
18216
|
const ignoreKeys = options?.ignoreKeys ?? DEFAULT_MERGE_IGNORE_KEYS;
|
|
18190
|
-
if (left
|
|
18191
|
-
if (left
|
|
18217
|
+
if (left == null && right == null) return void 0;
|
|
18218
|
+
if (left == null || right == null) return left ?? right;
|
|
18192
18219
|
const merged = { ...left };
|
|
18193
18220
|
for (const [key2, value] of Object.entries(right)) if (merged[key2] == null) merged[key2] = value;
|
|
18194
18221
|
else if (value == null) continue;
|
|
@@ -18213,8 +18240,8 @@ function _mergeDicts(left, right, options) {
|
|
|
18213
18240
|
return merged;
|
|
18214
18241
|
}
|
|
18215
18242
|
function _mergeLists(left, right, options) {
|
|
18216
|
-
if (left
|
|
18217
|
-
else if (left
|
|
18243
|
+
if (left == null && right == null) return void 0;
|
|
18244
|
+
else if (left == null || right == null) return left || right;
|
|
18218
18245
|
else {
|
|
18219
18246
|
const merged = [...left];
|
|
18220
18247
|
for (const item of right) if (typeof item === "object" && item !== null && "index" in item && typeof item.index === "number") {
|
|
@@ -18233,8 +18260,8 @@ function _mergeLists(left, right, options) {
|
|
|
18233
18260
|
}
|
|
18234
18261
|
}
|
|
18235
18262
|
function _mergeObj(left, right, options) {
|
|
18236
|
-
if (left
|
|
18237
|
-
if (left
|
|
18263
|
+
if (left == null && right == null) return void 0;
|
|
18264
|
+
if (left == null || right == null) return left ?? right;
|
|
18238
18265
|
else if (typeof left !== typeof right) throw new Error(`Cannot merge objects of different types.
|
|
18239
18266
|
Left ${typeof left}
|
|
18240
18267
|
Right ${typeof right}`);
|
|
@@ -30324,7 +30351,7 @@ var CallbackManager = class CallbackManager2 extends BaseCallbackManager {
|
|
|
30324
30351
|
callbackManager = callbackManager.copy(Array.isArray(localHandlers) ? localHandlers.map(ensureHandler) : localHandlers?.handlers, false);
|
|
30325
30352
|
}
|
|
30326
30353
|
const verboseEnabled = getEnvironmentVariable$2("LANGCHAIN_VERBOSE") === "true" || options?.verbose;
|
|
30327
|
-
const tracingV2Enabled = LangChainTracer.getTraceableRunTree()?.tracingEnabled
|
|
30354
|
+
const tracingV2Enabled = LangChainTracer.getTraceableRunTree()?.tracingEnabled ?? isTracingEnabled();
|
|
30328
30355
|
const tracingEnabled = tracingV2Enabled || (getEnvironmentVariable$2("LANGCHAIN_TRACING") ?? false);
|
|
30329
30356
|
if (verboseEnabled || tracingEnabled) {
|
|
30330
30357
|
if (!callbackManager) callbackManager = new CallbackManager2();
|
|
@@ -31899,7 +31926,9 @@ const defaultFailedAttemptHandler = (error) => {
|
|
|
31899
31926
|
if (typeof error !== "object" || error === null) return;
|
|
31900
31927
|
if ("message" in error && typeof error.message === "string" && (error.message.startsWith("Cancel") || error.message.startsWith("AbortError")) || "name" in error && typeof error.name === "string" && error.name === "AbortError") throw error;
|
|
31901
31928
|
if ("code" in error && typeof error.code === "string" && error.code === "ECONNABORTED") throw error;
|
|
31902
|
-
const
|
|
31929
|
+
const responseStatus = "response" in error && typeof error.response === "object" && error.response !== null && "status" in error.response && typeof error.response.status === "number" ? error.response.status : void 0;
|
|
31930
|
+
const directStatus = "status" in error && typeof error.status === "number" ? error.status : void 0;
|
|
31931
|
+
const status = responseStatus ?? directStatus;
|
|
31903
31932
|
if (status && STATUS_NO_RETRY$1.includes(+status)) throw error;
|
|
31904
31933
|
const code2 = "error" in error && typeof error.error === "object" && error.error !== null && "code" in error.error && typeof error.error.code === "string" ? error.error.code : void 0;
|
|
31905
31934
|
if (code2 === "insufficient_quota") {
|
|
@@ -41300,14 +41329,15 @@ var StreamManager = class {
|
|
|
41300
41329
|
};
|
|
41301
41330
|
getMutateFn = (kind, historyValues) => {
|
|
41302
41331
|
return (update) => {
|
|
41332
|
+
const stateValues = (this.state.values ?? [null, "stream"])[0];
|
|
41303
41333
|
const prev = {
|
|
41304
41334
|
...historyValues,
|
|
41305
|
-
...
|
|
41335
|
+
...stateValues ?? {}
|
|
41306
41336
|
};
|
|
41307
41337
|
const next = typeof update === "function" ? update(prev) : update;
|
|
41308
41338
|
this.setStreamValues({
|
|
41309
41339
|
...prev,
|
|
41310
|
-
...next
|
|
41340
|
+
...next ?? {}
|
|
41311
41341
|
}, kind);
|
|
41312
41342
|
};
|
|
41313
41343
|
};
|
|
@@ -41344,8 +41374,8 @@ var StreamManager = class {
|
|
|
41344
41374
|
if (this.matchEventType("checkpoints", event, data)) options.callbacks.onCheckpointEvent?.(data, { namespace });
|
|
41345
41375
|
if (this.matchEventType("tasks", event, data)) options.callbacks.onTaskEvent?.(data, { namespace });
|
|
41346
41376
|
if (this.matchEventType("debug", event, data)) options.callbacks.onDebugEvent?.(data, { namespace });
|
|
41347
|
-
if (event === "values") if ("__interrupt__" in data) this.setStreamValues((prev) => ({
|
|
41348
|
-
...prev,
|
|
41377
|
+
if (event === "values") if (data != null && typeof data === "object" && "__interrupt__" in data) this.setStreamValues((prev) => ({
|
|
41378
|
+
...prev ?? {},
|
|
41349
41379
|
...data
|
|
41350
41380
|
}));
|
|
41351
41381
|
else this.setStreamValues(data);
|
|
@@ -41359,7 +41389,7 @@ var StreamManager = class {
|
|
|
41359
41389
|
this.setStreamValues((streamValues) => {
|
|
41360
41390
|
const values$1 = {
|
|
41361
41391
|
...options.initialValues,
|
|
41362
|
-
...streamValues
|
|
41392
|
+
...streamValues ?? {}
|
|
41363
41393
|
};
|
|
41364
41394
|
let messages = options.getMessages(values$1).slice();
|
|
41365
41395
|
const { chunk, index: index2 } = this.messages.get(messageId, messages.length) ?? {};
|
|
@@ -42925,7 +42955,7 @@ var BaseClient = class {
|
|
|
42925
42955
|
const [url, init] = this.prepareFetchOptions(path2, options);
|
|
42926
42956
|
let finalInit = init;
|
|
42927
42957
|
if (this.onRequest) finalInit = await this.onRequest(url, init);
|
|
42928
|
-
const response = await this.asyncCaller.fetch(url, finalInit);
|
|
42958
|
+
const response = await this.asyncCaller.fetch(url.toString(), finalInit);
|
|
42929
42959
|
const body2 = (() => {
|
|
42930
42960
|
if (response.status === 202 || response.status === 204) return;
|
|
42931
42961
|
return response.json();
|
|
@@ -42955,7 +42985,7 @@ var BaseClient = class {
|
|
|
42955
42985
|
json: isReconnect ? void 0 : config2.json
|
|
42956
42986
|
});
|
|
42957
42987
|
if (this.onRequest != null) init = await this.onRequest(url, init);
|
|
42958
|
-
const response = await this.asyncCaller.fetch(url, init);
|
|
42988
|
+
const response = await this.asyncCaller.fetch(url.toString(), init);
|
|
42959
42989
|
if (!isReconnect && config2.onInitialResponse) await config2.onInitialResponse(response);
|
|
42960
42990
|
return {
|
|
42961
42991
|
response,
|
|
@@ -43922,7 +43952,7 @@ var UiClient = class UiClient2 extends BaseClient {
|
|
|
43922
43952
|
json: { name: agentName }
|
|
43923
43953
|
});
|
|
43924
43954
|
if (this.onRequest != null) init = await this.onRequest(url, init);
|
|
43925
|
-
return (await this.asyncCaller.fetch(url, init)).text();
|
|
43955
|
+
return (await this.asyncCaller.fetch(url.toString(), init)).text();
|
|
43926
43956
|
});
|
|
43927
43957
|
}
|
|
43928
43958
|
};
|
|
@@ -43987,6 +44017,13 @@ function unique(array) {
|
|
|
43987
44017
|
function findLast(array, predicate) {
|
|
43988
44018
|
for (let i2 = array.length - 1; i2 >= 0; i2 -= 1) if (predicate(array[i2])) return array[i2];
|
|
43989
44019
|
}
|
|
44020
|
+
async function* filterStream(stream, filter) {
|
|
44021
|
+
while (true) {
|
|
44022
|
+
const { value, done } = await stream.next();
|
|
44023
|
+
if (done) return value;
|
|
44024
|
+
if (filter(value)) yield value;
|
|
44025
|
+
}
|
|
44026
|
+
}
|
|
43990
44027
|
function getBranchSequence(history) {
|
|
43991
44028
|
const nodeIds = /* @__PURE__ */ new Set();
|
|
43992
44029
|
const childrenMap = {};
|
|
@@ -44446,11 +44483,12 @@ function useStreamLGP(options) {
|
|
|
44446
44483
|
};
|
|
44447
44484
|
await stream.start(async (signal) => {
|
|
44448
44485
|
threadIdStreamingRef.current = threadId;
|
|
44449
|
-
|
|
44486
|
+
const stream$1 = client2.runs.joinStream(threadId, runId, {
|
|
44450
44487
|
signal,
|
|
44451
44488
|
lastEventId,
|
|
44452
44489
|
streamMode: joinOptions?.streamMode
|
|
44453
44490
|
});
|
|
44491
|
+
return joinOptions?.filter != null ? filterStream(stream$1, joinOptions.filter) : stream$1;
|
|
44454
44492
|
}, {
|
|
44455
44493
|
getMessages,
|
|
44456
44494
|
setMessages,
|
|
@@ -45162,7 +45200,8 @@ const createDefaultThreadState = () => ({
|
|
|
45162
45200
|
openFiles: [],
|
|
45163
45201
|
activeTab: "agent",
|
|
45164
45202
|
fileContents: {},
|
|
45165
|
-
tokenUsage: null
|
|
45203
|
+
tokenUsage: null,
|
|
45204
|
+
draftInput: ""
|
|
45166
45205
|
});
|
|
45167
45206
|
const defaultStreamData = {
|
|
45168
45207
|
messages: [],
|
|
@@ -45227,6 +45266,7 @@ function ThreadStreamHolder({
|
|
|
45227
45266
|
function ThreadProvider({ children }) {
|
|
45228
45267
|
const [threadStates, setThreadStates] = reactExports.useState({});
|
|
45229
45268
|
const [activeThreadIds, setActiveThreadIds] = reactExports.useState(/* @__PURE__ */ new Set());
|
|
45269
|
+
const [loadingStates, setLoadingStates] = reactExports.useState({});
|
|
45230
45270
|
const initializedThreadsRef = reactExports.useRef(/* @__PURE__ */ new Set());
|
|
45231
45271
|
const actionsCache = reactExports.useRef({});
|
|
45232
45272
|
const streamDataRef = reactExports.useRef({});
|
|
@@ -45241,6 +45281,10 @@ function ThreadProvider({ children }) {
|
|
|
45241
45281
|
(threadId, data) => {
|
|
45242
45282
|
streamDataRef.current[threadId] = data;
|
|
45243
45283
|
notifyStreamSubscribers(threadId);
|
|
45284
|
+
setLoadingStates((prev) => {
|
|
45285
|
+
if (prev[threadId] === data.isLoading) return prev;
|
|
45286
|
+
return { ...prev, [threadId]: data.isLoading };
|
|
45287
|
+
});
|
|
45244
45288
|
},
|
|
45245
45289
|
[notifyStreamSubscribers]
|
|
45246
45290
|
);
|
|
@@ -45270,6 +45314,16 @@ function ThreadProvider({ children }) {
|
|
|
45270
45314
|
},
|
|
45271
45315
|
[threadStates]
|
|
45272
45316
|
);
|
|
45317
|
+
const getAllThreadStates = reactExports.useCallback(() => {
|
|
45318
|
+
return threadStates;
|
|
45319
|
+
}, [threadStates]);
|
|
45320
|
+
const getAllStreamLoadingStates = reactExports.useCallback(() => {
|
|
45321
|
+
return loadingStates;
|
|
45322
|
+
}, [loadingStates]);
|
|
45323
|
+
const subscribeToAllStreams = reactExports.useCallback(() => {
|
|
45324
|
+
return () => {
|
|
45325
|
+
};
|
|
45326
|
+
}, []);
|
|
45273
45327
|
const updateThreadState = reactExports.useCallback(
|
|
45274
45328
|
(threadId, updater) => {
|
|
45275
45329
|
setThreadStates((prev) => {
|
|
@@ -45469,6 +45523,9 @@ function ThreadProvider({ children }) {
|
|
|
45469
45523
|
updateThreadState(threadId, (state) => ({
|
|
45470
45524
|
fileContents: { ...state.fileContents, [path2]: content2 }
|
|
45471
45525
|
}));
|
|
45526
|
+
},
|
|
45527
|
+
setDraftInput: (input) => {
|
|
45528
|
+
updateThreadState(threadId, () => ({ draftInput: input }));
|
|
45472
45529
|
}
|
|
45473
45530
|
};
|
|
45474
45531
|
actionsCache.current[threadId] = actions;
|
|
@@ -45613,7 +45670,10 @@ function ThreadProvider({ children }) {
|
|
|
45613
45670
|
initializeThread,
|
|
45614
45671
|
cleanupThread,
|
|
45615
45672
|
subscribeToStream,
|
|
45616
|
-
getStreamData
|
|
45673
|
+
getStreamData,
|
|
45674
|
+
getAllThreadStates,
|
|
45675
|
+
getAllStreamLoadingStates,
|
|
45676
|
+
subscribeToAllStreams
|
|
45617
45677
|
}),
|
|
45618
45678
|
[
|
|
45619
45679
|
getThreadState,
|
|
@@ -45621,7 +45681,10 @@ function ThreadProvider({ children }) {
|
|
|
45621
45681
|
initializeThread,
|
|
45622
45682
|
cleanupThread,
|
|
45623
45683
|
subscribeToStream,
|
|
45624
|
-
getStreamData
|
|
45684
|
+
getStreamData,
|
|
45685
|
+
getAllThreadStates,
|
|
45686
|
+
getAllStreamLoadingStates,
|
|
45687
|
+
subscribeToAllStreams
|
|
45625
45688
|
]
|
|
45626
45689
|
);
|
|
45627
45690
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs(ThreadContext.Provider, { value: contextValue, children: [
|
|
@@ -45671,6 +45734,14 @@ function useThreadState(threadId) {
|
|
|
45671
45734
|
const actions = context.getThreadActions(threadId);
|
|
45672
45735
|
return { ...state, ...actions };
|
|
45673
45736
|
}
|
|
45737
|
+
function useAllThreadStates() {
|
|
45738
|
+
const context = useThreadContext();
|
|
45739
|
+
return context.getAllThreadStates();
|
|
45740
|
+
}
|
|
45741
|
+
function useAllStreamLoadingStates() {
|
|
45742
|
+
const context = useThreadContext();
|
|
45743
|
+
return context.getAllStreamLoadingStates();
|
|
45744
|
+
}
|
|
45674
45745
|
// @__NO_SIDE_EFFECTS__
|
|
45675
45746
|
function createSlot$3(ownerName) {
|
|
45676
45747
|
const SlotClone = /* @__PURE__ */ createSlotClone$3(ownerName);
|
|
@@ -50772,7 +50843,15 @@ function ThreadListItem({
|
|
|
50772
50843
|
] });
|
|
50773
50844
|
}
|
|
50774
50845
|
function ThreadSidebar() {
|
|
50775
|
-
const {
|
|
50846
|
+
const {
|
|
50847
|
+
threads,
|
|
50848
|
+
currentThreadId,
|
|
50849
|
+
createThread,
|
|
50850
|
+
selectThread,
|
|
50851
|
+
deleteThread,
|
|
50852
|
+
updateThread,
|
|
50853
|
+
setShowKanbanView
|
|
50854
|
+
} = useAppStore();
|
|
50776
50855
|
const [editingThreadId, setEditingThreadId] = reactExports.useState(null);
|
|
50777
50856
|
const [editingTitle, setEditingTitle] = reactExports.useState("");
|
|
50778
50857
|
const startEditing = (threadId, currentTitle) => {
|
|
@@ -50825,7 +50904,20 @@ function ThreadSidebar() {
|
|
|
50825
50904
|
thread.thread_id
|
|
50826
50905
|
)),
|
|
50827
50906
|
threads.length === 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "px-3 py-8 text-center text-sm text-muted-foreground", children: "No threads yet" })
|
|
50828
|
-
] }) })
|
|
50907
|
+
] }) }),
|
|
50908
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "p-2 border-t border-border", children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
50909
|
+
Button,
|
|
50910
|
+
{
|
|
50911
|
+
variant: "ghost",
|
|
50912
|
+
size: "sm",
|
|
50913
|
+
className: "w-full justify-start gap-2",
|
|
50914
|
+
onClick: () => setShowKanbanView(true),
|
|
50915
|
+
children: [
|
|
50916
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(LayoutGrid, { className: "size-4" }),
|
|
50917
|
+
"Overview"
|
|
50918
|
+
]
|
|
50919
|
+
}
|
|
50920
|
+
) })
|
|
50829
50921
|
] });
|
|
50830
50922
|
}
|
|
50831
50923
|
function TabBar({
|
|
@@ -75453,7 +75545,6 @@ function ContextUsageIndicator({
|
|
|
75453
75545
|
] });
|
|
75454
75546
|
}
|
|
75455
75547
|
function ChatContainer({ threadId }) {
|
|
75456
|
-
const [input, setInput] = reactExports.useState("");
|
|
75457
75548
|
const inputRef = reactExports.useRef(null);
|
|
75458
75549
|
const scrollRef = reactExports.useRef(null);
|
|
75459
75550
|
const isAtBottomRef = reactExports.useRef(true);
|
|
@@ -75466,13 +75557,15 @@ function ChatContainer({ threadId }) {
|
|
|
75466
75557
|
workspacePath,
|
|
75467
75558
|
tokenUsage,
|
|
75468
75559
|
currentModel,
|
|
75560
|
+
draftInput: input,
|
|
75469
75561
|
setTodos,
|
|
75470
75562
|
setWorkspaceFiles,
|
|
75471
75563
|
setWorkspacePath,
|
|
75472
75564
|
setPendingApproval,
|
|
75473
75565
|
appendMessage,
|
|
75474
75566
|
setError,
|
|
75475
|
-
clearError
|
|
75567
|
+
clearError,
|
|
75568
|
+
setDraftInput: setInput
|
|
75476
75569
|
} = useCurrentThread(threadId);
|
|
75477
75570
|
const streamData = useThreadStream(threadId);
|
|
75478
75571
|
const stream = streamData.stream;
|
|
@@ -76454,6 +76547,297 @@ function formatSize(bytes) {
|
|
|
76454
76547
|
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)}KB`;
|
|
76455
76548
|
return `${(bytes / (1024 * 1024)).toFixed(1)}MB`;
|
|
76456
76549
|
}
|
|
76550
|
+
const columnConfig = {
|
|
76551
|
+
pending: { badge: "outline", borderColor: "border-t-border" },
|
|
76552
|
+
in_progress: { badge: "info", borderColor: "border-t-status-info" },
|
|
76553
|
+
interrupted: { badge: "warning", borderColor: "border-t-status-warning" },
|
|
76554
|
+
done: { badge: "nominal", borderColor: "border-t-status-nominal" }
|
|
76555
|
+
};
|
|
76556
|
+
function KanbanColumn({
|
|
76557
|
+
title,
|
|
76558
|
+
status,
|
|
76559
|
+
count: count2,
|
|
76560
|
+
children
|
|
76561
|
+
}) {
|
|
76562
|
+
const config2 = columnConfig[status];
|
|
76563
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
76564
|
+
"div",
|
|
76565
|
+
{
|
|
76566
|
+
className: cn(
|
|
76567
|
+
"flex flex-col min-w-[200px] w-[200px] flex-1 bg-muted/30 rounded-sm border border-border border-t-2",
|
|
76568
|
+
config2.borderColor
|
|
76569
|
+
),
|
|
76570
|
+
children: [
|
|
76571
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between px-3 py-2 border-b border-border", children: [
|
|
76572
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-section-header", children: title }),
|
|
76573
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Badge, { variant: config2.badge, children: count2 })
|
|
76574
|
+
] }),
|
|
76575
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(ScrollArea, { className: "flex-1 min-h-0", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "p-2 space-y-2", children }) })
|
|
76576
|
+
]
|
|
76577
|
+
}
|
|
76578
|
+
);
|
|
76579
|
+
}
|
|
76580
|
+
const Card = reactExports.forwardRef(
|
|
76581
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
76582
|
+
"div",
|
|
76583
|
+
{
|
|
76584
|
+
ref,
|
|
76585
|
+
className: cn("rounded-sm border border-border bg-card text-card-foreground", className),
|
|
76586
|
+
...props
|
|
76587
|
+
}
|
|
76588
|
+
)
|
|
76589
|
+
);
|
|
76590
|
+
Card.displayName = "Card";
|
|
76591
|
+
const CardHeader = reactExports.forwardRef(
|
|
76592
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntimeExports.jsx("div", { ref, className: cn("flex flex-col space-y-1.5 p-4", className), ...props })
|
|
76593
|
+
);
|
|
76594
|
+
CardHeader.displayName = "CardHeader";
|
|
76595
|
+
const CardTitle = reactExports.forwardRef(
|
|
76596
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { ref, className: cn("text-section-header", className), ...props })
|
|
76597
|
+
);
|
|
76598
|
+
CardTitle.displayName = "CardTitle";
|
|
76599
|
+
const CardDescription = reactExports.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntimeExports.jsx("p", { ref, className: cn("text-sm text-muted-foreground", className), ...props }));
|
|
76600
|
+
CardDescription.displayName = "CardDescription";
|
|
76601
|
+
const CardContent = reactExports.forwardRef(
|
|
76602
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntimeExports.jsx("div", { ref, className: cn("p-4 pt-0", className), ...props })
|
|
76603
|
+
);
|
|
76604
|
+
CardContent.displayName = "CardContent";
|
|
76605
|
+
const CardFooter = reactExports.forwardRef(
|
|
76606
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntimeExports.jsx("div", { ref, className: cn("flex items-center p-4 pt-0", className), ...props })
|
|
76607
|
+
);
|
|
76608
|
+
CardFooter.displayName = "CardFooter";
|
|
76609
|
+
function ThreadStatusIcon({ threadId }) {
|
|
76610
|
+
const { isLoading } = useThreadStream(threadId);
|
|
76611
|
+
if (isLoading) {
|
|
76612
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { className: "size-4 shrink-0 text-status-info animate-spin" });
|
|
76613
|
+
}
|
|
76614
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(MessageSquare, { className: "size-4 shrink-0 text-muted-foreground" });
|
|
76615
|
+
}
|
|
76616
|
+
function ThreadKanbanCard({ thread, status, onClick }) {
|
|
76617
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
76618
|
+
Card,
|
|
76619
|
+
{
|
|
76620
|
+
className: cn(
|
|
76621
|
+
"cursor-pointer transition-all hover:border-border-emphasis hover:bg-background-interactive",
|
|
76622
|
+
status === "in_progress" && "border-status-info/50",
|
|
76623
|
+
status === "interrupted" && "!border-amber-500/50 !bg-amber-500/5"
|
|
76624
|
+
),
|
|
76625
|
+
onClick,
|
|
76626
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(CardContent, { className: "p-3", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-start gap-2", children: [
|
|
76627
|
+
status === "interrupted" ? /* @__PURE__ */ jsxRuntimeExports.jsx(MessageSquare, { className: "size-4 shrink-0 text-amber-500" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(ThreadStatusIcon, { threadId: thread.thread_id }),
|
|
76628
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 min-w-0", children: [
|
|
76629
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between gap-2", children: [
|
|
76630
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm font-medium truncate", children: thread.title || truncate(thread.thread_id, 20) }),
|
|
76631
|
+
status === "done" && /* @__PURE__ */ jsxRuntimeExports.jsx(Badge, { variant: "nominal", className: "shrink-0 text-[9px]", children: "DONE" })
|
|
76632
|
+
] }),
|
|
76633
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 mt-1 text-[10px] text-muted-foreground", children: [
|
|
76634
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Clock, { className: "size-3" }),
|
|
76635
|
+
formatRelativeTime(thread.updated_at)
|
|
76636
|
+
] })
|
|
76637
|
+
] })
|
|
76638
|
+
] }) })
|
|
76639
|
+
}
|
|
76640
|
+
);
|
|
76641
|
+
}
|
|
76642
|
+
function SubagentKanbanCard({
|
|
76643
|
+
subagent,
|
|
76644
|
+
parentThread,
|
|
76645
|
+
onClick
|
|
76646
|
+
}) {
|
|
76647
|
+
const isDone = subagent.status === "completed" || subagent.status === "failed";
|
|
76648
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
76649
|
+
Card,
|
|
76650
|
+
{
|
|
76651
|
+
className: cn(
|
|
76652
|
+
"cursor-pointer transition-all hover:border-border-emphasis hover:bg-background-interactive border-dashed",
|
|
76653
|
+
subagent.status === "running" && "border-status-info/50"
|
|
76654
|
+
),
|
|
76655
|
+
onClick,
|
|
76656
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(CardContent, { className: "p-3 overflow-hidden", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-start gap-2 min-w-0", children: [
|
|
76657
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
76658
|
+
Bot,
|
|
76659
|
+
{
|
|
76660
|
+
className: cn(
|
|
76661
|
+
"size-4 shrink-0",
|
|
76662
|
+
subagent.status === "running" ? "text-status-info" : "text-muted-foreground"
|
|
76663
|
+
)
|
|
76664
|
+
}
|
|
76665
|
+
),
|
|
76666
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 min-w-0 overflow-hidden", children: [
|
|
76667
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between gap-2", children: [
|
|
76668
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm font-medium truncate", children: subagent.name }),
|
|
76669
|
+
isDone && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
76670
|
+
Badge,
|
|
76671
|
+
{
|
|
76672
|
+
variant: subagent.status === "failed" ? "critical" : "nominal",
|
|
76673
|
+
className: "shrink-0 text-[9px]",
|
|
76674
|
+
children: subagent.status === "failed" ? "FAILED" : "DONE"
|
|
76675
|
+
}
|
|
76676
|
+
)
|
|
76677
|
+
] }),
|
|
76678
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-[10px] text-muted-foreground line-clamp-2 mt-0.5 break-words", children: subagent.description }),
|
|
76679
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center gap-1 mt-1 text-[10px] text-muted-foreground", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "truncate", children: [
|
|
76680
|
+
"↳ ",
|
|
76681
|
+
parentThread.title || truncate(parentThread.thread_id, 15)
|
|
76682
|
+
] }) })
|
|
76683
|
+
] })
|
|
76684
|
+
] }) })
|
|
76685
|
+
}
|
|
76686
|
+
);
|
|
76687
|
+
}
|
|
76688
|
+
function getThreadKanbanStatus(thread, isLoading, hasDraft, hasPendingApproval) {
|
|
76689
|
+
if (hasPendingApproval || thread.status === "interrupted") return "interrupted";
|
|
76690
|
+
if (thread.status === "busy" || isLoading) return "in_progress";
|
|
76691
|
+
if (hasDraft) return "pending";
|
|
76692
|
+
return "done";
|
|
76693
|
+
}
|
|
76694
|
+
function KanbanView() {
|
|
76695
|
+
const { threads, selectThread, showSubagentsInKanban } = useAppStore();
|
|
76696
|
+
const allThreadStates = useAllThreadStates();
|
|
76697
|
+
const loadingStates = useAllStreamLoadingStates();
|
|
76698
|
+
const handleCardClick = (threadId) => {
|
|
76699
|
+
selectThread(threadId);
|
|
76700
|
+
};
|
|
76701
|
+
const categorizedThreads = reactExports.useMemo(() => {
|
|
76702
|
+
const result = {
|
|
76703
|
+
pending: [],
|
|
76704
|
+
in_progress: [],
|
|
76705
|
+
interrupted: [],
|
|
76706
|
+
done: []
|
|
76707
|
+
};
|
|
76708
|
+
for (const thread of threads) {
|
|
76709
|
+
const isLoading = loadingStates[thread.thread_id] ?? false;
|
|
76710
|
+
const threadState = allThreadStates[thread.thread_id];
|
|
76711
|
+
const hasDraft = Boolean(threadState?.draftInput?.trim());
|
|
76712
|
+
const hasPendingApproval = Boolean(threadState?.pendingApproval);
|
|
76713
|
+
const status = getThreadKanbanStatus(thread, isLoading, hasDraft, hasPendingApproval);
|
|
76714
|
+
result[status].push({ thread, status });
|
|
76715
|
+
}
|
|
76716
|
+
return result;
|
|
76717
|
+
}, [threads, loadingStates, allThreadStates]);
|
|
76718
|
+
const categorizedSubagents = reactExports.useMemo(() => {
|
|
76719
|
+
if (!showSubagentsInKanban) {
|
|
76720
|
+
return { pending: [], in_progress: [], interrupted: [], done: [] };
|
|
76721
|
+
}
|
|
76722
|
+
const result = {
|
|
76723
|
+
pending: [],
|
|
76724
|
+
in_progress: [],
|
|
76725
|
+
interrupted: [],
|
|
76726
|
+
done: []
|
|
76727
|
+
};
|
|
76728
|
+
const threadMap = new Map(threads.map((t) => [t.thread_id, t]));
|
|
76729
|
+
for (const [threadId, state] of Object.entries(allThreadStates)) {
|
|
76730
|
+
const parentThread = threadMap.get(threadId);
|
|
76731
|
+
if (!parentThread || !state.subagents) continue;
|
|
76732
|
+
for (const subagent of state.subagents) {
|
|
76733
|
+
let status;
|
|
76734
|
+
switch (subagent.status) {
|
|
76735
|
+
case "pending":
|
|
76736
|
+
status = "pending";
|
|
76737
|
+
break;
|
|
76738
|
+
case "running":
|
|
76739
|
+
status = "in_progress";
|
|
76740
|
+
break;
|
|
76741
|
+
case "completed":
|
|
76742
|
+
status = "done";
|
|
76743
|
+
break;
|
|
76744
|
+
case "failed":
|
|
76745
|
+
status = "done";
|
|
76746
|
+
break;
|
|
76747
|
+
default:
|
|
76748
|
+
status = "pending";
|
|
76749
|
+
}
|
|
76750
|
+
result[status].push({ subagent, parentThread, status });
|
|
76751
|
+
}
|
|
76752
|
+
}
|
|
76753
|
+
return result;
|
|
76754
|
+
}, [threads, allThreadStates, showSubagentsInKanban]);
|
|
76755
|
+
const columnData = [
|
|
76756
|
+
{ status: "pending", title: "PENDING" },
|
|
76757
|
+
{ status: "in_progress", title: "IN PROGRESS" },
|
|
76758
|
+
{ status: "interrupted", title: "BLOCKED" },
|
|
76759
|
+
{ status: "done", title: "DONE" }
|
|
76760
|
+
];
|
|
76761
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex flex-col h-full bg-background", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 overflow-x-auto p-2", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex h-full min-w-max gap-2", children: columnData.map(({ status, title }) => {
|
|
76762
|
+
const threadItems = categorizedThreads[status];
|
|
76763
|
+
const subagentItems = categorizedSubagents[status];
|
|
76764
|
+
const totalCount = threadItems.length + subagentItems.length;
|
|
76765
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs(KanbanColumn, { title, status, count: totalCount, children: [
|
|
76766
|
+
threadItems.map(({ thread, status: threadStatus }) => /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
76767
|
+
ThreadKanbanCard,
|
|
76768
|
+
{
|
|
76769
|
+
thread,
|
|
76770
|
+
status: threadStatus,
|
|
76771
|
+
onClick: () => handleCardClick(thread.thread_id)
|
|
76772
|
+
},
|
|
76773
|
+
thread.thread_id
|
|
76774
|
+
)),
|
|
76775
|
+
subagentItems.map(({ subagent, parentThread }) => /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
76776
|
+
SubagentKanbanCard,
|
|
76777
|
+
{
|
|
76778
|
+
subagent,
|
|
76779
|
+
parentThread,
|
|
76780
|
+
onClick: () => handleCardClick(parentThread.thread_id)
|
|
76781
|
+
},
|
|
76782
|
+
subagent.id
|
|
76783
|
+
)),
|
|
76784
|
+
totalCount === 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-center text-sm text-muted-foreground py-8", children: "No items" })
|
|
76785
|
+
] }, status);
|
|
76786
|
+
}) }) }) });
|
|
76787
|
+
}
|
|
76788
|
+
function KanbanHeader({ className }) {
|
|
76789
|
+
const { showSubagentsInKanban, setShowSubagentsInKanban, threads } = useAppStore();
|
|
76790
|
+
const activeCount = threads.filter(
|
|
76791
|
+
(t) => t.status === "busy" || t.status === "interrupted"
|
|
76792
|
+
).length;
|
|
76793
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
76794
|
+
"div",
|
|
76795
|
+
{
|
|
76796
|
+
className: cn(
|
|
76797
|
+
"flex items-center justify-between px-3 app-no-drag relative overflow-hidden",
|
|
76798
|
+
className
|
|
76799
|
+
),
|
|
76800
|
+
children: [
|
|
76801
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "absolute inset-0 pointer-events-none opacity-[0.03]", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
76802
|
+
"div",
|
|
76803
|
+
{
|
|
76804
|
+
className: "absolute inset-0",
|
|
76805
|
+
style: {
|
|
76806
|
+
backgroundImage: "repeating-linear-gradient(0deg, transparent, transparent 2px, currentColor 2px, currentColor 3px)",
|
|
76807
|
+
backgroundSize: "100% 3px"
|
|
76808
|
+
}
|
|
76809
|
+
}
|
|
76810
|
+
) }),
|
|
76811
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1.5 text-[10px] font-mono uppercase tracking-wider text-muted-foreground", children: [
|
|
76812
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
76813
|
+
"div",
|
|
76814
|
+
{
|
|
76815
|
+
className: cn(
|
|
76816
|
+
"size-1.5 rounded-full",
|
|
76817
|
+
activeCount > 0 ? "bg-status-nominal animate-tactical-pulse" : "bg-muted-foreground"
|
|
76818
|
+
)
|
|
76819
|
+
}
|
|
76820
|
+
),
|
|
76821
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "tabular-nums", children: activeCount > 0 ? `${activeCount} ACTIVE` : "IDLE" })
|
|
76822
|
+
] }),
|
|
76823
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
76824
|
+
Button,
|
|
76825
|
+
{
|
|
76826
|
+
variant: showSubagentsInKanban ? "secondary" : "ghost",
|
|
76827
|
+
size: "sm",
|
|
76828
|
+
onClick: () => setShowSubagentsInKanban(!showSubagentsInKanban),
|
|
76829
|
+
className: "gap-2 h-7 relative",
|
|
76830
|
+
children: [
|
|
76831
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Bot, { className: "size-3.5" }),
|
|
76832
|
+
showSubagentsInKanban ? "Hide" : "Show",
|
|
76833
|
+
" Subagents"
|
|
76834
|
+
]
|
|
76835
|
+
}
|
|
76836
|
+
)
|
|
76837
|
+
]
|
|
76838
|
+
}
|
|
76839
|
+
);
|
|
76840
|
+
}
|
|
76457
76841
|
const HANDLE_WIDTH = 6;
|
|
76458
76842
|
function ResizeHandle({ onDrag }) {
|
|
76459
76843
|
const startXRef = reactExports.useRef(0);
|
|
@@ -76495,7 +76879,7 @@ const RIGHT_MIN = 250;
|
|
|
76495
76879
|
const RIGHT_MAX = 450;
|
|
76496
76880
|
const RIGHT_DEFAULT = 320;
|
|
76497
76881
|
function App() {
|
|
76498
|
-
const { currentThreadId, loadThreads, createThread } = useAppStore();
|
|
76882
|
+
const { currentThreadId, loadThreads, createThread, showKanbanView } = useAppStore();
|
|
76499
76883
|
const [isLoading, setIsLoading] = reactExports.useState(true);
|
|
76500
76884
|
const [leftWidth, setLeftWidth] = reactExports.useState(LEFT_DEFAULT);
|
|
76501
76885
|
const [rightWidth, setRightWidth] = reactExports.useState(RIGHT_DEFAULT);
|
|
@@ -76585,24 +76969,29 @@ function App() {
|
|
|
76585
76969
|
},
|
|
76586
76970
|
children: [
|
|
76587
76971
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "app-badge-name", children: "OPENWORK" }),
|
|
76588
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "app-badge-version", children: "0.
|
|
76972
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "app-badge-version", children: "0.2.0" })
|
|
76589
76973
|
]
|
|
76590
76974
|
}
|
|
76591
76975
|
),
|
|
76592
76976
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col flex-1 min-w-0", children: [
|
|
76593
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex h-9 w-full shrink-0 app-drag-region
|
|
76594
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: { width: leftWidth }, className: "shrink-0" }),
|
|
76977
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex h-9 w-full shrink-0 app-drag-region", children: [
|
|
76978
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: { width: leftWidth }, className: "shrink-0 bg-sidebar" }),
|
|
76595
76979
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-[1px] shrink-0" }),
|
|
76596
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 min-w-0", children: currentThreadId && /* @__PURE__ */ jsxRuntimeExports.jsx(TabBar, { className: "h-full border-b-0" }) })
|
|
76980
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 min-w-0 bg-background border-b border-border", children: showKanbanView ? /* @__PURE__ */ jsxRuntimeExports.jsx(KanbanHeader, { className: "h-full" }) : currentThreadId && /* @__PURE__ */ jsxRuntimeExports.jsx(TabBar, { className: "h-full border-b-0" }) })
|
|
76597
76981
|
] }),
|
|
76598
76982
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-1 overflow-hidden", children: [
|
|
76599
76983
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: { width: leftWidth }, className: "shrink-0", children: /* @__PURE__ */ jsxRuntimeExports.jsx(ThreadSidebar, {}) }),
|
|
76600
76984
|
/* @__PURE__ */ jsxRuntimeExports.jsx(ResizeHandle, { onDrag: handleLeftResize }),
|
|
76601
|
-
|
|
76985
|
+
showKanbanView ? (
|
|
76986
|
+
/* Kanban View - replaces center and right panels */
|
|
76987
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("main", { className: "flex flex-1 flex-col min-w-0 overflow-hidden", children: /* @__PURE__ */ jsxRuntimeExports.jsx(KanbanView, {}) })
|
|
76988
|
+
) : /* @__PURE__ */ jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment, { children: /* @__PURE__ */ jsxRuntimeExports.jsx("main", { className: "flex flex-1 flex-col min-w-0 overflow-hidden", children: currentThreadId ? /* @__PURE__ */ jsxRuntimeExports.jsx(TabbedPanel, { threadId: currentThreadId, showTabBar: false }) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex flex-1 items-center justify-center text-muted-foreground", children: "Select or create a thread to begin" }) }) })
|
|
76602
76989
|
] })
|
|
76603
76990
|
] }),
|
|
76604
|
-
/* @__PURE__ */ jsxRuntimeExports.
|
|
76605
|
-
|
|
76991
|
+
!showKanbanView && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
76992
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(ResizeHandle, { onDrag: handleRightResize }),
|
|
76993
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: { width: rightWidth }, className: "shrink-0", children: /* @__PURE__ */ jsxRuntimeExports.jsx(RightPanel, {}) })
|
|
76994
|
+
] })
|
|
76606
76995
|
] }) });
|
|
76607
76996
|
}
|
|
76608
76997
|
ReactDOM$1.createRoot(document.getElementById("root")).render(
|
package/out/renderer/index.html
CHANGED
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
http-equiv="Content-Security-Policy"
|
|
8
8
|
content="default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:"
|
|
9
9
|
/>
|
|
10
|
-
<script type="module" crossorigin src="./assets/index-
|
|
11
|
-
<link rel="stylesheet" crossorigin href="./assets/index-
|
|
10
|
+
<script type="module" crossorigin src="./assets/index-D1IgUk4g.js"></script>
|
|
11
|
+
<link rel="stylesheet" crossorigin href="./assets/index-CeMSVFwO.css">
|
|
12
12
|
</head>
|
|
13
13
|
<body>
|
|
14
14
|
<div id="root"></div>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "openwork",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "A tactical agent interface for deepagentsjs",
|
|
5
5
|
"main": "./out/main/index.js",
|
|
6
6
|
"files": [
|
|
@@ -46,14 +46,13 @@
|
|
|
46
46
|
"build": "npm run typecheck && electron-vite build"
|
|
47
47
|
},
|
|
48
48
|
"dependencies": {
|
|
49
|
-
"
|
|
50
|
-
"@langchain/
|
|
51
|
-
"@langchain/
|
|
49
|
+
"@langchain/anthropic": "^1.3.11",
|
|
50
|
+
"@langchain/core": "1.1.16",
|
|
51
|
+
"@langchain/google-genai": "^2.1.12",
|
|
52
52
|
"@langchain/langgraph": "^1.0.15",
|
|
53
53
|
"@langchain/langgraph-checkpoint": "^1.0.0",
|
|
54
54
|
"@langchain/langgraph-sdk": "^1.5.3",
|
|
55
|
-
"@langchain/openai": "^1.2.
|
|
56
|
-
"@langchain/google-genai": "^2.1.10",
|
|
55
|
+
"@langchain/openai": "^1.2.3",
|
|
57
56
|
"@radix-ui/react-context-menu": "^2.2.16",
|
|
58
57
|
"@radix-ui/react-dialog": "^1.1.15",
|
|
59
58
|
"@radix-ui/react-dropdown-menu": "^2.1.16",
|
|
@@ -69,8 +68,10 @@
|
|
|
69
68
|
"@radix-ui/react-tooltip": "^1.2.8",
|
|
70
69
|
"class-variance-authority": "^0.7.1",
|
|
71
70
|
"clsx": "^2.1.1",
|
|
72
|
-
"deepagents": "^1.5.
|
|
71
|
+
"deepagents": "^1.5.1",
|
|
72
|
+
"electron": "^39.2.6",
|
|
73
73
|
"electron-store": "^8.2.0",
|
|
74
|
+
"langchain": "^1.2.12",
|
|
74
75
|
"lucide-react": "^0.469.0",
|
|
75
76
|
"react-markdown": "^10.1.0",
|
|
76
77
|
"react-resizable-panels": "^4.4.0",
|