Skip to content

Commit 3bd8caf

Browse files
committed
refactor: normalize helper function names in format files
Remove format-specific suffixes (Gemini, Responses) from private helper functions since they're now scoped to their own files.
1 parent 38b1aee commit 3bd8caf

File tree

4 files changed

+282
-25
lines changed

4 files changed

+282
-25
lines changed

lib/fetch-wrapper/formats/bedrock.ts

Lines changed: 75 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,81 @@
1-
import type { FormatDescriptor, ToolOutput } from "../types"
1+
import type { FormatDescriptor, ToolOutput, ToolTracker } from "../types"
22
import type { PluginState } from "../../state"
33
import type { Logger } from "../../logger"
4-
import type { ToolTracker } from "../../api-formats/synth-instruction"
54
import { cacheToolParametersFromMessages } from "../../state/tool-cache"
6-
import { injectSynth, trackNewToolResults } from "../../api-formats/synth-instruction"
7-
import { injectPrunableList } from "../../api-formats/prunable-list"
5+
6+
// ============================================================================
7+
// Format-specific injection helpers (reuses OpenAI Chat logic)
8+
// ============================================================================
9+
10+
function isNudgeMessage(msg: any, nudgeText: string): boolean {
11+
if (typeof msg.content === 'string') {
12+
return msg.content === nudgeText
13+
}
14+
return false
15+
}
16+
17+
function injectSynth(messages: any[], instruction: string, nudgeText: string): boolean {
18+
for (let i = messages.length - 1; i >= 0; i--) {
19+
const msg = messages[i]
20+
if (msg.role === 'user') {
21+
// Skip nudge messages - find real user message
22+
if (isNudgeMessage(msg, nudgeText)) continue
23+
24+
if (typeof msg.content === 'string') {
25+
if (msg.content.includes(instruction)) return false
26+
msg.content = msg.content + '\n\n' + instruction
27+
} else if (Array.isArray(msg.content)) {
28+
const alreadyInjected = msg.content.some(
29+
(part: any) => part?.type === 'text' && typeof part.text === 'string' && part.text.includes(instruction)
30+
)
31+
if (alreadyInjected) return false
32+
msg.content.push({ type: 'text', text: instruction })
33+
}
34+
return true
35+
}
36+
}
37+
return false
38+
}
39+
40+
function trackNewToolResults(messages: any[], tracker: ToolTracker, protectedTools: Set<string>): number {
41+
let newCount = 0
42+
for (const m of messages) {
43+
if (m.role === 'tool' && m.tool_call_id) {
44+
if (!tracker.seenToolResultIds.has(m.tool_call_id)) {
45+
tracker.seenToolResultIds.add(m.tool_call_id)
46+
const toolName = tracker.getToolName?.(m.tool_call_id)
47+
if (!toolName || !protectedTools.has(toolName)) {
48+
tracker.toolResultCount++
49+
newCount++
50+
}
51+
}
52+
} else if (m.role === 'user' && Array.isArray(m.content)) {
53+
for (const part of m.content) {
54+
if (part.type === 'tool_result' && part.tool_use_id) {
55+
if (!tracker.seenToolResultIds.has(part.tool_use_id)) {
56+
tracker.seenToolResultIds.add(part.tool_use_id)
57+
const toolName = tracker.getToolName?.(part.tool_use_id)
58+
if (!toolName || !protectedTools.has(toolName)) {
59+
tracker.toolResultCount++
60+
newCount++
61+
}
62+
}
63+
}
64+
}
65+
}
66+
}
67+
return newCount
68+
}
69+
70+
function injectPrunableList(messages: any[], injection: string): boolean {
71+
if (!injection) return false
72+
messages.push({ role: 'user', content: injection })
73+
return true
74+
}
75+
76+
// ============================================================================
77+
// Format Descriptor
78+
// ============================================================================
879

