@witqq/agent-sdk 0.6.1 → 0.8.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.
- package/README.md +539 -6
- package/dist/{types-BvwNzZCj.d.cts → agent-CW9XbmG_.d.ts} +148 -95
- package/dist/{types-BvwNzZCj.d.ts → agent-DxY68NZL.d.cts} +148 -95
- package/dist/auth/index.cjs +260 -2
- package/dist/auth/index.cjs.map +1 -1
- package/dist/auth/index.d.cts +21 -138
- package/dist/auth/index.d.ts +21 -138
- package/dist/auth/index.js +260 -3
- package/dist/auth/index.js.map +1 -1
- package/dist/backends/claude.cjs +653 -140
- package/dist/backends/claude.cjs.map +1 -1
- package/dist/backends/claude.d.cts +4 -1
- package/dist/backends/claude.d.ts +4 -1
- package/dist/backends/claude.js +653 -140
- package/dist/backends/claude.js.map +1 -1
- package/dist/backends/copilot.cjs +428 -88
- package/dist/backends/copilot.cjs.map +1 -1
- package/dist/backends/copilot.d.cts +13 -4
- package/dist/backends/copilot.d.ts +13 -4
- package/dist/backends/copilot.js +428 -88
- package/dist/backends/copilot.js.map +1 -1
- package/dist/backends/vercel-ai.cjs +349 -77
- package/dist/backends/vercel-ai.cjs.map +1 -1
- package/dist/backends/vercel-ai.d.cts +3 -1
- package/dist/backends/vercel-ai.d.ts +3 -1
- package/dist/backends/vercel-ai.js +349 -77
- package/dist/backends/vercel-ai.js.map +1 -1
- package/dist/backends-BSrsBYFn.d.cts +39 -0
- package/dist/backends-BSrsBYFn.d.ts +39 -0
- package/dist/chat/accumulator.cjs +147 -0
- package/dist/chat/accumulator.cjs.map +1 -0
- package/dist/chat/accumulator.d.cts +64 -0
- package/dist/chat/accumulator.d.ts +64 -0
- package/dist/chat/accumulator.js +145 -0
- package/dist/chat/accumulator.js.map +1 -0
- package/dist/chat/backends.cjs +3524 -0
- package/dist/chat/backends.cjs.map +1 -0
- package/dist/chat/backends.d.cts +66 -0
- package/dist/chat/backends.d.ts +66 -0
- package/dist/chat/backends.js +3512 -0
- package/dist/chat/backends.js.map +1 -0
- package/dist/chat/context.cjs +280 -0
- package/dist/chat/context.cjs.map +1 -0
- package/dist/chat/context.d.cts +191 -0
- package/dist/chat/context.d.ts +191 -0
- package/dist/chat/context.js +277 -0
- package/dist/chat/context.js.map +1 -0
- package/dist/chat/core.cjs +305 -0
- package/dist/chat/core.cjs.map +1 -0
- package/dist/chat/core.d.cts +84 -0
- package/dist/chat/core.d.ts +84 -0
- package/dist/chat/core.js +282 -0
- package/dist/chat/core.js.map +1 -0
- package/dist/chat/errors.cjs +273 -0
- package/dist/chat/errors.cjs.map +1 -0
- package/dist/chat/errors.d.cts +97 -0
- package/dist/chat/errors.d.ts +97 -0
- package/dist/chat/errors.js +266 -0
- package/dist/chat/errors.js.map +1 -0
- package/dist/chat/events.cjs +203 -0
- package/dist/chat/events.cjs.map +1 -0
- package/dist/chat/events.d.cts +245 -0
- package/dist/chat/events.d.ts +245 -0
- package/dist/chat/events.js +196 -0
- package/dist/chat/events.js.map +1 -0
- package/dist/chat/index.cjs +5550 -0
- package/dist/chat/index.cjs.map +1 -0
- package/dist/chat/index.d.cts +77 -0
- package/dist/chat/index.d.ts +77 -0
- package/dist/chat/index.js +5505 -0
- package/dist/chat/index.js.map +1 -0
- package/dist/chat/react/theme.css +2517 -0
- package/dist/chat/react.cjs +3589 -0
- package/dist/chat/react.cjs.map +1 -0
- package/dist/chat/react.d.cts +1088 -0
- package/dist/chat/react.d.ts +1088 -0
- package/dist/chat/react.js +3547 -0
- package/dist/chat/react.js.map +1 -0
- package/dist/chat/runtime.cjs +1245 -0
- package/dist/chat/runtime.cjs.map +1 -0
- package/dist/chat/runtime.d.cts +182 -0
- package/dist/chat/runtime.d.ts +182 -0
- package/dist/chat/runtime.js +1243 -0
- package/dist/chat/runtime.js.map +1 -0
- package/dist/chat/server.cjs +2668 -0
- package/dist/chat/server.cjs.map +1 -0
- package/dist/chat/server.d.cts +648 -0
- package/dist/chat/server.d.ts +648 -0
- package/dist/chat/server.js +2628 -0
- package/dist/chat/server.js.map +1 -0
- package/dist/chat/sessions.cjs +380 -0
- package/dist/chat/sessions.cjs.map +1 -0
- package/dist/chat/sessions.d.cts +158 -0
- package/dist/chat/sessions.d.ts +158 -0
- package/dist/chat/sessions.js +376 -0
- package/dist/chat/sessions.js.map +1 -0
- package/dist/chat/sqlite.cjs +441 -0
- package/dist/chat/sqlite.cjs.map +1 -0
- package/dist/chat/sqlite.d.cts +128 -0
- package/dist/chat/sqlite.d.ts +128 -0
- package/dist/chat/sqlite.js +435 -0
- package/dist/chat/sqlite.js.map +1 -0
- package/dist/chat/state.cjs +190 -0
- package/dist/chat/state.cjs.map +1 -0
- package/dist/chat/state.d.cts +95 -0
- package/dist/chat/state.d.ts +95 -0
- package/dist/chat/state.js +180 -0
- package/dist/chat/state.js.map +1 -0
- package/dist/chat/storage.cjs +249 -0
- package/dist/chat/storage.cjs.map +1 -0
- package/dist/chat/storage.d.cts +197 -0
- package/dist/chat/storage.d.ts +197 -0
- package/dist/chat/storage.js +245 -0
- package/dist/chat/storage.js.map +1 -0
- package/dist/errors-C-so0M4t.d.cts +33 -0
- package/dist/errors-C-so0M4t.d.ts +33 -0
- package/dist/errors-CmVvczxZ.d.cts +28 -0
- package/dist/errors-CmVvczxZ.d.ts +28 -0
- package/dist/in-process-transport-C1JnJGVR.d.ts +228 -0
- package/dist/in-process-transport-C7DSqPyX.d.cts +228 -0
- package/dist/index.cjs +365 -59
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +322 -125
- package/dist/index.d.ts +322 -125
- package/dist/index.js +359 -60
- package/dist/index.js.map +1 -1
- package/dist/provider-types-PTSlRPNB.d.cts +39 -0
- package/dist/provider-types-PTSlRPNB.d.ts +39 -0
- package/dist/refresh-manager-B81PpYBr.d.cts +153 -0
- package/dist/refresh-manager-Dlv_iNZi.d.ts +153 -0
- package/dist/testing.cjs +383 -0
- package/dist/testing.cjs.map +1 -0
- package/dist/testing.d.cts +132 -0
- package/dist/testing.d.ts +132 -0
- package/dist/testing.js +377 -0
- package/dist/testing.js.map +1 -0
- package/dist/token-store-CSUBgYwn.d.ts +48 -0
- package/dist/token-store-CuC4hB9Z.d.cts +48 -0
- package/dist/transport-Cdh3M0tS.d.cts +68 -0
- package/dist/transport-Ciap4PWK.d.ts +68 -0
- package/dist/types-4vbcmPTp.d.cts +143 -0
- package/dist/types-BxggH0Yh.d.ts +143 -0
- package/dist/types-DRgd_9R7.d.cts +363 -0
- package/dist/types-ajANVzf7.d.ts +363 -0
- package/package.json +178 -6
|
@@ -0,0 +1,648 @@
|
|
|
1
|
+
import { IChatRuntime, ChatRuntimeOptions } from './runtime.cjs';
|
|
2
|
+
import { W as WritableResponse, I as IChatTransport } from '../transport-Cdh3M0tS.cjs';
|
|
3
|
+
import { I as IProviderStore, P as ProviderConfig } from '../provider-types-PTSlRPNB.cjs';
|
|
4
|
+
import { I as ITokenStore } from '../token-store-CuC4hB9Z.cjs';
|
|
5
|
+
export { F as FileTokenStore, a as FileTokenStoreOptions, b as InMemoryTokenStore } from '../token-store-CuC4hB9Z.cjs';
|
|
6
|
+
import { M as ModelInfo } from '../agent-DxY68NZL.cjs';
|
|
7
|
+
import { C as CopilotAuthToken, b as ClaudeAuthToken, A as AuthToken } from '../types-4vbcmPTp.cjs';
|
|
8
|
+
import { b as TokenRefreshOptions, a as TokenRefreshManager } from '../refresh-manager-B81PpYBr.cjs';
|
|
9
|
+
import '../types-DRgd_9R7.cjs';
|
|
10
|
+
import '../errors-C-so0M4t.cjs';
|
|
11
|
+
import './sessions.cjs';
|
|
12
|
+
import './storage.cjs';
|
|
13
|
+
import '../errors-CmVvczxZ.cjs';
|
|
14
|
+
import 'zod';
|
|
15
|
+
import './context.cjs';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Provider storage default implementations.
|
|
19
|
+
*
|
|
20
|
+
* Types (ProviderConfig, IProviderStore) are defined in ../provider-types.ts
|
|
21
|
+
* and re-exported here for backward compatibility.
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
/** In-memory provider store for testing and ephemeral use */
|
|
25
|
+
declare class InMemoryProviderStore implements IProviderStore {
|
|
26
|
+
private readonly providers;
|
|
27
|
+
create(config: ProviderConfig): Promise<void>;
|
|
28
|
+
get(id: string): Promise<ProviderConfig | null>;
|
|
29
|
+
update(id: string, changes: Partial<Omit<ProviderConfig, "id" | "createdAt">>): Promise<void>;
|
|
30
|
+
delete(id: string): Promise<void>;
|
|
31
|
+
list(): Promise<ProviderConfig[]>;
|
|
32
|
+
}
|
|
33
|
+
/** Options for FileProviderStore */
|
|
34
|
+
interface FileProviderStoreOptions {
|
|
35
|
+
/** Directory to store provider JSON files */
|
|
36
|
+
directory: string;
|
|
37
|
+
}
|
|
38
|
+
/** Filesystem-based provider store using JSON files (one per provider) */
|
|
39
|
+
declare class FileProviderStore implements IProviderStore {
|
|
40
|
+
private readonly dir;
|
|
41
|
+
constructor(options: FileProviderStoreOptions);
|
|
42
|
+
create(config: ProviderConfig): Promise<void>;
|
|
43
|
+
get(id: string): Promise<ProviderConfig | null>;
|
|
44
|
+
update(id: string, changes: Partial<Omit<ProviderConfig, "id" | "createdAt">>): Promise<void>;
|
|
45
|
+
delete(id: string): Promise<void>;
|
|
46
|
+
list(): Promise<ProviderConfig[]>;
|
|
47
|
+
private filePath;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Shared types for route modules.
|
|
52
|
+
*/
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Handler state — intentionally empty after stateless refactor (STAT-01).
|
|
56
|
+
* Preserved as a type for backward compatibility with custom route modules.
|
|
57
|
+
* Model resolution is now fully per-request via resolveRequestContext.
|
|
58
|
+
* @deprecated Will be removed in next major version.
|
|
59
|
+
*/
|
|
60
|
+
interface HandlerState {
|
|
61
|
+
/** @deprecated Model is now resolved per-request. This field is never set. */
|
|
62
|
+
currentModel?: string | undefined;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Shared context passed to every route module.
|
|
66
|
+
*/
|
|
67
|
+
interface RouteContext {
|
|
68
|
+
readonly runtime: IChatRuntime;
|
|
69
|
+
readonly maxBodySize: number;
|
|
70
|
+
readonly heartbeatMs?: number;
|
|
71
|
+
readonly hooks?: ChatServerHooks;
|
|
72
|
+
readonly providerStore?: IProviderStore;
|
|
73
|
+
readonly tokenStore?: ITokenStore;
|
|
74
|
+
readonly transportFactory?: TransportFactory;
|
|
75
|
+
readonly state: HandlerState;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* A route module handler.
|
|
79
|
+
* Returns `true` if the request was handled, `false` to try next module.
|
|
80
|
+
*/
|
|
81
|
+
type RouteHandler = (method: string, path: string, req: ReadableRequest, res: WritableResponse, ctx: RouteContext) => Promise<boolean>;
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* createChatHandler — maps RemoteChatClient contract endpoints to IChatRuntime calls.
|
|
85
|
+
*
|
|
86
|
+
* Routes are delegated to composable route modules in ./routes/.
|
|
87
|
+
* This file is a thin router (~90 lines) that assembles modules and handles errors.
|
|
88
|
+
*/
|
|
89
|
+
|
|
90
|
+
/** Minimal readable request interface (node:http IncomingMessage subset) */
|
|
91
|
+
interface ReadableRequest {
|
|
92
|
+
readonly method?: string;
|
|
93
|
+
readonly url?: string;
|
|
94
|
+
on(event: "data", listener: (chunk: Buffer | string) => void): unknown;
|
|
95
|
+
on(event: "end", listener: () => void): unknown;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Server-side hooks for customizing chat handler behavior.
|
|
100
|
+
* Consolidates filter, guard, and lifecycle callbacks into a single interface.
|
|
101
|
+
*/
|
|
102
|
+
interface ChatServerHooks {
|
|
103
|
+
/** Filter the model list before returning to client. */
|
|
104
|
+
filterModels?(models: ModelInfo[]): ModelInfo[];
|
|
105
|
+
/** Validate model selection on /model/switch and /send model override. Throw to reject. */
|
|
106
|
+
onModelSwitch?(model: string): void | Promise<void>;
|
|
107
|
+
/** Called before provider switch. Receives providerId and resolved backend name. Throw to reject. */
|
|
108
|
+
onProviderSwitch?(info: {
|
|
109
|
+
providerId: string;
|
|
110
|
+
backend: string;
|
|
111
|
+
}): void | Promise<void>;
|
|
112
|
+
/** Called before backend switch. Throw to reject. */
|
|
113
|
+
onBackendSwitch?(backend: string): void | Promise<void>;
|
|
114
|
+
/** Called before sending a message. Throw to reject. */
|
|
115
|
+
onBeforeSend?(sessionId: string, message: string): void | Promise<void>;
|
|
116
|
+
/** Global error handler for unhandled route errors. */
|
|
117
|
+
onError?(error: Error, context: {
|
|
118
|
+
route: string;
|
|
119
|
+
method: string;
|
|
120
|
+
}): void;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Factory for creating a chat transport for a /send request.
|
|
124
|
+
* Return an IChatTransport instance that will receive the event stream.
|
|
125
|
+
* Default: SSEChatTransport.
|
|
126
|
+
*/
|
|
127
|
+
type TransportFactory = (req: ReadableRequest, res: WritableResponse) => IChatTransport;
|
|
128
|
+
/** Configuration for createChatHandler */
|
|
129
|
+
interface ChatHandlerOptions {
|
|
130
|
+
/** Route prefix to strip from URL before matching. Default: "" (no prefix) */
|
|
131
|
+
prefix?: string;
|
|
132
|
+
/** Maximum request body size in bytes. Default: 1MB (1048576) */
|
|
133
|
+
maxBodySize?: number;
|
|
134
|
+
/** SSE heartbeat interval in milliseconds. 0 or undefined disables heartbeat. */
|
|
135
|
+
heartbeatMs?: number;
|
|
136
|
+
/** Optional provider store for provider CRUD routes. */
|
|
137
|
+
providerStore?: IProviderStore;
|
|
138
|
+
/** Optional token store for resolveRequestContext in /send. */
|
|
139
|
+
tokenStore?: ITokenStore;
|
|
140
|
+
/** Consolidated server hooks. */
|
|
141
|
+
hooks?: ChatServerHooks;
|
|
142
|
+
/** Custom transport factory for /send endpoint. Default: SSEChatTransport. */
|
|
143
|
+
transportFactory?: TransportFactory;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Create an HTTP request handler that maps RemoteChatClient contract
|
|
147
|
+
* endpoints to IChatRuntime method calls.
|
|
148
|
+
*
|
|
149
|
+
* Routes are handled by composable route modules (sessions, messages, config, providers).
|
|
150
|
+
* Model state is managed in a shared HandlerState object.
|
|
151
|
+
*/
|
|
152
|
+
declare function createChatHandler(runtime: IChatRuntime, options?: ChatHandlerOptions): (req: ReadableRequest, res: WritableResponse) => Promise<void>;
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* createAuthHandler — server-mediated authentication for all three backends.
|
|
156
|
+
*
|
|
157
|
+
* Routes:
|
|
158
|
+
* - POST /auth/start → Start auth flow (copilot device flow, claude OAuth, vercel-ai passthrough)
|
|
159
|
+
* - POST /auth/copilot/poll → Poll for Copilot device flow completion
|
|
160
|
+
* - POST /auth/claude/complete → Exchange Claude OAuth code for token
|
|
161
|
+
* - POST /auth/vercel/complete → Submit Vercel AI API key
|
|
162
|
+
* - GET /tokens/saved → List providers with saved tokens
|
|
163
|
+
* - POST /tokens/use → Load and activate a saved token
|
|
164
|
+
* - POST /tokens/clear → Clear all saved tokens and invoke onLogout
|
|
165
|
+
* - POST /auth/dispose → Clear pending flows and invoke onLogout
|
|
166
|
+
*/
|
|
167
|
+
|
|
168
|
+
/** Auth provider names recognized by the handler */
|
|
169
|
+
type AuthProvider = "copilot" | "claude" | "vercel-ai";
|
|
170
|
+
/** Copilot auth class interface (matches CopilotAuth public API) */
|
|
171
|
+
interface ICopilotAuth {
|
|
172
|
+
startDeviceFlow(options?: {
|
|
173
|
+
scopes?: string;
|
|
174
|
+
signal?: AbortSignal;
|
|
175
|
+
}): Promise<{
|
|
176
|
+
userCode: string;
|
|
177
|
+
verificationUrl: string;
|
|
178
|
+
waitForToken: (signal?: AbortSignal) => Promise<CopilotAuthToken>;
|
|
179
|
+
}>;
|
|
180
|
+
}
|
|
181
|
+
/** Claude auth class interface (matches ClaudeAuth public API) */
|
|
182
|
+
interface IClaudeAuth {
|
|
183
|
+
startOAuthFlow(options?: {
|
|
184
|
+
redirectUri?: string;
|
|
185
|
+
scopes?: string;
|
|
186
|
+
}): {
|
|
187
|
+
authorizeUrl: string;
|
|
188
|
+
completeAuth: (codeOrUrl: string) => Promise<ClaudeAuthToken>;
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
/** Callback invoked after successful authentication */
|
|
192
|
+
type OnAuthCallback = (provider: AuthProvider, token: AuthToken) => void | Promise<void>;
|
|
193
|
+
/** Configuration for createAuthHandler */
|
|
194
|
+
interface AuthHandlerOptions {
|
|
195
|
+
/** Token storage implementation */
|
|
196
|
+
tokenStore: ITokenStore;
|
|
197
|
+
/** Factory for creating CopilotAuth instances */
|
|
198
|
+
createCopilotAuth?: () => ICopilotAuth;
|
|
199
|
+
/** Factory for creating ClaudeAuth instances */
|
|
200
|
+
createClaudeAuth?: () => IClaudeAuth;
|
|
201
|
+
/** Called after successful authentication for any provider */
|
|
202
|
+
onAuth?: OnAuthCallback;
|
|
203
|
+
/** Called when dispose/logout is requested */
|
|
204
|
+
onLogout?: () => void | Promise<void>;
|
|
205
|
+
/** Route prefix to strip from URL before matching. Default: "" */
|
|
206
|
+
prefix?: string;
|
|
207
|
+
/** Maximum request body size in bytes. Default: 1MB */
|
|
208
|
+
maxBodySize?: number;
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Create an HTTP request handler for server-mediated authentication.
|
|
212
|
+
*
|
|
213
|
+
* @param options - Auth handler configuration (token store, auth factories, callbacks)
|
|
214
|
+
* @returns Async request handler `(req, res) => Promise<void>`
|
|
215
|
+
*
|
|
216
|
+
* @example
|
|
217
|
+
* ```ts
|
|
218
|
+
* import { CopilotAuth, ClaudeAuth } from "@witqq/agent-sdk/auth";
|
|
219
|
+
*
|
|
220
|
+
* const authHandler = createAuthHandler({
|
|
221
|
+
* tokenStore: new FileTokenStore({ directory: ".tokens" }),
|
|
222
|
+
* createCopilotAuth: () => new CopilotAuth(),
|
|
223
|
+
* createClaudeAuth: () => new ClaudeAuth(),
|
|
224
|
+
* onAuth: (provider, token) => {
|
|
225
|
+
* // Rebuild runtime with new credentials
|
|
226
|
+
* },
|
|
227
|
+
* });
|
|
228
|
+
* ```
|
|
229
|
+
*/
|
|
230
|
+
declare function createAuthHandler(options: AuthHandlerOptions): (req: ReadableRequest, res: WritableResponse) => Promise<void>;
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* createProviderHandler — CRUD handler for provider configurations.
|
|
234
|
+
*
|
|
235
|
+
* Routes (prefix already stripped by chat-server):
|
|
236
|
+
* - GET /providers → List all providers
|
|
237
|
+
* - GET /providers/{id} → Get single provider
|
|
238
|
+
* - POST /providers → Create provider
|
|
239
|
+
* - PUT /providers/{id} → Update provider
|
|
240
|
+
* - DELETE /providers/{id} → Delete provider
|
|
241
|
+
*/
|
|
242
|
+
|
|
243
|
+
/** Configuration for createProviderHandler */
|
|
244
|
+
interface ProviderHandlerOptions {
|
|
245
|
+
/** Provider storage implementation */
|
|
246
|
+
providerStore: IProviderStore;
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Create an HTTP request handler for provider CRUD operations.
|
|
250
|
+
*
|
|
251
|
+
* @param options - Provider handler configuration
|
|
252
|
+
* @returns Async request handler `(req, res) => Promise<void>`
|
|
253
|
+
*/
|
|
254
|
+
declare function createProviderHandler(options: ProviderHandlerOptions): (req: ReadableRequest, res: WritableResponse) => Promise<void>;
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* CORS middleware — standalone composable function.
|
|
258
|
+
* Returns true if it fully handled the request (OPTIONS preflight),
|
|
259
|
+
* false if the caller should continue processing.
|
|
260
|
+
*/
|
|
261
|
+
/** Configuration for CORS middleware */
|
|
262
|
+
interface CorsOptions {
|
|
263
|
+
/** Allowed origins. Default: "*" (any origin) */
|
|
264
|
+
origin?: string | string[];
|
|
265
|
+
/** Allowed HTTP methods. Default: common REST methods */
|
|
266
|
+
methods?: string[];
|
|
267
|
+
/** Allowed request headers. Default: ["Content-Type"] */
|
|
268
|
+
headers?: string[];
|
|
269
|
+
/** Max age for preflight cache in seconds. Default: 86400 (24h) */
|
|
270
|
+
maxAge?: number;
|
|
271
|
+
}
|
|
272
|
+
/** Minimal request interface for CORS */
|
|
273
|
+
interface CorsRequest {
|
|
274
|
+
readonly method?: string;
|
|
275
|
+
readonly headers?: Record<string, string | string[] | undefined>;
|
|
276
|
+
}
|
|
277
|
+
/** Minimal response interface for CORS */
|
|
278
|
+
interface CorsResponse {
|
|
279
|
+
setHeader(name: string, value: string): void;
|
|
280
|
+
writeHead(statusCode: number, headers?: Record<string, string>): unknown;
|
|
281
|
+
end(): void;
|
|
282
|
+
}
|
|
283
|
+
/**
|
|
284
|
+
* Create a CORS middleware function.
|
|
285
|
+
*
|
|
286
|
+
* @returns A function that sets CORS headers and handles OPTIONS preflight.
|
|
287
|
+
* Returns `true` if the request was fully handled (preflight),
|
|
288
|
+
* `false` if the caller should continue processing.
|
|
289
|
+
*/
|
|
290
|
+
declare function corsMiddleware(options?: CorsOptions): (req: CorsRequest, res: CorsResponse) => boolean;
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* ServiceManager — manages IAgentService lifecycle (create, cache, dispose).
|
|
294
|
+
*
|
|
295
|
+
* Reduces boilerplate in apps that need to create/dispose services on auth events.
|
|
296
|
+
* Pass to createChatServer to auto-wire onAuth/onLogout callbacks.
|
|
297
|
+
*
|
|
298
|
+
* @example
|
|
299
|
+
* ```ts
|
|
300
|
+
* const sm = new ServiceManager({
|
|
301
|
+
* createService: (backend, token) =>
|
|
302
|
+
* createAgentService(backend, { apiKey: token.accessToken }),
|
|
303
|
+
* });
|
|
304
|
+
*
|
|
305
|
+
* // Manual usage:
|
|
306
|
+
* await sm.handleAuth("copilot", token);
|
|
307
|
+
* const service = sm.getService("copilot");
|
|
308
|
+
*
|
|
309
|
+
* // Or auto-wired via createChatServer:
|
|
310
|
+
* createChatServer({ serviceManager: sm, auth: { tokenStore }, ... });
|
|
311
|
+
* ```
|
|
312
|
+
*/
|
|
313
|
+
|
|
314
|
+
/** Minimal IAgentService interface (avoids importing from main package) */
|
|
315
|
+
interface ManagedService {
|
|
316
|
+
dispose(): Promise<void> | void;
|
|
317
|
+
}
|
|
318
|
+
/** Callback for building a token refresh function per backend */
|
|
319
|
+
type RefreshFactory = (backend: string) => ((token: AuthToken) => Promise<AuthToken>) | undefined;
|
|
320
|
+
/** Configuration for ServiceManager */
|
|
321
|
+
interface ServiceManagerOptions {
|
|
322
|
+
/**
|
|
323
|
+
* Factory to create a service for a backend.
|
|
324
|
+
* Called on every auth event (old service is disposed first).
|
|
325
|
+
*/
|
|
326
|
+
createService: (backend: string, token: AuthToken) => ManagedService | Promise<ManagedService>;
|
|
327
|
+
/**
|
|
328
|
+
* Optional factory returning a refresh function per backend.
|
|
329
|
+
* If provided and the token has expiresIn, a TokenRefreshManager is started.
|
|
330
|
+
* On refresh → the stored token is updated and the service is recreated.
|
|
331
|
+
* On expiry → handleLogout() for that backend is called.
|
|
332
|
+
*/
|
|
333
|
+
refreshFactory?: RefreshFactory;
|
|
334
|
+
/** Override TokenRefreshManager options (threshold, retries, etc.) */
|
|
335
|
+
refreshOptions?: Partial<Pick<TokenRefreshOptions, "refreshThreshold" | "maxRetries" | "retryDelayMs">>;
|
|
336
|
+
/** Called when a token expires (before logout). */
|
|
337
|
+
onTokenExpired?: (backend: string) => void;
|
|
338
|
+
}
|
|
339
|
+
/**
|
|
340
|
+
* Manages IAgentService lifecycle: create, cache, and dispose on re-auth or logout.
|
|
341
|
+
* Optionally starts background token refresh when `refreshFactory` is configured.
|
|
342
|
+
*/
|
|
343
|
+
declare class ServiceManager {
|
|
344
|
+
private readonly _services;
|
|
345
|
+
private readonly _refreshManagers;
|
|
346
|
+
private readonly _options;
|
|
347
|
+
constructor(options: ServiceManagerOptions);
|
|
348
|
+
/**
|
|
349
|
+
* Handle auth event: dispose old service (if any) and create new one.
|
|
350
|
+
* If the token is refreshable and refreshFactory is configured, starts a
|
|
351
|
+
* TokenRefreshManager that auto-refreshes and recreates the service.
|
|
352
|
+
*/
|
|
353
|
+
handleAuth(backend: string, token: AuthToken): Promise<ManagedService>;
|
|
354
|
+
/**
|
|
355
|
+
* Handle logout: dispose all services, stop all refresh managers, clear cache.
|
|
356
|
+
*/
|
|
357
|
+
handleLogout(): Promise<void>;
|
|
358
|
+
/**
|
|
359
|
+
* Dispose the ServiceManager — stops all refresh managers and disposes all services.
|
|
360
|
+
*/
|
|
361
|
+
dispose(): Promise<void>;
|
|
362
|
+
/** Get cached service for a backend (undefined if not authenticated). */
|
|
363
|
+
getService(backend: string): ManagedService | undefined;
|
|
364
|
+
/** Check if a service exists for the given backend. */
|
|
365
|
+
hasService(backend: string): boolean;
|
|
366
|
+
/** Get all backend names with active services. */
|
|
367
|
+
get activeBackends(): string[];
|
|
368
|
+
/** Get active refresh manager for a backend (for testing/introspection). */
|
|
369
|
+
getRefreshManager(backend: string): TokenRefreshManager | undefined;
|
|
370
|
+
private _startRefreshManager;
|
|
371
|
+
private _stopRefreshManager;
|
|
372
|
+
private _recreateService;
|
|
373
|
+
private _logoutBackend;
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
/**
|
|
377
|
+
* createChatServer — one-call setup combining runtime, chat handler, auth handler, CORS,
|
|
378
|
+
* and static file serving into a single HTTP request handler.
|
|
379
|
+
*
|
|
380
|
+
* Routes:
|
|
381
|
+
* - CORS preflight (OPTIONS) on all paths
|
|
382
|
+
* - {chatPrefix}/* → createChatHandler routes
|
|
383
|
+
* - {authPrefix}/* → createAuthHandler routes (if tokenStore provided)
|
|
384
|
+
* - {staticPrefix}/* → static file serving (if staticDir provided)
|
|
385
|
+
* - Everything else → 404
|
|
386
|
+
*/
|
|
387
|
+
|
|
388
|
+
/**
|
|
389
|
+
* Configuration for auto-creating a ChatRuntime from options.
|
|
390
|
+
* Alternative to providing a pre-built IChatRuntime instance.
|
|
391
|
+
* Uses the same shape as ChatRuntimeOptions from the runtime module.
|
|
392
|
+
*/
|
|
393
|
+
type ChatRuntimeConfig = ChatRuntimeOptions;
|
|
394
|
+
/** Configuration for createChatServer */
|
|
395
|
+
interface ChatServerOptions {
|
|
396
|
+
/** Pre-built runtime instance. Either `runtime` or `runtimeConfig` must be provided. */
|
|
397
|
+
runtime?: IChatRuntime;
|
|
398
|
+
/** Config to auto-create a runtime. Used when `runtime` is not provided. */
|
|
399
|
+
runtimeConfig?: ChatRuntimeConfig;
|
|
400
|
+
/** Server-side hooks for customizing handler behavior. */
|
|
401
|
+
hooks?: ChatServerHooks;
|
|
402
|
+
/** Prefix for chat API routes. Default: "/api/chat" */
|
|
403
|
+
chatPrefix?: string;
|
|
404
|
+
/** Auth handler options. If provided, auth routes are mounted. */
|
|
405
|
+
auth?: AuthHandlerOptions;
|
|
406
|
+
/** Prefix for auth routes. Default: "/api/auth" */
|
|
407
|
+
authPrefix?: string;
|
|
408
|
+
/** CORS options. Pass false to disable CORS. Default: enabled with permissive settings */
|
|
409
|
+
cors?: CorsOptions | false;
|
|
410
|
+
/** Directory to serve static files from. Omit to disable static serving. */
|
|
411
|
+
staticDir?: string;
|
|
412
|
+
/** Prefix for static file routes. Default: "/" */
|
|
413
|
+
staticPrefix?: string;
|
|
414
|
+
/** Provider handler options. If provided, provider routes are mounted. */
|
|
415
|
+
providers?: ProviderHandlerOptions;
|
|
416
|
+
/** Prefix for provider routes. Default: "/api/providers" */
|
|
417
|
+
providerPrefix?: string;
|
|
418
|
+
/** Chat handler options (maxBodySize, etc.) */
|
|
419
|
+
chatHandlerOptions?: Omit<ChatHandlerOptions, "prefix">;
|
|
420
|
+
/**
|
|
421
|
+
* Path for the health check endpoint. Default: "/api/health".
|
|
422
|
+
* Set to `false` to disable. Returns `{ ok: true }`.
|
|
423
|
+
*/
|
|
424
|
+
healthPath?: string | false;
|
|
425
|
+
/**
|
|
426
|
+
* Auto-create a default provider when a backend authenticates for the first time.
|
|
427
|
+
*
|
|
428
|
+
* - `true` — uses built-in default models per backend
|
|
429
|
+
* - `Record<string, string>` — custom backend→model mapping (e.g. `{ copilot: "gpt-5-mini" }`)
|
|
430
|
+
* - `false` / omitted — disabled
|
|
431
|
+
*
|
|
432
|
+
* Requires both `auth` and `providers` to be configured.
|
|
433
|
+
*/
|
|
434
|
+
autoCreateProviders?: boolean | Record<string, string>;
|
|
435
|
+
/**
|
|
436
|
+
* Service lifecycle manager. When provided with `auth`, automatically wires:
|
|
437
|
+
* - `onAuth` → `serviceManager.handleAuth(backend, token)` (creates/caches service)
|
|
438
|
+
* - `onLogout` → `serviceManager.handleLogout()` (disposes all services)
|
|
439
|
+
*
|
|
440
|
+
* User's own `onAuth`/`onLogout` callbacks in `auth` are still called first.
|
|
441
|
+
*/
|
|
442
|
+
serviceManager?: ServiceManager;
|
|
443
|
+
}
|
|
444
|
+
/** Default model per backend for auto-created providers */
|
|
445
|
+
declare const DEFAULT_PROVIDER_MODELS: Record<string, string>;
|
|
446
|
+
/** Request handler type returned by createChatServer */
|
|
447
|
+
type RequestHandler = (req: ReadableRequest, res: WritableResponse) => Promise<void>;
|
|
448
|
+
/**
|
|
449
|
+
* Create a combined HTTP request handler that routes to chat, auth, static, or 404.
|
|
450
|
+
*
|
|
451
|
+
* @param options - Server configuration
|
|
452
|
+
* @returns Async request handler
|
|
453
|
+
*
|
|
454
|
+
* @example
|
|
455
|
+
* ```ts
|
|
456
|
+
* import http from "node:http";
|
|
457
|
+
* import { createChatServer } from "@witqq/agent-sdk/chat/server";
|
|
458
|
+
*
|
|
459
|
+
* const handler = createChatServer({
|
|
460
|
+
* runtime,
|
|
461
|
+
* auth: { tokenStore },
|
|
462
|
+
* staticDir: "./public",
|
|
463
|
+
* });
|
|
464
|
+
*
|
|
465
|
+
* http.createServer(handler).listen(3000);
|
|
466
|
+
* ```
|
|
467
|
+
*/
|
|
468
|
+
declare function createChatServer(options: ChatServerOptions): RequestHandler;
|
|
469
|
+
|
|
470
|
+
/**
|
|
471
|
+
* Shared server utilities — readBody and JSON response helpers.
|
|
472
|
+
*/
|
|
473
|
+
|
|
474
|
+
/** Error thrown by readBody with an HTTP status code */
|
|
475
|
+
declare class BodyParseError extends Error {
|
|
476
|
+
readonly statusCode: number;
|
|
477
|
+
constructor(message: string, statusCode: number);
|
|
478
|
+
}
|
|
479
|
+
/**
|
|
480
|
+
* Read and parse JSON request body with size limit.
|
|
481
|
+
* Throws BodyParseError on oversized, malformed, or errored requests.
|
|
482
|
+
*/
|
|
483
|
+
declare function readBody(req: ReadableRequest, maxSize?: number): Promise<Record<string, unknown>>;
|
|
484
|
+
/** Send a JSON response with given status code. */
|
|
485
|
+
declare function json(res: WritableResponse, data: unknown, status?: number): void;
|
|
486
|
+
|
|
487
|
+
/**
|
|
488
|
+
* AdapterPool — lazy adapter creation with concurrent dedup and eviction.
|
|
489
|
+
*
|
|
490
|
+
* Replaces the pattern where ServiceManager + backend factories create adapters
|
|
491
|
+
* eagerly on auth. AdapterPool creates adapters on first use, keyed by backend name.
|
|
492
|
+
*
|
|
493
|
+
* Key properties:
|
|
494
|
+
* - Lazy: adapters created on first getAdapter() call
|
|
495
|
+
* - Concurrent dedup: multiple concurrent getAdapter() calls for same backend share one creation
|
|
496
|
+
* - Never cache failures: if factory throws, next call retries
|
|
497
|
+
* - Eviction: evict(backend) disposes cached adapter (e.g. on token rotation)
|
|
498
|
+
*
|
|
499
|
+
* @example
|
|
500
|
+
* ```ts
|
|
501
|
+
* const pool = new AdapterPool({
|
|
502
|
+
* factory: async (backend) => {
|
|
503
|
+
* const token = await tokenStore.load(backend);
|
|
504
|
+
* const service = createAgentService(backend, { apiKey: token.accessToken });
|
|
505
|
+
* return new VercelAIChatAdapter({ agentConfig: { ... }, agentService: service });
|
|
506
|
+
* },
|
|
507
|
+
* });
|
|
508
|
+
*
|
|
509
|
+
* const adapter = await pool.getAdapter("vercel-ai");
|
|
510
|
+
* // On token rotation:
|
|
511
|
+
* await pool.evict("vercel-ai");
|
|
512
|
+
* ```
|
|
513
|
+
*/
|
|
514
|
+
/** Minimal adapter interface (avoids importing full IChatBackend) */
|
|
515
|
+
interface PooledAdapter {
|
|
516
|
+
dispose(): Promise<void> | void;
|
|
517
|
+
}
|
|
518
|
+
/** Factory function to create an adapter for a given backend */
|
|
519
|
+
type AdapterFactory<T extends PooledAdapter = PooledAdapter> = (backend: string) => Promise<T>;
|
|
520
|
+
/** Configuration for AdapterPool */
|
|
521
|
+
interface AdapterPoolOptions<T extends PooledAdapter = PooledAdapter> {
|
|
522
|
+
/** Factory to create an adapter for a backend. Called lazily on first getAdapter(). */
|
|
523
|
+
factory: AdapterFactory<T>;
|
|
524
|
+
}
|
|
525
|
+
/**
|
|
526
|
+
* Lazy adapter pool with concurrent dedup and eviction.
|
|
527
|
+
* Thread-safe: concurrent getAdapter() calls for the same backend share a single creation promise.
|
|
528
|
+
*/
|
|
529
|
+
declare class AdapterPool<T extends PooledAdapter = PooledAdapter> {
|
|
530
|
+
private readonly _cached;
|
|
531
|
+
private readonly _pending;
|
|
532
|
+
private readonly _factory;
|
|
533
|
+
private _disposed;
|
|
534
|
+
constructor(options: AdapterPoolOptions<T>);
|
|
535
|
+
/**
|
|
536
|
+
* Get or create an adapter for the given backend.
|
|
537
|
+
* Concurrent calls for the same backend share one creation promise.
|
|
538
|
+
* Failed creations are NOT cached — next call retries.
|
|
539
|
+
*/
|
|
540
|
+
getAdapter(backend: string): Promise<T>;
|
|
541
|
+
/**
|
|
542
|
+
* Evict (dispose and remove) the cached adapter for a backend.
|
|
543
|
+
* Use after token rotation to force re-creation on next getAdapter().
|
|
544
|
+
*/
|
|
545
|
+
evict(backend: string): Promise<void>;
|
|
546
|
+
/** Check if a backend has a cached adapter. */
|
|
547
|
+
has(backend: string): boolean;
|
|
548
|
+
/** Get all backend names with cached adapters. */
|
|
549
|
+
get activeBackends(): string[];
|
|
550
|
+
/** Dispose all cached adapters and mark pool as unusable. */
|
|
551
|
+
dispose(): Promise<void>;
|
|
552
|
+
private _create;
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
/**
|
|
556
|
+
* Request context resolution — per-request credential + model lookup.
|
|
557
|
+
*
|
|
558
|
+
* Resolves a providerId into a RequestContext containing backend name,
|
|
559
|
+
* credentials (AuthToken), and model identifier. This enables stateless
|
|
560
|
+
* request handling where each request carries its own context.
|
|
561
|
+
*
|
|
562
|
+
* @example
|
|
563
|
+
* ```ts
|
|
564
|
+
* const ctx = await resolveRequestContext("my-copilot-provider", {
|
|
565
|
+
* providerStore,
|
|
566
|
+
* tokenStore,
|
|
567
|
+
* });
|
|
568
|
+
* // ctx = { backend: "copilot", credentials: { accessToken: "..." }, model: "gpt-5-mini" }
|
|
569
|
+
* ```
|
|
570
|
+
*/
|
|
571
|
+
|
|
572
|
+
/** Per-request context carrying backend, credentials, and model */
|
|
573
|
+
interface RequestContext {
|
|
574
|
+
/** Backend name (e.g. "copilot", "claude", "vercel-ai") */
|
|
575
|
+
backend: string;
|
|
576
|
+
/** Resolved authentication token */
|
|
577
|
+
credentials: AuthToken;
|
|
578
|
+
/** Model identifier from provider config */
|
|
579
|
+
model: string;
|
|
580
|
+
/** Original provider config for reference */
|
|
581
|
+
provider: ProviderConfig;
|
|
582
|
+
}
|
|
583
|
+
/** Dependencies for context resolution */
|
|
584
|
+
interface RequestContextDeps {
|
|
585
|
+
/** Provider store to look up provider config */
|
|
586
|
+
providerStore: IProviderStore;
|
|
587
|
+
/** Token store to load credentials for the backend */
|
|
588
|
+
tokenStore: ITokenStore;
|
|
589
|
+
}
|
|
590
|
+
/**
|
|
591
|
+
* Resolve a providerId into a full RequestContext.
|
|
592
|
+
*
|
|
593
|
+
* Flow: providerId → ProviderConfig (from providerStore) → AuthToken (from tokenStore) → RequestContext
|
|
594
|
+
*
|
|
595
|
+
* @throws ChatError with PROVIDER_NOT_FOUND if provider doesn't exist
|
|
596
|
+
* @throws ChatError with AUTH_REQUIRED if no token found for the provider's backend
|
|
597
|
+
*/
|
|
598
|
+
declare function resolveRequestContext(providerId: string, deps: RequestContextDeps): Promise<RequestContext>;
|
|
599
|
+
|
|
600
|
+
/**
|
|
601
|
+
* Session CRUD route handlers.
|
|
602
|
+
*
|
|
603
|
+
* Routes:
|
|
604
|
+
* - POST /sessions/create → Create session
|
|
605
|
+
* - GET /sessions/:id → Get session
|
|
606
|
+
* - GET /sessions → List sessions
|
|
607
|
+
* - DELETE /sessions/:id → Delete session
|
|
608
|
+
* - GET /sessions/:id/context-stats → Get context window stats
|
|
609
|
+
*/
|
|
610
|
+
|
|
611
|
+
declare const sessionRoutes: RouteHandler;
|
|
612
|
+
|
|
613
|
+
/**
|
|
614
|
+
* Message route handlers (send + abort).
|
|
615
|
+
*
|
|
616
|
+
* Routes:
|
|
617
|
+
* - POST /send → Stream response via transport (SSE by default)
|
|
618
|
+
* - POST /abort → Cancel in-flight stream
|
|
619
|
+
*/
|
|
620
|
+
|
|
621
|
+
declare const messageRoutes: RouteHandler;
|
|
622
|
+
|
|
623
|
+
/**
|
|
624
|
+
* Configuration route handlers (model/backend/provider switching, listing).
|
|
625
|
+
*
|
|
626
|
+
* Routes:
|
|
627
|
+
* - GET /models → List available models
|
|
628
|
+
* - GET /backends → List available backends
|
|
629
|
+
* - POST /model/switch → Switch active model (handler state)
|
|
630
|
+
* - POST /provider/switch → Switch provider (resolves backend + model)
|
|
631
|
+
*/
|
|
632
|
+
|
|
633
|
+
declare const configRoutes: RouteHandler;
|
|
634
|
+
|
|
635
|
+
/**
|
|
636
|
+
* Provider CRUD route handlers.
|
|
637
|
+
*
|
|
638
|
+
* Routes:
|
|
639
|
+
* - GET /providers → List all providers
|
|
640
|
+
* - GET /providers/:id → Get single provider
|
|
641
|
+
* - POST /providers → Create provider
|
|
642
|
+
* - PUT /providers/:id → Update provider
|
|
643
|
+
* - DELETE /providers/:id → Delete provider
|
|
644
|
+
*/
|
|
645
|
+
|
|
646
|
+
declare const providerRoutes: RouteHandler;
|
|
647
|
+
|
|
648
|
+
export { type AdapterFactory, AdapterPool, type AdapterPoolOptions, type AuthHandlerOptions, type AuthProvider, BodyParseError, type ChatHandlerOptions, type ChatRuntimeConfig, type ChatServerHooks, type ChatServerOptions, type CorsOptions, DEFAULT_PROVIDER_MODELS, FileProviderStore, type FileProviderStoreOptions, type HandlerState, type IClaudeAuth, type ICopilotAuth, IProviderStore, ITokenStore, InMemoryProviderStore, type ManagedService, type OnAuthCallback, type PooledAdapter, ProviderConfig, type ProviderHandlerOptions, type ReadableRequest, type RefreshFactory, type RequestContext, type RequestContextDeps, type RequestHandler, type RouteContext, type RouteHandler, ServiceManager, type ServiceManagerOptions, type TransportFactory, WritableResponse, configRoutes, corsMiddleware, createAuthHandler, createChatHandler, createChatServer, createProviderHandler, json, messageRoutes, providerRoutes, readBody, resolveRequestContext, sessionRoutes };
|