mirror of
https://github.com/getcompanion-ai/co-mono.git
synced 2026-04-22 01:02:16 +00:00
Fix X-Initiator header logic for GitHub Copilot
Check last message role instead of any message in history. This matches the original correct implementation from PR #200. fixes #209
This commit is contained in:
parent
13b8af1f36
commit
575dcb2676
5 changed files with 18 additions and 14 deletions
2
package-lock.json
generated
2
package-lock.json
generated
|
|
@ -6555,7 +6555,7 @@
|
||||||
"chalk": "^5.5.0"
|
"chalk": "^5.5.0"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
"pi": "dist/cli.js"
|
"pi-pods": "dist/cli.js"
|
||||||
},
|
},
|
||||||
"devDependencies": {},
|
"devDependencies": {},
|
||||||
"engines": {
|
"engines": {
|
||||||
|
|
|
||||||
|
|
@ -3225,7 +3225,7 @@ export const MODELS = {
|
||||||
cost: {
|
cost: {
|
||||||
input: 0.24,
|
input: 0.24,
|
||||||
output: 0.38,
|
output: 0.38,
|
||||||
cacheRead: 0.19,
|
cacheRead: 0.11,
|
||||||
cacheWrite: 0,
|
cacheWrite: 0,
|
||||||
},
|
},
|
||||||
contextWindow: 163840,
|
contextWindow: 163840,
|
||||||
|
|
|
||||||
|
|
@ -302,9 +302,11 @@ function createClient(model: Model<"openai-completions">, context: Context, apiK
|
||||||
const headers = { ...model.headers };
|
const headers = { ...model.headers };
|
||||||
if (model.provider === "github-copilot") {
|
if (model.provider === "github-copilot") {
|
||||||
// Copilot expects X-Initiator to indicate whether the request is user-initiated
|
// Copilot expects X-Initiator to indicate whether the request is user-initiated
|
||||||
// or agent-initiated. It's an agent call if ANY message in history has assistant/tool role.
|
// or agent-initiated (e.g. follow-up after assistant/tool messages). If there is
|
||||||
|
// no prior message, default to user-initiated.
|
||||||
const messages = context.messages || [];
|
const messages = context.messages || [];
|
||||||
const isAgentCall = messages.some((msg) => msg.role === "assistant" || msg.role === "toolResult");
|
const lastMessage = messages[messages.length - 1];
|
||||||
|
const isAgentCall = lastMessage ? lastMessage.role !== "user" : false;
|
||||||
headers["X-Initiator"] = isAgentCall ? "agent" : "user";
|
headers["X-Initiator"] = isAgentCall ? "agent" : "user";
|
||||||
headers["Openai-Intent"] = "conversation-edits";
|
headers["Openai-Intent"] = "conversation-edits";
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -310,9 +310,11 @@ function createClient(model: Model<"openai-responses">, context: Context, apiKey
|
||||||
const headers = { ...model.headers };
|
const headers = { ...model.headers };
|
||||||
if (model.provider === "github-copilot") {
|
if (model.provider === "github-copilot") {
|
||||||
// Copilot expects X-Initiator to indicate whether the request is user-initiated
|
// Copilot expects X-Initiator to indicate whether the request is user-initiated
|
||||||
// or agent-initiated. It's an agent call if ANY message in history has assistant/tool role.
|
// or agent-initiated (e.g. follow-up after assistant/tool messages). If there is
|
||||||
|
// no prior message, default to user-initiated.
|
||||||
const messages = context.messages || [];
|
const messages = context.messages || [];
|
||||||
const isAgentCall = messages.some((msg) => msg.role === "assistant" || msg.role === "toolResult");
|
const lastMessage = messages[messages.length - 1];
|
||||||
|
const isAgentCall = lastMessage ? lastMessage.role !== "user" : false;
|
||||||
headers["X-Initiator"] = isAgentCall ? "agent" : "user";
|
headers["X-Initiator"] = isAgentCall ? "agent" : "user";
|
||||||
headers["Openai-Intent"] = "conversation-edits";
|
headers["Openai-Intent"] = "conversation-edits";
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -175,7 +175,7 @@ describe("GitHub Copilot Headers", () => {
|
||||||
expect(lastOpenAIConfig?.defaultHeaders?.["X-Initiator"]).toBe("user");
|
expect(lastOpenAIConfig?.defaultHeaders?.["X-Initiator"]).toBe("user");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("sets X-Initiator: agent when assistant message exists in history", async () => {
|
it("sets X-Initiator: agent when last message is assistant", async () => {
|
||||||
const context: Context = {
|
const context: Context = {
|
||||||
messages: [{ role: "user", content: "Hello", timestamp: Date.now() }, assistantMessage],
|
messages: [{ role: "user", content: "Hello", timestamp: Date.now() }, assistantMessage],
|
||||||
};
|
};
|
||||||
|
|
@ -186,7 +186,7 @@ describe("GitHub Copilot Headers", () => {
|
||||||
expect(lastOpenAIConfig?.defaultHeaders?.["X-Initiator"]).toBe("agent");
|
expect(lastOpenAIConfig?.defaultHeaders?.["X-Initiator"]).toBe("agent");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("sets X-Initiator: agent when toolResult exists in history", async () => {
|
it("sets X-Initiator: agent when last message is toolResult", async () => {
|
||||||
const context: Context = {
|
const context: Context = {
|
||||||
messages: [{ role: "user", content: "Hello", timestamp: Date.now() }, toolResultMessage],
|
messages: [{ role: "user", content: "Hello", timestamp: Date.now() }, toolResultMessage],
|
||||||
};
|
};
|
||||||
|
|
@ -197,7 +197,7 @@ describe("GitHub Copilot Headers", () => {
|
||||||
expect(lastOpenAIConfig?.defaultHeaders?.["X-Initiator"]).toBe("agent");
|
expect(lastOpenAIConfig?.defaultHeaders?.["X-Initiator"]).toBe("agent");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("sets X-Initiator: agent for multi-turn conversation (last is user, but assistant in history)", async () => {
|
it("sets X-Initiator: user for multi-turn conversation when last message is user", async () => {
|
||||||
const context: Context = {
|
const context: Context = {
|
||||||
messages: [
|
messages: [
|
||||||
{ role: "user", content: "Hello", timestamp: Date.now() },
|
{ role: "user", content: "Hello", timestamp: Date.now() },
|
||||||
|
|
@ -209,7 +209,7 @@ describe("GitHub Copilot Headers", () => {
|
||||||
const stream = streamOpenAICompletions(copilotCompletionsModel, context, { apiKey: "test-key" });
|
const stream = streamOpenAICompletions(copilotCompletionsModel, context, { apiKey: "test-key" });
|
||||||
await consumeStream(stream);
|
await consumeStream(stream);
|
||||||
|
|
||||||
expect(lastOpenAIConfig?.defaultHeaders?.["X-Initiator"]).toBe("agent");
|
expect(lastOpenAIConfig?.defaultHeaders?.["X-Initiator"]).toBe("user");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("sets X-Initiator: user when there are no messages", async () => {
|
it("sets X-Initiator: user when there are no messages", async () => {
|
||||||
|
|
@ -259,7 +259,7 @@ describe("GitHub Copilot Headers", () => {
|
||||||
expect(lastOpenAIConfig?.defaultHeaders?.["X-Initiator"]).toBe("user");
|
expect(lastOpenAIConfig?.defaultHeaders?.["X-Initiator"]).toBe("user");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("sets X-Initiator: agent when assistant message exists in history", async () => {
|
it("sets X-Initiator: agent when last message is assistant", async () => {
|
||||||
const context: Context = {
|
const context: Context = {
|
||||||
messages: [
|
messages: [
|
||||||
{ role: "user", content: "Hello", timestamp: Date.now() },
|
{ role: "user", content: "Hello", timestamp: Date.now() },
|
||||||
|
|
@ -273,7 +273,7 @@ describe("GitHub Copilot Headers", () => {
|
||||||
expect(lastOpenAIConfig?.defaultHeaders?.["X-Initiator"]).toBe("agent");
|
expect(lastOpenAIConfig?.defaultHeaders?.["X-Initiator"]).toBe("agent");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("sets X-Initiator: agent when toolResult exists in history", async () => {
|
it("sets X-Initiator: agent when last message is toolResult", async () => {
|
||||||
const context: Context = {
|
const context: Context = {
|
||||||
messages: [{ role: "user", content: "Hello", timestamp: Date.now() }, toolResultMessage],
|
messages: [{ role: "user", content: "Hello", timestamp: Date.now() }, toolResultMessage],
|
||||||
};
|
};
|
||||||
|
|
@ -284,7 +284,7 @@ describe("GitHub Copilot Headers", () => {
|
||||||
expect(lastOpenAIConfig?.defaultHeaders?.["X-Initiator"]).toBe("agent");
|
expect(lastOpenAIConfig?.defaultHeaders?.["X-Initiator"]).toBe("agent");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("sets X-Initiator: agent for multi-turn conversation (last is user, but assistant in history)", async () => {
|
it("sets X-Initiator: user for multi-turn conversation when last message is user", async () => {
|
||||||
const context: Context = {
|
const context: Context = {
|
||||||
messages: [
|
messages: [
|
||||||
{ role: "user", content: "Hello", timestamp: Date.now() },
|
{ role: "user", content: "Hello", timestamp: Date.now() },
|
||||||
|
|
@ -296,7 +296,7 @@ describe("GitHub Copilot Headers", () => {
|
||||||
const stream = streamOpenAIResponses(copilotResponsesModel, context, { apiKey: "test-key" });
|
const stream = streamOpenAIResponses(copilotResponsesModel, context, { apiKey: "test-key" });
|
||||||
await consumeStream(stream);
|
await consumeStream(stream);
|
||||||
|
|
||||||
expect(lastOpenAIConfig?.defaultHeaders?.["X-Initiator"]).toBe("agent");
|
expect(lastOpenAIConfig?.defaultHeaders?.["X-Initiator"]).toBe("user");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("sets X-Initiator: user when there are no messages", async () => {
|
it("sets X-Initiator: user when there are no messages", async () => {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue