copilot-router 1.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 (54) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +241 -0
  3. package/dist/cli.d.ts +2 -0
  4. package/dist/cli.js +32 -0
  5. package/dist/lib/api-config.d.ts +15 -0
  6. package/dist/lib/api-config.js +30 -0
  7. package/dist/lib/database.d.ts +60 -0
  8. package/dist/lib/database.js +228 -0
  9. package/dist/lib/error.d.ts +11 -0
  10. package/dist/lib/error.js +34 -0
  11. package/dist/lib/state.d.ts +9 -0
  12. package/dist/lib/state.js +3 -0
  13. package/dist/lib/token-manager.d.ts +95 -0
  14. package/dist/lib/token-manager.js +241 -0
  15. package/dist/lib/utils.d.ts +8 -0
  16. package/dist/lib/utils.js +10 -0
  17. package/dist/main.d.ts +1 -0
  18. package/dist/main.js +97 -0
  19. package/dist/routes/anthropic/routes.d.ts +2 -0
  20. package/dist/routes/anthropic/routes.js +155 -0
  21. package/dist/routes/anthropic/stream-translation.d.ts +3 -0
  22. package/dist/routes/anthropic/stream-translation.js +136 -0
  23. package/dist/routes/anthropic/translation.d.ts +4 -0
  24. package/dist/routes/anthropic/translation.js +241 -0
  25. package/dist/routes/anthropic/types.d.ts +165 -0
  26. package/dist/routes/anthropic/types.js +2 -0
  27. package/dist/routes/anthropic/utils.d.ts +2 -0
  28. package/dist/routes/anthropic/utils.js +12 -0
  29. package/dist/routes/auth/routes.d.ts +2 -0
  30. package/dist/routes/auth/routes.js +158 -0
  31. package/dist/routes/gemini/routes.d.ts +2 -0
  32. package/dist/routes/gemini/routes.js +163 -0
  33. package/dist/routes/gemini/translation.d.ts +5 -0
  34. package/dist/routes/gemini/translation.js +215 -0
  35. package/dist/routes/gemini/types.d.ts +63 -0
  36. package/dist/routes/gemini/types.js +2 -0
  37. package/dist/routes/openai/routes.d.ts +2 -0
  38. package/dist/routes/openai/routes.js +215 -0
  39. package/dist/routes/utility/routes.d.ts +2 -0
  40. package/dist/routes/utility/routes.js +28 -0
  41. package/dist/services/copilot/create-chat-completions.d.ts +130 -0
  42. package/dist/services/copilot/create-chat-completions.js +32 -0
  43. package/dist/services/copilot/create-embeddings.d.ts +20 -0
  44. package/dist/services/copilot/create-embeddings.js +19 -0
  45. package/dist/services/copilot/get-models.d.ts +51 -0
  46. package/dist/services/copilot/get-models.js +45 -0
  47. package/dist/services/github/get-device-code.d.ts +11 -0
  48. package/dist/services/github/get-device-code.js +21 -0
  49. package/dist/services/github/get-user.d.ts +11 -0
  50. package/dist/services/github/get-user.js +17 -0
  51. package/dist/services/github/poll-access-token.d.ts +13 -0
  52. package/dist/services/github/poll-access-token.js +56 -0
  53. package/package.json +56 -0
  54. package/public/index.html +419 -0
