@supen-ai/cli 1.3.4 → 1.4.1

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.
Files changed (139) hide show
  1. package/README.md +1 -1
  2. package/daemon/dist/agent-sdk/drivers/codex-app-server-driver.d.ts.map +1 -1
  3. package/daemon/dist/agent-sdk/drivers/codex-app-server-driver.js +0 -2
  4. package/daemon/dist/agent-sdk/drivers/codex-app-server-driver.js.map +1 -1
  5. package/daemon/dist/agent-sdk/drivers/registry.d.ts +2 -8
  6. package/daemon/dist/agent-sdk/drivers/registry.d.ts.map +1 -1
  7. package/daemon/dist/agent-sdk/drivers/registry.js +7 -138
  8. package/daemon/dist/agent-sdk/drivers/registry.js.map +1 -1
  9. package/daemon/dist/agent-sdk/index.d.ts +0 -11
  10. package/daemon/dist/agent-sdk/index.d.ts.map +1 -1
  11. package/daemon/dist/agent-sdk/index.js +0 -11
  12. package/daemon/dist/agent-sdk/index.js.map +1 -1
  13. package/daemon/dist/agent-sdk/session-manager.d.ts +1 -1
  14. package/daemon/dist/agent-sdk/session-manager.d.ts.map +1 -1
  15. package/daemon/dist/agent-sdk/session-manager.js +1 -2
  16. package/daemon/dist/agent-sdk/session-manager.js.map +1 -1
  17. package/daemon/dist/channels/acp.d.ts.map +1 -1
  18. package/daemon/dist/channels/acp.js +2 -3
  19. package/daemon/dist/channels/acp.js.map +1 -1
  20. package/daemon/dist/channels/http-routes.js +6 -6
  21. package/daemon/dist/channels/http-routes.js.map +1 -1
  22. package/daemon/dist/core/config.d.ts +1 -1
  23. package/daemon/dist/core/config.d.ts.map +1 -1
  24. package/daemon/dist/core/config.js +1 -1
  25. package/daemon/dist/core/config.js.map +1 -1
  26. package/daemon/dist/core/cortex.d.ts.map +1 -1
  27. package/daemon/dist/core/cortex.js +90 -205
  28. package/daemon/dist/core/cortex.js.map +1 -1
  29. package/daemon/dist/core/env.js +1 -1
  30. package/daemon/dist/core/gateway.d.ts.map +1 -1
  31. package/daemon/dist/core/gateway.js +1 -11
  32. package/daemon/dist/core/gateway.js.map +1 -1
  33. package/daemon/dist/core/loop-guard.d.ts +1 -1
  34. package/daemon/dist/core/loop-guard.js +1 -1
  35. package/daemon/dist/core/protocol-adapter.d.ts +1 -3
  36. package/daemon/dist/core/protocol-adapter.d.ts.map +1 -1
  37. package/daemon/dist/core/protocol-adapter.js +1 -3
  38. package/daemon/dist/core/protocol-adapter.js.map +1 -1
  39. package/daemon/dist/core/thread-context.d.ts +76 -0
  40. package/daemon/dist/core/thread-context.d.ts.map +1 -0
  41. package/daemon/dist/core/thread-context.js +308 -0
  42. package/daemon/dist/core/thread-context.js.map +1 -0
  43. package/daemon/dist/http/routes/rpc.d.ts.map +1 -1
  44. package/daemon/dist/http/routes/rpc.js +18 -1
  45. package/daemon/dist/http/routes/rpc.js.map +1 -1
  46. package/daemon/dist/http/routes/sessions.js +1 -1
  47. package/daemon/dist/http/routes/system.d.ts +3 -0
  48. package/daemon/dist/http/routes/system.d.ts.map +1 -1
  49. package/daemon/dist/http/routes/system.js +437 -141
  50. package/daemon/dist/http/routes/system.js.map +1 -1
  51. package/daemon/dist/index.d.ts.map +1 -1
  52. package/daemon/dist/index.js +2 -1
  53. package/daemon/dist/index.js.map +1 -1
  54. package/daemon/dist/mcp/index.d.ts +2 -6
  55. package/daemon/dist/mcp/index.d.ts.map +1 -1
  56. package/daemon/dist/mcp/index.js +2 -6
  57. package/daemon/dist/mcp/index.js.map +1 -1
  58. package/daemon/dist/mcp/tools.d.ts +5 -7
  59. package/daemon/dist/mcp/tools.d.ts.map +1 -1
  60. package/daemon/dist/mcp/tools.js +4 -8
  61. package/daemon/dist/mcp/tools.js.map +1 -1
  62. package/daemon/dist/tools/built-ins.d.ts +9 -84
  63. package/daemon/dist/tools/built-ins.d.ts.map +1 -1
  64. package/daemon/dist/tools/built-ins.js +3 -3
  65. package/daemon/dist/tools/built-ins.js.map +1 -1
  66. package/daemon/dist/tools/local-tool.d.ts +7 -0
  67. package/daemon/dist/tools/local-tool.d.ts.map +1 -0
  68. package/daemon/dist/tools/local-tool.js +4 -0
  69. package/daemon/dist/tools/local-tool.js.map +1 -0
  70. package/daemon/dist/tools/skill-tools.d.ts +5 -8
  71. package/daemon/dist/tools/skill-tools.d.ts.map +1 -1
  72. package/daemon/dist/tools/skill-tools.js +6 -10
  73. package/daemon/dist/tools/skill-tools.js.map +1 -1
  74. package/daemon/package.json +6 -9
  75. package/dist/backend.js +5 -5
  76. package/dist/backend.js.map +1 -1
  77. package/dist/bootstrap.js +2 -6
  78. package/dist/bootstrap.js.map +1 -1
  79. package/dist/computer.js +1 -1
  80. package/dist/doctor.js +1 -1
  81. package/dist/doctor.js.map +1 -1
  82. package/dist/index.js +1 -1
  83. package/dist/repl.js +6 -66
  84. package/dist/repl.js.map +1 -1
  85. package/dist/service.js +2 -3
  86. package/dist/service.js.map +1 -1
  87. package/package.json +3 -6
  88. package/daemon/dist/agent-sdk/drivers/acpx-driver.d.ts +0 -21
  89. package/daemon/dist/agent-sdk/drivers/acpx-driver.d.ts.map +0 -1
  90. package/daemon/dist/agent-sdk/drivers/acpx-driver.js +0 -488
  91. package/daemon/dist/agent-sdk/drivers/acpx-driver.js.map +0 -1
  92. package/daemon/dist/agent-sdk/drivers/claude-acpx-driver.d.ts +0 -5
  93. package/daemon/dist/agent-sdk/drivers/claude-acpx-driver.d.ts.map +0 -1
  94. package/daemon/dist/agent-sdk/drivers/claude-acpx-driver.js +0 -7
  95. package/daemon/dist/agent-sdk/drivers/claude-acpx-driver.js.map +0 -1
  96. package/daemon/dist/agent-sdk/drivers/claude-cli-direct-driver.d.ts +0 -20
  97. package/daemon/dist/agent-sdk/drivers/claude-cli-direct-driver.d.ts.map +0 -1
  98. package/daemon/dist/agent-sdk/drivers/claude-cli-direct-driver.js +0 -264
  99. package/daemon/dist/agent-sdk/drivers/claude-cli-direct-driver.js.map +0 -1
  100. package/daemon/dist/agent-sdk/drivers/claude-code-driver.d.ts +0 -29
  101. package/daemon/dist/agent-sdk/drivers/claude-code-driver.d.ts.map +0 -1
  102. package/daemon/dist/agent-sdk/drivers/claude-code-driver.js +0 -24
  103. package/daemon/dist/agent-sdk/drivers/claude-code-driver.js.map +0 -1
  104. package/daemon/dist/agent-sdk/drivers/claude-code-events.d.ts +0 -25
  105. package/daemon/dist/agent-sdk/drivers/claude-code-events.d.ts.map +0 -1
  106. package/daemon/dist/agent-sdk/drivers/claude-code-events.js +0 -58
  107. package/daemon/dist/agent-sdk/drivers/claude-code-events.js.map +0 -1
  108. package/daemon/dist/agent-sdk/drivers/claude-code-items.d.ts +0 -41
  109. package/daemon/dist/agent-sdk/drivers/claude-code-items.d.ts.map +0 -1
  110. package/daemon/dist/agent-sdk/drivers/claude-code-items.js +0 -77
  111. package/daemon/dist/agent-sdk/drivers/claude-code-items.js.map +0 -1
  112. package/daemon/dist/agent-sdk/drivers/codex-acpx-driver.d.ts +0 -5
  113. package/daemon/dist/agent-sdk/drivers/codex-acpx-driver.d.ts.map +0 -1
  114. package/daemon/dist/agent-sdk/drivers/codex-acpx-driver.js +0 -7
  115. package/daemon/dist/agent-sdk/drivers/codex-acpx-driver.js.map +0 -1
  116. package/daemon/dist/agent-sdk/drivers/codex-exec-driver.d.ts +0 -28
  117. package/daemon/dist/agent-sdk/drivers/codex-exec-driver.d.ts.map +0 -1
  118. package/daemon/dist/agent-sdk/drivers/codex-exec-driver.js +0 -219
  119. package/daemon/dist/agent-sdk/drivers/codex-exec-driver.js.map +0 -1
  120. package/daemon/dist/agent-sdk/drivers/codex-exec-events.d.ts +0 -9
  121. package/daemon/dist/agent-sdk/drivers/codex-exec-events.d.ts.map +0 -1
  122. package/daemon/dist/agent-sdk/drivers/codex-exec-events.js +0 -82
  123. package/daemon/dist/agent-sdk/drivers/codex-exec-events.js.map +0 -1
  124. package/daemon/dist/agent-sdk/drivers/codex-exec-items.d.ts +0 -9
  125. package/daemon/dist/agent-sdk/drivers/codex-exec-items.d.ts.map +0 -1
  126. package/daemon/dist/agent-sdk/drivers/codex-exec-items.js +0 -86
  127. package/daemon/dist/agent-sdk/drivers/codex-exec-items.js.map +0 -1
  128. package/daemon/dist/agent-sdk/drivers/gemini-cli-driver.d.ts +0 -17
  129. package/daemon/dist/agent-sdk/drivers/gemini-cli-driver.d.ts.map +0 -1
  130. package/daemon/dist/agent-sdk/drivers/gemini-cli-driver.js +0 -255
  131. package/daemon/dist/agent-sdk/drivers/gemini-cli-driver.js.map +0 -1
  132. package/daemon/dist/core/sdk-wrapper.d.ts +0 -36
  133. package/daemon/dist/core/sdk-wrapper.d.ts.map +0 -1
  134. package/daemon/dist/core/sdk-wrapper.js +0 -533
  135. package/daemon/dist/core/sdk-wrapper.js.map +0 -1
  136. package/daemon/dist/skills/claude_code.d.ts +0 -25
  137. package/daemon/dist/skills/claude_code.d.ts.map +0 -1
  138. package/daemon/dist/skills/claude_code.js +0 -49
  139. package/daemon/dist/skills/claude_code.js.map +0 -1
