@supen-ai/cli 1.3.3 → 1.4.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.
Files changed (138) hide show
  1. package/README.md +1 -1
  2. package/daemon/dist/agent-sdk/driver-output-ui.d.ts +1 -1
  3. package/daemon/dist/agent-sdk/driver-output-ui.d.ts.map +1 -1
  4. package/daemon/dist/agent-sdk/driver-output-ui.js +10 -275
  5. package/daemon/dist/agent-sdk/driver-output-ui.js.map +1 -1
  6. package/daemon/dist/agent-sdk/drivers/codex-app-server-driver.d.ts.map +1 -1
  7. package/daemon/dist/agent-sdk/drivers/codex-app-server-driver.js +0 -2
  8. package/daemon/dist/agent-sdk/drivers/codex-app-server-driver.js.map +1 -1
  9. package/daemon/dist/agent-sdk/drivers/registry.d.ts +2 -8
  10. package/daemon/dist/agent-sdk/drivers/registry.d.ts.map +1 -1
  11. package/daemon/dist/agent-sdk/drivers/registry.js +7 -138
  12. package/daemon/dist/agent-sdk/drivers/registry.js.map +1 -1
  13. package/daemon/dist/agent-sdk/index.d.ts +0 -11
  14. package/daemon/dist/agent-sdk/index.d.ts.map +1 -1
  15. package/daemon/dist/agent-sdk/index.js +0 -11
  16. package/daemon/dist/agent-sdk/index.js.map +1 -1
  17. package/daemon/dist/agent-sdk/session-manager.d.ts +1 -1
  18. package/daemon/dist/agent-sdk/session-manager.d.ts.map +1 -1
  19. package/daemon/dist/agent-sdk/session-manager.js +1 -2
  20. package/daemon/dist/agent-sdk/session-manager.js.map +1 -1
  21. package/daemon/dist/channels/acp.d.ts.map +1 -1
  22. package/daemon/dist/channels/acp.js +2 -3
  23. package/daemon/dist/channels/acp.js.map +1 -1
  24. package/daemon/dist/channels/http-routes.js +6 -6
  25. package/daemon/dist/channels/http-routes.js.map +1 -1
  26. package/daemon/dist/core/config.d.ts +1 -1
  27. package/daemon/dist/core/config.d.ts.map +1 -1
  28. package/daemon/dist/core/config.js +1 -1
  29. package/daemon/dist/core/config.js.map +1 -1
  30. package/daemon/dist/core/cortex.d.ts.map +1 -1
  31. package/daemon/dist/core/cortex.js +90 -222
  32. package/daemon/dist/core/cortex.js.map +1 -1
  33. package/daemon/dist/core/env.js +1 -1
  34. package/daemon/dist/core/gateway.d.ts.map +1 -1
  35. package/daemon/dist/core/gateway.js +1 -11
  36. package/daemon/dist/core/gateway.js.map +1 -1
  37. package/daemon/dist/core/loop-guard.d.ts +1 -1
  38. package/daemon/dist/core/loop-guard.js +1 -1
  39. package/daemon/dist/core/protocol-adapter.d.ts +1 -3
  40. package/daemon/dist/core/protocol-adapter.d.ts.map +1 -1
  41. package/daemon/dist/core/protocol-adapter.js +1 -3
  42. package/daemon/dist/core/protocol-adapter.js.map +1 -1
  43. package/daemon/dist/core/thread-runtime-state.d.ts.map +1 -1
  44. package/daemon/dist/core/thread-runtime-state.js +1 -37
  45. package/daemon/dist/core/thread-runtime-state.js.map +1 -1
  46. package/daemon/dist/http/routes/rpc.d.ts.map +1 -1
  47. package/daemon/dist/http/routes/rpc.js +16 -1
  48. package/daemon/dist/http/routes/rpc.js.map +1 -1
  49. package/daemon/dist/http/routes/system.d.ts +2 -0
  50. package/daemon/dist/http/routes/system.d.ts.map +1 -1
  51. package/daemon/dist/http/routes/system.js +487 -482
  52. package/daemon/dist/http/routes/system.js.map +1 -1
  53. package/daemon/dist/mcp/index.d.ts +2 -6
  54. package/daemon/dist/mcp/index.d.ts.map +1 -1
  55. package/daemon/dist/mcp/index.js +2 -6
  56. package/daemon/dist/mcp/index.js.map +1 -1
  57. package/daemon/dist/mcp/tools.d.ts +5 -7
  58. package/daemon/dist/mcp/tools.d.ts.map +1 -1
  59. package/daemon/dist/mcp/tools.js +4 -8
  60. package/daemon/dist/mcp/tools.js.map +1 -1
  61. package/daemon/dist/tools/built-ins.d.ts +9 -84
  62. package/daemon/dist/tools/built-ins.d.ts.map +1 -1
  63. package/daemon/dist/tools/built-ins.js +3 -3
  64. package/daemon/dist/tools/built-ins.js.map +1 -1
  65. package/daemon/dist/tools/local-tool.d.ts +7 -0
  66. package/daemon/dist/tools/local-tool.d.ts.map +1 -0
  67. package/daemon/dist/tools/local-tool.js +4 -0
  68. package/daemon/dist/tools/local-tool.js.map +1 -0
  69. package/daemon/dist/tools/skill-tools.d.ts +5 -8
  70. package/daemon/dist/tools/skill-tools.d.ts.map +1 -1
  71. package/daemon/dist/tools/skill-tools.js +6 -10
  72. package/daemon/dist/tools/skill-tools.js.map +1 -1
  73. package/daemon/package.json +6 -9
  74. package/dist/backend.js +5 -5
  75. package/dist/backend.js.map +1 -1
  76. package/dist/bootstrap.js +2 -6
  77. package/dist/bootstrap.js.map +1 -1
  78. package/dist/computer.js +1 -1
  79. package/dist/doctor.js +1 -1
  80. package/dist/doctor.js.map +1 -1
  81. package/dist/index.js +1 -1
  82. package/dist/repl.js +6 -66
  83. package/dist/repl.js.map +1 -1
  84. package/dist/service.js +2 -3
  85. package/dist/service.js.map +1 -1
  86. package/package.json +3 -6
  87. package/daemon/dist/agent-sdk/drivers/acpx-driver.d.ts +0 -21
  88. package/daemon/dist/agent-sdk/drivers/acpx-driver.d.ts.map +0 -1
  89. package/daemon/dist/agent-sdk/drivers/acpx-driver.js +0 -488
  90. package/daemon/dist/agent-sdk/drivers/acpx-driver.js.map +0 -1
  91. package/daemon/dist/agent-sdk/drivers/claude-acpx-driver.d.ts +0 -5
  92. package/daemon/dist/agent-sdk/drivers/claude-acpx-driver.d.ts.map +0 -1
  93. package/daemon/dist/agent-sdk/drivers/claude-acpx-driver.js +0 -7
  94. package/daemon/dist/agent-sdk/drivers/claude-acpx-driver.js.map +0 -1
  95. package/daemon/dist/agent-sdk/drivers/claude-cli-direct-driver.d.ts +0 -20
  96. package/daemon/dist/agent-sdk/drivers/claude-cli-direct-driver.d.ts.map +0 -1
  97. package/daemon/dist/agent-sdk/drivers/claude-cli-direct-driver.js +0 -264
  98. package/daemon/dist/agent-sdk/drivers/claude-cli-direct-driver.js.map +0 -1
  99. package/daemon/dist/agent-sdk/drivers/claude-code-driver.d.ts +0 -29
  100. package/daemon/dist/agent-sdk/drivers/claude-code-driver.d.ts.map +0 -1
  101. package/daemon/dist/agent-sdk/drivers/claude-code-driver.js +0 -24
  102. package/daemon/dist/agent-sdk/drivers/claude-code-driver.js.map +0 -1
  103. package/daemon/dist/agent-sdk/drivers/claude-code-events.d.ts +0 -25
  104. package/daemon/dist/agent-sdk/drivers/claude-code-events.d.ts.map +0 -1
  105. package/daemon/dist/agent-sdk/drivers/claude-code-events.js +0 -58
  106. package/daemon/dist/agent-sdk/drivers/claude-code-events.js.map +0 -1
  107. package/daemon/dist/agent-sdk/drivers/claude-code-items.d.ts +0 -41
  108. package/daemon/dist/agent-sdk/drivers/claude-code-items.d.ts.map +0 -1
  109. package/daemon/dist/agent-sdk/drivers/claude-code-items.js +0 -77
  110. package/daemon/dist/agent-sdk/drivers/claude-code-items.js.map +0 -1
  111. package/daemon/dist/agent-sdk/drivers/codex-acpx-driver.d.ts +0 -5
  112. package/daemon/dist/agent-sdk/drivers/codex-acpx-driver.d.ts.map +0 -1
  113. package/daemon/dist/agent-sdk/drivers/codex-acpx-driver.js +0 -7
  114. package/daemon/dist/agent-sdk/drivers/codex-acpx-driver.js.map +0 -1
  115. package/daemon/dist/agent-sdk/drivers/codex-exec-driver.d.ts +0 -28
  116. package/daemon/dist/agent-sdk/drivers/codex-exec-driver.d.ts.map +0 -1
  117. package/daemon/dist/agent-sdk/drivers/codex-exec-driver.js +0 -219
  118. package/daemon/dist/agent-sdk/drivers/codex-exec-driver.js.map +0 -1
  119. package/daemon/dist/agent-sdk/drivers/codex-exec-events.d.ts +0 -9
  120. package/daemon/dist/agent-sdk/drivers/codex-exec-events.d.ts.map +0 -1
  121. package/daemon/dist/agent-sdk/drivers/codex-exec-events.js +0 -82
  122. package/daemon/dist/agent-sdk/drivers/codex-exec-events.js.map +0 -1
  123. package/daemon/dist/agent-sdk/drivers/codex-exec-items.d.ts +0 -9
  124. package/daemon/dist/agent-sdk/drivers/codex-exec-items.d.ts.map +0 -1
  125. package/daemon/dist/agent-sdk/drivers/codex-exec-items.js +0 -86
  126. package/daemon/dist/agent-sdk/drivers/codex-exec-items.js.map +0 -1
  127. package/daemon/dist/agent-sdk/drivers/gemini-cli-driver.d.ts +0 -17
  128. package/daemon/dist/agent-sdk/drivers/gemini-cli-driver.d.ts.map +0 -1
  129. package/daemon/dist/agent-sdk/drivers/gemini-cli-driver.js +0 -255
  130. package/daemon/dist/agent-sdk/drivers/gemini-cli-driver.js.map +0 -1
  131. package/daemon/dist/core/sdk-wrapper.d.ts +0 -36
  132. package/daemon/dist/core/sdk-wrapper.d.ts.map +0 -1
  133. package/daemon/dist/core/sdk-wrapper.js +0 -533
  134. package/daemon/dist/core/sdk-wrapper.js.map +0 -1
  135. package/daemon/dist/skills/claude_code.d.ts +0 -25
  136. package/daemon/dist/skills/claude_code.d.ts.map +0 -1
  137. package/daemon/dist/skills/claude_code.js +0 -49
  138. 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,41 +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';