@@ -0,0 +1,136 @@
1
+ import { mapOpenAIStopReasonToAnthropic } from "./utils.js";
2
+ function isToolBlockOpen(state) {
3
+ if (!state.contentBlockOpen)
4
+ return false;
5
+ return Object.values(state.toolCalls).some((tc) => tc.anthropicBlockIndex === state.contentBlockIndex);
6
+ }
7
+ export function translateChunkToAnthropicEvents(chunk, state) {
8
+ const events = [];
9
+ if (chunk.choices.length === 0)
10
+ return events;
11
+ const choice = chunk.choices[0];
12
+ const { delta } = choice;
13
+ if (!state.messageStartSent) {
14
+ events.push({
15
+ type: "message_start",
16
+ message: {
17
+ id: chunk.id,
18
+ type: "message",
19
+ role: "assistant",
20
+ content: [],
21
+ model: chunk.model,
22
+ stop_reason: null,
23
+ stop_sequence: null,
24
+ usage: {
25
+ input_tokens: (chunk.usage?.prompt_tokens ?? 0) -
26
+ (chunk.usage?.prompt_tokens_details?.cached_tokens ?? 0),
27
+ output_tokens: 0,
28
+ ...(chunk.usage?.prompt_tokens_details?.cached_tokens !== undefined && {
29
+ cache_read_input_tokens: chunk.usage.prompt_tokens_details.cached_tokens,
30
+ }),
31
+ },
32
+ },
33
+ });
34
+ state.messageStartSent = true;
35
+ }
36
+ if (delta.content) {
37
+ if (isToolBlockOpen(state)) {
38
+ events.push({
39
+ type: "content_block_stop",
40
+ index: state.contentBlockIndex,
41
+ });
42
+ state.contentBlockIndex++;
43
+ state.contentBlockOpen = false;
44
+ }
45
+ if (!state.contentBlockOpen) {
46
+ events.push({
47
+ type: "content_block_start",
48
+ index: state.contentBlockIndex,
49
+ content_block: {
50
+ type: "text",
51
+ text: "",
52
+ },
53
+ });
54
+ state.contentBlockOpen = true;
55
+ }
56
+ events.push({
57
+ type: "content_block_delta",
58
+ index: state.contentBlockIndex,
59
+ delta: {
60
+ type: "text_delta",
61
+ text: delta.content,
62
+ },
63
+ });
64
+ }
65
+ if (delta.tool_calls) {
66
+ for (const toolCall of delta.tool_calls) {
67
+ if (toolCall.id && toolCall.function?.name) {
68
+ if (state.contentBlockOpen) {
69
+ events.push({
70
+ type: "content_block_stop",
71
+ index: state.contentBlockIndex,
72
+ });
73
+ state.contentBlockIndex++;
74
+ state.contentBlockOpen = false;
75
+ }
76
+ const anthropicBlockIndex = state.contentBlockIndex;
77
+ state.toolCalls[toolCall.index] = {
78
+ id: toolCall.id,
79
+ name: toolCall.function.name,
80
+ anthropicBlockIndex,
81
+ };
82
+ events.push({
83
+ type: "content_block_start",
84
+ index: anthropicBlockIndex,
85
+ content_block: {
86
+ type: "tool_use",
87
+ id: toolCall.id,
88
+ name: toolCall.function.name,
89
+ input: {},
90
+ },
91
+ });
92
+ state.contentBlockOpen = true;
93
+ }
94
+ if (toolCall.function?.arguments) {
95
+ const toolCallInfo = state.toolCalls[toolCall.index];
96
+ if (toolCallInfo) {
97
+ events.push({
98
+ type: "content_block_delta",
99
+ index: toolCallInfo.anthropicBlockIndex,
100
+ delta: {
101
+ type: "input_json_delta",
102
+ partial_json: toolCall.function.arguments,
103
+ },
104
+ });
105
+ }
106
+ }
107
+ }
108
+ }
109
+ if (choice.finish_reason) {
110
+ if (state.contentBlockOpen) {
111
+ events.push({
112
+ type: "content_block_stop",
113
+ index: state.contentBlockIndex,
114
+ });
115
+ state.contentBlockOpen = false;
116
+ }
117
+ events.push({
118
+ type: "message_delta",
119
+ delta: {
120
+ stop_reason: mapOpenAIStopReasonToAnthropic(choice.finish_reason),
121
+ stop_sequence: null,
122
+ },
123
+ usage: {
124
+ input_tokens: (chunk.usage?.prompt_tokens ?? 0) -
125
+ (chunk.usage?.prompt_tokens_details?.cached_tokens ?? 0),
126
+ output_tokens: chunk.usage?.completion_tokens ?? 0,
127
+ ...(chunk.usage?.prompt_tokens_details?.cached_tokens !== undefined && {
128
+ cache_read_input_tokens: chunk.usage.prompt_tokens_details.cached_tokens,
129
+ }),
130
+ },
131
+ }, {
132
+ type: "message_stop",
133
+ });
134
+ }
135
+ return events;
136
+ }
@@ -0,0 +1,4 @@
1
+ import { type ChatCompletionResponse, type ChatCompletionsPayload } from "../../services/copilot/create-chat-completions.js";
2
+ import { type AnthropicMessagesPayload, type AnthropicResponse } from "./types.js";
3
+ export declare function translateToOpenAI(payload: AnthropicMessagesPayload): ChatCompletionsPayload;
4
+ export declare function translateToAnthropic(response: ChatCompletionResponse): AnthropicResponse;
@@ -0,0 +1,241 @@
1
+ import { mapOpenAIStopReasonToAnthropic } from "./utils.js";
2
+ // Payload translation
3
+ export function translateToOpenAI(payload) {
4
+ return {
5
+ model: translateModelName(payload.model),
6
+ messages: translateAnthropicMessagesToOpenAI(payload.messages, payload.system),
7
+ max_tokens: payload.max_tokens,
8
+ stop: payload.stop_sequences,
9
+ stream: payload.stream,
10
+ temperature: payload.temperature,
11
+ top_p: payload.top_p,
12
+ user: payload.metadata?.user_id,
13
+ tools: translateAnthropicToolsToOpenAI(payload.tools),
14
+ tool_choice: translateAnthropicToolChoiceToOpenAI(payload.tool_choice),
15
+ };
16
+ }
17
+ function translateModelName(model) {
18
+ // Claude models
19
+ if (model.startsWith("claude-sonne-4.5") || model.startsWith("claude-sonnet-4-5")) {
20
+ return "claude-sonnet-4.5";
21
+ }
22
+ else if (model.startsWith("claude-opus-4.5") || model.startsWith("claude-opus-4-5")) {
23
+ return "claude-opus-4.5";
24
+ }
25
+ else if (model.startsWith("claude-haiku-4.5") || model.startsWith("claude-haiku-4-5")) {
26
+ return "claude-haiku-4.5";
27
+ }
28
+ // GPT models
29
+ else if (model.startsWith("gpt-5.2-codex") || model.startsWith("gpt-5-2-codex")) {
30
+ return "gpt-5.2-codex";
31
+ }
32
+ else if (model.startsWith("gpt-5.2") || model.startsWith("gpt-5-2")) {
33
+ return "gpt-5.2";
34
+ }
35
+ // Gemini models
36
+ else if (model.startsWith("gemini-3-pro") || model.startsWith("gemini-3.0-pro")) {
37
+ return "gemini-3-pro-preview";
38
+ }
39
+ return model;
40
+ }
41
+ function translateAnthropicMessagesToOpenAI(anthropicMessages, system) {
42
+ const systemMessages = handleSystemPrompt(system);
43
+ const otherMessages = anthropicMessages.flatMap((message) => message.role === "user"
44
+ ? handleUserMessage(message)
45
+ : handleAssistantMessage(message));
46
+ return [...systemMessages, ...otherMessages];
47
+ }
48
+ function handleSystemPrompt(system) {
49
+ if (!system)
50
+ return [];
51
+ if (typeof system === "string") {
52
+ return [{ role: "system", content: system }];
53
+ }
54
+ else {
55
+ const systemText = system.map((block) => block.text).join("\n\n");
56
+ return [{ role: "system", content: systemText }];
57
+ }
58
+ }
59
+ function handleUserMessage(message) {
60
+ const newMessages = [];
61
+ if (Array.isArray(message.content)) {
62
+ const toolResultBlocks = message.content.filter((block) => block.type === "tool_result");
63
+ const otherBlocks = message.content.filter((block) => block.type !== "tool_result");
64
+ for (const block of toolResultBlocks) {
65
+ newMessages.push({
66
+ role: "tool",
67
+ tool_call_id: block.tool_use_id,
68
+ content: mapContent(block.content),
69
+ });
70
+ }
71
+ if (otherBlocks.length > 0) {
72
+ newMessages.push({
73
+ role: "user",
74
+ content: mapContent(otherBlocks),
75
+ });
76
+ }
77
+ }
78
+ else {
79
+ newMessages.push({
80
+ role: "user",
81
+ content: mapContent(message.content),
82
+ });
83
+ }
84
+ return newMessages;
85
+ }
86
+ function handleAssistantMessage(message) {
87
+ if (!Array.isArray(message.content)) {
88
+ return [
89
+ {
90
+ role: "assistant",
91
+ content: mapContent(message.content),
92
+ },
93
+ ];
94
+ }
95
+ const toolUseBlocks = message.content.filter((block) => block.type === "tool_use");
96
+ const textBlocks = message.content.filter((block) => block.type === "text");
97
+ const thinkingBlocks = message.content.filter((block) => block.type === "thinking");
98
+ const allTextContent = [
99
+ ...textBlocks.map((b) => b.text),
100
+ ...thinkingBlocks.map((b) => b.thinking),
101
+ ].join("\n\n");
102
+ return toolUseBlocks.length > 0
103
+ ? [
104
+ {
105
+ role: "assistant",
106
+ content: allTextContent || null,
107
+ tool_calls: toolUseBlocks.map((toolUse) => ({
108
+ id: toolUse.id,
109
+ type: "function",
110
+ function: {
111
+ name: toolUse.name,
112
+ arguments: JSON.stringify(toolUse.input),
113
+ },
114
+ })),
115
+ },
116
+ ]
117
+ : [
118
+ {
119
+ role: "assistant",
120
+ content: mapContent(message.content),
121
+ },
122
+ ];
123
+ }
124
+ function mapContent(content) {
125
+ if (typeof content === "string")
126
+ return content;
127
+ if (!Array.isArray(content))
128
+ return null;
129
+ const hasImage = content.some((block) => block.type === "image");
130
+ if (!hasImage) {
131
+ return content
132
+ .filter((block) => block.type === "text" || block.type === "thinking")
133
+ .map((block) => (block.type === "text" ? block.text : block.thinking))
134
+ .join("\n\n");
135
+ }
136
+ const contentParts = [];
137
+ for (const block of content) {
138
+ switch (block.type) {
139
+ case "text":
140
+ contentParts.push({ type: "text", text: block.text });
141
+ break;
142
+ case "thinking":
143
+ contentParts.push({ type: "text", text: block.thinking });
144
+ break;
145
+ case "image":
146
+ contentParts.push({
147
+ type: "image_url",
148
+ image_url: {
149
+ url: `data:${block.source.media_type};base64,${block.source.data}`,
150
+ },
151
+ });
152
+ break;
153
+ }
154
+ }
155
+ return contentParts;
156
+ }
157
+ function translateAnthropicToolsToOpenAI(anthropicTools) {
158
+ if (!anthropicTools)
159
+ return undefined;
160
+ return anthropicTools.map((tool) => ({
161
+ type: "function",
162
+ function: {
163
+ name: tool.name,
164
+ description: tool.description,
165
+ parameters: tool.input_schema,
166
+ },
167
+ }));
168
+ }
169
+ function translateAnthropicToolChoiceToOpenAI(anthropicToolChoice) {
170
+ if (!anthropicToolChoice)
171
+ return undefined;
172
+ switch (anthropicToolChoice.type) {
173
+ case "auto":
174
+ return "auto";
175
+ case "any":
176
+ return "required";
177
+ case "tool":
178
+ if (anthropicToolChoice.name) {
179
+ return { type: "function", function: { name: anthropicToolChoice.name } };
180
+ }
181
+ return undefined;
182
+ case "none":
183
+ return "none";
184
+ default:
185
+ return undefined;
186
+ }
187
+ }
188
+ // Response translation
189
+ export function translateToAnthropic(response) {
190
+ const allTextBlocks = [];
191
+ const allToolUseBlocks = [];
192
+ let stopReason = null;
193
+ stopReason = response.choices[0]?.finish_reason ?? stopReason;
194
+ for (const choice of response.choices) {
195
+ const textBlocks = getAnthropicTextBlocks(choice.message.content);
196
+ const toolUseBlocks = getAnthropicToolUseBlocks(choice.message.tool_calls);
197
+ allTextBlocks.push(...textBlocks);
198
+ allToolUseBlocks.push(...toolUseBlocks);
199
+ if (choice.finish_reason === "tool_calls" || stopReason === "stop") {
200
+ stopReason = choice.finish_reason;
201
+ }
202
+ }
203
+ return {
204
+ id: response.id,
205
+ type: "message",
206
+ role: "assistant",
207
+ model: response.model,
208
+ content: [...allTextBlocks, ...allToolUseBlocks],
209
+ stop_reason: mapOpenAIStopReasonToAnthropic(stopReason),
210
+ stop_sequence: null,
211
+ usage: {
212
+ input_tokens: (response.usage?.prompt_tokens ?? 0) -
213
+ (response.usage?.prompt_tokens_details?.cached_tokens ?? 0),
214
+ output_tokens: response.usage?.completion_tokens ?? 0,
215
+ ...(response.usage?.prompt_tokens_details?.cached_tokens !== undefined && {
216
+ cache_read_input_tokens: response.usage.prompt_tokens_details.cached_tokens,
217
+ }),
218
+ },
219
+ };
220
+ }
221
+ function getAnthropicTextBlocks(messageContent) {
222
+ if (typeof messageContent === "string") {
223
+ return [{ type: "text", text: messageContent }];
224
+ }
225
+ if (Array.isArray(messageContent)) {
226
+ return messageContent
227
+ .filter((part) => part.type === "text")
228
+ .map((part) => ({ type: "text", text: part.text }));
229
+ }
230
+ return [];
231
+ }
232
+ function getAnthropicToolUseBlocks(toolCalls) {
233
+ if (!toolCalls)
234
+ return [];
235
+ return toolCalls.map((toolCall) => ({
236
+ type: "tool_use",
237
+ id: toolCall.id,
238
+ name: toolCall.function.name,
239
+ input: JSON.parse(toolCall.function.arguments),
240
+ }));
241
+ }
@@ -0,0 +1,165 @@
1
+ export interface AnthropicMessagesPayload {
2
+ model: string;
3
+ messages: Array<AnthropicMessage>;
4
+ max_tokens: number;
5
+ system?: string | Array<AnthropicTextBlock>;
6
+ metadata?: {
7
+ user_id?: string;
8
+ };
9
+ stop_sequences?: Array<string>;
10
+ stream?: boolean;
11
+ temperature?: number;
12
+ top_p?: number;
13
+ top_k?: number;
14
+ tools?: Array<AnthropicTool>;
15
+ tool_choice?: {
16
+ type: "auto" | "any" | "tool" | "none";
17
+ name?: string;
18
+ };
19
+ thinking?: {
20
+ type: "enabled";
21
+ budget_tokens?: number;
22
+ };
23
+ service_tier?: "auto" | "standard_only";
24
+ }
25
+ export interface AnthropicTextBlock {
26
+ type: "text";
27
+ text: string;
28
+ }
29
+ export interface AnthropicImageBlock {
30
+ type: "image";
31
+ source: {
32
+ type: "base64";
33
+ media_type: "image/jpeg" | "image/png" | "image/gif" | "image/webp";
34
+ data: string;
35
+ };
36
+ }
37
+ export interface AnthropicToolResultBlock {
38
+ type: "tool_result";
39
+ tool_use_id: string;
40
+ content: string;
41
+ is_error?: boolean;
42
+ }
43
+ export interface AnthropicToolUseBlock {
44
+ type: "tool_use";
45
+ id: string;
46
+ name: string;
47
+ input: Record<string, unknown>;
48
+ }
49
+ export interface AnthropicThinkingBlock {
50
+ type: "thinking";
51
+ thinking: string;
52
+ }
53
+ export type AnthropicUserContentBlock = AnthropicTextBlock | AnthropicImageBlock | AnthropicToolResultBlock;
54
+ export type AnthropicAssistantContentBlock = AnthropicTextBlock | AnthropicToolUseBlock | AnthropicThinkingBlock;
55
+ export interface AnthropicUserMessage {
56
+ role: "user";
57
+ content: string | Array<AnthropicUserContentBlock>;
58
+ }
59
+ export interface AnthropicAssistantMessage {
60
+ role: "assistant";
61
+ content: string | Array<AnthropicAssistantContentBlock>;
62
+ }
63
+ export type AnthropicMessage = AnthropicUserMessage | AnthropicAssistantMessage;
64
+ export interface AnthropicTool {
65
+ name: string;
66
+ description?: string;
67
+ input_schema: Record<string, unknown>;
68
+ }
69
+ export interface AnthropicResponse {
70
+ id: string;
71
+ type: "message";
72
+ role: "assistant";
73
+ content: Array<AnthropicAssistantContentBlock>;
74
+ model: string;
75
+ stop_reason: "end_turn" | "max_tokens" | "stop_sequence" | "tool_use" | "pause_turn" | "refusal" | null;
76
+ stop_sequence: string | null;
77
+ usage: {
78
+ input_tokens: number;
79
+ output_tokens: number;
80
+ cache_creation_input_tokens?: number;
81
+ cache_read_input_tokens?: number;
82
+ service_tier?: "standard" | "priority" | "batch";
83
+ };
84
+ }
85
+ export interface AnthropicMessageStartEvent {
86
+ type: "message_start";
87
+ message: Omit<AnthropicResponse, "content" | "stop_reason" | "stop_sequence"> & {
88
+ content: [];
89
+ stop_reason: null;
90
+ stop_sequence: null;
91
+ };
92
+ }
93
+ export interface AnthropicContentBlockStartEvent {
94
+ type: "content_block_start";
95
+ index: number;
96
+ content_block: {
97
+ type: "text";
98
+ text: string;
99
+ } | (Omit<AnthropicToolUseBlock, "input"> & {
100
+ input: Record<string, unknown>;
101
+ }) | {
102
+ type: "thinking";
103
+ thinking: string;
104
+ };
105
+ }
106
+ export interface AnthropicContentBlockDeltaEvent {
107
+ type: "content_block_delta";
108
+ index: number;
109
+ delta: {
110
+ type: "text_delta";
111
+ text: string;
112
+ } | {
113
+ type: "input_json_delta";
114
+ partial_json: string;
115
+ } | {
116
+ type: "thinking_delta";
117
+ thinking: string;
118
+ } | {
119
+ type: "signature_delta";
120
+ signature: string;
121
+ };
122
+ }
123
+ export interface AnthropicContentBlockStopEvent {
124
+ type: "content_block_stop";
125
+ index: number;
126
+ }
127
+ export interface AnthropicMessageDeltaEvent {
128
+ type: "message_delta";
129
+ delta: {
130
+ stop_reason?: AnthropicResponse["stop_reason"];
131
+ stop_sequence?: string | null;
132
+ };
133
+ usage?: {
134
+ input_tokens?: number;
135
+ output_tokens: number;
136
+ cache_creation_input_tokens?: number;
137
+ cache_read_input_tokens?: number;
138
+ };
139
+ }
140
+ export interface AnthropicMessageStopEvent {
141
+ type: "message_stop";
142
+ }
143
+ export interface AnthropicPingEvent {
144
+ type: "ping";
145
+ }
146
+ export interface AnthropicErrorEvent {
147
+ type: "error";
148
+ error: {
149
+ type: string;
150
+ message: string;
151
+ };
152
+ }
153
+ export type AnthropicStreamEventData = AnthropicMessageStartEvent | AnthropicContentBlockStartEvent | AnthropicContentBlockDeltaEvent | AnthropicContentBlockStopEvent | AnthropicMessageDeltaEvent | AnthropicMessageStopEvent | AnthropicPingEvent | AnthropicErrorEvent;
154
+ export interface AnthropicStreamState {
155
+ messageStartSent: boolean;
156
+ contentBlockIndex: number;
157
+ contentBlockOpen: boolean;
158
+ toolCalls: {
159
+ [openAIToolIndex: number]: {
160
+ id: string;
161
+ name: string;
162
+ anthropicBlockIndex: number;
163
+ };
164
+ };
165
+ }
@@ -0,0 +1,2 @@
1
+ // Anthropic API Types
2
+ export {};
@@ -0,0 +1,2 @@
1
+ import { type AnthropicResponse } from "./types.js";
2
+ export declare function mapOpenAIStopReasonToAnthropic(finishReason: "stop" | "length" | "tool_calls" | "content_filter" | null): AnthropicResponse["stop_reason"];
@@ -0,0 +1,12 @@
1
+ export function mapOpenAIStopReasonToAnthropic(finishReason) {
2
+ if (finishReason === null) {
3
+ return null;
4
+ }
5
+ const stopReasonMap = {
6
+ stop: "end_turn",
7
+ length: "max_tokens",
8
+ tool_calls: "tool_use",
9
+ content_filter: "end_turn",
10
+ };
11
+ return stopReasonMap[finishReason];
12
+ }
@@ -0,0 +1,2 @@
1
+ import { OpenAPIHono } from "@hono/zod-openapi";
2
+ export declare function registerAuthRoutes(app: OpenAPIHono): void;