@intelligo-dev/chat 1.0.0-beta.5
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/LICENSE +201 -0
- package/README.md +75 -0
- package/dist/body.d.ts +41 -0
- package/dist/body.d.ts.map +1 -0
- package/dist/body.js +113 -0
- package/dist/body.js.map +1 -0
- package/dist/client.d.ts +56 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +62 -0
- package/dist/client.js.map +1 -0
- package/dist/config.d.ts +195 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +20 -0
- package/dist/config.js.map +1 -0
- package/dist/errors.d.ts +23 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +39 -0
- package/dist/errors.js.map +1 -0
- package/dist/handler.d.ts +30 -0
- package/dist/handler.d.ts.map +1 -0
- package/dist/handler.js +544 -0
- package/dist/handler.js.map +1 -0
- package/dist/index.d.ts +30 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -0
- package/dist/messages.d.ts +19 -0
- package/dist/messages.d.ts.map +1 -0
- package/dist/messages.js +34 -0
- package/dist/messages.js.map +1 -0
- package/dist/quota.d.ts +24 -0
- package/dist/quota.d.ts.map +1 -0
- package/dist/quota.js +41 -0
- package/dist/quota.js.map +1 -0
- package/dist/testing.d.ts +43 -0
- package/dist/testing.d.ts.map +1 -0
- package/dist/testing.js +89 -0
- package/dist/testing.js.map +1 -0
- package/dist/title.d.ts +7 -0
- package/dist/title.d.ts.map +1 -0
- package/dist/title.js +15 -0
- package/dist/title.js.map +1 -0
- package/dist/usage.d.ts +19 -0
- package/dist/usage.d.ts.map +1 -0
- package/dist/usage.js +26 -0
- package/dist/usage.js.map +1 -0
- package/dist/windowing.d.ts +39 -0
- package/dist/windowing.d.ts.map +1 -0
- package/dist/windowing.js +80 -0
- package/dist/windowing.js.map +1 -0
- package/package.json +63 -0
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What an application tells the chat transport, and what it is told back.
|
|
3
|
+
*
|
|
4
|
+
* Two things are required — the execution boundary and a way to turn a
|
|
5
|
+
* model id into a model — because those are the two things a framework
|
|
6
|
+
* must never guess (ADR-0003, ADR-0007). Everything else has a default
|
|
7
|
+
* that gives a clean install a working chat with no API keys: one
|
|
8
|
+
* agent, one prompt, no tools, a window of forty messages, a truncated
|
|
9
|
+
* first line as the title.
|
|
10
|
+
*
|
|
11
|
+
* Each optional field is a seam a real product needed and used to
|
|
12
|
+
* fork the route to get: an agent resolved per conversation from a
|
|
13
|
+
* table, a history pruned and summarised before the model sees it,
|
|
14
|
+
* image attachments, reasoning streamed to the client, a model-written
|
|
15
|
+
* title, telemetry on every turn. None of them carry product
|
|
16
|
+
* vocabulary; all of them close over the caller's tenancy so the model
|
|
17
|
+
* never has to be told which workspace it is in.
|
|
18
|
+
*/
|
|
19
|
+
import type { LanguageModel, StopCondition, ToolSet, UIMessage } from "ai";
|
|
20
|
+
import type { Conversation } from "@intelligo-dev/core/conversations";
|
|
21
|
+
import type { Executions } from "@intelligo-dev/executions";
|
|
22
|
+
import type { ChatAttachmentPolicy } from "./body.js";
|
|
23
|
+
import type { ChatErrorCode } from "./client.js";
|
|
24
|
+
import type { ChatMessages } from "./errors.js";
|
|
25
|
+
import type { TokenUsage } from "./usage.js";
|
|
26
|
+
import type { ConversationWindowOptions } from "./windowing.js";
|
|
27
|
+
export type { ChatAttachmentPolicy } from "./body.js";
|
|
28
|
+
export type { ChatMessages, ChatMessageKey, ChatMessageParams } from "./errors.js";
|
|
29
|
+
/** The resolved caller. Every read and write is scoped to this pair. */
|
|
30
|
+
export interface ChatActor {
|
|
31
|
+
workspaceId: string;
|
|
32
|
+
userId: string;
|
|
33
|
+
}
|
|
34
|
+
/** What is known about a turn before the agent is resolved. */
|
|
35
|
+
export interface ChatTurnContext extends ChatActor {
|
|
36
|
+
request: Request;
|
|
37
|
+
conversationId: string;
|
|
38
|
+
/**
|
|
39
|
+
* Fields the client transport sent beyond the AI SDK's own — an
|
|
40
|
+
* `agentId`, a model choice. Opaque to the transport; `resolveAgent`
|
|
41
|
+
* reads them.
|
|
42
|
+
*/
|
|
43
|
+
body: Record<string, unknown>;
|
|
44
|
+
/** The existing row, or null on a conversation's first turn. */
|
|
45
|
+
conversation: Conversation | null;
|
|
46
|
+
trigger: "submit-message" | "regenerate-message" | undefined;
|
|
47
|
+
}
|
|
48
|
+
/** The agent this turn runs as. */
|
|
49
|
+
export interface ResolvedAgent {
|
|
50
|
+
/** Stored on the conversation row when the transport creates it. */
|
|
51
|
+
id: string;
|
|
52
|
+
systemPrompt: string;
|
|
53
|
+
tools?: ToolSet;
|
|
54
|
+
/** Names the model may call this turn; every tool when omitted. */
|
|
55
|
+
activeTools?: string[];
|
|
56
|
+
/** Added after `stepCountIs(maxSteps)`, e.g. `hasToolCall("askUser")`. */
|
|
57
|
+
stopWhen?: StopCondition<ToolSet> | StopCondition<ToolSet>[];
|
|
58
|
+
/** Overrides `model.defaultId`. Must be a registered model id. */
|
|
59
|
+
modelId?: string;
|
|
60
|
+
maxSteps?: number;
|
|
61
|
+
/** Overrides the config's; `null` disables the gate for this agent. */
|
|
62
|
+
featureKey?: string | null;
|
|
63
|
+
capability?: string;
|
|
64
|
+
}
|
|
65
|
+
/** A turn with its agent resolved — what the hooks below receive. */
|
|
66
|
+
export interface ChatTurn extends ChatTurnContext {
|
|
67
|
+
agent: ResolvedAgent;
|
|
68
|
+
/** The persisted history, read lazily: not every `prepareMessages` needs it. */
|
|
69
|
+
history: () => Promise<UIMessage[]>;
|
|
70
|
+
}
|
|
71
|
+
/** What the model is shown. */
|
|
72
|
+
export interface PreparedTurn {
|
|
73
|
+
messages: UIMessage[];
|
|
74
|
+
/** Replaces the agent's system prompt when set — a summary prefix, injected context. */
|
|
75
|
+
system?: string;
|
|
76
|
+
}
|
|
77
|
+
export interface RateLimitDecision {
|
|
78
|
+
allowed: boolean;
|
|
79
|
+
retryAfterSeconds?: number;
|
|
80
|
+
limit?: number;
|
|
81
|
+
remaining?: number;
|
|
82
|
+
resetAt?: Date;
|
|
83
|
+
}
|
|
84
|
+
export interface ChatTurnEvents {
|
|
85
|
+
/** The execution is open and the model is about to run. */
|
|
86
|
+
start?: (event: {
|
|
87
|
+
turn: ChatTurn;
|
|
88
|
+
executionId: string;
|
|
89
|
+
requestId: string;
|
|
90
|
+
modelId: string;
|
|
91
|
+
}) => void | Promise<void>;
|
|
92
|
+
/** The run settled — after a normal finish, or after the client aborted. */
|
|
93
|
+
complete?: (event: {
|
|
94
|
+
turn: ChatTurn;
|
|
95
|
+
executionId: string;
|
|
96
|
+
modelId: string;
|
|
97
|
+
usage: TokenUsage;
|
|
98
|
+
aborted: boolean;
|
|
99
|
+
finishReason?: string;
|
|
100
|
+
rawFinishReason?: string;
|
|
101
|
+
providerMetadata?: unknown;
|
|
102
|
+
warnings?: unknown[];
|
|
103
|
+
}) => void | Promise<void>;
|
|
104
|
+
/** Something threw. `phase` says where; the turn may or may not have an agent yet. */
|
|
105
|
+
fail?: (event: {
|
|
106
|
+
turn: ChatTurnContext;
|
|
107
|
+
error: unknown;
|
|
108
|
+
phase: "stream" | "settlement" | "persistence" | "title" | "unhandled";
|
|
109
|
+
}) => void | Promise<void>;
|
|
110
|
+
/** The transport answered with a refusal rather than a stream. */
|
|
111
|
+
refuse?: (event: {
|
|
112
|
+
actor: ChatActor | null;
|
|
113
|
+
conversationId: string | null;
|
|
114
|
+
code: ChatErrorCode;
|
|
115
|
+
status: number;
|
|
116
|
+
reasonCode?: string;
|
|
117
|
+
}) => void | Promise<void>;
|
|
118
|
+
}
|
|
119
|
+
export interface ChatServerConfig {
|
|
120
|
+
/** The execution boundary, with its ports bound by the composition root. */
|
|
121
|
+
executions: Executions;
|
|
122
|
+
model: {
|
|
123
|
+
/** Must be registered in `@intelligo-dev/executions/pricing`. */
|
|
124
|
+
defaultId: string;
|
|
125
|
+
resolve: (modelId: string, turn: ChatTurnContext) => LanguageModel | Promise<LanguageModel>;
|
|
126
|
+
};
|
|
127
|
+
/** Runs first on every request — the place to call `composeIntelligo()`. */
|
|
128
|
+
onRequest?: () => void | Promise<void>;
|
|
129
|
+
/** Plan feature key gating the surface. `null` disables the gate. Default `"chat"`. */
|
|
130
|
+
featureKey?: string | null;
|
|
131
|
+
/** Capability recorded on each execution. Default `"chat.message"`. */
|
|
132
|
+
capability?: string;
|
|
133
|
+
/** Longest user message accepted, in characters. Default 8000. */
|
|
134
|
+
maxMessageLength?: number;
|
|
135
|
+
/** Model steps one turn may take (a tool call and the reply using it are two). Default 5. */
|
|
136
|
+
maxSteps?: number;
|
|
137
|
+
/**
|
|
138
|
+
* The one-agent shorthand. Ignored when `resolveAgent` is set.
|
|
139
|
+
* `tools` may close over the turn's tenancy.
|
|
140
|
+
*/
|
|
141
|
+
agent?: {
|
|
142
|
+
/** Default `"assistant"`. */
|
|
143
|
+
id?: string;
|
|
144
|
+
systemPrompt?: string;
|
|
145
|
+
tools?: ToolSet | ((turn: ChatTurnContext) => ToolSet | Promise<ToolSet>);
|
|
146
|
+
};
|
|
147
|
+
/**
|
|
148
|
+
* Which agent runs this turn — from the body, the row, a table. The
|
|
149
|
+
* default resolves `agent`, keeping the id the conversation was
|
|
150
|
+
* created with.
|
|
151
|
+
*/
|
|
152
|
+
resolveAgent?: (turn: ChatTurnContext) => ResolvedAgent | Promise<ResolvedAgent>;
|
|
153
|
+
/**
|
|
154
|
+
* What the model is shown. The default windows the incoming
|
|
155
|
+
* transcript by `windowing`. An application that prunes, summarises
|
|
156
|
+
* or injects context binds its own; `turn.history()` reads the
|
|
157
|
+
* persisted messages when the client's copy is not to be trusted.
|
|
158
|
+
*/
|
|
159
|
+
prepareMessages?: (turn: ChatTurn, incoming: UIMessage[]) => PreparedTurn | Promise<PreparedTurn>;
|
|
160
|
+
/** Default `{ maxMessages: 40 }`; `false` shows the model everything. */
|
|
161
|
+
windowing?: ConversationWindowOptions | false;
|
|
162
|
+
/** File parts the transport accepts. Default `false`: any file part is a 400. */
|
|
163
|
+
attachments?: ChatAttachmentPolicy | false;
|
|
164
|
+
/** Stream the model's reasoning parts to the client. Default false. */
|
|
165
|
+
reasoning?: boolean;
|
|
166
|
+
/**
|
|
167
|
+
* Titles a conversation from its first user message when the row is
|
|
168
|
+
* created. Sync: stored on create. Async: the row is created untitled,
|
|
169
|
+
* renamed when the promise resolves, and the client is sent a
|
|
170
|
+
* transient `data-chat-title` part. Default: first line, truncated.
|
|
171
|
+
*/
|
|
172
|
+
deriveTitle?: (firstUserText: string, turn: ChatTurnContext) => string | null | Promise<string | null>;
|
|
173
|
+
/**
|
|
174
|
+
* Where the turn's messages go. Default: the user message that
|
|
175
|
+
* opened the turn and the assistant reply, upserted through core.
|
|
176
|
+
* `false` persists nothing.
|
|
177
|
+
*/
|
|
178
|
+
persist?: false | ((turn: ChatTurn, result: {
|
|
179
|
+
userMessage: UIMessage | null;
|
|
180
|
+
responseMessage: UIMessage;
|
|
181
|
+
isContinuation: boolean;
|
|
182
|
+
}) => Promise<void>);
|
|
183
|
+
/** Adjusts what settlement records — a floor for providers that report nothing. */
|
|
184
|
+
normalizeUsage?: (usage: TokenUsage) => TokenUsage;
|
|
185
|
+
/** Merged into the execution's metadata on begin and complete. */
|
|
186
|
+
metadata?: (turn: ChatTurn) => Record<string, unknown>;
|
|
187
|
+
onTurn?: ChatTurnEvents;
|
|
188
|
+
/** Localised refusal copy. Default: English. */
|
|
189
|
+
messages?: (request: Request) => ChatMessages | Promise<ChatMessages>;
|
|
190
|
+
/** Default: `requireWorkspace()`. Throw to answer 401. */
|
|
191
|
+
authenticate?: (request: Request) => Promise<ChatActor>;
|
|
192
|
+
/** Default: the workspace plan's per-minute limit. `false` disables. */
|
|
193
|
+
rateLimit?: false | ((actor: ChatActor) => Promise<RateLimitDecision>);
|
|
194
|
+
}
|
|
195
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What an application tells the chat transport, and what it is told back.
|
|
3
|
+
*
|
|
4
|
+
* Two things are required — the execution boundary and a way to turn a
|
|
5
|
+
* model id into a model — because those are the two things a framework
|
|
6
|
+
* must never guess (ADR-0003, ADR-0007). Everything else has a default
|
|
7
|
+
* that gives a clean install a working chat with no API keys: one
|
|
8
|
+
* agent, one prompt, no tools, a window of forty messages, a truncated
|
|
9
|
+
* first line as the title.
|
|
10
|
+
*
|
|
11
|
+
* Each optional field is a seam a real product needed and used to
|
|
12
|
+
* fork the route to get: an agent resolved per conversation from a
|
|
13
|
+
* table, a history pruned and summarised before the model sees it,
|
|
14
|
+
* image attachments, reasoning streamed to the client, a model-written
|
|
15
|
+
* title, telemetry on every turn. None of them carry product
|
|
16
|
+
* vocabulary; all of them close over the caller's tenancy so the model
|
|
17
|
+
* never has to be told which workspace it is in.
|
|
18
|
+
*/
|
|
19
|
+
export {};
|
|
20
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG"}
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Refusals: one status per code, one message key per situation.
|
|
3
|
+
*
|
|
4
|
+
* The transport never invents copy. It asks a translator for a key,
|
|
5
|
+
* and the application binds that translator to its own message files
|
|
6
|
+
* (`messages(request)` in the config). The English table below is the
|
|
7
|
+
* default a deployment gets when it binds nothing.
|
|
8
|
+
*/
|
|
9
|
+
import type { ChatErrorBody, ChatErrorCode } from "./client.js";
|
|
10
|
+
export declare const CHAT_ERROR_STATUS: Readonly<Record<ChatErrorCode, number>>;
|
|
11
|
+
/**
|
|
12
|
+
* Every message the transport can answer with. One key per situation,
|
|
13
|
+
* not per code: `BAD_REQUEST` has three.
|
|
14
|
+
*/
|
|
15
|
+
export type ChatMessageKey = "invalidBody" | "messageTooLong" | "attachmentRejected" | "unauthorized" | "rateLimited" | "featureGated" | "notFound" | "quotaExceeded" | "billingNotConfigured" | "internalError" | "streamError";
|
|
16
|
+
export type ChatMessageParams = Record<string, string | number>;
|
|
17
|
+
/** Resolves a message key in the caller's locale. */
|
|
18
|
+
export type ChatMessages = (key: ChatMessageKey, params?: ChatMessageParams) => string;
|
|
19
|
+
/** The default translator: English, with `{param}` interpolation. */
|
|
20
|
+
export declare const DEFAULT_CHAT_MESSAGES: ChatMessages;
|
|
21
|
+
/** A JSON refusal with the status its code fixes. */
|
|
22
|
+
export declare function refuse(code: ChatErrorCode, error: string, extra?: Partial<Omit<ChatErrorBody, "error" | "code">>, headers?: Record<string, string>): Response;
|
|
23
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE7D,eAAO,MAAM,iBAAiB,EAAE,QAAQ,CAAC,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,CASrE,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,cAAc,GACtB,aAAa,GACb,gBAAgB,GAChB,oBAAoB,GACpB,cAAc,GACd,aAAa,GACb,cAAc,GACd,UAAU,GACV,eAAe,GACf,sBAAsB,GACtB,eAAe,GACf,aAAa,CAAC;AAElB,MAAM,MAAM,iBAAiB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC;AAEhE,qDAAqD;AACrD,MAAM,MAAM,YAAY,GAAG,CACzB,GAAG,EAAE,cAAc,EACnB,MAAM,CAAC,EAAE,iBAAiB,KACvB,MAAM,CAAC;AAgBZ,qEAAqE;AACrE,eAAO,MAAM,qBAAqB,EAAE,YAGjC,CAAC;AAEJ,qDAAqD;AACrD,wBAAgB,MAAM,CACpB,IAAI,EAAE,aAAa,EACnB,KAAK,EAAE,MAAM,EACb,KAAK,GAAE,OAAO,CAAC,IAAI,CAAC,aAAa,EAAE,OAAO,GAAG,MAAM,CAAC,CAAM,EAC1D,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,GACnC,QAAQ,CAGV"}
|
package/dist/errors.js
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Refusals: one status per code, one message key per situation.
|
|
3
|
+
*
|
|
4
|
+
* The transport never invents copy. It asks a translator for a key,
|
|
5
|
+
* and the application binds that translator to its own message files
|
|
6
|
+
* (`messages(request)` in the config). The English table below is the
|
|
7
|
+
* default a deployment gets when it binds nothing.
|
|
8
|
+
*/
|
|
9
|
+
export const CHAT_ERROR_STATUS = {
|
|
10
|
+
BAD_REQUEST: 400,
|
|
11
|
+
UNAUTHORIZED: 401,
|
|
12
|
+
QUOTA_EXCEEDED: 402,
|
|
13
|
+
FEATURE_GATED: 403,
|
|
14
|
+
NOT_FOUND: 404,
|
|
15
|
+
RATE_LIMITED: 429,
|
|
16
|
+
INTERNAL: 500,
|
|
17
|
+
BILLING_NOT_CONFIGURED: 503,
|
|
18
|
+
};
|
|
19
|
+
const ENGLISH = {
|
|
20
|
+
invalidBody: "Invalid request body.",
|
|
21
|
+
messageTooLong: "Message is too long (max {max} characters).",
|
|
22
|
+
attachmentRejected: "That attachment type isn't accepted.",
|
|
23
|
+
unauthorized: "Unauthorized.",
|
|
24
|
+
rateLimited: "Rate limit exceeded. Try again in {seconds}s.",
|
|
25
|
+
featureGated: "Chat isn't included in your current plan.",
|
|
26
|
+
notFound: "That conversation no longer exists.",
|
|
27
|
+
quotaExceeded: "Usage quota exceeded. Upgrade your plan or purchase credits.",
|
|
28
|
+
billingNotConfigured: "Billing is not configured for this deployment.",
|
|
29
|
+
internalError: "Something went wrong.",
|
|
30
|
+
streamError: "Something went wrong while generating a response.",
|
|
31
|
+
};
|
|
32
|
+
/** The default translator: English, with `{param}` interpolation. */
|
|
33
|
+
export const DEFAULT_CHAT_MESSAGES = (key, params = {}) => ENGLISH[key].replace(/\{(\w+)\}/g, (match, name) => name in params ? String(params[name]) : match);
|
|
34
|
+
/** A JSON refusal with the status its code fixes. */
|
|
35
|
+
export function refuse(code, error, extra = {}, headers = {}) {
|
|
36
|
+
const body = { error, code, ...extra };
|
|
37
|
+
return Response.json(body, { status: CHAT_ERROR_STATUS[code], headers });
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,MAAM,CAAC,MAAM,iBAAiB,GAA4C;IACxE,WAAW,EAAE,GAAG;IAChB,YAAY,EAAE,GAAG;IACjB,cAAc,EAAE,GAAG;IACnB,aAAa,EAAE,GAAG;IAClB,SAAS,EAAE,GAAG;IACd,YAAY,EAAE,GAAG;IACjB,QAAQ,EAAE,GAAG;IACb,sBAAsB,EAAE,GAAG;CAC5B,CAAC;AA2BF,MAAM,OAAO,GAA6C;IACxD,WAAW,EAAE,uBAAuB;IACpC,cAAc,EAAE,6CAA6C;IAC7D,kBAAkB,EAAE,sCAAsC;IAC1D,YAAY,EAAE,eAAe;IAC7B,WAAW,EAAE,+CAA+C;IAC5D,YAAY,EAAE,2CAA2C;IACzD,QAAQ,EAAE,qCAAqC;IAC/C,aAAa,EAAE,8DAA8D;IAC7E,oBAAoB,EAAE,gDAAgD;IACtE,aAAa,EAAE,uBAAuB;IACtC,WAAW,EAAE,mDAAmD;CACjE,CAAC;AAEF,qEAAqE;AACrE,MAAM,CAAC,MAAM,qBAAqB,GAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,EAAE,EAAE,EAAE,CACtE,OAAO,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,YAAY,EAAE,CAAC,KAAK,EAAE,IAAY,EAAE,EAAE,CACzD,IAAI,IAAI,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAC9C,CAAC;AAEJ,qDAAqD;AACrD,MAAM,UAAU,MAAM,CACpB,IAAmB,EACnB,KAAa,EACb,QAAwD,EAAE,EAC1D,UAAkC,EAAE;IAEpC,MAAM,IAAI,GAAkB,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,KAAK,EAAE,CAAC;IACtD,OAAO,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,iBAAiB,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC;AAC3E,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The chat transport: one turn, from request to settled execution.
|
|
3
|
+
*
|
|
4
|
+
* onRequest → parse → authenticate → rate limit → load the row →
|
|
5
|
+
* resolveAgent → feature gate → create the row → prepareMessages →
|
|
6
|
+
* executions.begin() → streamText → settle → persist.
|
|
7
|
+
*
|
|
8
|
+
* Framework-agnostic on the request side: Web `Request` in, `Response`
|
|
9
|
+
* out. A Next.js route file is two lines
|
|
10
|
+
* (`export const { POST, DELETE } = createChatHandler(config)`), and a
|
|
11
|
+
* Hono app or a test calls the same functions. The request's headers
|
|
12
|
+
* reach `requireWorkspace()` through `core/request-context`, bound
|
|
13
|
+
* once by the composition root — never through `next/*` here.
|
|
14
|
+
*
|
|
15
|
+
* Entitlement is decided at `executions.begin()`, after the agent and
|
|
16
|
+
* model are resolved, so the hold matches what will actually run
|
|
17
|
+
* (ADR-0003, ADR-0007). Everything before it is cheaper and answers
|
|
18
|
+
* without opening an execution.
|
|
19
|
+
*
|
|
20
|
+
* Every terminal path settles exactly once: `complete()` is
|
|
21
|
+
* compare-and-swap in the boundary, so whichever of finish, abort or
|
|
22
|
+
* error gets there first wins and the others are no-ops.
|
|
23
|
+
*/
|
|
24
|
+
import type { ChatServerConfig } from "./config.js";
|
|
25
|
+
export type ChatHandler = {
|
|
26
|
+
POST: (request: Request) => Promise<Response>;
|
|
27
|
+
DELETE: (request: Request) => Promise<Response>;
|
|
28
|
+
};
|
|
29
|
+
export declare function createChatHandler(config: ChatServerConfig): ChatHandler;
|
|
30
|
+
//# sourceMappingURL=handler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../src/handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAiCH,OAAO,KAAK,EAEV,gBAAgB,EAMjB,MAAM,UAAU,CAAC;AA6DlB,MAAM,MAAM,WAAW,GAAG;IACxB,IAAI,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC9C,MAAM,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;CACjD,CAAC;AAEF,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,gBAAgB,GAAG,WAAW,CA2iBvE"}
|