xcode-copilot-server 2.2.0 → 3.0.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 (150) hide show
  1. package/README.md +83 -26
  2. package/config.json5 +13 -8
  3. package/dist/cli-validators.js +2 -2
  4. package/dist/cli-validators.js.map +1 -1
  5. package/dist/config.d.ts +1 -1
  6. package/dist/config.js +1 -1
  7. package/dist/config.js.map +1 -1
  8. package/dist/conversation-manager.d.ts +2 -1
  9. package/dist/conversation-manager.js +20 -1
  10. package/dist/conversation-manager.js.map +1 -1
  11. package/dist/handlers/responses/streaming.d.ts +6 -0
  12. package/dist/handlers/responses/streaming.js +265 -0
  13. package/dist/handlers/responses/streaming.js.map +1 -0
  14. package/dist/handlers/responses/tool-result-handler.d.ts +4 -0
  15. package/dist/handlers/responses/tool-result-handler.js +9 -0
  16. package/dist/handlers/responses/tool-result-handler.js.map +1 -0
  17. package/dist/handlers/responses.d.ts +4 -0
  18. package/dist/handlers/responses.js +164 -0
  19. package/dist/handlers/responses.js.map +1 -0
  20. package/dist/handlers/streaming-utils.d.ts +1 -0
  21. package/dist/handlers/streaming-utils.js +3 -0
  22. package/dist/handlers/streaming-utils.js.map +1 -1
  23. package/dist/index.js +23 -108
  24. package/dist/index.js.map +1 -1
  25. package/dist/providers/claude/count-tokens.d.ts +3 -0
  26. package/dist/providers/claude/count-tokens.js +72 -0
  27. package/dist/providers/claude/count-tokens.js.map +1 -0
  28. package/dist/providers/claude/handler.d.ts +4 -0
  29. package/dist/providers/claude/handler.js +150 -0
  30. package/dist/providers/claude/handler.js.map +1 -0
  31. package/dist/providers/claude/prompt.d.ts +2 -0
  32. package/dist/providers/claude/prompt.js +52 -0
  33. package/dist/providers/claude/prompt.js.map +1 -0
  34. package/dist/providers/claude/provider.d.ts +5 -0
  35. package/dist/providers/claude/provider.js +28 -0
  36. package/dist/providers/claude/provider.js.map +1 -0
  37. package/dist/providers/claude/schemas.d.ts +140 -0
  38. package/dist/providers/claude/schemas.js +58 -0
  39. package/dist/providers/claude/schemas.js.map +1 -0
  40. package/dist/providers/claude/streaming.d.ts +6 -0
  41. package/dist/providers/claude/streaming.js +116 -0
  42. package/dist/providers/claude/streaming.js.map +1 -0
  43. package/dist/providers/claude/tool-results.d.ts +4 -0
  44. package/dist/providers/claude/tool-results.js +19 -0
  45. package/dist/providers/claude/tool-results.js.map +1 -0
  46. package/dist/providers/codex/handler.d.ts +4 -0
  47. package/dist/providers/codex/handler.js +164 -0
  48. package/dist/providers/codex/handler.js.map +1 -0
  49. package/dist/providers/codex/prompt.d.ts +4 -0
  50. package/dist/providers/codex/prompt.js +58 -0
  51. package/dist/providers/codex/prompt.js.map +1 -0
  52. package/dist/providers/codex/provider.d.ts +5 -0
  53. package/dist/providers/codex/provider.js +24 -0
  54. package/dist/providers/codex/provider.js.map +1 -0
  55. package/dist/providers/codex/schemas.d.ts +122 -0
  56. package/dist/providers/codex/schemas.js +55 -0
  57. package/dist/providers/codex/schemas.js.map +1 -0
  58. package/dist/providers/codex/streaming.d.ts +9 -0
  59. package/dist/providers/codex/streaming.js +172 -0
  60. package/dist/providers/codex/streaming.js.map +1 -0
  61. package/dist/providers/codex/tool-results.d.ts +4 -0
  62. package/dist/providers/codex/tool-results.js +9 -0
  63. package/dist/providers/codex/tool-results.js.map +1 -0
  64. package/dist/providers/codex.d.ts +5 -0
  65. package/dist/providers/codex.js +24 -0
  66. package/dist/providers/codex.js.map +1 -0
  67. package/dist/providers/index.d.ts +6 -1
  68. package/dist/providers/index.js +5 -3
  69. package/dist/providers/index.js.map +1 -1
  70. package/dist/providers/openai/handler.d.ts +4 -0
  71. package/dist/providers/openai/handler.js +120 -0
  72. package/dist/providers/openai/handler.js.map +1 -0
  73. package/dist/providers/openai/models.d.ts +3 -0
  74. package/dist/providers/openai/models.js +28 -0
  75. package/dist/providers/openai/models.js.map +1 -0
  76. package/dist/providers/openai/prompt.d.ts +3 -0
  77. package/dist/providers/openai/prompt.js +38 -0
  78. package/dist/providers/openai/prompt.js.map +1 -0
  79. package/dist/providers/openai/provider.d.ts +5 -0
  80. package/dist/providers/openai/provider.js +25 -0
  81. package/dist/providers/openai/provider.js.map +1 -0
  82. package/dist/providers/openai/schemas.d.ts +98 -0
  83. package/dist/providers/openai/schemas.js +76 -0
  84. package/dist/providers/openai/schemas.js.map +1 -0
  85. package/dist/providers/openai/streaming.d.ts +4 -0
  86. package/dist/providers/openai/streaming.js +121 -0
  87. package/dist/providers/openai/streaming.js.map +1 -0
  88. package/dist/providers/shared/errors.d.ts +5 -0
  89. package/dist/providers/shared/errors.js +10 -0
  90. package/dist/providers/shared/errors.js.map +1 -0
  91. package/dist/providers/shared/model-resolver.d.ts +3 -0
  92. package/dist/providers/shared/model-resolver.js +45 -0
  93. package/dist/providers/shared/model-resolver.js.map +1 -0
  94. package/dist/providers/shared/prompt-utils.d.ts +1 -0
  95. package/dist/providers/shared/prompt-utils.js +15 -0
  96. package/dist/providers/shared/prompt-utils.js.map +1 -0
  97. package/dist/providers/shared/session-config.d.ts +15 -0
  98. package/dist/providers/shared/session-config.js +98 -0
  99. package/dist/providers/shared/session-config.js.map +1 -0
  100. package/dist/providers/shared/streaming-core.d.ts +19 -0
  101. package/dist/providers/shared/streaming-core.js +176 -0
  102. package/dist/providers/shared/streaming-core.js.map +1 -0
  103. package/dist/providers/shared/streaming-utils.d.ts +10 -0
  104. package/dist/providers/shared/streaming-utils.js +28 -0
  105. package/dist/providers/shared/streaming-utils.js.map +1 -0
  106. package/dist/schemas/config.d.ts +19 -1
  107. package/dist/schemas/config.js +2 -1
  108. package/dist/schemas/config.js.map +1 -1
  109. package/dist/schemas/responses.d.ts +122 -0
  110. package/dist/schemas/responses.js +54 -0
  111. package/dist/schemas/responses.js.map +1 -0
  112. package/dist/server.js +1 -2
  113. package/dist/server.js.map +1 -1
  114. package/dist/settings-patcher/anthropic.d.ts +5 -0
  115. package/dist/{settings-patcher.js → settings-patcher/anthropic.js} +3 -7
  116. package/dist/settings-patcher/anthropic.js.map +1 -0
  117. package/dist/settings-patcher/claude.d.ts +5 -0
  118. package/dist/settings-patcher/claude.js +75 -0
  119. package/dist/settings-patcher/claude.js.map +1 -0
  120. package/dist/settings-patcher/codex.d.ts +23 -0
  121. package/dist/settings-patcher/codex.js +114 -0
  122. package/dist/settings-patcher/codex.js.map +1 -0
  123. package/dist/settings-patcher/index.d.ts +15 -0
  124. package/dist/settings-patcher/index.js +9 -0
  125. package/dist/settings-patcher/index.js.map +1 -0
  126. package/dist/{settings-patcher.d.ts → settings-patcher/types.d.ts} +1 -5
  127. package/dist/settings-patcher/types.js +2 -0
  128. package/dist/settings-patcher/types.js.map +1 -0
  129. package/dist/startup.d.ts +11 -0
  130. package/dist/startup.js +154 -0
  131. package/dist/startup.js.map +1 -0
  132. package/dist/tool-bridge/constants.d.ts +2 -0
  133. package/dist/tool-bridge/constants.js +3 -0
  134. package/dist/tool-bridge/constants.js.map +1 -0
  135. package/dist/tool-bridge/index.d.ts +1 -0
  136. package/dist/tool-bridge/index.js +1 -0
  137. package/dist/tool-bridge/index.js.map +1 -1
  138. package/dist/tool-bridge/routes.js +2 -1
  139. package/dist/tool-bridge/routes.js.map +1 -1
  140. package/dist/tool-bridge/session-lifecycle.js +1 -1
  141. package/dist/tool-bridge/state.d.ts +1 -1
  142. package/dist/tool-bridge/tool-cache.d.ts +1 -1
  143. package/dist/ui.d.ts +7 -0
  144. package/dist/ui.js +8 -0
  145. package/dist/ui.js.map +1 -1
  146. package/dist/utils/responses-prompt.d.ts +4 -0
  147. package/dist/utils/responses-prompt.js +58 -0
  148. package/dist/utils/responses-prompt.js.map +1 -0
  149. package/package.json +1 -1
  150. package/dist/settings-patcher.js.map +0 -1