980
/**
1081
* Format descriptor for AWS Bedrock Converse API.

lib/fetch-wrapper/formats/gemini.ts

Lines changed: 67 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,69 @@
1-
import type { FormatDescriptor, ToolOutput } from "../types"
2-
import { PRUNED_CONTENT_MESSAGE } from "../types"
1+
import type { FormatDescriptor, ToolOutput, ToolTracker } from "../types"
32
import type { PluginState } from "../../state"
43
import type { Logger } from "../../logger"
5-
import type { ToolTracker } from "../../api-formats/synth-instruction"
6-
import { injectSynthGemini, trackNewToolResultsGemini } from "../../api-formats/synth-instruction"
7-
import { injectPrunableListGemini } from "../../api-formats/prunable-list"
4+
5+
// ============================================================================
6+
// Format-specific injection helpers
7+
// ============================================================================
8+
9+
function isNudgeContent(content: any, nudgeText: string): boolean {
10+
if (Array.isArray(content.parts) && content.parts.length === 1) {
11+
const part = content.parts[0]
12+
return part?.text === nudgeText
13+
}
14+
return false
15+
}
16+
17+
function injectSynth(contents: any[], instruction: string, nudgeText: string): boolean {
18+
for (let i = contents.length - 1; i >= 0; i--) {
19+
const content = contents[i]
20+
if (content.role === 'user' && Array.isArray(content.parts)) {
21+
// Skip nudge messages - find real user message
22+
if (isNudgeContent(content, nudgeText)) continue
23+
24+
const alreadyInjected = content.parts.some(
25+
(part: any) => part?.text && typeof part.text === 'string' && part.text.includes(instruction)
26+
)
27+
if (alreadyInjected) return false
28+
content.parts.push({ text: instruction })
29+
return true
30+
}
31+
}
32+
return false
33+
}
34+
35+
function trackNewToolResults(contents: any[], tracker: ToolTracker, protectedTools: Set<string>): number {
36+
let newCount = 0
37+
let positionCounter = 0
38+
for (const content of contents) {
39+
if (!Array.isArray(content.parts)) continue
40+
for (const part of content.parts) {
41+
if (part.functionResponse) {
42+
const positionId = `gemini_pos_${positionCounter}`
43+
positionCounter++
44+
if (!tracker.seenToolResultIds.has(positionId)) {
45+
tracker.seenToolResultIds.add(positionId)
46+
const toolName = part.functionResponse.name
47+
if (!toolName || !protectedTools.has(toolName)) {
48+
tracker.toolResultCount++
49+
newCount++
50+
}
51+
}
52+
}
53+
}
54+
}
55+
return newCount
56+
}
57+
58+
function injectPrunableList(contents: any[], injection: string): boolean {
59+
if (!injection) return false
60+
contents.push({ role: 'user', parts: [{ text: injection }] })
61+
return true
62+
}
63+
64+
// ============================================================================
65+
// Format Descriptor
66+
// ============================================================================
867

968
/**
1069
* Format descriptor for Google/Gemini API.
@@ -36,15 +95,15 @@ export const geminiFormat: FormatDescriptor = {
3695
},
3796

3897
injectSynth(data: any[], instruction: string, nudgeText: string): boolean {
39-
return injectSynthGemini(data, instruction, nudgeText)
98+
return injectSynth(data, instruction, nudgeText)
4099
},
41100

42101
trackNewToolResults(data: any[], tracker: ToolTracker, protectedTools: Set<string>): number {
43-
return trackNewToolResultsGemini(data, tracker, protectedTools)
102+
return trackNewToolResults(data, tracker, protectedTools)
44103
},
45104

46105
injectPrunableList(data: any[], injection: string): boolean {
47-
return injectPrunableListGemini(data, injection)
106+
return injectPrunableList(data, injection)
48107
},
49108

50109
extractToolOutputs(data: any[], state: PluginState): ToolOutput[] {

lib/fetch-wrapper/formats/openai-chat.ts

Lines changed: 75 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,81 @@
1-
import type { FormatDescriptor, ToolOutput } from "../types"
2-
import { PRUNED_CONTENT_MESSAGE } from "../types"
1+
import type { FormatDescriptor, ToolOutput, ToolTracker } from "../types"
32
import type { PluginState } from "../../state"
43
import type { Logger } from "../../logger"
5-
import type { ToolTracker } from "../../api-formats/synth-instruction"
64
import { cacheToolParametersFromMessages } from "../../state/tool-cache"
7-
import { injectSynth, trackNewToolResults } from "../../api-formats/synth-instruction"
8-
import { injectPrunableList } from "../../api-formats/prunable-list"
5+
6+
// ============================================================================
7+
// Format-specific injection helpers
8+
// ============================================================================
9+
10+
function isNudgeMessage(msg: any, nudgeText: string): boolean {
11+
if (typeof msg.content === 'string') {
12+
return msg.content === nudgeText
13+
}
14+
return false
15+
}
16+
17+
function injectSynth(messages: any[], instruction: string, nudgeText: string): boolean {
18+
for (let i = messages.length - 1; i >= 0; i--) {
19+
const msg = messages[i]
20+
if (msg.role === 'user') {
21+
// Skip nudge messages - find real user message
22+
if (isNudgeMessage(msg, nudgeText)) continue
23+
24+
if (typeof msg.content === 'string') {
25+
if (msg.content.includes(instruction)) return false
26+
msg.content = msg.content + '\n\n' + instruction
27+
} else if (Array.isArray(msg.content)) {
28+
const alreadyInjected = msg.content.some(
29+
(part: any) => part?.type === 'text' && typeof part.text === 'string' && part.text.includes(instruction)
30+
)
31+
if (alreadyInjected) return false
32+
msg.content.push({ type: 'text', text: instruction })
33+
}
34+
return true
35+
}
36+
}
37+
return false
38+
}
39+
40+
function trackNewToolResults(messages: any[], tracker: ToolTracker, protectedTools: Set<string>): number {
41+
let newCount = 0
42+
for (const m of messages) {
43+
if (m.role === 'tool' && m.tool_call_id) {
44+
if (!tracker.seenToolResultIds.has(m.tool_call_id)) {
45+
tracker.seenToolResultIds.add(m.tool_call_id)
46+
const toolName = tracker.getToolName?.(m.tool_call_id)
47+
if (!toolName || !protectedTools.has(toolName)) {
48+
tracker.toolResultCount++
49+
newCount++
50+
}
51+
}
52+
} else if (m.role === 'user' && Array.isArray(m.content)) {
53+
for (const part of m.content) {
54+
if (part.type === 'tool_result' && part.tool_use_id) {
55+
if (!tracker.seenToolResultIds.has(part.tool_use_id)) {
56+
tracker.seenToolResultIds.add(part.tool_use_id)
57+
const toolName = tracker.getToolName?.(part.tool_use_id)
58+
if (!toolName || !protectedTools.has(toolName)) {
59+
tracker.toolResultCount++
60+
newCount++
61+
}
62+
}
63+
}
64+
}
65+
}
66+
}
67+
return newCount
68+
}
69+
70+
function injectPrunableList(messages: any[], injection: string): boolean {
71+
if (!injection) return false
72+
messages.push({ role: 'user', content: injection })
73+
return true
74+
}
75+
76+
// ============================================================================
77+
// Format Descriptor
78+
// ============================================================================
979

1080
/**
1181
* Format descriptor for OpenAI Chat Completions and Anthropic APIs.

lib/fetch-wrapper/formats/openai-responses.ts

Lines changed: 65 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,68 @@
1-
import type { FormatDescriptor, ToolOutput } from "../types"
2-
import { PRUNED_CONTENT_MESSAGE } from "../types"
1+
import type { FormatDescriptor, ToolOutput, ToolTracker } from "../types"
32
import type { PluginState } from "../../state"
43
import type { Logger } from "../../logger"
5-
import type { ToolTracker } from "../../api-formats/synth-instruction"
64
import { cacheToolParametersFromInput } from "../../state/tool-cache"
7-
import { injectSynthResponses, trackNewToolResultsResponses } from "../../api-formats/synth-instruction"
8-
import { injectPrunableListResponses } from "../../api-formats/prunable-list"
5+
6+
// ============================================================================
7+
// Format-specific injection helpers
8+
// ============================================================================
9+
10+
function isNudgeItem(item: any, nudgeText: string): boolean {
11+
if (typeof item.content === 'string') {
12+
return item.content === nudgeText
13+
}
14+
return false
15+
}
16+
17+
function injectSynth(input: any[], instruction: string, nudgeText: string): boolean {
18+
for (let i = input.length - 1; i >= 0; i--) {
19+
const item = input[i]
20+
if (item.type === 'message' && item.role === 'user') {
21+
// Skip nudge messages - find real user message
22+
if (isNudgeItem(item, nudgeText)) continue
23+
24+
if (typeof item.content === 'string') {
25+
if (item.content.includes(instruction)) return false
26+
item.content = item.content + '\n\n' + instruction
27+
} else if (Array.isArray(item.content)) {
28+
const alreadyInjected = item.content.some(
29+
(part: any) => part?.type === 'input_text' && typeof part.text === 'string' && part.text.includes(instruction)
30+
)
31+
if (alreadyInjected) return false
32+
item.content.push({ type: 'input_text', text: instruction })
33+
}
34+
return true
35+
}
36+
}
37+
return false
38+
}
39+
40+
function trackNewToolResults(input: any[], tracker: ToolTracker, protectedTools: Set<string>): number {
41+
let newCount = 0
42+
for (const item of input) {
43+
if (item.type === 'function_call_output' && item.call_id) {
44+
if (!tracker.seenToolResultIds.has(item.call_id)) {
45+
tracker.seenToolResultIds.add(item.call_id)
46+
const toolName = tracker.getToolName?.(item.call_id)
47+
if (!toolName || !protectedTools.has(toolName)) {
48+
tracker.toolResultCount++
49+
newCount++
50+
}
51+
}
52+
}
53+
}
54+
return newCount
55+
}
56+
57+
function injectPrunableList(input: any[], injection: string): boolean {
58+
if (!injection) return false
59+
input.push({ type: 'message', role: 'user', content: injection })
60+
return true
61+
}
62+
63+
// ============================================================================
64+
// Format Descriptor
65+
// ============================================================================
966

1067
/**
1168
* Format descriptor for OpenAI Responses API (GPT-5 models via sdk.responses()).
@@ -31,15 +88,15 @@ export const openaiResponsesFormat: FormatDescriptor = {
3188
},
3289

3390
injectSynth(data: any[], instruction: string, nudgeText: string): boolean {
34-
return injectSynthResponses(data, instruction, nudgeText)
91+
return injectSynth(data, instruction, nudgeText)
3592
},
3693

3794
trackNewToolResults(data: any[], tracker: ToolTracker, protectedTools: Set<string>): number {
38-
return trackNewToolResultsResponses(data, tracker, protectedTools)
95+
return trackNewToolResults(data, tracker, protectedTools)
3996
},
4097

4198
injectPrunableList(data: any[], injection: string): boolean {
42-
return injectPrunableListResponses(data, injection)
99+
return injectPrunableList(data, injection)
43100
},
44101

45102
extractToolOutputs(data: any[], state: PluginState): ToolOutput[] {

0 commit comments

Comments
 (0)