@supen-ai/cli 1.4.0 → 1.4.2
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 +1 -1
- package/daemon/dist/agent-sdk/app-server-stream.js +5 -5
- package/daemon/dist/agent-sdk/app-server-stream.js.map +1 -1
- package/daemon/dist/agent-sdk/drivers/codex-app-server-driver.d.ts +3 -2
- package/daemon/dist/agent-sdk/drivers/codex-app-server-driver.d.ts.map +1 -1
- package/daemon/dist/agent-sdk/drivers/codex-app-server-driver.js +72 -49
- package/daemon/dist/agent-sdk/drivers/codex-app-server-driver.js.map +1 -1
- package/daemon/dist/agent-sdk/drivers/driver.d.ts +8 -8
- package/daemon/dist/agent-sdk/drivers/driver.d.ts.map +1 -1
- package/daemon/dist/agent-sdk/index.d.ts +4 -4
- package/daemon/dist/agent-sdk/index.d.ts.map +1 -1
- package/daemon/dist/agent-sdk/index.js +2 -2
- package/daemon/dist/agent-sdk/index.js.map +1 -1
- package/daemon/dist/agent-sdk/intelligence/contracts.d.ts +2 -2
- package/daemon/dist/agent-sdk/intelligence/contracts.d.ts.map +1 -1
- package/daemon/dist/agent-sdk/memory/subsystem.d.ts +1 -1
- package/daemon/dist/agent-sdk/memory/subsystem.d.ts.map +1 -1
- package/daemon/dist/agent-sdk/{session-events.d.ts → thread-events.d.ts} +18 -18
- package/daemon/dist/agent-sdk/thread-events.d.ts.map +1 -0
- package/daemon/dist/agent-sdk/{session-events.js → thread-events.js} +15 -15
- package/daemon/dist/agent-sdk/thread-events.js.map +1 -0
- package/daemon/dist/agent-sdk/{session-manager.d.ts → thread-manager.d.ts} +9 -9
- package/daemon/dist/agent-sdk/thread-manager.d.ts.map +1 -0
- package/daemon/dist/agent-sdk/{session-manager.js → thread-manager.js} +7 -7
- package/daemon/dist/agent-sdk/thread-manager.js.map +1 -0
- package/daemon/dist/agent-sdk/types.d.ts +18 -18
- package/daemon/dist/agent-sdk/types.d.ts.map +1 -1
- package/daemon/dist/automation-event-listener.js +6 -6
- package/daemon/dist/automation-event-listener.js.map +1 -1
- package/daemon/dist/automation-runner.d.ts +1 -1
- package/daemon/dist/automation-runner.d.ts.map +1 -1
- package/daemon/dist/automation-runner.js +24 -24
- package/daemon/dist/automation-runner.js.map +1 -1
- package/daemon/dist/autonomy/memory-rules.d.ts +2 -2
- package/daemon/dist/autonomy/memory-rules.d.ts.map +1 -1
- package/daemon/dist/autonomy/memory-rules.js +1 -1
- package/daemon/dist/autonomy/memory-rules.js.map +1 -1
- package/daemon/dist/autonomy/session-autonomy.d.ts +4 -4
- package/daemon/dist/autonomy/session-autonomy.d.ts.map +1 -1
- package/daemon/dist/autonomy/session-autonomy.js +5 -5
- package/daemon/dist/autonomy/session-autonomy.js.map +1 -1
- package/daemon/dist/bin/mcp-os.js +1 -1
- package/daemon/dist/bin/mcp-os.js.map +1 -1
- package/daemon/dist/bin/mcp-scheduler.js +1 -1
- package/daemon/dist/bin/mcp-scheduler.js.map +1 -1
- package/daemon/dist/bin/supen-sys.js +1 -1
- package/daemon/dist/bin/supen-sys.js.map +1 -1
- package/daemon/dist/bootstrap/hub-bootstrap.js +1 -1
- package/daemon/dist/bootstrap/hub-bootstrap.js.map +1 -1
- package/daemon/dist/channels/http-routes.d.ts.map +1 -1
- package/daemon/dist/channels/http-routes.js +54 -60
- package/daemon/dist/channels/http-routes.js.map +1 -1
- package/daemon/dist/channels/http.js +2 -2
- package/daemon/dist/channels/http.js.map +1 -1
- package/daemon/dist/channels/index.d.ts +0 -1
- package/daemon/dist/channels/index.d.ts.map +1 -1
- package/daemon/dist/channels/index.js +0 -2
- package/daemon/dist/channels/index.js.map +1 -1
- package/daemon/dist/channels/registry.d.ts +1 -1
- package/daemon/dist/channels/registry.d.ts.map +1 -1
- package/daemon/dist/commands/builtin.d.ts +1 -1
- package/daemon/dist/commands/builtin.d.ts.map +1 -1
- package/daemon/dist/commands/builtin.js +2 -2
- package/daemon/dist/commands/builtin.js.map +1 -1
- package/daemon/dist/commands/catalog.js +3 -3
- package/daemon/dist/commands/catalog.js.map +1 -1
- package/daemon/dist/core/config.d.ts +0 -2
- package/daemon/dist/core/config.d.ts.map +1 -1
- package/daemon/dist/core/config.js +0 -5
- package/daemon/dist/core/config.js.map +1 -1
- package/daemon/dist/core/control-commands.d.ts +3 -3
- package/daemon/dist/core/control-commands.d.ts.map +1 -1
- package/daemon/dist/core/control-commands.js +6 -6
- package/daemon/dist/core/control-commands.js.map +1 -1
- package/daemon/dist/core/control-log.d.ts +4 -4
- package/daemon/dist/core/control-log.d.ts.map +1 -1
- package/daemon/dist/core/control-log.js +12 -12
- package/daemon/dist/core/control-log.js.map +1 -1
- package/daemon/dist/core/cortex.d.ts +4 -4
- package/daemon/dist/core/cortex.d.ts.map +1 -1
- package/daemon/dist/core/cortex.js +98 -117
- package/daemon/dist/core/cortex.js.map +1 -1
- package/daemon/dist/core/dispatcher.d.ts +3 -3
- package/daemon/dist/core/dispatcher.js +18 -18
- package/daemon/dist/core/dispatcher.js.map +1 -1
- package/daemon/dist/core/gateway-protocol.d.ts +0 -1
- package/daemon/dist/core/gateway-protocol.d.ts.map +1 -1
- package/daemon/dist/core/gateway.d.ts +3 -3
- package/daemon/dist/core/gateway.d.ts.map +1 -1
- package/daemon/dist/core/gateway.js +26 -26
- package/daemon/dist/core/gateway.js.map +1 -1
- package/daemon/dist/core/hub-snapshot.d.ts +1 -1
- package/daemon/dist/core/hub-snapshot.d.ts.map +1 -1
- package/daemon/dist/core/hub-snapshot.js +1 -1
- package/daemon/dist/core/hub-snapshot.js.map +1 -1
- package/daemon/dist/core/pairing.d.ts +2 -2
- package/daemon/dist/core/pairing.js +3 -3
- package/daemon/dist/core/pairing.js.map +1 -1
- package/daemon/dist/core/store.d.ts +38 -38
- package/daemon/dist/core/store.d.ts.map +1 -1
- package/daemon/dist/core/store.js +285 -289
- package/daemon/dist/core/store.js.map +1 -1
- package/daemon/dist/core/task-artifacts.d.ts +4 -4
- package/daemon/dist/core/task-artifacts.d.ts.map +1 -1
- package/daemon/dist/core/task-artifacts.js +10 -10
- package/daemon/dist/core/task-artifacts.js.map +1 -1
- package/daemon/dist/core/thread-context.d.ts +76 -0
- package/daemon/dist/core/thread-context.d.ts.map +1 -0
- package/daemon/dist/core/thread-context.js +308 -0
- package/daemon/dist/core/thread-context.js.map +1 -0
- package/daemon/dist/core/types.d.ts +28 -28
- package/daemon/dist/core/types.d.ts.map +1 -1
- package/daemon/dist/core/utils.js +1 -1
- package/daemon/dist/core/utils.js.map +1 -1
- package/daemon/dist/http/router.d.ts +2 -2
- package/daemon/dist/http/router.d.ts.map +1 -1
- package/daemon/dist/http/router.js +5 -5
- package/daemon/dist/http/router.js.map +1 -1
- package/daemon/dist/http/routes/agents.js +3 -3
- package/daemon/dist/http/routes/agents.js.map +1 -1
- package/daemon/dist/http/routes/automations.d.ts +2 -2
- package/daemon/dist/http/routes/automations.d.ts.map +1 -1
- package/daemon/dist/http/routes/automations.js +23 -23
- package/daemon/dist/http/routes/automations.js.map +1 -1
- package/daemon/dist/http/routes/chat-input.d.ts +1 -1
- package/daemon/dist/http/routes/chat-input.d.ts.map +1 -1
- package/daemon/dist/http/routes/chat-input.js +2 -2
- package/daemon/dist/http/routes/chat-input.js.map +1 -1
- package/daemon/dist/http/routes/plugins.d.ts.map +1 -1
- package/daemon/dist/http/routes/plugins.js +6 -74
- package/daemon/dist/http/routes/plugins.js.map +1 -1
- package/daemon/dist/http/routes/rpc.d.ts +3 -3
- package/daemon/dist/http/routes/rpc.d.ts.map +1 -1
- package/daemon/dist/http/routes/rpc.js +93 -92
- package/daemon/dist/http/routes/rpc.js.map +1 -1
- package/daemon/dist/http/routes/system.d.ts +8 -7
- package/daemon/dist/http/routes/system.d.ts.map +1 -1
- package/daemon/dist/http/routes/system.js +225 -111
- package/daemon/dist/http/routes/system.js.map +1 -1
- package/daemon/dist/http/routes/threads.d.ts +11 -0
- package/daemon/dist/http/routes/threads.d.ts.map +1 -0
- package/daemon/dist/http/routes/{sessions.js → threads.js} +158 -158
- package/daemon/dist/http/routes/threads.js.map +1 -0
- package/daemon/dist/http/stream.d.ts +2 -2
- package/daemon/dist/http/stream.d.ts.map +1 -1
- package/daemon/dist/http/stream.js +3 -3
- package/daemon/dist/http/stream.js.map +1 -1
- package/daemon/dist/http/thread-title.d.ts +1 -1
- package/daemon/dist/http/thread-title.d.ts.map +1 -1
- package/daemon/dist/http/thread-title.js +6 -6
- package/daemon/dist/http/thread-title.js.map +1 -1
- package/daemon/dist/http/websocket.d.ts +2 -2
- package/daemon/dist/http/websocket.d.ts.map +1 -1
- package/daemon/dist/http/websocket.js +11 -11
- package/daemon/dist/http/websocket.js.map +1 -1
- package/daemon/dist/index.d.ts +3 -3
- package/daemon/dist/index.d.ts.map +1 -1
- package/daemon/dist/index.js +65 -81
- package/daemon/dist/index.js.map +1 -1
- package/daemon/dist/mcp/aggregate-config.d.ts +1 -1
- package/daemon/dist/mcp/index.js +1 -1
- package/daemon/dist/mcp/index.js.map +1 -1
- package/daemon/dist/mcp/tools.d.ts +1 -1
- package/daemon/dist/mcp/tools.js +1 -1
- package/daemon/dist/plugins/hub.d.ts +2 -8
- package/daemon/dist/plugins/hub.d.ts.map +1 -1
- package/daemon/dist/plugins/hub.js +63 -214
- package/daemon/dist/plugins/hub.js.map +1 -1
- package/daemon/dist/plugins/types.d.ts +10 -0
- package/daemon/dist/plugins/types.d.ts.map +1 -1
- package/daemon/dist/sub-agent.d.ts +3 -3
- package/daemon/dist/sub-agent.d.ts.map +1 -1
- package/daemon/dist/sub-agent.js +8 -8
- package/daemon/dist/sub-agent.js.map +1 -1
- package/daemon/dist/sync/supabase-sync.js +18 -18
- package/daemon/dist/sync/supabase-sync.js.map +1 -1
- package/daemon/dist/task-executor.js +1 -1
- package/daemon/dist/task-executor.js.map +1 -1
- package/daemon/dist/tools/shell.js +1 -1
- package/daemon/dist/tools/shell.js.map +1 -1
- package/daemon/dist/tools/types.d.ts +1 -1
- package/daemon/dist/tools/types.d.ts.map +1 -1
- package/daemon/package.json +1 -1
- package/dist/computer.js +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/daemon/dist/acp-client.d.ts +0 -42
- package/daemon/dist/acp-client.d.ts.map +0 -1
- package/daemon/dist/acp-client.js +0 -149
- package/daemon/dist/acp-client.js.map +0 -1
- package/daemon/dist/acp-types.d.ts +0 -98
- package/daemon/dist/acp-types.d.ts.map +0 -1
- package/daemon/dist/acp-types.js +0 -2
- package/daemon/dist/acp-types.js.map +0 -1
- package/daemon/dist/agent-sdk/session-events.d.ts.map +0 -1
- package/daemon/dist/agent-sdk/session-events.js.map +0 -1
- package/daemon/dist/agent-sdk/session-manager.d.ts.map +0 -1
- package/daemon/dist/agent-sdk/session-manager.js.map +0 -1
- package/daemon/dist/channels/acp.d.ts +0 -23
- package/daemon/dist/channels/acp.d.ts.map +0 -1
- package/daemon/dist/channels/acp.js +0 -915
- package/daemon/dist/channels/acp.js.map +0 -1
- package/daemon/dist/http/routes/sessions.d.ts +0 -11
- package/daemon/dist/http/routes/sessions.d.ts.map +0 -1
- package/daemon/dist/http/routes/sessions.js.map +0 -1
|
@@ -3,9 +3,8 @@ import path from 'path';
|
|
|
3
3
|
import { logger } from './logger.js';
|
|
4
4
|
import { getGatewayInstance, getLlmToken, getLlmTokenOrWait } from './gateway.js';
|
|
5
5
|
import { AGENT_MIND_FILES, ASSISTANT_NAME, agentPaths, getAgentModelConfig, } from './config.js';
|
|
6
|
-
import { cleanupTaskFolderWithoutMeaningfulArtifacts, ensureTaskArtifactLayout,
|
|
7
|
-
import { getUsageStats, appendGlobalUsage,
|
|
8
|
-
import { appendThreadEvent } from './thread-event-log.js';
|
|
6
|
+
import { cleanupTaskFolderWithoutMeaningfulArtifacts, ensureTaskArtifactLayout, resolveThreadTaskArtifactPaths, } from './task-artifacts.js';
|
|
7
|
+
import { getUsageStats, appendGlobalUsage, clearThreadSdkSessionId, ensureThread, updateThreadStatus, updateThreadSdkSessionId, updateThreadUsage, getThreadForAgent, storeThreadUiEvent, } from './store.js';
|
|
9
8
|
import { LoopGuard } from './loop-guard.js';
|
|
10
9
|
import { convertSdkEventToUiMessageChunks, enrichUiMessageChunksWithDocumentRefs, serializeUiMessageChunks, } from './protocol-adapter.js';
|
|
11
10
|
import { resolveMcpServers } from '../mcp/default-servers.js';
|
|
@@ -15,10 +14,10 @@ import { resolveInstalledPluginMcpServers } from '../plugins/hub.js';
|
|
|
15
14
|
import { resolveEnabledSkillMcpServers } from '../skills/mcp-config.js';
|
|
16
15
|
import { getRuntimeSpaceEnvVars, withRuntimeSpaceEnv } from './space-env.js';
|
|
17
16
|
import { buildAssistantOutputExcerpt, buildObservableToolDetail, buildTaskContextExcerpt, excerptText, } from './observable-logging.js';
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
17
|
+
import { classifyThreadInsight } from '../agent-sdk/thread-events.js';
|
|
18
|
+
import { ThreadManager } from '../agent-sdk/thread-manager.js';
|
|
20
19
|
import { convertDriverOutputsToUiMessageChunks } from '../agent-sdk/driver-output-ui.js';
|
|
21
|
-
import {
|
|
20
|
+
import { createThread, createTurn } from '../agent-sdk/thread-events.js';
|
|
22
21
|
import { createFileMemorySubsystem } from '../agent-sdk/memory/filesystem.js';
|
|
23
22
|
function isVisualRuntimeAttachment(attachment) {
|
|
24
23
|
const type = typeof attachment?.type === 'string' ? attachment.type : '';
|
|
@@ -105,7 +104,7 @@ function appendNormalizedOutputToFinalText(normalizedOutputs, current) {
|
|
|
105
104
|
let next = current;
|
|
106
105
|
let receivedText = false;
|
|
107
106
|
for (const output of normalizedOutputs) {
|
|
108
|
-
if (output.kind === '
|
|
107
|
+
if (output.kind === 'thread-event' && output.event?.type === 'text.delta') {
|
|
109
108
|
const payload = output.event.payload;
|
|
110
109
|
const text = typeof payload?.text === 'string' ? payload.text : '';
|
|
111
110
|
if (text) {
|
|
@@ -149,7 +148,7 @@ function appendNormalizedOutputToFinalText(normalizedOutputs, current) {
|
|
|
149
148
|
}
|
|
150
149
|
function extractTerminalResultText(normalizedOutputs) {
|
|
151
150
|
for (const output of normalizedOutputs) {
|
|
152
|
-
if (output.kind !== '
|
|
151
|
+
if (output.kind !== 'thread-event')
|
|
153
152
|
continue;
|
|
154
153
|
if (output.event?.type !== 'turn.completed')
|
|
155
154
|
continue;
|
|
@@ -162,7 +161,7 @@ function extractTerminalResultText(normalizedOutputs) {
|
|
|
162
161
|
}
|
|
163
162
|
function extractTerminalFailureText(normalizedOutputs) {
|
|
164
163
|
for (const output of normalizedOutputs) {
|
|
165
|
-
if (output.kind !== '
|
|
164
|
+
if (output.kind !== 'thread-event')
|
|
166
165
|
continue;
|
|
167
166
|
if (output.event?.type !== 'turn.failed' && output.event?.type !== 'turn.cancelled')
|
|
168
167
|
continue;
|
|
@@ -211,10 +210,10 @@ const RECENT_JOURNAL_TOTAL_MAX_CHARS = 6_000;
|
|
|
211
210
|
function resolveAgentRuntimePaths(agentId) {
|
|
212
211
|
return agentPaths(agentId);
|
|
213
212
|
}
|
|
214
|
-
function nativeSessionPrewarmKey(agentId,
|
|
213
|
+
function nativeSessionPrewarmKey(agentId, threadId, driverId, options) {
|
|
215
214
|
return [
|
|
216
215
|
agentId,
|
|
217
|
-
|
|
216
|
+
threadId,
|
|
218
217
|
driverId,
|
|
219
218
|
options?.model || '',
|
|
220
219
|
options?.effort || '',
|
|
@@ -229,7 +228,7 @@ function pruneNativeSessionPrewarmCache(now = Date.now()) {
|
|
|
229
228
|
continue;
|
|
230
229
|
nativeSessionPrewarmCache.delete(key);
|
|
231
230
|
entry.promise
|
|
232
|
-
.then((
|
|
231
|
+
.then((thread) => thread.close())
|
|
233
232
|
.catch(() => { });
|
|
234
233
|
}
|
|
235
234
|
}
|
|
@@ -261,7 +260,7 @@ function extractUsageTotals(raw) {
|
|
|
261
260
|
return null;
|
|
262
261
|
return { tokensIn: input, tokensOut: output };
|
|
263
262
|
}
|
|
264
|
-
function reportUsageToGateway(agentId,
|
|
263
|
+
function reportUsageToGateway(agentId, threadId, tokensIn, tokensOut) {
|
|
265
264
|
const gateway = getGatewayInstance();
|
|
266
265
|
if (!gateway || !gateway.isConnected())
|
|
267
266
|
return;
|
|
@@ -274,7 +273,7 @@ function reportUsageToGateway(agentId, sessionId, tokensIn, tokensOut) {
|
|
|
274
273
|
gateway.reportUsage({
|
|
275
274
|
token: getLlmToken(),
|
|
276
275
|
agent_id: agentId,
|
|
277
|
-
thread_id:
|
|
276
|
+
thread_id: threadId,
|
|
278
277
|
provider: selectedModel?.provider_id,
|
|
279
278
|
model: selectedModel?.model,
|
|
280
279
|
input_tokens: tokensIn,
|
|
@@ -290,25 +289,25 @@ export class AgentCortex {
|
|
|
290
289
|
lastInputTokens = 0;
|
|
291
290
|
lastOutputTokens = 0;
|
|
292
291
|
loopGuard;
|
|
293
|
-
|
|
292
|
+
threadManager = new ThreadManager();
|
|
294
293
|
memorySubsystem;
|
|
295
|
-
|
|
296
|
-
constructor(agentId,
|
|
294
|
+
threadRecord;
|
|
295
|
+
constructor(agentId, threadId, events = {}) {
|
|
297
296
|
this.events = events;
|
|
298
|
-
const
|
|
299
|
-
|
|
297
|
+
const threadRecord = getThreadForAgent(agentId, threadId) ||
|
|
298
|
+
ensureThread({
|
|
300
299
|
agent_id: agentId,
|
|
301
|
-
|
|
300
|
+
thread_id: threadId,
|
|
302
301
|
channel: 'daemon',
|
|
303
302
|
agent_name: agentId,
|
|
304
303
|
});
|
|
305
|
-
this.
|
|
304
|
+
this.threadRecord = threadRecord;
|
|
306
305
|
this.state = {
|
|
307
306
|
status: 'idle',
|
|
308
307
|
agent_id: agentId,
|
|
309
|
-
|
|
310
|
-
sdk_session_id:
|
|
311
|
-
backend_driver_id:
|
|
308
|
+
thread_id: threadId,
|
|
309
|
+
sdk_session_id: threadRecord?.sdk_session_id,
|
|
310
|
+
backend_driver_id: threadRecord?.backend_driver_id,
|
|
312
311
|
activity: { phase: 'idle' },
|
|
313
312
|
recent_logs: [],
|
|
314
313
|
last_activity_at: Date.now(),
|
|
@@ -320,7 +319,7 @@ export class AgentCortex {
|
|
|
320
319
|
return { ...this.state };
|
|
321
320
|
}
|
|
322
321
|
resolveBackendDriverId(explicitDriverId) {
|
|
323
|
-
const driverId = this.
|
|
322
|
+
const driverId = this.threadManager.resolveDriverId(explicitDriverId || this.state.backend_driver_id);
|
|
324
323
|
if (this.state.backend_driver_id !== driverId) {
|
|
325
324
|
this.state.backend_driver_id = driverId;
|
|
326
325
|
}
|
|
@@ -333,7 +332,7 @@ export class AgentCortex {
|
|
|
333
332
|
async buildMcpServersConfig() {
|
|
334
333
|
// The user's global MCP config (own custom servers, catalog toggles, env
|
|
335
334
|
// overrides) is owned by the gateway. Fetch with a short TTL so every
|
|
336
|
-
//
|
|
335
|
+
// thread pick-up reflects recent toggles without a per-thread
|
|
337
336
|
// round-trip penalty.
|
|
338
337
|
const globalConfig = await fetchGlobalMcpConfig();
|
|
339
338
|
const localEnvOverrides = getMcpEnvOverrides();
|
|
@@ -343,7 +342,7 @@ export class AgentCortex {
|
|
|
343
342
|
};
|
|
344
343
|
const disabledIds = new Set(globalConfig.disabled_mcp_server_ids);
|
|
345
344
|
const pluginMcpServers = await resolveInstalledPluginMcpServers();
|
|
346
|
-
// Preload built-in catalog MCP servers for every
|
|
345
|
+
// Preload built-in catalog MCP servers for every thread, skipping ids
|
|
347
346
|
// the user disabled globally. Skills/manager declarations may override by
|
|
348
347
|
// id below.
|
|
349
348
|
const runtimeEnv = withRuntimeSpaceEnv(process.env);
|
|
@@ -403,11 +402,11 @@ export class AgentCortex {
|
|
|
403
402
|
}
|
|
404
403
|
async createNativeSdkSession(options) {
|
|
405
404
|
const paths = resolveAgentRuntimePaths(this.state.agent_id);
|
|
406
|
-
const artifacts =
|
|
407
|
-
const
|
|
405
|
+
const artifacts = resolveThreadTaskArtifactPaths(this.threadRecord, this.state.task_id);
|
|
406
|
+
const threadKey = `${this.state.agent_id}:${this.state.thread_id}`;
|
|
408
407
|
const driverId = this.resolveBackendDriverId();
|
|
409
|
-
const
|
|
410
|
-
const sdkTurn = createTurn({
|
|
408
|
+
const sdkThread = createThread({ id: this.state.thread_id });
|
|
409
|
+
const sdkTurn = createTurn({ threadId: sdkThread.id });
|
|
411
410
|
this.initBrain(paths.base, artifacts.cwd);
|
|
412
411
|
ensureTaskArtifactLayout(artifacts);
|
|
413
412
|
if (shouldWaitForGatewayToken(this.state.agent_id)) {
|
|
@@ -421,10 +420,10 @@ export class AgentCortex {
|
|
|
421
420
|
}
|
|
422
421
|
}
|
|
423
422
|
const mcpServers = await this.buildMcpServersConfig();
|
|
424
|
-
return this.
|
|
423
|
+
return this.threadManager.createThreadForTurn({
|
|
425
424
|
driverId,
|
|
426
425
|
agentId: this.state.agent_id,
|
|
427
|
-
|
|
426
|
+
thread: sdkThread,
|
|
428
427
|
turn: sdkTurn,
|
|
429
428
|
cwd: artifacts.cwd,
|
|
430
429
|
writableRoots: artifacts.writableRoots,
|
|
@@ -433,7 +432,7 @@ export class AgentCortex {
|
|
|
433
432
|
permissionMode: options?.permissionMode,
|
|
434
433
|
networkAccess: options?.networkAccess,
|
|
435
434
|
trustedDataHosts: options?.trustedDataHosts,
|
|
436
|
-
env: this.
|
|
435
|
+
env: this.threadRecord.environment_snapshot?.environment_variables,
|
|
437
436
|
resume: options?.resume === false ? undefined : this.state.sdk_session_id,
|
|
438
437
|
mcpServers,
|
|
439
438
|
systemPromptAppend: this.preparePrompt(paths.base, artifacts),
|
|
@@ -443,7 +442,7 @@ export class AgentCortex {
|
|
|
443
442
|
const now = Date.now();
|
|
444
443
|
pruneNativeSessionPrewarmCache(now);
|
|
445
444
|
const driverId = this.resolveBackendDriverId();
|
|
446
|
-
const key = nativeSessionPrewarmKey(this.state.agent_id, this.state.
|
|
445
|
+
const key = nativeSessionPrewarmKey(this.state.agent_id, this.state.thread_id, driverId, options);
|
|
447
446
|
const prewarmed = nativeSessionPrewarmCache.get(key);
|
|
448
447
|
if (prewarmed && prewarmed.expiresAt > now) {
|
|
449
448
|
nativeSessionPrewarmCache.delete(key);
|
|
@@ -451,16 +450,16 @@ export class AgentCortex {
|
|
|
451
450
|
return await prewarmed.promise;
|
|
452
451
|
}
|
|
453
452
|
catch (err) {
|
|
454
|
-
logger.debug({ err, agent_id: this.state.agent_id,
|
|
453
|
+
logger.debug({ err, agent_id: this.state.agent_id, thread_id: this.state.thread_id }, 'Native thread prewarm was unavailable; creating a fresh thread');
|
|
455
454
|
}
|
|
456
455
|
}
|
|
457
456
|
return this.createNativeSdkSession(options);
|
|
458
457
|
}
|
|
459
|
-
async
|
|
458
|
+
async prewarmNativeThread(options) {
|
|
460
459
|
const now = Date.now();
|
|
461
460
|
pruneNativeSessionPrewarmCache(now);
|
|
462
461
|
const driverId = this.resolveBackendDriverId();
|
|
463
|
-
const key = nativeSessionPrewarmKey(this.state.agent_id, this.state.
|
|
462
|
+
const key = nativeSessionPrewarmKey(this.state.agent_id, this.state.thread_id, driverId, options);
|
|
464
463
|
const existing = nativeSessionPrewarmCache.get(key);
|
|
465
464
|
if (existing && existing.expiresAt > now) {
|
|
466
465
|
try {
|
|
@@ -482,9 +481,9 @@ export class AgentCortex {
|
|
|
482
481
|
networkAccess: options?.networkAccess,
|
|
483
482
|
trustedDataHosts: options?.trustedDataHosts,
|
|
484
483
|
waitForTokenTimeoutMs: 1_500,
|
|
485
|
-
}).then(async (
|
|
486
|
-
await
|
|
487
|
-
return
|
|
484
|
+
}).then(async (thread) => {
|
|
485
|
+
await thread.prepare?.();
|
|
486
|
+
return thread;
|
|
488
487
|
}),
|
|
489
488
|
};
|
|
490
489
|
nativeSessionPrewarmCache.set(key, entry);
|
|
@@ -493,7 +492,7 @@ export class AgentCortex {
|
|
|
493
492
|
return;
|
|
494
493
|
nativeSessionPrewarmCache.delete(key);
|
|
495
494
|
entry.promise
|
|
496
|
-
.then((
|
|
495
|
+
.then((thread) => thread.close())
|
|
497
496
|
.catch(() => { });
|
|
498
497
|
}, NATIVE_SESSION_PREWARM_TTL_MS);
|
|
499
498
|
timeout.unref?.();
|
|
@@ -504,12 +503,12 @@ export class AgentCortex {
|
|
|
504
503
|
if (nativeSessionPrewarmCache.get(key) === entry) {
|
|
505
504
|
nativeSessionPrewarmCache.delete(key);
|
|
506
505
|
}
|
|
507
|
-
logger.debug({ err, agent_id: this.state.agent_id,
|
|
506
|
+
logger.debug({ err, agent_id: this.state.agent_id, thread_id: this.state.thread_id }, 'Native thread prewarm failed');
|
|
508
507
|
}
|
|
509
508
|
}
|
|
510
509
|
async run(taskId, prompt, options) {
|
|
511
510
|
if (this.state.status === 'busy') {
|
|
512
|
-
throw new Error(`Cortex ${this.state.agent_id}:${this.state.
|
|
511
|
+
throw new Error(`Cortex ${this.state.agent_id}:${this.state.thread_id} is already busy.`);
|
|
513
512
|
}
|
|
514
513
|
this.state.task_id = taskId || `task-${Date.now()}`;
|
|
515
514
|
this.state.status = 'busy';
|
|
@@ -520,11 +519,11 @@ export class AgentCortex {
|
|
|
520
519
|
this.loopGuard.reset();
|
|
521
520
|
if (options?.resume === false && this.state.sdk_session_id) {
|
|
522
521
|
this.state.sdk_session_id = undefined;
|
|
523
|
-
|
|
522
|
+
clearThreadSdkSessionId(this.state.agent_id, this.state.thread_id);
|
|
524
523
|
}
|
|
525
|
-
|
|
524
|
+
updateThreadStatus(this.state.agent_id, this.state.thread_id, 'running');
|
|
526
525
|
const paths = resolveAgentRuntimePaths(this.state.agent_id);
|
|
527
|
-
const artifacts =
|
|
526
|
+
const artifacts = resolveThreadTaskArtifactPaths(this.threadRecord, this.state.task_id);
|
|
528
527
|
this.initBrain(paths.base, artifacts.cwd);
|
|
529
528
|
ensureTaskArtifactLayout(artifacts);
|
|
530
529
|
logger.info({
|
|
@@ -535,7 +534,7 @@ export class AgentCortex {
|
|
|
535
534
|
await this.notifyState();
|
|
536
535
|
let runtimeTimeout = null;
|
|
537
536
|
let runtimeTimedOut = false;
|
|
538
|
-
let
|
|
537
|
+
let activeThread = null;
|
|
539
538
|
const runtimeTimeoutMs = typeof options?.timeoutMs === 'number' && Number.isFinite(options.timeoutMs)
|
|
540
539
|
? Math.max(0, options.timeoutMs)
|
|
541
540
|
: 0;
|
|
@@ -559,12 +558,12 @@ export class AgentCortex {
|
|
|
559
558
|
.join('\n\n');
|
|
560
559
|
const mcpServers = await this.buildMcpServersConfig();
|
|
561
560
|
const driverId = this.resolveBackendDriverId();
|
|
562
|
-
const
|
|
563
|
-
const sdkTurn = createTurn({
|
|
564
|
-
const
|
|
561
|
+
const sdkThread = createThread({ id: this.state.thread_id });
|
|
562
|
+
const sdkTurn = createTurn({ threadId: sdkThread.id });
|
|
563
|
+
const thread = await this.threadManager.createThreadForTurn({
|
|
565
564
|
driverId,
|
|
566
565
|
agentId: this.state.agent_id,
|
|
567
|
-
|
|
566
|
+
thread: sdkThread,
|
|
568
567
|
turn: sdkTurn,
|
|
569
568
|
cwd: artifacts.cwd,
|
|
570
569
|
writableRoots: artifacts.writableRoots,
|
|
@@ -573,18 +572,18 @@ export class AgentCortex {
|
|
|
573
572
|
permissionMode: options?.permissionMode,
|
|
574
573
|
networkAccess: options?.networkAccess,
|
|
575
574
|
trustedDataHosts: options?.trustedDataHosts,
|
|
576
|
-
env: this.
|
|
575
|
+
env: this.threadRecord.environment_snapshot?.environment_variables,
|
|
577
576
|
resume: options?.resume === false ? undefined : this.state.sdk_session_id,
|
|
578
577
|
mcpServers,
|
|
579
578
|
systemPromptAppend: systemPrompt,
|
|
580
579
|
});
|
|
581
|
-
|
|
580
|
+
activeThread = thread;
|
|
582
581
|
if (runtimeTimeoutMs > 0) {
|
|
583
582
|
runtimeTimeout = setTimeout(() => {
|
|
584
583
|
runtimeTimedOut = true;
|
|
585
584
|
this.controller?.abort();
|
|
586
585
|
try {
|
|
587
|
-
|
|
586
|
+
activeThread?.close();
|
|
588
587
|
}
|
|
589
588
|
catch {
|
|
590
589
|
// Closing is best-effort; the loop below will surface the timeout.
|
|
@@ -595,26 +594,26 @@ export class AgentCortex {
|
|
|
595
594
|
this.state.activity.action = 'thinking';
|
|
596
595
|
await this.notifyState();
|
|
597
596
|
// Send the prompt to the SDK session
|
|
598
|
-
await
|
|
597
|
+
await thread.send(prompt);
|
|
599
598
|
let finalText = '';
|
|
600
599
|
let receivedStreamedText = false;
|
|
601
|
-
const stream =
|
|
600
|
+
const stream = thread.stream();
|
|
602
601
|
for await (const message of stream) {
|
|
603
602
|
if (runtimeTimedOut) {
|
|
604
603
|
throw new Error(runtimeTimeoutMessage);
|
|
605
604
|
}
|
|
606
605
|
if (this.controller?.signal.aborted) {
|
|
607
|
-
|
|
606
|
+
thread.close();
|
|
608
607
|
throw new Error('Aborted');
|
|
609
608
|
}
|
|
610
609
|
const msg = message;
|
|
611
|
-
if (msg.
|
|
612
|
-
this.state.sdk_session_id = msg.
|
|
613
|
-
|
|
610
|
+
if (msg.thread_id && !this.state.sdk_session_id) {
|
|
611
|
+
this.state.sdk_session_id = msg.thread_id;
|
|
612
|
+
updateThreadSdkSessionId(this.state.agent_id, this.state.thread_id, msg.thread_id);
|
|
614
613
|
}
|
|
615
|
-
const normalizedOutputs = this.
|
|
614
|
+
const normalizedOutputs = this.threadManager.normalizeOutput({
|
|
616
615
|
driverId: this.state.backend_driver_id,
|
|
617
|
-
|
|
616
|
+
threadId: this.state.thread_id,
|
|
618
617
|
turnId: sdkTurn.id,
|
|
619
618
|
output: msg,
|
|
620
619
|
});
|
|
@@ -680,14 +679,14 @@ export class AgentCortex {
|
|
|
680
679
|
await this.events.onReply?.(finalText);
|
|
681
680
|
await this.consolidateMemory(paths.base, finalText);
|
|
682
681
|
try {
|
|
683
|
-
const usage = extractUsageTotals(await
|
|
682
|
+
const usage = extractUsageTotals(await thread.getContextUsage?.());
|
|
684
683
|
if (usage) {
|
|
685
|
-
reportUsageToGateway(this.state.agent_id, this.state.
|
|
684
|
+
reportUsageToGateway(this.state.agent_id, this.state.thread_id, usage.tokensIn, usage.tokensOut);
|
|
686
685
|
try {
|
|
687
|
-
|
|
686
|
+
updateThreadUsage(this.state.agent_id, this.state.thread_id, usage.tokensIn, usage.tokensOut);
|
|
688
687
|
}
|
|
689
688
|
catch {
|
|
690
|
-
appendGlobalUsage(this.state.agent_id, this.state.
|
|
689
|
+
appendGlobalUsage(this.state.agent_id, this.state.thread_id, usage.tokensIn, usage.tokensOut);
|
|
691
690
|
}
|
|
692
691
|
}
|
|
693
692
|
}
|
|
@@ -697,19 +696,19 @@ export class AgentCortex {
|
|
|
697
696
|
message: usageErr instanceof Error ? usageErr.message : String(usageErr),
|
|
698
697
|
stack: usageErr instanceof Error ? usageErr.stack : undefined,
|
|
699
698
|
agent_id: this.state.agent_id,
|
|
700
|
-
|
|
701
|
-
}, 'Failed to persist
|
|
699
|
+
thread_id: this.state.thread_id,
|
|
700
|
+
}, 'Failed to persist thread usage after run');
|
|
702
701
|
}
|
|
703
702
|
this.state.status = 'idle';
|
|
704
703
|
this.state.last_activity_at = Date.now();
|
|
705
704
|
this.state.activity = { phase: 'done' };
|
|
706
|
-
|
|
705
|
+
updateThreadStatus(this.state.agent_id, this.state.thread_id, 'idle');
|
|
707
706
|
}
|
|
708
707
|
catch (err) {
|
|
709
708
|
if (runtimeTimedOut) {
|
|
710
709
|
this.state.status = 'error';
|
|
711
710
|
this.state.activity = { phase: 'error', action: runtimeTimeoutMessage };
|
|
712
|
-
|
|
711
|
+
updateThreadStatus(this.state.agent_id, this.state.thread_id, 'error');
|
|
713
712
|
logger.error({ err, agent_id: this.state.agent_id, task_id: this.state.task_id }, 'Cortex: Task timed out');
|
|
714
713
|
try {
|
|
715
714
|
await this.events.onError?.(runtimeTimeoutMessage, new Error(runtimeTimeoutMessage));
|
|
@@ -719,12 +718,12 @@ export class AgentCortex {
|
|
|
719
718
|
else if (this.controller?.signal.aborted) {
|
|
720
719
|
this.state.status = 'interrupted';
|
|
721
720
|
this.state.activity = { phase: 'interrupted' };
|
|
722
|
-
|
|
721
|
+
updateThreadStatus(this.state.agent_id, this.state.thread_id, 'idle');
|
|
723
722
|
}
|
|
724
723
|
else {
|
|
725
724
|
this.state.status = 'error';
|
|
726
725
|
this.state.activity = { phase: 'error', action: err.message };
|
|
727
|
-
|
|
726
|
+
updateThreadStatus(this.state.agent_id, this.state.thread_id, 'error');
|
|
728
727
|
logger.error({ err, agent_id: this.state.agent_id }, 'Cortex: Loop failed');
|
|
729
728
|
const displayError = `> 🚨 **Agent Pipeline Halted:**\n> ${err.message}`;
|
|
730
729
|
try {
|
|
@@ -752,14 +751,14 @@ export class AgentCortex {
|
|
|
752
751
|
}
|
|
753
752
|
async runNativeStream(taskId, messages, options) {
|
|
754
753
|
if (this.state.status === 'busy') {
|
|
755
|
-
throw new Error(`Cortex ${this.state.agent_id}:${this.state.
|
|
754
|
+
throw new Error(`Cortex ${this.state.agent_id}:${this.state.thread_id} is already busy.`);
|
|
756
755
|
}
|
|
757
756
|
this.state.task_id = taskId || `task-${Date.now()}`;
|
|
758
757
|
this.state.status = 'busy';
|
|
759
758
|
this.controller = new AbortController();
|
|
760
|
-
|
|
759
|
+
updateThreadStatus(this.state.agent_id, this.state.thread_id, 'running');
|
|
761
760
|
const paths = resolveAgentRuntimePaths(this.state.agent_id);
|
|
762
|
-
const artifacts =
|
|
761
|
+
const artifacts = resolveThreadTaskArtifactPaths(this.threadRecord, this.state.task_id);
|
|
763
762
|
ensureTaskArtifactLayout(artifacts);
|
|
764
763
|
logger.info({
|
|
765
764
|
agent_id: this.state.agent_id,
|
|
@@ -792,7 +791,7 @@ export class AgentCortex {
|
|
|
792
791
|
prompt_excerpt: promptExcerpt,
|
|
793
792
|
context_excerpt: contextExcerpt,
|
|
794
793
|
}, 'Task stream context');
|
|
795
|
-
|
|
794
|
+
storeThreadUiEvent(this.state.agent_id, this.state.thread_id, {
|
|
796
795
|
id: `${this.state.task_id}:task-started:${Date.now()}`,
|
|
797
796
|
timestamp: new Date().toISOString(),
|
|
798
797
|
task_id: this.state.task_id,
|
|
@@ -811,7 +810,7 @@ export class AgentCortex {
|
|
|
811
810
|
});
|
|
812
811
|
const encoder = new TextEncoder();
|
|
813
812
|
const agentId = this.state.agent_id;
|
|
814
|
-
const
|
|
813
|
+
const threadId = this.state.thread_id;
|
|
815
814
|
const self = this;
|
|
816
815
|
return new ReadableStream({
|
|
817
816
|
async start(controller) {
|
|
@@ -832,8 +831,8 @@ export class AgentCortex {
|
|
|
832
831
|
let receivedIncrementalText = false;
|
|
833
832
|
let receivedIncrementalReasoning = false;
|
|
834
833
|
const assistantMessageId = `${taskId}-assistant`;
|
|
835
|
-
const sdkSessionRecord =
|
|
836
|
-
const sdkTurn = createTurn({
|
|
834
|
+
const sdkSessionRecord = createThread({ id: self.state.thread_id });
|
|
835
|
+
const sdkTurn = createTurn({ threadId: sdkSessionRecord.id });
|
|
837
836
|
const isAborted = () => self.controller?.signal.aborted === true;
|
|
838
837
|
const abortSdkSession = () => {
|
|
839
838
|
try {
|
|
@@ -847,30 +846,12 @@ export class AgentCortex {
|
|
|
847
846
|
const persistUiChunks = (chunks) => {
|
|
848
847
|
const timestamp = new Date().toISOString();
|
|
849
848
|
for (const chunk of chunks) {
|
|
850
|
-
|
|
849
|
+
storeThreadUiEvent(self.state.agent_id, self.state.thread_id, {
|
|
851
850
|
id: `${taskId}:${timestamp}:${Math.random().toString(36).slice(2, 8)}`,
|
|
852
851
|
timestamp,
|
|
853
852
|
task_id: taskId,
|
|
854
853
|
chunk,
|
|
855
854
|
});
|
|
856
|
-
if (chunk.type === 'data-codex-event') {
|
|
857
|
-
const data = chunk.data && typeof chunk.data === 'object'
|
|
858
|
-
? chunk.data
|
|
859
|
-
: {};
|
|
860
|
-
const raw = data.raw && typeof data.raw === 'object'
|
|
861
|
-
? data.raw
|
|
862
|
-
: null;
|
|
863
|
-
if (raw && typeof raw.method === 'string') {
|
|
864
|
-
appendThreadEvent({
|
|
865
|
-
threadId: self.state.session_id,
|
|
866
|
-
runtimeThreadId: self.state.sdk_session_id || self.state.session_id,
|
|
867
|
-
source: 'codex-app-server',
|
|
868
|
-
eventType: raw.method,
|
|
869
|
-
rawPayload: raw,
|
|
870
|
-
receivedAt: timestamp,
|
|
871
|
-
});
|
|
872
|
-
}
|
|
873
|
-
}
|
|
874
855
|
}
|
|
875
856
|
};
|
|
876
857
|
const nextTextPartId = () => {
|
|
@@ -1087,9 +1068,9 @@ export class AgentCortex {
|
|
|
1087
1068
|
type: message.type,
|
|
1088
1069
|
method: typeof message.method === 'string' ? message.method : undefined,
|
|
1089
1070
|
}, 'Task stream event');
|
|
1090
|
-
if (message.
|
|
1091
|
-
self.state.sdk_session_id = message.
|
|
1092
|
-
|
|
1071
|
+
if (message.thread_id && !self.state.sdk_session_id) {
|
|
1072
|
+
self.state.sdk_session_id = message.thread_id;
|
|
1073
|
+
updateThreadSdkSessionId(self.state.agent_id, self.state.thread_id, message.thread_id);
|
|
1093
1074
|
}
|
|
1094
1075
|
if (message.type === 'assistant') {
|
|
1095
1076
|
const phase = typeof message.phase === 'string' ? message.phase : '';
|
|
@@ -1123,9 +1104,9 @@ export class AgentCortex {
|
|
|
1123
1104
|
receivedIncrementalReasoning = true;
|
|
1124
1105
|
}
|
|
1125
1106
|
}
|
|
1126
|
-
const normalizedOutputs = self.
|
|
1107
|
+
const normalizedOutputs = self.threadManager.normalizeOutput({
|
|
1127
1108
|
driverId: self.state.backend_driver_id,
|
|
1128
|
-
|
|
1109
|
+
threadId: self.state.thread_id,
|
|
1129
1110
|
turnId: sdkTurn.id,
|
|
1130
1111
|
output: message,
|
|
1131
1112
|
});
|
|
@@ -1199,7 +1180,7 @@ export class AgentCortex {
|
|
|
1199
1180
|
: extractTerminalFailureText(normalizedOutputs);
|
|
1200
1181
|
if (terminalFailureText && !streamError) {
|
|
1201
1182
|
streamError = new Error(terminalFailureText);
|
|
1202
|
-
|
|
1183
|
+
clearThreadSdkSessionId(self.state.agent_id, self.state.thread_id);
|
|
1203
1184
|
self.state.sdk_session_id = undefined;
|
|
1204
1185
|
}
|
|
1205
1186
|
if (message.type === 'result') {
|
|
@@ -1265,7 +1246,7 @@ export class AgentCortex {
|
|
|
1265
1246
|
self.controller?.signal.removeEventListener('abort', abortSdkSession);
|
|
1266
1247
|
self.state.status = 'idle';
|
|
1267
1248
|
self.state.last_activity_at = Date.now();
|
|
1268
|
-
|
|
1249
|
+
updateThreadStatus(self.state.agent_id, self.state.thread_id, 'idle');
|
|
1269
1250
|
await self.notifyState();
|
|
1270
1251
|
self.controller = null;
|
|
1271
1252
|
if (streamError && !wasAborted) {
|
|
@@ -1283,12 +1264,12 @@ export class AgentCortex {
|
|
|
1283
1264
|
try {
|
|
1284
1265
|
const usage = extractUsageTotals(await sdkSession?.getContextUsage?.());
|
|
1285
1266
|
if (usage) {
|
|
1286
|
-
reportUsageToGateway(self.state.agent_id, self.state.
|
|
1267
|
+
reportUsageToGateway(self.state.agent_id, self.state.thread_id, usage.tokensIn, usage.tokensOut);
|
|
1287
1268
|
try {
|
|
1288
|
-
|
|
1269
|
+
updateThreadUsage(self.state.agent_id, self.state.thread_id, usage.tokensIn, usage.tokensOut);
|
|
1289
1270
|
}
|
|
1290
1271
|
catch {
|
|
1291
|
-
appendGlobalUsage(self.state.agent_id, self.state.
|
|
1272
|
+
appendGlobalUsage(self.state.agent_id, self.state.thread_id, usage.tokensIn, usage.tokensOut);
|
|
1292
1273
|
}
|
|
1293
1274
|
}
|
|
1294
1275
|
}
|
|
@@ -1298,15 +1279,15 @@ export class AgentCortex {
|
|
|
1298
1279
|
message: usageErr instanceof Error ? usageErr.message : String(usageErr),
|
|
1299
1280
|
stack: usageErr instanceof Error ? usageErr.stack : undefined,
|
|
1300
1281
|
agent_id: self.state.agent_id,
|
|
1301
|
-
|
|
1302
|
-
}, 'Failed to persist
|
|
1282
|
+
thread_id: self.state.thread_id,
|
|
1283
|
+
}, 'Failed to persist thread usage after native stream run');
|
|
1303
1284
|
}
|
|
1304
1285
|
try {
|
|
1305
|
-
const taskFolderRemoved = cleanupTaskFolderWithoutMeaningfulArtifacts(self.state.
|
|
1286
|
+
const taskFolderRemoved = cleanupTaskFolderWithoutMeaningfulArtifacts(self.state.thread_id, self.state.task_id);
|
|
1306
1287
|
if (taskFolderRemoved) {
|
|
1307
1288
|
logger.info({
|
|
1308
1289
|
agent_id: self.state.agent_id,
|
|
1309
|
-
|
|
1290
|
+
thread_id: self.state.thread_id,
|
|
1310
1291
|
task_id: self.state.task_id,
|
|
1311
1292
|
}, 'Removed completed task folder without meaningful artifacts');
|
|
1312
1293
|
}
|
|
@@ -1315,7 +1296,7 @@ export class AgentCortex {
|
|
|
1315
1296
|
logger.warn({
|
|
1316
1297
|
cleanupErr,
|
|
1317
1298
|
agent_id: self.state.agent_id,
|
|
1318
|
-
|
|
1299
|
+
thread_id: self.state.thread_id,
|
|
1319
1300
|
task_id: self.state.task_id,
|
|
1320
1301
|
}, 'Failed to remove completed task folder without meaningful artifacts');
|
|
1321
1302
|
}
|
|
@@ -1472,16 +1453,16 @@ ${result}`;
|
|
|
1472
1453
|
summary = data.choices?.[0]?.message?.content?.trim();
|
|
1473
1454
|
if (summary && !summary.toLowerCase().includes('no new facts')) {
|
|
1474
1455
|
await this.memorySubsystem.writeEphemeral({
|
|
1475
|
-
scope: '
|
|
1456
|
+
scope: 'thread',
|
|
1476
1457
|
content: summary,
|
|
1477
1458
|
tags: ['consolidated', 'task-result'],
|
|
1478
1459
|
});
|
|
1479
|
-
const classification =
|
|
1460
|
+
const classification = classifyThreadInsight({
|
|
1480
1461
|
summary,
|
|
1481
1462
|
successfulOutcomeCount: 0,
|
|
1482
1463
|
repetitionCount: 0,
|
|
1483
1464
|
});
|
|
1484
|
-
logger.info({ classification, agent_id: this.state.agent_id }, 'Classified extracted
|
|
1465
|
+
logger.info({ classification, agent_id: this.state.agent_id }, 'Classified extracted thread insight');
|
|
1485
1466
|
const entry = `\n- [${now.toISOString()}] Task: ${this.state.task_id}\n Facts: ${summary.replace(/\n/g, '\n ')}\n`;
|
|
1486
1467
|
fs.mkdirSync(path.dirname(journalPath), { recursive: true });
|
|
1487
1468
|
fs.appendFileSync(journalPath, entry, 'utf-8');
|