@@ -1,12 +1,11 @@
1
1
  import fs from 'fs';
2
2
  import path from 'path';
3
- import Anthropic from '@anthropic-ai/sdk';
4
3
  import { logger } from './logger.js';
5
4
  import { getGatewayInstance, getLlmToken, getLlmTokenOrWait } from './gateway.js';
6
5
  import { AGENT_MIND_FILES, ASSISTANT_NAME, agentPaths, getAgentModelConfig, } from './config.js';
7
6
  import { cleanupTaskFolderWithoutMeaningfulArtifacts, ensureTaskArtifactLayout, resolveSessionTaskArtifactPaths, } from './task-artifacts.js';
8
7
  import { getUsageStats, appendGlobalUsage, clearSessionSdkId, ensureSession, updateSessionStatus, updateSessionSdkId, updateSessionUsage, getSessionForAgent, storeSessionUiEvent, } from './store.js';
9
- import { usesAnthropicMessagesApi } from '../http/thread-title.js';
8
+ import { appendThreadEvent } from './thread-event-log.js';
10
9
  import { LoopGuard } from './loop-guard.js';
11
10
  import { convertSdkEventToUiMessageChunks, enrichUiMessageChunksWithDocumentRefs, serializeUiMessageChunks, } from './protocol-adapter.js';
12
11
  import { resolveMcpServers } from '../mcp/default-servers.js';
@@ -16,7 +15,6 @@ import { resolveInstalledPluginMcpServers } from '../plugins/hub.js';
16
15
  import { resolveEnabledSkillMcpServers } from '../skills/mcp-config.js';
17
16
  import { getRuntimeSpaceEnvVars, withRuntimeSpaceEnv } from './space-env.js';
18
17
  import { buildAssistantOutputExcerpt, buildObservableToolDetail, buildTaskContextExcerpt, excerptText, } from './observable-logging.js';
19
- import { shouldWaitForGatewayToken } from './sdk-wrapper.js';
20
18
  import { classifySessionInsight } from '../agent-sdk/session-events.js';
21
19
  import { SessionManager } from '../agent-sdk/session-manager.js';
22
20
  import { convertDriverOutputsToUiMessageChunks } from '../agent-sdk/driver-output-ui.js';
@@ -88,14 +86,16 @@ function resolveRuntimeAttachments(message, artifacts) {
88
86
  })
89
87
  .filter((attachment) => Boolean(attachment));
90
88
  }
91
- const APP_SERVER_REASONING_DELTA_METHODS = new Set([
92
- 'item/reasoningSummary/delta',
93
- 'item/reasoning/delta',
94
- 'item/reasoning/summaryTextDelta',
95
- 'item/reasoning/textDelta',
96
- 'item/plan/delta',
97
- 'item/reasoning/summaryPartAdded',
98
- ]);
89
+ function shouldWaitForGatewayToken(agentId) {
90
+ if (getLlmToken())
91
+ return false;
92
+ const selectedModel = getAgentModelConfig(agentId, true)[0];
93
+ const providerId = selectedModel?.provider_id?.toLowerCase() || '';
94
+ const isGatewayBackedProvider = providerId === 'supen' || providerId === 'babelark';
95
+ if (isGatewayBackedProvider)
96
+ return true;
97
+ return !selectedModel?.api_key;
98
+ }
99
99
  function shouldPersistUiChunkToChat(chunk) {
100
100
  return true;
101
101
  }
@@ -125,45 +125,30 @@ function appendNormalizedOutputToFinalText(normalizedOutputs, current) {
125
125
  }
126
126
  if (output.kind === 'app-server-event') {
127
127
  const event = output.event;
128
- const params = event?.params;
129
128
  if (event?.method === 'item/agentMessage/delta') {
129
+ const delta = typeof event.params?.delta === 'string' ? event.params.delta : '';
130
+ if (delta) {
131
+ next += delta;
132
+ receivedText = true;
133
+ }
130
134
  continue;
131
135
  }
132
136
  if (event?.method === 'item/completed') {
133
- const item = params?.item && typeof params.item === 'object'
134
- ? params.item
135
- : {};
136
- const phase = typeof item.phase === 'string' ? item.phase : '';
137
- if (phase && phase !== 'final_answer') {
138
- continue;
139
- }
140
- const text = item.type === 'agentMessage' && typeof item.text === 'string' ? item.text : '';
141
- if (text) {
137
+ const item = event.params?.item;
138
+ const text = typeof item?.text === 'string' ? item.text : '';
139
+ const phase = typeof item?.phase === 'string' ? item.phase : '';
140
+ if (item?.type === 'agentMessage' && text && (!phase || phase === 'final_answer')) {
142
141
  next = text;
143
142
  receivedText = true;
144
143
  }
145
144
  }
145
+ continue;
146
146
  }
147
147
  }