250
- }
251
- function isAppServerAgentMessageDeltaChunk(chunk) {
252
- if (chunk.type !== 'data-codex-event')
253
- return false;
254
- const data = chunk.data && typeof chunk.data === 'object'
255
- ? chunk.data
256
- : null;
257
- const raw = data?.raw && typeof data.raw === 'object'
258
- ? data.raw
259
- : null;
260
- return raw?.method === 'item/agentMessage/delta';
186
+ function chunksContainCodexEvent(chunks) {
187
+ return chunks.some((chunk) => chunk.type === 'data-codex-event');
261
188
  }
262
189
  function extractUiErrorText(chunks) {
263
190
  for (const chunk of chunks) {
@@ -904,8 +831,6 @@ export class AgentCortex {
904
831
  let emittedTextToUi = false;
905
832
  let receivedIncrementalText = false;
906
833
  let receivedIncrementalReasoning = false;
907
- const appServerDeltaReasoningItemIds = new Set();
908
- const appServerCommandOutputByItemId = new Map();
909
834
  const assistantMessageId = `${taskId}-assistant`;
910
835
  const sdkSessionRecord = createSession({ id: self.state.session_id });
911
836
  const sdkTurn = createTurn({ sessionId: sdkSessionRecord.id });
@@ -928,6 +853,24 @@ export class AgentCortex {
928
853
  task_id: taskId,
929
854
  chunk,
930
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
+ }
931
874
  }
932
875
  };
933
876
  const nextTextPartId = () => {
@@ -1022,7 +965,7 @@ export class AgentCortex {
1022
965
  if (chunksContainTextDelta(normalizedChunks)) {
1023
966
  emittedTextToUi = true;
1024
967
  }
1025
- if (chunksContainAppServerAgentMessage(normalizedChunks)) {
968
+ if (chunksContainCodexEvent(normalizedChunks)) {
1026
969
  emittedTextToUi = true;
1027
970
  }
1028
971
  persistUiChunks(normalizedChunks);
@@ -1092,21 +1035,6 @@ export class AgentCortex {
1092
1035
  logger.error({ err: callbackError }, 'runNativeStream: onError failed');
1093
1036
  }
1094
1037
  };
1095
- enqueueUiMessageChunks([
1096
- {
1097
- type: 'data-codex-event',
1098
- data: {
1099
- eventType: 'system',
1100
- subtype: 'status',
1101
- raw: {
1102
- type: 'system',
1103
- subtype: 'status',
1104
- status: 'requesting',
1105
- message: 'Thinking',
1106
- },
1107
- },
1108
- },
1109
- ]);
1110
1038
  try {
1111
1039
  sdkSession = await self.ensureNativeSdkSession({
1112
1040
  model: options?.model,
@@ -1216,75 +1144,31 @@ export class AgentCortex {
1216
1144
  receivedIncrementalText = true;
1217
1145
  }
1218
1146
  }
1219
- const completedReasoningSnapshotIdsWithPriorDeltas = new Set();
1220
- for (const output of normalizedOutputs) {
1221
- if (output.kind !== 'app-server-event')
1222
- continue;
1223
- const event = output.event;
1224
- const params = event.params && typeof event.params === 'object'
1225
- ? event.params
1226
- : {};
1227
- if (APP_SERVER_REASONING_DELTA_METHODS.has(event.method)) {
1228
- const itemId = typeof params.itemId === 'string' ? params.itemId : '';
1229
- if (itemId) {
1230
- appServerDeltaReasoningItemIds.add(itemId);
1231
- }
1232
- continue;
1233
- }
1234
- if (event.method === 'item/agentMessage/delta') {
1235
- continue;
1236
- }
1237
- if (event.method !== 'item/completed')
1238
- continue;
1239
- const item = params.item && typeof params.item === 'object'
1240
- ? params.item
1241
- : {};
1242
- const itemId = typeof item.id === 'string' ? item.id : '';
1243
- if (item.type === 'reasoning' && itemId && appServerDeltaReasoningItemIds.has(itemId)) {
1244
- completedReasoningSnapshotIdsWithPriorDeltas.add(itemId);
1245
- }
1246
- }
1247
- const normalizedChunksBaseRaw = convertDriverOutputsToUiMessageChunks(normalizedOutputs, {
1248
- commandOutputByItemId: appServerCommandOutputByItemId,
1249
- });
1250
- const normalizedChunksBase = normalizedChunksBaseRaw.filter((chunk) => {
1251
- if (chunk.type === 'reasoning-delta' &&
1252
- typeof chunk.id === 'string' &&
1253
- completedReasoningSnapshotIdsWithPriorDeltas.has(chunk.id)) {
1254
- return false;
1255
- }
1256
- return true;
1257
- });
1258
- const fallbackChunksBase = convertSdkEventToUiMessageChunks(message);
1259
- 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
1260
1150
  ? normalizedChunksBase
1261
- : fallbackChunksBase;
1262
- const hasAppServerAgentMessageEvent = normalizedOutputs.some((output) => output.kind === 'app-server-event');
1263
- const baseChunks = baseChunksSource.filter((chunk) => {
1264
- if (receivedIncrementalText &&
1265
- hasAppServerAgentMessageEvent &&
1266
- isAppServerAgentMessageDeltaChunk(chunk)) {
1267
- return false;
1268
- }
1269
- if (receivedIncrementalText &&
1270
- message.type === 'assistant' &&
1271
- normalizedChunksBase.length === 0 &&
1272
- chunk.type === 'text-delta') {
1273
- return false;
1274
- }
1275
- if (receivedIncrementalReasoning &&
1276
- message.type === 'assistant' &&
1277
- (chunk.type === 'reasoning-start' ||
1278
- chunk.type === 'reasoning-delta' ||
1279
- chunk.type === 'reasoning-end')) {
1280
- return false;
1281
- }
1282
- return true;
1283
- });
1284
- const chunks = enrichUiMessageChunksWithDocumentRefs(baseChunks, {
1285
- agentId,
1286
- workspaceRoot: artifacts.artifactRoot,
1287
- });
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
+ });
1288
1172
  const emittedErrorChunk = chunks.some((chunk) => chunk.type === 'error');
1289
1173
  const uiErrorText = extractUiErrorText(chunks);
1290
1174
  if (uiErrorText && !streamError) {
@@ -1297,8 +1181,11 @@ export class AgentCortex {
1297
1181
  output_excerpt: buildAssistantOutputExcerpt(serializeUiMessageChunks(chunks)?.trim() ?? ''),
1298
1182
  }, 'Task stream chunk');
1299
1183
  enqueueUiMessageChunks(chunks);
1184
+ emittedTextToUi = true;
1300
1185
  }
1301
- const terminalResultText = extractTerminalResultText(normalizedOutputs);
1186
+ const terminalResultText = hasAppServerEvent
1187
+ ? ''
1188
+ : extractTerminalResultText(normalizedOutputs);
1302
1189
  if (terminalResultText && !finalText.trim()) {
1303
1190
  finalText = terminalResultText;
1304
1191
  }
@@ -1307,7 +1194,9 @@ export class AgentCortex {
1307
1194
  { type: 'text-delta', id: '1', delta: terminalResultText },
1308
1195
  ]);
1309
1196
  }
1310
- const terminalFailureText = extractTerminalFailureText(normalizedOutputs);
1197
+ const terminalFailureText = hasAppServerEvent
1198
+ ? ''
1199
+ : extractTerminalFailureText(normalizedOutputs);
1311
1200
  if (terminalFailureText && !streamError) {
1312
1201
  streamError = new Error(terminalFailureText);
1313
1202
  clearSessionSdkId(self.state.agent_id, self.state.session_id);
@@ -1562,46 +1451,25 @@ ${result}`;
1562
1451
  headers['Authorization'] = `Bearer ${llmToken}`;
1563
1452
  }
1564
1453
  let summary;
1565
- const modelForApiDetection = selectedModel
1566
- ? { ...selectedModel, api_key: llmToken || selectedModel.api_key }
1567
- : null;
1568
- if (usesAnthropicMessagesApi(modelForApiDetection)) {
1569
- const client = new Anthropic({
1570
- apiKey: llmToken,
1571
- baseURL: process.env.TEST_ANTHROPIC_BASE_URL || selectedModel?.base_url || undefined,
1572
- });
1573
- const response = await client.messages.create({
1574
- model: selectedModel?.model || 'claude-3-5-sonnet-latest',
1575
- 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',
1576
1465
  messages: [{ role: 'user', content: summaryPrompt }],
1577
- });
1578
- summary = response.content
1579
- .filter((block) => block.type === 'text')
1580
- .map((block) => block.text)
1581
- .join('\n')
1582
- .trim();
1583
- }
1584
- else {
1585
- const baseUrl = process.env.TEST_ANTHROPIC_BASE_URL ||
1586
- selectedModel?.base_url ||
1587
- 'http://127.0.0.1:2755/api/llm/openrouter';
1588
- const endpoint = baseUrl.endsWith('/v1')
1589
- ? `${baseUrl}/chat/completions`
1590
- : `${baseUrl}/v1/chat/completions`;
1591
- const response = await fetch(endpoint, {
1592
- method: 'POST',
1593
- headers,
1594
- body: JSON.stringify({
1595
- model: selectedModel?.model || 'google/gemini-2.5-flash',
1596
- messages: [{ role: 'user', content: summaryPrompt }],
1597
- })
1598
- });
1599
- if (!response.ok) {
1600
- throw new Error(`Failed to call LLM: ${response.status} ${response.statusText}`);
1601
- }
1602
- const data = await response.json();
1603
- 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}`);
1604
1470
  }
1471
+ const data = await response.json();
1472
+ summary = data.choices?.[0]?.message?.content?.trim();
1605
1473
  if (summary && !summary.toLowerCase().includes('no new facts')) {
1606
1474
  await this.memorySubsystem.writeEphemeral({
1607
1475
  scope: 'session',