@@ -0,0 +1,164 @@
1
+ import { ResponsesRequestSchema, filterFunctionTools } from "./schemas.js";
2
+ import { genId } from "./schemas.js";
3
+ import { formatResponsesPrompt, extractInstructions, extractFunctionCallOutputs, } from "./prompt.js";
4
+ import { resolveModel } from "../shared/model-resolver.js";
5
+ import { createSessionConfig } from "../shared/session-config.js";
6
+ import { resolveResponsesToolResults } from "./tool-results.js";
7
+ import { handleResponsesStreaming, startResponseStream } from "./streaming.js";
8
+ import { sendOpenAIError as sendError } from "../shared/errors.js";
9
+ export function createResponsesHandler({ service, logger, config, port }, manager) {
10
+ return async function handleResponses(request, reply) {
11
+ const parseResult = ResponsesRequestSchema.safeParse(request.body);
12
+ if (!parseResult.success) {
13
+ const firstIssue = parseResult.error.issues[0];
14
+ logger.debug(`Request validation failed: ${JSON.stringify(parseResult.error.issues)}`);
15
+ logger.debug(`Raw body keys: ${JSON.stringify(Object.keys((request.body ?? {})))}`);
16
+ sendError(reply, 400, "invalid_request_error", firstIssue?.message ?? "Invalid request body");
17
+ return;
18
+ }
19
+ const req = parseResult.data;
20
+ const callOutputs = extractFunctionCallOutputs(req.input);
21
+ logger.debug(`function_call_output items: ${String(callOutputs.length)}${callOutputs.length > 0 ? ` (call_ids: ${callOutputs.map((o) => o.call_id).join(", ")})` : ""}`);
22
+ if (callOutputs.length > 0) {
23
+ const existingConv = manager.findByContinuationIds(callOutputs.map((o) => o.call_id));
24
+ if (existingConv) {
25
+ const state = existingConv.state;
26
+ logger.info(`Continuation for conversation ${existingConv.id} (hasPending=${String(state.hasPending)}, sessionActive=${String(state.sessionActive)})`);
27
+ state.setReply(reply);
28
+ startResponseStream(reply, genId("resp"), req.model);
29
+ reply.raw.on("close", () => {
30
+ if (state.currentReply === reply) {
31
+ logger.info("Client disconnected during continuation");
32
+ state.cleanup();
33
+ state.notifyStreamingDone();
34
+ }
35
+ });
36
+ resolveResponsesToolResults(callOutputs, state, logger);
37
+ await state.waitForStreamingDone();
38
+ existingConv.sentMessageCount = Array.isArray(req.input) ? req.input.length : 1;
39
+ return;
40
+ }
41
+ }
42
+ const { conversation, isReuse } = manager.findForNewRequest();
43
+ const state = conversation.state;
44
+ state.markSessionActive();
45
+ logger.info(isReuse
46
+ ? `Reusing primary conversation ${conversation.id}`
47
+ : `New conversation ${conversation.id}`);
48
+ if (isReuse && conversation.model && conversation.model !== req.model) {
49
+ logger.warn(`Model mismatch: session uses "${conversation.model}" but request sent "${req.model}" (SDK does not support mid-session model switching)`);
50
+ }
51
+ const tools = req.tools ? filterFunctionTools(req.tools) : undefined;
52
+ const hasTools = !!tools?.length;
53
+ const hasBridge = hasTools && config.toolBridge;
54
+ // Responses API tools use `parameters`, bridge uses `input_schema`
55
+ if (tools?.length) {
56
+ const bridgeTools = tools.map((t) => ({
57
+ name: t.name,
58
+ description: t.description,
59
+ input_schema: t.parameters ?? {},
60
+ }));
61
+ state.cacheTools(bridgeTools);
62
+ }
63
+ const inputLength = Array.isArray(req.input) ? req.input.length : 1;
64
+ const slicedInput = isReuse && Array.isArray(req.input)
65
+ ? req.input.slice(conversation.sentMessageCount)
66
+ : req.input;
67
+ let prompt;
68
+ try {
69
+ prompt = formatResponsesPrompt(slicedInput, config.excludedFilePatterns);
70
+ }
71
+ catch (err) {
72
+ sendError(reply, 400, "invalid_request_error", err instanceof Error ? err.message : String(err));
73
+ if (isReuse) {
74
+ state.markSessionInactive();
75
+ }
76
+ else {
77
+ manager.remove(conversation.id);
78
+ }
79
+ return;
80
+ }
81
+ logger.debug(`Prompt (${isReuse ? "incremental" : "full"}): ${String(prompt.length)} chars`);
82
+ if (!isReuse) {
83
+ const systemMessage = req.instructions ?? extractInstructions(req.input);
84
+ logger.debug(`System message length: ${String(systemMessage?.length ?? 0)} chars`);
85
+ logger.debug(`Tools in request: ${tools ? String(tools.length) : "0"}`);
86
+ if (tools) {
87
+ logger.debug(`Tool names: ${tools.map((t) => t.name).join(", ")}`);
88
+ }
89
+ let copilotModel = req.model;
90
+ let supportsReasoningEffort = false;
91
+ try {
92
+ const models = await service.listModels();
93
+ const resolved = resolveModel(req.model, models, logger);
94
+ if (!resolved) {
95
+ sendError(reply, 400, "invalid_request_error", `Model "${req.model}" is not available. Available models: ${models.map((m) => m.id).join(", ")}`);
96
+ manager.remove(conversation.id);
97
+ return;
98
+ }
99
+ copilotModel = resolved;
100
+ if (config.reasoningEffort) {
101
+ const modelInfo = models.find((m) => m.id === copilotModel);
102
+ supportsReasoningEffort =
103
+ modelInfo?.capabilities.supports.reasoningEffort ?? false;
104
+ if (!supportsReasoningEffort) {
105
+ logger.debug(`Model "${copilotModel}" does not support reasoning effort, ignoring config`);
106
+ }
107
+ }
108
+ }
109
+ catch (err) {
110
+ logger.warn("Failed to list models, passing model through as-is:", err);
111
+ }
112
+ conversation.model = copilotModel;
113
+ if (hasBridge) {
114
+ logger.info("Tool bridge active (in-process MCP)");
115
+ }
116
+ const sessionConfig = createSessionConfig({
117
+ model: copilotModel,
118
+ systemMessage,
119
+ logger,
120
+ config,
121
+ supportsReasoningEffort,
122
+ cwd: service.cwd,
123
+ hasToolBridge: hasBridge,
124
+ port,
125
+ conversationId: conversation.id,
126
+ });
127
+ try {
128
+ conversation.session = await service.createSession(sessionConfig);
129
+ }
130
+ catch (err) {
131
+ logger.error("Creating session failed:", err);
132
+ sendError(reply, 500, "api_error", "Failed to create session");
133
+ manager.remove(conversation.id);
134
+ return;
135
+ }
136
+ }
137
+ if (!conversation.session) {
138
+ logger.error("Primary conversation has no session, clearing");
139
+ manager.clearPrimary();
140
+ sendError(reply, 500, "api_error", "Session lost, please retry");
141
+ return;
142
+ }
143
+ state.setReply(reply);
144
+ const responseId = genId("resp");
145
+ try {
146
+ logger.info(`Streaming response for conversation ${conversation.id}`);
147
+ await handleResponsesStreaming(state, conversation.session, prompt, req.model, logger, hasBridge, responseId);
148
+ conversation.sentMessageCount = inputLength;
149
+ if (conversation.isPrimary && state.hadError) {
150
+ manager.clearPrimary();
151
+ }
152
+ }
153
+ catch (err) {
154
+ logger.error("Request failed:", err);
155
+ if (conversation.isPrimary) {
156
+ manager.clearPrimary();
157
+ }
158
+ if (!reply.sent) {
159
+ sendError(reply, 500, "api_error", err instanceof Error ? err.message : "Internal error");
160
+ }
161
+ }
162
+ };
163
+ }
164
+ //# sourceMappingURL=handler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handler.js","sourceRoot":"","sources":["../../../src/providers/codex/handler.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { InputItem, FunctionCallOutputInput } from "./schemas.js";
2
+ export declare function formatResponsesPrompt(input: string | InputItem[], excludedFilePatterns: string[]): string;
3
+ export declare function extractInstructions(input: string | InputItem[]): string | undefined;
4
+ export declare function extractFunctionCallOutputs(input: string | InputItem[]): FunctionCallOutputInput[];
@@ -0,0 +1,58 @@
1
+ import { filterExcludedFiles } from "../shared/prompt-utils.js";
2
+ function extractContent(content) {
3
+ if (typeof content === "string")
4
+ return content;
5
+ return content
6
+ .filter((c) => typeof c["text"] === "string")
7
+ .map((c) => c.text)
8
+ .join("");
9
+ }
10
+ export function formatResponsesPrompt(input, excludedFilePatterns) {
11
+ if (typeof input === "string") {
12
+ return `[User]: ${filterExcludedFiles(input, excludedFilePatterns)}`;
13
+ }
14
+ const parts = [];
15
+ for (const item of input) {
16
+ if ("role" in item) {
17
+ const content = extractContent(item.content);
18
+ switch (item.role) {
19
+ case "system":
20
+ case "developer":
21
+ continue;
22
+ case "user":
23
+ parts.push(`[User]: ${filterExcludedFiles(content, excludedFilePatterns)}`);
24
+ break;
25
+ case "assistant":
26
+ if (content)
27
+ parts.push(`[Assistant]: ${content}`);
28
+ break;
29
+ }
30
+ }
31
+ else if (item.type === "function_call") {
32
+ parts.push(`[Assistant called tool ${item.name} with args: ${item.arguments}]`);
33
+ }
34
+ else {
35
+ parts.push(`[Tool result for ${item.call_id}]: ${item.output}`);
36
+ }
37
+ }
38
+ return parts.join("\n\n");
39
+ }
40
+ export function extractInstructions(input) {
41
+ if (typeof input === "string")
42
+ return undefined;
43
+ const parts = [];
44
+ for (const item of input) {
45
+ if ("role" in item && (item.role === "system" || item.role === "developer")) {
46
+ const text = extractContent(item.content);
47
+ if (text)
48
+ parts.push(text);
49
+ }
50
+ }
51
+ return parts.length > 0 ? parts.join("\n\n") : undefined;
52
+ }
53
+ export function extractFunctionCallOutputs(input) {
54
+ if (typeof input === "string")
55
+ return [];
56
+ return input.filter((item) => "type" in item && item.type === "function_call_output");
57
+ }
58
+ //# sourceMappingURL=prompt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt.js","sourceRoot":"","sources":["../../../src/providers/codex/prompt.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAEhE,SAAS,cAAc,CAAC,OAA2C;IACjE,IAAI,OAAO,OAAO,KAAK,QAAQ;QAAE,OAAO,OAAO,CAAC;IAChD,OAAO,OAAO;SACX,MAAM,CAAC,CAAC,CAAC,EAAmD,EAAE,CAC7D,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,QAAQ,CAC9B;SACA,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;SAClB,IAAI,CAAC,EAAE,CAAC,CAAC;AACd,CAAC;AAED,MAAM,UAAU,qBAAqB,CACnC,KAA2B,EAC3B,oBAA8B;IAE9B,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,WAAW,mBAAmB,CAAC,KAAK,EAAE,oBAAoB,CAAC,EAAE,CAAC;IACvE,CAAC;IAED,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,MAAM,IAAI,IAAI,EAAE,CAAC;YACnB,MAAM,OAAO,GAAG,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAC7C,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;gBAClB,KAAK,QAAQ,CAAC;gBACd,KAAK,WAAW;oBACd,SAAS;gBACX,KAAK,MAAM;oBACT,KAAK,CAAC,IAAI,CAAC,WAAW,mBAAmB,CAAC,OAAO,EAAE,oBAAoB,CAAC,EAAE,CAAC,CAAC;oBAC5E,MAAM;gBACR,KAAK,WAAW;oBACd,IAAI,OAAO;wBAAE,KAAK,CAAC,IAAI,CAAC,gBAAgB,OAAO,EAAE,CAAC,CAAC;oBACnD,MAAM;YACV,CAAC;QACH,CAAC;aAAM,IAAI,IAAI,CAAC,IAAI,KAAK,eAAe,EAAE,CAAC;YACzC,KAAK,CAAC,IAAI,CAAC,0BAA0B,IAAI,CAAC,IAAI,eAAe,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC;QAClF,CAAC;aAAM,CAAC;YACN,KAAK,CAAC,IAAI,CAAC,oBAAoB,IAAI,CAAC,OAAO,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;QAClE,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AAC5B,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,KAA2B;IAC7D,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAC;IAEhD,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,MAAM,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,IAAI,KAAK,WAAW,CAAC,EAAE,CAAC;YAC5E,MAAM,IAAI,GAAG,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAC1C,IAAI,IAAI;gBAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC7B,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AAC3D,CAAC;AAED,MAAM,UAAU,0BAA0B,CACxC,KAA2B;IAE3B,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,EAAE,CAAC;IACzC,OAAO,KAAK,CAAC,MAAM,CACjB,CAAC,IAAI,EAAmC,EAAE,CACxC,MAAM,IAAI,IAAI,IAAI,IAAI,CAAC,IAAI,KAAK,sBAAsB,CACzD,CAAC;AACJ,CAAC"}
@@ -0,0 +1,5 @@
1
+ export declare const codexProvider: {
2
+ name: string;
3
+ routes: string[];
4
+ register(app: import("fastify").FastifyInstance<import("fastify").RawServerDefault, import("node:http").IncomingMessage, import("node:http").ServerResponse<import("node:http").IncomingMessage>, import("fastify").FastifyBaseLogger, import("fastify").FastifyTypeProviderDefault>, ctx: import("../../context.js").AppContext): void;
5
+ };
@@ -0,0 +1,24 @@
1
+ import { registerToolBridge } from "../../tool-bridge/index.js";
2
+ import { createResponsesHandler } from "./handler.js";
3
+ export const codexProvider = {
4
+ name: "Codex",
5
+ routes: ["POST /v1/responses"],
6
+ register(app, ctx) {
7
+ app.addHook("onRequest", (request, reply, done) => {
8
+ if (request.url.startsWith("/mcp/")) {
9
+ done();
10
+ return;
11
+ }
12
+ const ua = request.headers["user-agent"] ?? "";
13
+ if (!ua.startsWith("Xcode/")) {
14
+ ctx.logger.warn(`Rejected request from unexpected user-agent: ${ua}`);
15
+ void reply.code(403).type("application/json").send('{"error":"Forbidden"}\n');
16
+ return;
17
+ }
18
+ done();
19
+ });
20
+ const manager = registerToolBridge(app, ctx.logger);
21
+ app.post("/v1/responses", createResponsesHandler(ctx, manager));
22
+ },
23
+ };
24
+ //# sourceMappingURL=provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.js","sourceRoot":"","sources":["../../../src/providers/codex/provider.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAC;AAEtD,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,IAAI,EAAE,OAAO;IACb,MAAM,EAAE,CAAC,oBAAoB,CAAC;IAE9B,QAAQ,CAAC,GAAG,EAAE,GAAG;QACf,GAAG,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;YAChD,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;gBACpC,IAAI,EAAE,CAAC;gBACP,OAAO;YACT,CAAC;YACD,MAAM,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC;YAC/C,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC7B,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,gDAAgD,EAAE,EAAE,CAAC,CAAC;gBACtE,KAAK,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;gBAC9E,OAAO;YACT,CAAC;YACD,IAAI,EAAE,CAAC;QACT,CAAC,CAAC,CAAC;QAEH,MAAM,OAAO,GAAG,kBAAkB,CAAC,GAAG,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;QACpD,GAAG,CAAC,IAAI,CAAC,eAAe,EAAE,sBAAsB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC;IAClE,CAAC;CACiB,CAAC"}
@@ -0,0 +1,122 @@
1
+ import { z } from "zod";
2
+ declare const ResponsesInputMessageSchema: z.ZodObject<{
3
+ type: z.ZodOptional<z.ZodLiteral<"message">>;
4
+ role: z.ZodEnum<{
5
+ system: "system";
6
+ developer: "developer";
7
+ user: "user";
8
+ assistant: "assistant";
9
+ }>;
10
+ content: z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>]>;
11
+ }, z.core.$strip>;
12
+ declare const FunctionCallInputSchema: z.ZodObject<{
13
+ type: z.ZodLiteral<"function_call">;
14
+ id: z.ZodOptional<z.ZodString>;
15
+ call_id: z.ZodString;
16
+ name: z.ZodString;
17
+ arguments: z.ZodString;
18
+ }, z.core.$strip>;
19
+ declare const FunctionCallOutputInputSchema: z.ZodObject<{
20
+ type: z.ZodLiteral<"function_call_output">;
21
+ call_id: z.ZodString;
22
+ output: z.ZodString;
23
+ }, z.core.$strip>;
24
+ declare const InputItemSchema: z.ZodUnion<readonly [z.ZodObject<{
25
+ type: z.ZodOptional<z.ZodLiteral<"message">>;
26
+ role: z.ZodEnum<{
27
+ system: "system";
28
+ developer: "developer";
29
+ user: "user";
30
+ assistant: "assistant";
31
+ }>;
32
+ content: z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>]>;
33
+ }, z.core.$strip>, z.ZodObject<{
34
+ type: z.ZodLiteral<"function_call">;
35
+ id: z.ZodOptional<z.ZodString>;
36
+ call_id: z.ZodString;
37
+ name: z.ZodString;
38
+ arguments: z.ZodString;
39
+ }, z.core.$strip>, z.ZodObject<{
40
+ type: z.ZodLiteral<"function_call_output">;
41
+ call_id: z.ZodString;
42
+ output: z.ZodString;
43
+ }, z.core.$strip>]>;
44
+ export type InputItem = z.infer<typeof InputItemSchema>;
45
+ export type InputMessage = z.infer<typeof ResponsesInputMessageSchema>;
46
+ export type FunctionCallInput = z.infer<typeof FunctionCallInputSchema>;
47
+ export type FunctionCallOutputInput = z.infer<typeof FunctionCallOutputInputSchema>;
48
+ declare const FunctionToolSchema: z.ZodObject<{
49
+ type: z.ZodLiteral<"function">;
50
+ name: z.ZodString;
51
+ description: z.ZodOptional<z.ZodString>;
52
+ parameters: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
53
+ strict: z.ZodOptional<z.ZodBoolean>;
54
+ }, z.core.$strip>;
55
+ export type ResponsesTool = z.infer<typeof FunctionToolSchema>;
56
+ /** Narrow to function tools only (ignore web_search, code_interpreter, etc.) */
57
+ export declare function filterFunctionTools(tools: Record<string, unknown>[]): ResponsesTool[];
58
+ export declare const ResponsesRequestSchema: z.ZodObject<{
59
+ model: z.ZodString;
60
+ input: z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
61
+ type: z.ZodOptional<z.ZodLiteral<"message">>;
62
+ role: z.ZodEnum<{
63
+ system: "system";
64
+ developer: "developer";
65
+ user: "user";
66
+ assistant: "assistant";
67
+ }>;
68
+ content: z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>]>;
69
+ }, z.core.$strip>, z.ZodObject<{
70
+ type: z.ZodLiteral<"function_call">;
71
+ id: z.ZodOptional<z.ZodString>;
72
+ call_id: z.ZodString;
73
+ name: z.ZodString;
74
+ arguments: z.ZodString;
75
+ }, z.core.$strip>, z.ZodObject<{
76
+ type: z.ZodLiteral<"function_call_output">;
77
+ call_id: z.ZodString;
78
+ output: z.ZodString;
79
+ }, z.core.$strip>]>>]>;
80
+ instructions: z.ZodOptional<z.ZodString>;
81
+ tools: z.ZodOptional<z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
82
+ stream: z.ZodOptional<z.ZodBoolean>;
83
+ temperature: z.ZodOptional<z.ZodNumber>;
84
+ previous_response_id: z.ZodOptional<z.ZodString>;
85
+ }, z.core.$strip>;
86
+ export type ResponsesRequest = z.infer<typeof ResponsesRequestSchema>;
87
+ export interface MessageContent {
88
+ type: "output_text";
89
+ text: string;
90
+ annotations: unknown[];
91
+ }
92
+ export interface MessageOutputItem {
93
+ type: "message";
94
+ id: string;
95
+ status: "in_progress" | "completed";
96
+ role: "assistant";
97
+ content: MessageContent[];
98
+ }
99
+ export interface FunctionCallOutputItem {
100
+ type: "function_call";
101
+ id: string;
102
+ call_id: string;
103
+ name: string;
104
+ arguments: string;
105
+ status: "in_progress" | "completed";
106
+ }
107
+ export type OutputItem = MessageOutputItem | FunctionCallOutputItem;
108
+ export interface ResponseObject {
109
+ id: string;
110
+ object: "response";
111
+ created_at: number;
112
+ model: string;
113
+ status: "in_progress" | "completed" | "incomplete" | "failed";
114
+ output: OutputItem[];
115
+ error?: {
116
+ code: string;
117
+ message: string;
118
+ } | null;
119
+ }
120
+ export declare function currentTimestamp(): number;
121
+ export declare function genId(prefix: string): string;
122
+ export {};
@@ -0,0 +1,55 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { z } from "zod";
3
+ const ResponsesInputMessageSchema = z.object({
4
+ type: z.literal("message").optional(),
5
+ role: z.enum(["user", "assistant", "system", "developer"]),
6
+ content: z.union([z.string(), z.array(z.record(z.string(), z.unknown()))]),
7
+ });
8
+ const FunctionCallInputSchema = z.object({
9
+ type: z.literal("function_call"),
10
+ id: z.string().optional(),
11
+ call_id: z.string(),
12
+ name: z.string(),
13
+ arguments: z.string(),
14
+ });
15
+ const FunctionCallOutputInputSchema = z.object({
16
+ type: z.literal("function_call_output"),
17
+ call_id: z.string(),
18
+ output: z.string(),
19
+ });
20
+ const InputItemSchema = z.union([
21
+ ResponsesInputMessageSchema,
22
+ FunctionCallInputSchema,
23
+ FunctionCallOutputInputSchema,
24
+ ]);
25
+ /** Accept any tool shape in the request; we only process function tools. */
26
+ const RawToolSchema = z.record(z.string(), z.unknown());
27
+ const FunctionToolSchema = z.object({
28
+ type: z.literal("function"),
29
+ name: z.string(),
30
+ description: z.string().optional(),
31
+ parameters: z.record(z.string(), z.unknown()).optional(),
32
+ strict: z.boolean().optional(),
33
+ });
34
+ /** Narrow to function tools only (ignore web_search, code_interpreter, etc.) */
35
+ export function filterFunctionTools(tools) {
36
+ return tools
37
+ .filter((t) => t.type === "function")
38
+ .map((t) => FunctionToolSchema.parse(t));
39
+ }
40
+ export const ResponsesRequestSchema = z.object({
41
+ model: z.string().min(1, "Model is required"),
42
+ input: z.union([z.string(), z.array(InputItemSchema)]),
43
+ instructions: z.string().optional(),
44
+ tools: z.array(RawToolSchema).optional(),
45
+ stream: z.boolean().optional(),
46
+ temperature: z.number().optional(),
47
+ previous_response_id: z.string().optional(),
48
+ });
49
+ export function currentTimestamp() {
50
+ return Math.floor(Date.now() / 1000);
51
+ }
52
+ export function genId(prefix) {
53
+ return `${prefix}_${randomUUID()}`;
54
+ }
55
+ //# sourceMappingURL=schemas.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schemas.js","sourceRoot":"","sources":["../../../src/providers/codex/schemas.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import type { FastifyReply } from "fastify";
2
+ import type { CopilotSession } from "@github/copilot-sdk";
3
+ import type { Logger } from "../../logger.js";
4
+ import type { ToolBridgeState } from "../../tool-bridge/state.js";
5
+ export interface SeqCounter {
6
+ value: number;
7
+ }
8
+ export declare function startResponseStream(reply: FastifyReply, responseId: string, model: string, seq?: SeqCounter): SeqCounter;
9
+ export declare function handleResponsesStreaming(state: ToolBridgeState, session: CopilotSession, prompt: string, model: string, logger: Logger, hasBridge: boolean, responseId: string): Promise<void>;
@@ -0,0 +1,172 @@
1
+ import { currentTimestamp, genId } from "./schemas.js";
2
+ import { SSE_HEADERS, sendSSEEvent as sendEvent, sendSSEComment } from "../shared/streaming-utils.js";
3
+ import { runSessionStreaming } from "../shared/streaming-core.js";
4
+ function nextSeq(counter) {
5
+ return counter.value++;
6
+ }
7
+ export function startResponseStream(reply, responseId, model, seq) {
8
+ const counter = seq ?? { value: 0 };
9
+ reply.raw.writeHead(200, SSE_HEADERS);
10
+ const response = {
11
+ id: responseId,
12
+ object: "response",
13
+ created_at: currentTimestamp(),
14
+ model,
15
+ status: "in_progress",
16
+ output: [],
17
+ };
18
+ sendEvent(reply, "response.created", { response }, nextSeq(counter));
19
+ sendEvent(reply, "response.in_progress", { response }, nextSeq(counter));
20
+ return counter;
21
+ }
22
+ function createResponsesProtocol(responseId, model, seq, getReply) {
23
+ let messageItem = null;
24
+ let messageStarted = false;
25
+ let outputIndex = 0;
26
+ const outputItems = [];
27
+ const accumulatedText = [];
28
+ // Keepalive every 15s so the client doesn't time out while
29
+ // waiting for internal tool execution to finish
30
+ const keepaliveInterval = setInterval(() => {
31
+ const r = getReply();
32
+ if (r)
33
+ sendSSEComment(r);
34
+ }, 15_000);
35
+ function ensureMessageItem(r) {
36
+ if (!messageStarted) {
37
+ messageItem = {
38
+ type: "message",
39
+ id: genId("msg"),
40
+ status: "in_progress",
41
+ role: "assistant",
42
+ content: [],
43
+ };
44
+ sendEvent(r, "response.output_item.added", {
45
+ output_index: outputIndex,
46
+ item: messageItem,
47
+ }, nextSeq(seq));
48
+ sendEvent(r, "response.content_part.added", {
49
+ item_id: messageItem.id,
50
+ output_index: outputIndex,
51
+ content_index: 0,
52
+ part: { type: "output_text", text: "", annotations: [] },
53
+ }, nextSeq(seq));
54
+ messageStarted = true;
55
+ }
56
+ }
57
+ function closeMessageItem(r) {
58
+ if (!messageStarted || !messageItem)
59
+ return;
60
+ const fullText = accumulatedText.join("");
61
+ sendEvent(r, "response.output_text.done", {
62
+ item_id: messageItem.id,
63
+ output_index: outputIndex,
64
+ content_index: 0,
65
+ text: fullText,
66
+ }, nextSeq(seq));
67
+ sendEvent(r, "response.content_part.done", {
68
+ item_id: messageItem.id,
69
+ output_index: outputIndex,
70
+ content_index: 0,
71
+ part: { type: "output_text", text: fullText, annotations: [] },
72
+ }, nextSeq(seq));
73
+ messageItem.status = "completed";
74
+ messageItem.content = [{ type: "output_text", text: fullText, annotations: [] }];
75
+ outputItems.push(messageItem);
76
+ sendEvent(r, "response.output_item.done", {
77
+ output_index: outputIndex,
78
+ item: messageItem,
79
+ }, nextSeq(seq));
80
+ outputIndex++;
81
+ messageStarted = false;
82
+ messageItem = null;
83
+ }
84
+ function emitFunctionCallItems(r, toolRequests) {
85
+ for (const tr of toolRequests) {
86
+ const callId = tr.toolCallId;
87
+ const itemId = genId("fc");
88
+ const argsJson = tr.arguments != null ? JSON.stringify(tr.arguments) : "{}";
89
+ const fcItem = {
90
+ type: "function_call",
91
+ id: itemId,
92
+ call_id: callId,
93
+ name: tr.name,
94
+ arguments: argsJson,
95
+ status: "in_progress",
96
+ };
97
+ sendEvent(r, "response.output_item.added", {
98
+ output_index: outputIndex,
99
+ item: fcItem,
100
+ }, nextSeq(seq));
101
+ const doneItem = { ...fcItem, status: "completed" };
102
+ sendEvent(r, "response.output_item.done", {
103
+ output_index: outputIndex,
104
+ item: doneItem,
105
+ }, nextSeq(seq));
106
+ outputItems.push(doneItem);
107
+ outputIndex++;
108
+ }
109
+ }
110
+ function sendResponseEnvelope(r, status) {
111
+ const response = {
112
+ id: responseId,
113
+ object: "response",
114
+ created_at: currentTimestamp(),
115
+ model,
116
+ status,
117
+ output: outputItems,
118
+ };
119
+ sendEvent(r, `response.${status}`, { response }, nextSeq(seq));
120
+ }
121
+ return {
122
+ flushDeltas(r, deltas) {
123
+ ensureMessageItem(r);
124
+ if (!messageItem)
125
+ return;
126
+ for (const text of deltas) {
127
+ sendEvent(r, "response.output_text.delta", {
128
+ item_id: messageItem.id,
129
+ output_index: outputIndex,
130
+ content_index: 0,
131
+ delta: text,
132
+ }, nextSeq(seq));
133
+ accumulatedText.push(text);
134
+ }
135
+ },
136
+ emitToolsAndFinish(r, tools) {
137
+ closeMessageItem(r);
138
+ emitFunctionCallItems(r, tools);
139
+ sendResponseEnvelope(r, "completed");
140
+ },
141
+ sendCompleted(r) {
142
+ if (!messageStarted)
143
+ ensureMessageItem(r);
144
+ closeMessageItem(r);
145
+ sendResponseEnvelope(r, "completed");
146
+ },
147
+ sendFailed(r) {
148
+ if (messageStarted)
149
+ closeMessageItem(r);
150
+ sendResponseEnvelope(r, "failed");
151
+ },
152
+ teardown() {
153
+ clearInterval(keepaliveInterval);
154
+ },
155
+ reset() {
156
+ messageStarted = false;
157
+ messageItem = null;
158
+ outputIndex = 0;
159
+ outputItems.length = 0;
160
+ accumulatedText.length = 0;
161
+ },
162
+ };
163
+ }
164
+ export async function handleResponsesStreaming(state, session, prompt, model, logger, hasBridge, responseId) {
165
+ const reply = state.currentReply;
166
+ if (!reply)
167
+ throw new Error("No reply set on bridge state");
168
+ const seq = startResponseStream(reply, responseId, model);
169
+ const protocol = createResponsesProtocol(responseId, model, seq, () => state.currentReply);
170
+ return runSessionStreaming(state, session, prompt, logger, hasBridge, protocol, reply);
171
+ }
172
+ //# sourceMappingURL=streaming.js.map