148
148
  return { next, receivedText };
149
149
  }
150
150
  function extractTerminalResultText(normalizedOutputs) {
151
151
  for (const output of normalizedOutputs) {
152
- if (output.kind === 'app-server-event') {
153
- const event = output.event;
154
- if (event?.method !== 'turn/completed')
155
- continue;
156
- const params = event.params;
157
- const turn = params?.turn && typeof params.turn === 'object'
158
- ? params.turn
159
- : {};
160
- if (turn.status && turn.status !== 'completed')
161
- continue;
162
- const result = typeof turn.result === 'string' ? turn.result : '';
163
- if (result.trim())
164
- return result;
165
- continue;
166
- }
167
152
  if (output.kind !== 'session-event')
168
153
  continue;
169
154
  if (output.event?.type !== 'turn.completed')
@@ -177,31 +162,6 @@ function extractTerminalResultText(normalizedOutputs) {
177
162
  }
178
163
  function extractTerminalFailureText(normalizedOutputs) {
179
164
  for (const output of normalizedOutputs) {
180
- if (output.kind === 'app-server-event') {
181
- const event = output.event;
182
- if (event?.method !== 'turn/completed' && event?.method !== 'turn/failed' && event?.method !== 'turn/cancelled') {
183
- continue;
184
- }
185
- const params = event.params;
186
- const turn = params?.turn && typeof params.turn === 'object'
187
- ? params.turn
188
- : {};
189
- const status = typeof turn.status === 'string' ? turn.status : '';
190
- if (event.method === 'turn/completed' && status !== 'failed' && status !== 'cancelled') {
191
- continue;
192
- }
193
- const error = turn.error && typeof turn.error === 'object'
194
- ? turn.error
195
- : {};
196
- const candidates = [error.message, turn.error, params?.error, params?.message];
197
- for (const candidate of candidates) {
198
- if (typeof candidate === 'string' && candidate.trim())
199
- return candidate.trim();
200
- }
201
- return status === 'cancelled' || event.method === 'turn/cancelled'
202
- ? 'Agent turn was cancelled.'
203
- : 'Agent turn failed before producing a result.';
204
- }
205
165
  if (output.kind !== 'session-event')
206
166
  continue;
207
167
  if (output.event?.type !== 'turn.failed' && output.event?.type !== 'turn.cancelled')
@@ -223,30 +183,8 @@ function chunksContainTextDelta(chunks) {
223
183
  return chunk.type === 'text-delta' && typeof chunk.delta === 'string' && chunk.delta.length > 0;
224
184
  });
225
185
  }
226
- function chunksContainAppServerAgentMessage(chunks) {
227
- return chunks.some((chunk) => isAppServerAgentMessageChunk(chunk));
228
- }
229
- function isAppServerAgentMessageChunk(chunk) {
230
- if (chunk.type !== 'data-codex-event')
231
- return false;
232
- const data = chunk.data && typeof chunk.data === 'object'
233
- ? chunk.data
234
- : null;
235
- const raw = data?.raw && typeof data.raw === 'object'
236
- ? data.raw
237
- : null;
238
- const method = typeof raw?.method === 'string' ? raw.method : '';
239
- if (method === 'item/agentMessage/delta')
240
- return true;
241
- if (method !== 'item/completed')
242
- return false;
243
- const params = raw?.params && typeof raw.params === 'object'
244
- ? raw.params
245
- : null;
246
- const item = params?.item && typeof params.item === 'object'
247
- ? params.item
248
- : null;
249
- return item?.type === 'agentMessage';
186
+ function chunksContainCodexEvent(chunks) {
187
+ return chunks.some((chunk) => chunk.type === 'data-codex-event');
250
188
  }
251
189
  function extractUiErrorText(chunks) {
252
190
  for (const chunk of chunks) {
@@ -893,8 +831,6 @@ export class AgentCortex {
893
831
  let emittedTextToUi = false;
894
832
  let receivedIncrementalText = false;
895
833
  let receivedIncrementalReasoning = false;
896
- const appServerDeltaReasoningItemIds = new Set();
897
- const appServerCommandOutputByItemId = new Map();
898
834
  const assistantMessageId = `${taskId}-assistant`;
899
835
  const sdkSessionRecord = createSession({ id: self.state.session_id });
900
836
  const sdkTurn = createTurn({ sessionId: sdkSessionRecord.id });
@@ -917,6 +853,24 @@ export class AgentCortex {
917
853
  task_id: taskId,
918
854
  chunk,
919
855
  });
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
+ }
920
874
  }
921
875
  };
922
876
  const nextTextPartId = () => {
@@ -1011,7 +965,7 @@ export class AgentCortex {
1011
965
  if (chunksContainTextDelta(normalizedChunks)) {
1012
966
  emittedTextToUi = true;
1013
967
  }
1014
- if (chunksContainAppServerAgentMessage(normalizedChunks)) {
968
+ if (chunksContainCodexEvent(normalizedChunks)) {
1015
969
  emittedTextToUi = true;
1016
970
  }
1017
971
  persistUiChunks(normalizedChunks);
@@ -1081,21 +1035,6 @@ export class AgentCortex {
1081
1035
  logger.error({ err: callbackError }, 'runNativeStream: onError failed');
1082
1036
  }
1083
1037
  };
1084
- enqueueUiMessageChunks([
1085
- {
1086
- type: 'data-codex-event',
1087
- data: {
1088
- eventType: 'system',
1089
- subtype: 'status',
1090
- raw: {
1091
- type: 'system',
1092
- subtype: 'status',
1093
- status: 'requesting',
1094
- message: 'Thinking',
1095
- },
1096
- },
1097
- },
1098
- ]);
1099
1038
  try {
1100
1039
  sdkSession = await self.ensureNativeSdkSession({
1101
1040
  model: options?.model,
@@ -1205,69 +1144,31 @@ export class AgentCortex {
1205
1144
  receivedIncrementalText = true;
1206
1145
  }
1207
1146
  }
1208
- const completedReasoningSnapshotIdsWithPriorDeltas = new Set();
1209
- for (const output of normalizedOutputs) {
1210
- if (output.kind !== 'app-server-event')
1211
- continue;
1212
- const event = output.event;
1213
- const params = event.params && typeof event.params === 'object'
1214
- ? event.params
1215
- : {};
1216
- if (APP_SERVER_REASONING_DELTA_METHODS.has(event.method)) {
1217
- const itemId = typeof params.itemId === 'string' ? params.itemId : '';
1218
- if (itemId) {
1219
- appServerDeltaReasoningItemIds.add(itemId);
1220
- }
1221
- continue;
1222
- }
1223
- if (event.method === 'item/agentMessage/delta') {
1224
- continue;
1225
- }
1226
- if (event.method !== 'item/completed')
1227
- continue;
1228
- const item = params.item && typeof params.item === 'object'
1229
- ? params.item
1230
- : {};
1231
- const itemId = typeof item.id === 'string' ? item.id : '';
1232
- if (item.type === 'reasoning' && itemId && appServerDeltaReasoningItemIds.has(itemId)) {
1233
- completedReasoningSnapshotIdsWithPriorDeltas.add(itemId);
1234
- }
1235
- }
1236
- const normalizedChunksBaseRaw = convertDriverOutputsToUiMessageChunks(normalizedOutputs, {
1237
- commandOutputByItemId: appServerCommandOutputByItemId,
1238
- });
1239
- const normalizedChunksBase = normalizedChunksBaseRaw.filter((chunk) => {
1240
- if (chunk.type === 'reasoning-delta' &&
1241
- typeof chunk.id === 'string' &&
1242
- completedReasoningSnapshotIdsWithPriorDeltas.has(chunk.id)) {
1243
- return false;
1244
- }
1245
- return true;
1246
- });
1247
- const fallbackChunksBase = convertSdkEventToUiMessageChunks(message);
1248
- const baseChunksSource = normalizedChunksBase.length > 0
1147
+ const hasAppServerEvent = normalizedOutputs.some((output) => output.kind === 'app-server-event');
1148
+ const normalizedChunksBase = convertDriverOutputsToUiMessageChunks(normalizedOutputs);
1149
+ const chunks = hasAppServerEvent
1249
1150
  ? normalizedChunksBase
1250
- : fallbackChunksBase;
1251
- const baseChunks = baseChunksSource.filter((chunk) => {
1252
- if (receivedIncrementalText &&
1253
- message.type === 'assistant' &&
1254
- normalizedChunksBase.length === 0 &&
1255
- chunk.type === 'text-delta') {
1256
- return false;
1257
- }
1258
- if (receivedIncrementalReasoning &&
1259
- message.type === 'assistant' &&
1260
- (chunk.type === 'reasoning-start' ||
1261
- chunk.type === 'reasoning-delta' ||
1262
- chunk.type === 'reasoning-end')) {
1263
- return false;
1264
- }
1265
- return true;
1266
- });
1267
- const chunks = enrichUiMessageChunksWithDocumentRefs(baseChunks, {
1268
- agentId,
1269
- workspaceRoot: artifacts.artifactRoot,
1270
- });
1151
+ : enrichUiMessageChunksWithDocumentRefs((normalizedChunksBase.length > 0
1152
+ ? normalizedChunksBase
1153
+ : convertSdkEventToUiMessageChunks(message)).filter((chunk) => {
1154
+ if (receivedIncrementalText &&
1155
+ message.type === 'assistant' &&
1156
+ normalizedChunksBase.length === 0 &&
1157
+ chunk.type === 'text-delta') {
1158
+ return false;
1159
+ }
1160
+ if (receivedIncrementalReasoning &&
1161
+ message.type === 'assistant' &&
1162
+ (chunk.type === 'reasoning-start' ||
1163
+ chunk.type === 'reasoning-delta' ||
1164
+ chunk.type === 'reasoning-end')) {
1165
+ return false;
1166
+ }
1167
+ return true;
1168
+ }), {
1169
+ agentId,
1170
+ workspaceRoot: artifacts.artifactRoot,
1171
+ });
1271
1172
  const emittedErrorChunk = chunks.some((chunk) => chunk.type === 'error');
1272
1173
  const uiErrorText = extractUiErrorText(chunks);
1273
1174
  if (uiErrorText && !streamError) {
@@ -1280,8 +1181,11 @@ export class AgentCortex {
1280
1181
  output_excerpt: buildAssistantOutputExcerpt(serializeUiMessageChunks(chunks)?.trim() ?? ''),
1281
1182
  }, 'Task stream chunk');
1282
1183
  enqueueUiMessageChunks(chunks);
1184
+ emittedTextToUi = true;
1283
1185
  }
1284
- const terminalResultText = extractTerminalResultText(normalizedOutputs);
1186
+ const terminalResultText = hasAppServerEvent
1187
+ ? ''
1188
+ : extractTerminalResultText(normalizedOutputs);
1285
1189
  if (terminalResultText && !finalText.trim()) {
1286
1190
  finalText = terminalResultText;
1287
1191
  }
@@ -1290,7 +1194,9 @@ export class AgentCortex {
1290
1194
  { type: 'text-delta', id: '1', delta: terminalResultText },
1291
1195
  ]);
1292
1196
  }
1293
- const terminalFailureText = extractTerminalFailureText(normalizedOutputs);
1197
+ const terminalFailureText = hasAppServerEvent
1198
+ ? ''
1199
+ : extractTerminalFailureText(normalizedOutputs);
1294
1200
  if (terminalFailureText && !streamError) {
1295
1201
  streamError = new Error(terminalFailureText);
1296
1202
  clearSessionSdkId(self.state.agent_id, self.state.session_id);
@@ -1545,46 +1451,25 @@ ${result}`;
1545
1451
  headers['Authorization'] = `Bearer ${llmToken}`;
1546
1452
  }
1547
1453
  let summary;
1548
- const modelForApiDetection = selectedModel
1549
- ? { ...selectedModel, api_key: llmToken || selectedModel.api_key }
1550
- : null;
1551
- if (usesAnthropicMessagesApi(modelForApiDetection)) {
1552
- const client = new Anthropic({
1553
- apiKey: llmToken,
1554
- baseURL: process.env.TEST_ANTHROPIC_BASE_URL || selectedModel?.base_url || undefined,
1555
- });
1556
- const response = await client.messages.create({
1557
- model: selectedModel?.model || 'claude-3-5-sonnet-latest',
1558
- max_tokens: 400,
1454
+ const baseUrl = process.env.TEST_ANTHROPIC_BASE_URL ||
1455
+ selectedModel?.base_url ||
1456
+ 'http://127.0.0.1:2755/api/llm/openrouter';
1457
+ const endpoint = baseUrl.endsWith('/v1')
1458
+ ? `${baseUrl}/chat/completions`
1459
+ : `${baseUrl}/v1/chat/completions`;
1460
+ const response = await fetch(endpoint, {
1461
+ method: 'POST',
1462
+ headers,
1463
+ body: JSON.stringify({
1464
+ model: selectedModel?.model || 'google/gemini-2.5-flash',
1559
1465
  messages: [{ role: 'user', content: summaryPrompt }],
1560
- });
1561
- summary = response.content
1562
- .filter((block) => block.type === 'text')
1563
- .map((block) => block.text)
1564
- .join('\n')
1565
- .trim();
1566
- }
1567
- else {
1568
- const baseUrl = process.env.TEST_ANTHROPIC_BASE_URL ||
1569
- selectedModel?.base_url ||
1570
- 'http://127.0.0.1:2755/api/llm/openrouter';
1571
- const endpoint = baseUrl.endsWith('/v1')
1572
- ? `${baseUrl}/chat/completions`
1573
- : `${baseUrl}/v1/chat/completions`;
1574
- const response = await fetch(endpoint, {
1575
- method: 'POST',
1576
- headers,
1577
- body: JSON.stringify({
1578
- model: selectedModel?.model || 'google/gemini-2.5-flash',
1579
- messages: [{ role: 'user', content: summaryPrompt }],
1580
- })
1581
- });
1582
- if (!response.ok) {
1583
- throw new Error(`Failed to call LLM: ${response.status} ${response.statusText}`);
1584
- }
1585
- const data = await response.json();
1586
- summary = data.choices?.[0]?.message?.content?.trim();
1466
+ })
1467
+ });
1468
+ if (!response.ok) {
1469
+ throw new Error(`Failed to call LLM: ${response.status} ${response.statusText}`);
1587
1470
  }
1471
+ const data = await response.json();
1472
+ summary = data.choices?.[0]?.message?.content?.trim();
1588
1473
  if (summary && !summary.toLowerCase().includes('no new facts')) {
1589
1474
  await this.memorySubsystem.writeEphemeral({
1590
1475
  scope: 'session',