Skip to content

Commit c239bf5

Browse files
committed
Revert "refactor(agents): deduplicate code and add documentation"
1 parent b132d99 commit c239bf5

File tree

2 files changed

+69
-200
lines changed

2 files changed

+69
-200
lines changed

agents/context-pruner.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,11 @@ export function getTextContent(message: Message): string {
7070

7171
/**
7272
* Summarizes a tool call into a human-readable description.
73-
* DUPLICATE: Keep in sync with the copy inside handleSteps (required for serialization).
73+
* Handles various tool types with appropriate formatting.
74+
*
75+
* @param toolName - The name of the tool
76+
* @param input - The tool's input parameters
77+
* @returns A concise summary of the tool call
7478
*/
7579
export function summarizeToolCall(
7680
toolName: string,
@@ -365,7 +369,7 @@ const definition: AgentDefinition = {
365369
}
366370

367371
/**
368-
* DUPLICATE: Keep in sync with module-level summarizeToolCall (required for serialization).
372+
* Summarizes a tool call into a human-readable description.
369373
*/
370374
function summarizeToolCall(
371375
toolName: string,

agents/file-explorer/file-picker.ts

Lines changed: 63 additions & 198 deletions
Original file line numberDiff line numberDiff line change
@@ -9,86 +9,6 @@ import type { StepText, ToolCall } from '../types/agent-definition'
99

1010
type FilePickerMode = 'default' | 'max'
1111

12-
/**
13-
* Type guard to check if value is a non-null object.
14-
* DUPLICATE: Keep in sync with copies inside handleStepsDefault and handleStepsMax (required for serialization).
15-
*/
16-
function isObject(value: unknown): value is Record<string, unknown> {
17-
return value !== null && typeof value === 'object'
18-
}
19-
20-
/**
21-
* Extracts spawn results from tool result array, returning agent values.
22-
* DUPLICATE: Keep in sync with copies inside handleStepsDefault and handleStepsMax (required for serialization).
23-
*/
24-
function extractSpawnResults(results: unknown[] | undefined): unknown[] {
25-
if (!results || results.length === 0) return []
26-
const jsonResult = results.find(
27-
(r): r is { type: 'json'; value: unknown } =>
28-
isObject(r) && r.type === 'json',
29-
)
30-
if (!jsonResult?.value) return []
31-
const spawnedResults = Array.isArray(jsonResult.value)
32-
? jsonResult.value
33-
: [jsonResult.value]
34-
// Each spawned result may be an object with a .value property (spawn wrapper)
35-
// or the agent output directly (type: 'lastMessage' or type: 'error')
36-
return spawnedResults
37-
.map((result: unknown) => {
38-
if (!isObject(result)) return undefined
39-
// If it's a spawn wrapper with .value, extract the value
40-
if ('value' in result && result.type !== 'lastMessage' && result.type !== 'error') {
41-
return result.value
42-
}
43-
// Otherwise it's the agent output directly
44-
return result
45-
})
46-
.filter(Boolean)
47-
}
48-
49-
/**
50-
* Extracts the most recent assistant text from an agent's output.
51-
* DUPLICATE: Keep in sync with copies inside handleStepsDefault and handleStepsMax (required for serialization).
52-
*/
53-
function extractLastMessageText(agentOutput: unknown): string | null {
54-
if (!isObject(agentOutput)) return null
55-
if (agentOutput.type !== 'lastMessage' || !Array.isArray(agentOutput.value)) {
56-
return null
57-
}
58-
for (let i = agentOutput.value.length - 1; i >= 0; i--) {
59-
const message = agentOutput.value[i]
60-
if (
61-
isObject(message) &&
62-
message.role === 'assistant' &&
63-
Array.isArray(message.content)
64-
) {
65-
for (const part of message.content) {
66-
if (
67-
isObject(part) &&
68-
part.type === 'text' &&
69-
typeof part.text === 'string'
70-
) {
71-
return part.text
72-
}
73-
}
74-
}
75-
}
76-
return null
77-
}
78-
79-
/**
80-
* Extracts error message from agent output if present.
81-
* DUPLICATE: Keep in sync with copies inside handleStepsDefault and handleStepsMax (required for serialization).
82-
*/
83-
function extractErrorMessage(agentOutput: unknown): string | null {
84-
if (!isObject(agentOutput)) return null
85-
if (agentOutput.type === 'error') {
86-
if (typeof agentOutput.message === 'string') return agentOutput.message
87-
if (typeof agentOutput.value === 'string') return agentOutput.value
88-
}
89-
return null
90-
}
91-
9212
export const createFilePicker = (
9313
mode: FilePickerMode,
9414
): Omit<SecretAgentDefinition, 'id'> => {
@@ -147,71 +67,6 @@ const handleStepsDefault: SecretAgentDefinition['handleSteps'] = function* ({
14767
prompt,
14868
params,
14969
}) {
150-
// ============================================================================
151-
// Helper functions duplicated inside generator for sandbox serialization.
152-
// DUPLICATE: Keep in sync with module-level versions.
153-
// ============================================================================
154-
function isObject(value: unknown): value is Record<string, unknown> {
155-
return value !== null && typeof value === 'object'
156-
}
157-
158-
function extractSpawnResults(results: unknown[] | undefined): unknown[] {
159-
if (!results || results.length === 0) return []
160-
const jsonResult = results.find(
161-
(r): r is { type: 'json'; value: unknown } =>
162-
isObject(r) && r.type === 'json',
163-
)
164-
if (!jsonResult?.value) return []
165-
const spawnedResults = Array.isArray(jsonResult.value)
166-
? jsonResult.value
167-
: [jsonResult.value]
168-
return spawnedResults
169-
.map((result: unknown) => {
170-
if (!isObject(result)) return undefined
171-
if ('value' in result && result.type !== 'lastMessage' && result.type !== 'error') {
172-
return result.value
173-
}
174-
return result
175-
})
176-
.filter(Boolean)
177-
}
178-
179-
function extractLastMessageText(agentOutput: unknown): string | null {
180-
if (!isObject(agentOutput)) return null
181-
if (agentOutput.type !== 'lastMessage' || !Array.isArray(agentOutput.value)) {
182-
return null
183-
}
184-
for (let i = agentOutput.value.length - 1; i >= 0; i--) {
185-
const message = agentOutput.value[i]
186-
if (
187-
isObject(message) &&
188-
message.role === 'assistant' &&
189-
Array.isArray(message.content)
190-
) {
191-
for (const part of message.content) {
192-
if (
193-
isObject(part) &&
194-
part.type === 'text' &&
195-
typeof part.text === 'string'
196-
) {
197-
return part.text
198-
}
199-
}
200-
}
201-
}
202-
return null
203-
}
204-
205-
function extractErrorMessage(agentOutput: unknown): string | null {
206-
if (!isObject(agentOutput)) return null
207-
if (agentOutput.type === 'error') {
208-
if (typeof agentOutput.message === 'string') return agentOutput.message
209-
if (typeof agentOutput.value === 'string') return agentOutput.value
210-
}
211-
return null
212-
}
213-
// ============================================================================
214-
21570
const { toolResult: fileListerResults } = yield {
21671
toolName: 'spawn_agents',
21772
input: {
@@ -265,78 +120,50 @@ const handleStepsDefault: SecretAgentDefinition['handleSteps'] = function* ({
265120

266121
yield 'STEP'
267122

268-
}
269-
270-
// handleSteps for max mode - spawns 2 file-listers in parallel
271-
const handleStepsMax: SecretAgentDefinition['handleSteps'] = function* ({
272-
prompt,
273-
params,
274-
}) {
275-
// ============================================================================
276-
// Helper functions duplicated inside generator for sandbox serialization.
277-
// DUPLICATE: Keep in sync with module-level versions.
278-
// ============================================================================
279-
function isObject(value: unknown): value is Record<string, unknown> {
280-
return value !== null && typeof value === 'object'
281-
}
282-
283-
function extractSpawnResults(results: unknown[] | undefined): unknown[] {
123+
function extractSpawnResults(results: any[] | undefined): any[] {
284124
if (!results || results.length === 0) return []
285-
const jsonResult = results.find(
286-
(r): r is { type: 'json'; value: unknown } =>
287-
isObject(r) && r.type === 'json',
288-
)
125+
const jsonResult = results.find((r) => r.type === 'json')
289126
if (!jsonResult?.value) return []
290127
const spawnedResults = Array.isArray(jsonResult.value)
291128
? jsonResult.value
292129
: [jsonResult.value]
293-
return spawnedResults
294-
.map((result: unknown) => {
295-
if (!isObject(result)) return undefined
296-
if ('value' in result && result.type !== 'lastMessage' && result.type !== 'error') {
297-
return result.value
298-
}
299-
return result
300-
})
301-
.filter(Boolean)
130+
return spawnedResults.map((result: any) => result?.value).filter(Boolean)
302131
}
303132

304-
function extractLastMessageText(agentOutput: unknown): string | null {
305-
if (!isObject(agentOutput)) return null
306-
if (agentOutput.type !== 'lastMessage' || !Array.isArray(agentOutput.value)) {
307-
return null
308-
}
309-
for (let i = agentOutput.value.length - 1; i >= 0; i--) {
310-
const message = agentOutput.value[i]
311-
if (
312-
isObject(message) &&
313-
message.role === 'assistant' &&
314-
Array.isArray(message.content)
315-
) {
316-
for (const part of message.content) {
317-
if (
318-
isObject(part) &&
319-
part.type === 'text' &&
320-
typeof part.text === 'string'
321-
) {
322-
return part.text
133+
function extractLastMessageText(agentOutput: any): string | null {
134+
if (!agentOutput) return null
135+
if (
136+
agentOutput.type === 'lastMessage' &&
137+
Array.isArray(agentOutput.value)
138+
) {
139+
for (let i = agentOutput.value.length - 1; i >= 0; i--) {
140+
const message = agentOutput.value[i]
141+
if (message.role === 'assistant' && Array.isArray(message.content)) {
142+
for (const part of message.content) {
143+
if (part.type === 'text' && typeof part.text === 'string') {
144+
return part.text
145+
}
323146
}
324147
}
325148
}
326149
}
327150
return null
328151
}
329152

330-
function extractErrorMessage(agentOutput: unknown): string | null {
331-
if (!isObject(agentOutput)) return null
153+
function extractErrorMessage(agentOutput: any): string | null {
154+
if (!agentOutput) return null
332155
if (agentOutput.type === 'error') {
333-
if (typeof agentOutput.message === 'string') return agentOutput.message
334-
if (typeof agentOutput.value === 'string') return agentOutput.value
156+
return agentOutput.message ?? agentOutput.value ?? null
335157
}
336158
return null
337159
}
338-
// ============================================================================
160+
}
339161

162+
// handleSteps for max mode - spawns 2 file-listers in parallel
163+
const handleStepsMax: SecretAgentDefinition['handleSteps'] = function* ({
164+
prompt,
165+
params,
166+
}) {
340167
const { toolResult: fileListerResults } = yield {
341168
toolName: 'spawn_agents',
342169
input: {
@@ -394,6 +221,44 @@ const handleStepsMax: SecretAgentDefinition['handleSteps'] = function* ({
394221
}
395222

396223
yield 'STEP'
224+
225+
function extractSpawnResults(results: any[] | undefined): any[] {
226+
if (!results || results.length === 0) return []
227+
const jsonResult = results.find((r) => r.type === 'json')
228+
if (!jsonResult?.value) return []
229+
const spawnedResults = Array.isArray(jsonResult.value)
230+
? jsonResult.value
231+
: [jsonResult.value]
232+
return spawnedResults.map((result: any) => result?.value).filter(Boolean)
233+
}
234+
235+
function extractLastMessageText(agentOutput: any): string | null {
236+
if (!agentOutput) return null
237+
if (
238+
agentOutput.type === 'lastMessage' &&
239+
Array.isArray(agentOutput.value)
240+
) {
241+
for (let i = agentOutput.value.length - 1; i >= 0; i--) {
242+
const message = agentOutput.value[i]
243+
if (message.role === 'assistant' && Array.isArray(message.content)) {
244+
for (const part of message.content) {
245+
if (part.type === 'text' && typeof part.text === 'string') {
246+
return part.text
247+
}
248+
}
249+
}
250+
}
251+
}
252+
return null
253+
}
254+
255+
function extractErrorMessage(agentOutput: any): string | null {
256+
if (!agentOutput) return null
257+
if (agentOutput.type === 'error') {
258+
return agentOutput.message ?? agentOutput.value ?? null
259+
}
260+
return null
261+
}
397262
}
398263

399264
const definition: SecretAgentDefinition = {

0 commit comments

Comments
 (0)