@witqq/agent-sdk 0.7.0 → 0.9.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/dist/{types-CqvUAYxt.d.ts → agent-C6H2CgJA.d.cts} +139 -102
- package/dist/{types-CqvUAYxt.d.cts → agent-F7oB6eKp.d.ts} +139 -102
- package/dist/auth/index.cjs +72 -1
- package/dist/auth/index.cjs.map +1 -1
- package/dist/auth/index.d.cts +21 -154
- package/dist/auth/index.d.ts +21 -154
- package/dist/auth/index.js +72 -1
- package/dist/auth/index.js.map +1 -1
- package/dist/backends/claude.cjs +480 -261
- package/dist/backends/claude.cjs.map +1 -1
- package/dist/backends/claude.d.cts +3 -1
- package/dist/backends/claude.d.ts +3 -1
- package/dist/backends/claude.js +480 -261
- package/dist/backends/claude.js.map +1 -1
- package/dist/backends/copilot.cjs +337 -112
- package/dist/backends/copilot.cjs.map +1 -1
- package/dist/backends/copilot.d.cts +12 -4
- package/dist/backends/copilot.d.ts +12 -4
- package/dist/backends/copilot.js +337 -112
- package/dist/backends/copilot.js.map +1 -1
- package/dist/backends/mock-llm.cjs +719 -0
- package/dist/backends/mock-llm.cjs.map +1 -0
- package/dist/backends/mock-llm.d.cts +37 -0
- package/dist/backends/mock-llm.d.ts +37 -0
- package/dist/backends/mock-llm.js +717 -0
- package/dist/backends/mock-llm.js.map +1 -0
- package/dist/backends/vercel-ai.cjs +301 -61
- 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 +301 -61
- package/dist/backends/vercel-ai.js.map +1 -1
- package/dist/backends-Cno0gZjy.d.cts +114 -0
- package/dist/backends-Cno0gZjy.d.ts +114 -0
- package/dist/chat/accumulator.cjs +1 -1
- package/dist/chat/accumulator.cjs.map +1 -1
- package/dist/chat/accumulator.d.cts +5 -2
- package/dist/chat/accumulator.d.ts +5 -2
- package/dist/chat/accumulator.js +1 -1
- package/dist/chat/accumulator.js.map +1 -1
- package/dist/chat/backends.cjs +1084 -821
- package/dist/chat/backends.cjs.map +1 -1
- package/dist/chat/backends.d.cts +10 -6
- package/dist/chat/backends.d.ts +10 -6
- package/dist/chat/backends.js +1082 -800
- package/dist/chat/backends.js.map +1 -1
- package/dist/chat/context.cjs +50 -0
- package/dist/chat/context.cjs.map +1 -1
- package/dist/chat/context.d.cts +27 -3
- package/dist/chat/context.d.ts +27 -3
- package/dist/chat/context.js +50 -0
- package/dist/chat/context.js.map +1 -1
- package/dist/chat/core.cjs +60 -27
- package/dist/chat/core.cjs.map +1 -1
- package/dist/chat/core.d.cts +41 -382
- package/dist/chat/core.d.ts +41 -382
- package/dist/chat/core.js +58 -28
- package/dist/chat/core.js.map +1 -1
- package/dist/chat/errors.cjs +48 -26
- package/dist/chat/errors.cjs.map +1 -1
- package/dist/chat/errors.d.cts +6 -31
- package/dist/chat/errors.d.ts +6 -31
- package/dist/chat/errors.js +48 -25
- package/dist/chat/errors.js.map +1 -1
- package/dist/chat/events.cjs.map +1 -1
- package/dist/chat/events.d.cts +6 -2
- package/dist/chat/events.d.ts +6 -2
- package/dist/chat/events.js.map +1 -1
- package/dist/chat/index.cjs +1612 -1125
- package/dist/chat/index.cjs.map +1 -1
- package/dist/chat/index.d.cts +35 -10
- package/dist/chat/index.d.ts +35 -10
- package/dist/chat/index.js +1600 -1097
- package/dist/chat/index.js.map +1 -1
- package/dist/chat/react/theme.css +2517 -0
- package/dist/chat/react.cjs +2212 -1158
- package/dist/chat/react.cjs.map +1 -1
- package/dist/chat/react.d.cts +665 -122
- package/dist/chat/react.d.ts +665 -122
- package/dist/chat/react.js +2191 -1156
- package/dist/chat/react.js.map +1 -1
- package/dist/chat/runtime.cjs +405 -186
- package/dist/chat/runtime.cjs.map +1 -1
- package/dist/chat/runtime.d.cts +92 -28
- package/dist/chat/runtime.d.ts +92 -28
- package/dist/chat/runtime.js +405 -186
- package/dist/chat/runtime.js.map +1 -1
- package/dist/chat/server.cjs +2247 -212
- package/dist/chat/server.cjs.map +1 -1
- package/dist/chat/server.d.cts +451 -90
- package/dist/chat/server.d.ts +451 -90
- package/dist/chat/server.js +2234 -213
- package/dist/chat/server.js.map +1 -1
- package/dist/chat/sessions.cjs +64 -66
- package/dist/chat/sessions.cjs.map +1 -1
- package/dist/chat/sessions.d.cts +37 -118
- package/dist/chat/sessions.d.ts +37 -118
- package/dist/chat/sessions.js +65 -67
- package/dist/chat/sessions.js.map +1 -1
- package/dist/chat/sqlite.cjs +536 -0
- package/dist/chat/sqlite.cjs.map +1 -0
- package/dist/chat/sqlite.d.cts +164 -0
- package/dist/chat/sqlite.d.ts +164 -0
- package/dist/chat/sqlite.js +527 -0
- package/dist/chat/sqlite.js.map +1 -0
- package/dist/chat/state.cjs +14 -1
- package/dist/chat/state.cjs.map +1 -1
- package/dist/chat/state.d.cts +5 -2
- package/dist/chat/state.d.ts +5 -2
- package/dist/chat/state.js +14 -1
- package/dist/chat/state.js.map +1 -1
- package/dist/chat/storage.cjs +58 -33
- package/dist/chat/storage.cjs.map +1 -1
- package/dist/chat/storage.d.cts +18 -8
- package/dist/chat/storage.d.ts +18 -8
- package/dist/chat/storage.js +59 -34
- package/dist/chat/storage.js.map +1 -1
- 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-C2oPTYs6.d.ts → in-process-transport-7EIit9Xk.d.ts} +72 -33
- package/dist/{in-process-transport-DG-w5G6k.d.cts → in-process-transport-Ct9YcX8I.d.cts} +72 -33
- package/dist/index.cjs +354 -60
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +294 -123
- package/dist/index.d.ts +294 -123
- package/dist/index.js +347 -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 +1107 -0
- package/dist/testing.cjs.map +1 -0
- package/dist/testing.d.cts +144 -0
- package/dist/testing.d.ts +144 -0
- package/dist/testing.js +1101 -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-DX1Nhm4N.d.cts → transport-DLWCN18G.d.cts} +5 -4
- package/dist/{transport-D1OaUgRk.d.ts → transport-DsuS-GeM.d.ts} +5 -4
- package/dist/{types-CGF7AEX1.d.cts → types-4vbcmPTp.d.cts} +4 -2
- package/dist/{types-Bh5AhqD-.d.ts → types-BxggH0Yh.d.ts} +4 -2
- package/dist/types-DgtI1hzh.d.ts +364 -0
- package/dist/types-DkSXALKg.d.cts +364 -0
- package/package.json +41 -5
- package/LICENSE +0 -21
- package/README.md +0 -948
- package/dist/errors-BDLbNu9w.d.cts +0 -13
- package/dist/errors-BDLbNu9w.d.ts +0 -13
- package/dist/types-DLZzlJxt.d.ts +0 -39
- package/dist/types-tE0CXwBl.d.cts +0 -39
package/dist/chat/server.d.cts
CHANGED
|
@@ -1,46 +1,130 @@
|
|
|
1
|
-
import { IChatRuntime } from './runtime.cjs';
|
|
2
|
-
import { W as WritableResponse
|
|
3
|
-
import {
|
|
4
|
-
import '
|
|
5
|
-
|
|
6
|
-
import '
|
|
7
|
-
import '../types-
|
|
1
|
+
import { IChatRuntime, ChatRuntimeOptions } from './runtime.cjs';
|
|
2
|
+
import { W as WritableResponse, I as IChatTransport } from '../transport-DLWCN18G.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-C6H2CgJA.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-DkSXALKg.cjs';
|
|
10
|
+
import '../errors-C-so0M4t.cjs';
|
|
8
11
|
import './sessions.cjs';
|
|
9
12
|
import './storage.cjs';
|
|
10
|
-
import '../errors-
|
|
13
|
+
import '../errors-CmVvczxZ.cjs';
|
|
14
|
+
import 'zod';
|
|
11
15
|
import './context.cjs';
|
|
12
16
|
|
|
13
17
|
/**
|
|
14
|
-
*
|
|
18
|
+
* Provider storage default implementations.
|
|
15
19
|
*
|
|
16
|
-
*
|
|
17
|
-
* -
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
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.
|
|
27
88
|
*/
|
|
28
89
|
|
|
29
90
|
/** Minimal readable request interface (node:http IncomingMessage subset) */
|
|
30
91
|
interface ReadableRequest {
|
|
31
92
|
readonly method?: string;
|
|
32
93
|
readonly url?: string;
|
|
33
|
-
on(event: "data", listener: (chunk: Buffer | string) => void):
|
|
34
|
-
on(event: "end", listener: () => void):
|
|
94
|
+
on(event: "data", listener: (chunk: Buffer | string) => void): unknown;
|
|
95
|
+
on(event: "end", listener: () => void): unknown;
|
|
35
96
|
}
|
|
97
|
+
|
|
36
98
|
/**
|
|
37
|
-
*
|
|
38
|
-
*
|
|
99
|
+
* Server-side hooks for customizing chat handler behavior.
|
|
100
|
+
* Consolidates filter, guard, and lifecycle callbacks into a single interface.
|
|
39
101
|
*/
|
|
40
|
-
interface
|
|
41
|
-
|
|
42
|
-
|
|
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;
|
|
43
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;
|
|
44
128
|
/** Configuration for createChatHandler */
|
|
45
129
|
interface ChatHandlerOptions {
|
|
46
130
|
/** Route prefix to strip from URL before matching. Default: "" (no prefix) */
|
|
@@ -49,72 +133,24 @@ interface ChatHandlerOptions {
|
|
|
49
133
|
maxBodySize?: number;
|
|
50
134
|
/** SSE heartbeat interval in milliseconds. 0 or undefined disables heartbeat. */
|
|
51
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;
|
|
52
144
|
}
|
|
53
145
|
/**
|
|
54
|
-
* Create an HTTP request handler that maps
|
|
146
|
+
* Create an HTTP request handler that maps RemoteChatClient contract
|
|
55
147
|
* endpoints to IChatRuntime method calls.
|
|
56
148
|
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
* @returns Async request handler `(req, res) => Promise<void>`
|
|
60
|
-
*
|
|
61
|
-
* @example
|
|
62
|
-
* ```ts
|
|
63
|
-
* const handler = createChatHandler(runtime, { prefix: "/api/chat" });
|
|
64
|
-
* http.createServer(async (req, res) => {
|
|
65
|
-
* if (req.url?.startsWith("/api/chat")) {
|
|
66
|
-
* await handler(req, res);
|
|
67
|
-
* return;
|
|
68
|
-
* }
|
|
69
|
-
* res.writeHead(404).end();
|
|
70
|
-
* });
|
|
71
|
-
* ```
|
|
149
|
+
* Routes are handled by composable route modules (sessions, messages, config, providers).
|
|
150
|
+
* Model state is managed in a shared HandlerState object.
|
|
72
151
|
*/
|
|
73
152
|
declare function createChatHandler(runtime: IChatRuntime, options?: ChatHandlerOptions): (req: ReadableRequest, res: WritableResponse) => Promise<void>;
|
|
74
153
|
|
|
75
|
-
/**
|
|
76
|
-
* Token storage abstraction and default filesystem implementation.
|
|
77
|
-
*/
|
|
78
|
-
|
|
79
|
-
/** Token storage interface for server-side token management */
|
|
80
|
-
interface ITokenStore {
|
|
81
|
-
/** Save a token for a provider. Overwrites if exists. */
|
|
82
|
-
save(provider: string, token: AuthToken): Promise<void>;
|
|
83
|
-
/** Load a previously saved token. Returns null if not found. */
|
|
84
|
-
load(provider: string): Promise<AuthToken | null>;
|
|
85
|
-
/** Remove a specific provider's token. */
|
|
86
|
-
clear(provider: string): Promise<void>;
|
|
87
|
-
/** Remove all stored tokens. */
|
|
88
|
-
clearAll(): Promise<void>;
|
|
89
|
-
/** List provider names that have saved tokens. */
|
|
90
|
-
list(): Promise<string[]>;
|
|
91
|
-
}
|
|
92
|
-
/** In-memory token store for testing and ephemeral use */
|
|
93
|
-
declare class InMemoryTokenStore implements ITokenStore {
|
|
94
|
-
private readonly tokens;
|
|
95
|
-
save(provider: string, token: AuthToken): Promise<void>;
|
|
96
|
-
load(provider: string): Promise<AuthToken | null>;
|
|
97
|
-
clear(provider: string): Promise<void>;
|
|
98
|
-
clearAll(): Promise<void>;
|
|
99
|
-
list(): Promise<string[]>;
|
|
100
|
-
}
|
|
101
|
-
/** Options for FileTokenStore */
|
|
102
|
-
interface FileTokenStoreOptions {
|
|
103
|
-
/** Directory to store token JSON files. Default: ".tokens" in cwd */
|
|
104
|
-
directory: string;
|
|
105
|
-
}
|
|
106
|
-
/** Filesystem-based token store using JSON files (one per provider) */
|
|
107
|
-
declare class FileTokenStore implements ITokenStore {
|
|
108
|
-
private readonly dir;
|
|
109
|
-
constructor(options: FileTokenStoreOptions);
|
|
110
|
-
save(provider: string, token: AuthToken): Promise<void>;
|
|
111
|
-
load(provider: string): Promise<AuthToken | null>;
|
|
112
|
-
clear(provider: string): Promise<void>;
|
|
113
|
-
clearAll(): Promise<void>;
|
|
114
|
-
list(): Promise<string[]>;
|
|
115
|
-
private filePath;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
154
|
/**
|
|
119
155
|
* createAuthHandler — server-mediated authentication for all three backends.
|
|
120
156
|
*
|
|
@@ -193,6 +229,30 @@ interface AuthHandlerOptions {
|
|
|
193
229
|
*/
|
|
194
230
|
declare function createAuthHandler(options: AuthHandlerOptions): (req: ReadableRequest, res: WritableResponse) => Promise<void>;
|
|
195
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
|
+
|
|
196
256
|
/**
|
|
197
257
|
* CORS middleware — standalone composable function.
|
|
198
258
|
* Returns true if it fully handled the request (OPTIONS preflight),
|
|
@@ -217,7 +277,7 @@ interface CorsRequest {
|
|
|
217
277
|
/** Minimal response interface for CORS */
|
|
218
278
|
interface CorsResponse {
|
|
219
279
|
setHeader(name: string, value: string): void;
|
|
220
|
-
writeHead(statusCode: number):
|
|
280
|
+
writeHead(statusCode: number, headers?: Record<string, string>): unknown;
|
|
221
281
|
end(): void;
|
|
222
282
|
}
|
|
223
283
|
/**
|
|
@@ -229,6 +289,90 @@ interface CorsResponse {
|
|
|
229
289
|
*/
|
|
230
290
|
declare function corsMiddleware(options?: CorsOptions): (req: CorsRequest, res: CorsResponse) => boolean;
|
|
231
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
|
+
|
|
232
376
|
/**
|
|
233
377
|
* createChatServer — one-call setup combining runtime, chat handler, auth handler, CORS,
|
|
234
378
|
* and static file serving into a single HTTP request handler.
|
|
@@ -241,10 +385,20 @@ declare function corsMiddleware(options?: CorsOptions): (req: CorsRequest, res:
|
|
|
241
385
|
* - Everything else → 404
|
|
242
386
|
*/
|
|
243
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;
|
|
244
394
|
/** Configuration for createChatServer */
|
|
245
395
|
interface ChatServerOptions {
|
|
246
|
-
/**
|
|
247
|
-
runtime
|
|
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;
|
|
248
402
|
/** Prefix for chat API routes. Default: "/api/chat" */
|
|
249
403
|
chatPrefix?: string;
|
|
250
404
|
/** Auth handler options. If provided, auth routes are mounted. */
|
|
@@ -257,9 +411,38 @@ interface ChatServerOptions {
|
|
|
257
411
|
staticDir?: string;
|
|
258
412
|
/** Prefix for static file routes. Default: "/" */
|
|
259
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;
|
|
260
418
|
/** Chat handler options (maxBodySize, etc.) */
|
|
261
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;
|
|
262
443
|
}
|
|
444
|
+
/** Default model per backend for auto-created providers */
|
|
445
|
+
declare const DEFAULT_PROVIDER_MODELS: Record<string, string>;
|
|
263
446
|
/** Request handler type returned by createChatServer */
|
|
264
447
|
type RequestHandler = (req: ReadableRequest, res: WritableResponse) => Promise<void>;
|
|
265
448
|
/**
|
|
@@ -284,4 +467,182 @@ type RequestHandler = (req: ReadableRequest, res: WritableResponse) => Promise<v
|
|
|
284
467
|
*/
|
|
285
468
|
declare function createChatServer(options: ChatServerOptions): RequestHandler;
|
|
286
469
|
|
|
287
|
-
|
|
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 };
|