clay-server 3.4.0-beta.21 → 3.4.0-beta.22
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.
|
@@ -8,6 +8,7 @@ var fs = require("fs");
|
|
|
8
8
|
var { CodexAppServer } = require("../codex-app-server");
|
|
9
9
|
var skillDiscovery = require("../skill-discovery");
|
|
10
10
|
var { resolveOsUserInfo } = require("../../os-users");
|
|
11
|
+
var backgroundTasks = require("../codex-background-tasks");
|
|
11
12
|
|
|
12
13
|
// --- Event flattening ---
|
|
13
14
|
// Converts app-server JSON-RPC notifications into flat objects with a yokeType field.
|
|
@@ -672,6 +673,7 @@ function createEventState(model) {
|
|
|
672
673
|
toolBlocks: {},
|
|
673
674
|
commandInputs: {},
|
|
674
675
|
planTexts: {},
|
|
676
|
+
backgroundTasks: backgroundTasks.createState(),
|
|
675
677
|
};
|
|
676
678
|
}
|
|
677
679
|
|
|
@@ -698,6 +700,7 @@ function createCodexQueryHandle(appServer, queryOpts) {
|
|
|
698
700
|
var eventWaiting = null;
|
|
699
701
|
var iteratorDone = false;
|
|
700
702
|
var finishedNotified = false;
|
|
703
|
+
var removeBackgroundTaskReset = null;
|
|
701
704
|
|
|
702
705
|
function notifyFinished() {
|
|
703
706
|
if (finishedNotified) return;
|
|
@@ -722,6 +725,12 @@ function createCodexQueryHandle(appServer, queryOpts) {
|
|
|
722
725
|
}
|
|
723
726
|
}
|
|
724
727
|
|
|
728
|
+
if (typeof queryOpts.registerBackgroundTaskReset === "function") {
|
|
729
|
+
removeBackgroundTaskReset = queryOpts.registerBackgroundTaskReset(function() {
|
|
730
|
+
backgroundTasks.emitReset(state.backgroundTasks, pushEvent);
|
|
731
|
+
});
|
|
732
|
+
}
|
|
733
|
+
|
|
725
734
|
function endIterator() {
|
|
726
735
|
iteratorDone = true;
|
|
727
736
|
if (eventWaiting) {
|
|
@@ -729,6 +738,10 @@ function createCodexQueryHandle(appServer, queryOpts) {
|
|
|
729
738
|
eventWaiting = null;
|
|
730
739
|
resolve({ value: undefined, done: true });
|
|
731
740
|
}
|
|
741
|
+
if (removeBackgroundTaskReset) {
|
|
742
|
+
removeBackgroundTaskReset();
|
|
743
|
+
removeBackgroundTaskReset = null;
|
|
744
|
+
}
|
|
732
745
|
notifyFinished();
|
|
733
746
|
}
|
|
734
747
|
|
|
@@ -934,6 +947,10 @@ function createCodexQueryHandle(appServer, queryOpts) {
|
|
|
934
947
|
pushEvent(yokeEvents[i]);
|
|
935
948
|
}
|
|
936
949
|
|
|
950
|
+
if (method === "turn/completed" || method === "turn/failed") {
|
|
951
|
+
backgroundTasks.poll(appServer, state.threadId, state.backgroundTasks, pushEvent).catch(function() {});
|
|
952
|
+
}
|
|
953
|
+
|
|
937
954
|
// Resolve turn promise when turn ends
|
|
938
955
|
if (method === "turn/completed" || method === "turn/failed") {
|
|
939
956
|
if (turnResolve) {
|
|
@@ -1246,6 +1263,20 @@ function createCodexAdapter(opts) {
|
|
|
1246
1263
|
];
|
|
1247
1264
|
var _cachedModels = CODEX_MODELS.slice();
|
|
1248
1265
|
var _appServer = null;
|
|
1266
|
+
var _backgroundTaskResetListeners = [];
|
|
1267
|
+
|
|
1268
|
+
function registerBackgroundTaskReset(listener) {
|
|
1269
|
+
_backgroundTaskResetListeners.push(listener);
|
|
1270
|
+
return function() {
|
|
1271
|
+
var index = _backgroundTaskResetListeners.indexOf(listener);
|
|
1272
|
+
if (index !== -1) _backgroundTaskResetListeners.splice(index, 1);
|
|
1273
|
+
};
|
|
1274
|
+
}
|
|
1275
|
+
|
|
1276
|
+
function emitBackgroundTaskReset() {
|
|
1277
|
+
var listeners = _backgroundTaskResetListeners.slice();
|
|
1278
|
+
for (var i = 0; i < listeners.length; i++) listeners[i]();
|
|
1279
|
+
}
|
|
1249
1280
|
var _initPromise = null;
|
|
1250
1281
|
var _shutdownPromise = null;
|
|
1251
1282
|
var _refCount = 0;
|
|
@@ -1541,6 +1572,7 @@ function createCodexAdapter(opts) {
|
|
|
1541
1572
|
// Spawn and initialize app-server
|
|
1542
1573
|
_appServer = _createAppServer(serverOpts);
|
|
1543
1574
|
await _appServer.start();
|
|
1575
|
+
emitBackgroundTaskReset();
|
|
1544
1576
|
|
|
1545
1577
|
await _appServer.send("initialize", {
|
|
1546
1578
|
clientInfo: { name: "clay", title: "Clay", version: "1.0.0" },
|
|
@@ -1676,6 +1708,7 @@ function createCodexAdapter(opts) {
|
|
|
1676
1708
|
canUseTool: queryOpts.canUseTool || null,
|
|
1677
1709
|
onElicitation: queryOpts.onElicitation || null,
|
|
1678
1710
|
resumeSessionId: queryOpts.resumeSessionId || null,
|
|
1711
|
+
registerBackgroundTaskReset: registerBackgroundTaskReset,
|
|
1679
1712
|
};
|
|
1680
1713
|
|
|
1681
1714
|
// Reasoning effort
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
function terminalList(result) {
|
|
2
|
+
if (Array.isArray(result)) return result;
|
|
3
|
+
if (!result || typeof result !== "object") return [];
|
|
4
|
+
if (Array.isArray(result.terminals)) return result.terminals;
|
|
5
|
+
if (Array.isArray(result.backgroundTerminals)) return result.backgroundTerminals;
|
|
6
|
+
if (Array.isArray(result.items)) return result.items;
|
|
7
|
+
return [];
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
function isLiveTerminal(terminal) {
|
|
11
|
+
var status = String((terminal && (terminal.status || terminal.state)) || "").toLowerCase();
|
|
12
|
+
return status !== "exited" && status !== "terminated" && status !== "completed" && status !== "failed";
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function mapTerminals(result) {
|
|
16
|
+
var terminals = terminalList(result);
|
|
17
|
+
var tasks = [];
|
|
18
|
+
for (var i = 0; i < terminals.length; i++) {
|
|
19
|
+
var terminal = terminals[i] || {};
|
|
20
|
+
var taskId = terminal.id || terminal.terminalId || terminal.taskId || "";
|
|
21
|
+
if (!taskId || !isLiveTerminal(terminal)) continue;
|
|
22
|
+
tasks.push({
|
|
23
|
+
task_id: String(taskId),
|
|
24
|
+
task_type: "shell",
|
|
25
|
+
description: terminal.commandLine || terminal.command || terminal.name || "",
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
return tasks;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function taskIds(tasks) {
|
|
32
|
+
var ids = {};
|
|
33
|
+
for (var i = 0; i < tasks.length; i++) ids[tasks[i].task_id] = true;
|
|
34
|
+
return ids;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function sameMembership(first, second) {
|
|
38
|
+
var firstKeys = Object.keys(first || {});
|
|
39
|
+
var secondKeys = Object.keys(second || {});
|
|
40
|
+
if (firstKeys.length !== secondKeys.length) return false;
|
|
41
|
+
for (var i = 0; i < firstKeys.length; i++) {
|
|
42
|
+
if (!second[firstKeys[i]]) return false;
|
|
43
|
+
}
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function createState() {
|
|
48
|
+
return { taskIds: null };
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function emitIfChanged(state, tasks, pushEvent) {
|
|
52
|
+
var ids = taskIds(tasks);
|
|
53
|
+
if (state.taskIds === null && tasks.length === 0) {
|
|
54
|
+
state.taskIds = ids;
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
if (state.taskIds && sameMembership(state.taskIds, ids)) return false;
|
|
58
|
+
state.taskIds = ids;
|
|
59
|
+
pushEvent({ yokeType: "background_tasks_changed", tasks: tasks });
|
|
60
|
+
return true;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function poll(appServer, threadId, state, pushEvent) {
|
|
64
|
+
if (!appServer || !threadId || appServer._clayBackgroundTasksPollingDisabled) return Promise.resolve(false);
|
|
65
|
+
return appServer.send("thread/backgroundTerminals/list", { threadId: threadId }).then(function(result) {
|
|
66
|
+
return emitIfChanged(state, mapTerminals(result), pushEvent);
|
|
67
|
+
}).catch(function() {
|
|
68
|
+
appServer._clayBackgroundTasksPollingDisabled = true;
|
|
69
|
+
return false;
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function emitReset(state, pushEvent) {
|
|
74
|
+
state.taskIds = {};
|
|
75
|
+
pushEvent({ yokeType: "background_tasks_changed", tasks: [] });
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
module.exports = {
|
|
79
|
+
createState: createState,
|
|
80
|
+
mapTerminals: mapTerminals,
|
|
81
|
+
emitIfChanged: emitIfChanged,
|
|
82
|
+
poll: poll,
|
|
83
|
+
emitReset: emitReset,
|
|
84
|
+
};
|
package/package.json
CHANGED