Skip to content

Commit 6b3687e

Browse files
yepashkovqwencoder
andcommitted
fix: improve X-Initiator detection for tool calls to prevent premium overcharge
The current isAgent detection only checks the last message role, which fails when tool results are returned. Tool call responses often have role: 'user' or contain tool_result parts, causing GitHub to incorrectly charge premium requests for agent-initiated actions. This fix checks the entire message context for tool calls (tool_result parts or role: 'tool') and marks the request as agent-initiated when tools are present, preventing incorrect premium request charges. Fixes #8030 Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
1 parent 2719063 commit 6b3687e

1 file changed

Lines changed: 18 additions & 3 deletions

File tree

  • packages/opencode/src/plugin/github-copilot

packages/opencode/src/plugin/github-copilot/copilot.ts

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,30 +83,45 @@ export async function CopilotAuthPlugin(input: PluginInput): Promise<Hooks> {
8383
// Completions API
8484
if (body?.messages && url.includes("completions")) {
8585
const last = body.messages[body.messages.length - 1]
86+
const hasToolCalls = body.messages.some(
87+
(msg: any) =>
88+
Array.isArray(msg.content) && msg.content.some((part: any) => part?.type === "tool_result") ||
89+
msg.role === "tool",
90+
)
8691
return {
8792
isVision: body.messages.some(
8893
(msg: any) =>
8994
Array.isArray(msg.content) && msg.content.some((part: any) => part.type === "image_url"),
9095
),
91-
isAgent: last?.role !== "user",
96+
isAgent: hasToolCalls || last?.role !== "user",
9297
}
9398
}
9499

95100
// Responses API
96101
if (body?.input) {
97102
const last = body.input[body.input.length - 1]
103+
const hasToolCalls = body.input.some(
104+
(item: any) =>
105+
Array.isArray(item?.content) && item.content.some((part: any) => part?.type === "tool_result") ||
106+
item.role === "tool",
107+
)
98108
return {
99109
isVision: body.input.some(
100110
(item: any) =>
101111
Array.isArray(item?.content) && item.content.some((part: any) => part.type === "input_image"),
102112
),
103-
isAgent: last?.role !== "user",
113+
isAgent: hasToolCalls || last?.role !== "user",
104114
}
105115
}
106116

107117
// Messages API
108118
if (body?.messages) {
109119
const last = body.messages[body.messages.length - 1]
120+
const hasToolCalls = body.messages.some(
121+
(msg: any) =>
122+
Array.isArray(msg.content) && msg.content.some((part: any) => part?.type === "tool_result") ||
123+
msg.role === "tool",
124+
)
110125
const hasNonToolCalls =
111126
Array.isArray(last?.content) && last.content.some((part: any) => part?.type !== "tool_result")
112127
return {
@@ -122,7 +137,7 @@ export async function CopilotAuthPlugin(input: PluginInput): Promise<Hooks> {
122137
part.content.some((nested: any) => nested?.type === "image")),
123138
),
124139
),
125-
isAgent: !(last?.role === "user" && hasNonToolCalls),
140+
isAgent: hasToolCalls || !(last?.role === "user" && hasNonToolCalls),
126141
}
127142
}
128143
} catch {}

0 commit comments

Comments
 (0)