@yadsh/dsh-qa-surface 0.10.0 → 0.11.1
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 +310 -48
- package/lib/access/service.js +49 -10
- package/lib/access/service.js.map +1 -1
- package/lib/account-remotes.js +41 -0
- package/lib/account-remotes.js.map +1 -1
- package/lib/accounts/database.js +140 -0
- package/lib/accounts/database.js.map +1 -1
- package/lib/accounts/errors.js.map +1 -1
- package/lib/accounts/service-token.js +103 -0
- package/lib/accounts/service-token.js.map +1 -0
- package/lib/accounts/store.js +291 -5
- package/lib/accounts/store.js.map +1 -1
- package/lib/admin/conversation-log.js +14 -8
- package/lib/admin/conversation-log.js.map +1 -1
- package/lib/admin/permissions.js +5 -0
- package/lib/admin/permissions.js.map +1 -1
- package/lib/admin/quality-store.js +4 -0
- package/lib/admin/quality-store.js.map +1 -1
- package/lib/admin/service.js +173 -0
- package/lib/admin/service.js.map +1 -1
- package/lib/admin/session-log.js +39 -8
- package/lib/admin/session-log.js.map +1 -1
- package/lib/attachment-rules.js +39 -6
- package/lib/attachment-rules.js.map +1 -1
- package/lib/cli.js +83 -1
- package/lib/cli.js.map +1 -1
- package/lib/client/QaAccountsController.js +213 -4
- package/lib/client/QaAccountsController.js.map +1 -1
- package/lib/client/QaSessionController.js +37 -21
- package/lib/client/QaSessionController.js.map +1 -1
- package/lib/client/QaSurface.js +28 -4
- package/lib/client/QaSurface.js.map +1 -1
- package/lib/client/admin/QaAdmin.js +9 -1
- package/lib/client/admin/QaAdmin.js.map +1 -1
- package/lib/client/admin/pages/SkillFiles.js +78 -0
- package/lib/client/admin/pages/SkillFiles.js.map +1 -0
- package/lib/client/admin/pages/Users.js +65 -1
- package/lib/client/admin/pages/Users.js.map +1 -1
- package/lib/client/admin/routes.js +8 -1
- package/lib/client/admin/routes.js.map +1 -1
- package/lib/client/admin/styles.js +2 -0
- package/lib/client/admin/styles.js.map +1 -1
- package/lib/client/attachments.js +41 -11
- package/lib/client/attachments.js.map +1 -1
- package/lib/client/components/QaAuthGate.js +19 -10
- package/lib/client/components/QaAuthGate.js.map +1 -1
- package/lib/client/components/QaChangelog.js +43 -0
- package/lib/client/components/QaChangelog.js.map +1 -1
- package/lib/client/index.js +13 -0
- package/lib/client/index.js.map +1 -1
- package/lib/client/lineage.js +64 -0
- package/lib/client/lineage.js.map +1 -1
- package/lib/client/settings/sections/attachments.js +6 -5
- package/lib/client/settings/sections/attachments.js.map +1 -1
- package/lib/client/settings/sections/notes.js +22 -4
- package/lib/client/settings/sections/notes.js.map +1 -1
- package/lib/client/styles.js +9 -0
- package/lib/client/styles.js.map +1 -1
- package/lib/client/types.js.map +1 -1
- package/lib/client/user-settings/IntegrationTokensPage.js +150 -0
- package/lib/client/user-settings/IntegrationTokensPage.js.map +1 -0
- package/lib/client/user-settings/PasswordSettingsPage.js +48 -0
- package/lib/client/user-settings/PasswordSettingsPage.js.map +1 -0
- package/lib/client/user-settings/SkillCatalog.js +2 -2
- package/lib/client/user-settings/SkillCatalog.js.map +1 -1
- package/lib/client/user-settings/UserSettingsDialog.js +17 -2
- package/lib/client/user-settings/UserSettingsDialog.js.map +1 -1
- package/lib/client/user-settings/copy.js +20 -0
- package/lib/client/user-settings/copy.js.map +1 -1
- package/lib/client.js +2480 -137
- package/lib/client.js.map +1 -1
- package/lib/config-resolvers/attachments.js +6 -5
- package/lib/config-resolvers/attachments.js.map +1 -1
- package/lib/config-resolvers/defaults.js +23 -2
- package/lib/config-resolvers/defaults.js.map +1 -1
- package/lib/config-resolvers/integration.js +94 -0
- package/lib/config-resolvers/integration.js.map +1 -0
- package/lib/config-resolvers/notes.js +2 -0
- package/lib/config-resolvers/notes.js.map +1 -1
- package/lib/config.js +72 -0
- package/lib/config.js.map +1 -1
- package/lib/index.js +197 -2
- package/lib/index.js.map +1 -1
- package/lib/integration/answer.js +100 -0
- package/lib/integration/answer.js.map +1 -0
- package/lib/integration/attachments.js +246 -0
- package/lib/integration/attachments.js.map +1 -0
- package/lib/integration/contract.js +53 -0
- package/lib/integration/contract.js.map +1 -0
- package/lib/integration/host-runner.js +243 -0
- package/lib/integration/host-runner.js.map +1 -0
- package/lib/integration/http.js +576 -0
- package/lib/integration/http.js.map +1 -0
- package/lib/integration/service.js +373 -0
- package/lib/integration/service.js.map +1 -0
- package/lib/integration/transcript-reader.js +202 -0
- package/lib/integration/transcript-reader.js.map +1 -0
- package/lib/integration/transcript.js +148 -0
- package/lib/integration/transcript.js.map +1 -0
- package/lib/personal-skills/index.js +2 -2
- package/lib/personal-skills/index.js.map +1 -1
- package/lib/personal-skills/paths.js +14 -8
- package/lib/personal-skills/paths.js.map +1 -1
- package/lib/personal-skills/provider.js +16 -4
- package/lib/personal-skills/provider.js.map +1 -1
- package/lib/personal-skills/service.js +240 -30
- package/lib/personal-skills/service.js.map +1 -1
- package/lib/prompt-notes.js +58 -0
- package/lib/prompt-notes.js.map +1 -1
- package/lib/provenance/document-preview.js +10 -1
- package/lib/provenance/document-preview.js.map +1 -1
- package/lib/qa-tools/catalog.js +12 -1
- package/lib/qa-tools/catalog.js.map +1 -1
- package/lib/qa-tools/docs-tools.js +563 -0
- package/lib/qa-tools/docs-tools.js.map +1 -0
- package/lib/resolve-config.js +4 -0
- package/lib/resolve-config.js.map +1 -1
- package/lib/secure-session.js +83 -3
- package/lib/secure-session.js.map +1 -1
- package/lib/shared/integration-tokens.js +23 -0
- package/lib/shared/integration-tokens.js.map +1 -0
- package/lib/typert.host.js +1176 -213
- package/lib/typert.remote-client.d.ts +27 -1
- package/lib/typert.remote-client.js +911 -69
- package/lib/types/access/service.d.ts +33 -2
- package/lib/types/account-remotes.d.ts +30 -1
- package/lib/types/accounts/database.d.ts +53 -0
- package/lib/types/accounts/errors.d.ts +5 -1
- package/lib/types/accounts/service-token.d.ts +70 -0
- package/lib/types/accounts/store.d.ts +131 -1
- package/lib/types/admin/conversation-log.d.ts +12 -0
- package/lib/types/admin/service.d.ts +56 -1
- package/lib/types/admin/session-log.d.ts +21 -0
- package/lib/types/attachment-rules.d.ts +26 -3
- package/lib/types/client/QaAccountsController.d.ts +64 -5
- package/lib/types/client/QaSessionController.d.ts +24 -2
- package/lib/types/client/admin/pages/SkillFiles.d.ts +17 -0
- package/lib/types/client/admin/routes.d.ts +2 -0
- package/lib/types/client/attachments.d.ts +21 -4
- package/lib/types/client/lineage.d.ts +42 -0
- package/lib/types/client/settings/sections/notes.d.ts +5 -3
- package/lib/types/client/types.d.ts +71 -1
- package/lib/types/client/user-settings/IntegrationTokensPage.d.ts +21 -0
- package/lib/types/client/user-settings/PasswordSettingsPage.d.ts +19 -0
- package/lib/types/client/user-settings/UserSettingsDialog.d.ts +11 -2
- package/lib/types/client/user-settings/copy.d.ts +10 -1
- package/lib/types/config-resolvers/integration.d.ts +47 -0
- package/lib/types/config.d.ts +10 -0
- package/lib/types/index.d.ts +73 -1
- package/lib/types/integration/answer.d.ts +65 -0
- package/lib/types/integration/attachments.d.ts +85 -0
- package/lib/types/integration/contract.d.ts +196 -0
- package/lib/types/integration/host-runner.d.ts +44 -0
- package/lib/types/integration/http.d.ts +79 -0
- package/lib/types/integration/service.d.ts +120 -0
- package/lib/types/integration/transcript-reader.d.ts +100 -0
- package/lib/types/integration/transcript.d.ts +59 -0
- package/lib/types/personal-skills/index.d.ts +2 -2
- package/lib/types/personal-skills/paths.d.ts +15 -3
- package/lib/types/personal-skills/provider.d.ts +14 -2
- package/lib/types/personal-skills/service.d.ts +89 -14
- package/lib/types/prompt-notes.d.ts +28 -0
- package/lib/types/provenance/document-preview.d.ts +4 -0
- package/lib/types/qa-tools/catalog.d.ts +1 -1
- package/lib/types/qa-tools/docs-tools.d.ts +160 -0
- package/lib/types/secure-session.d.ts +52 -1
- package/lib/types/shared/integration-tokens.d.ts +24 -0
- package/lib/types/types.d.ts +170 -2
- package/package.json +2 -2
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"host-runner.js","sourceRoot":"","sources":["../../src/integration/host-runner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,576 @@
|
|
|
1
|
+
import { isIntegrationDocumentMediaType, isIntegrationTextMediaType, } from "./attachments.js";
|
|
2
|
+
import { QA_INTEGRATION_MAX_TRANSCRIPT_MESSAGES } from "./transcript.js";
|
|
3
|
+
import { QaIntegrationError, } from "./contract.js";
|
|
4
|
+
/**
|
|
5
|
+
* The integration API's HTTP transport.
|
|
6
|
+
*
|
|
7
|
+
* Three exact routes under one configurable base path — the required
|
|
8
|
+
* `POST {base}/ask`, `GET {base}/session` and the optional `GET {base}/health`
|
|
9
|
+
* of the ticket bridge contract — speaking `application/json` and
|
|
10
|
+
* `multipart/form-data`, which is what the bridge sends. Everything below the
|
|
11
|
+
* transport (credentials, scopes, budgets, turns) lives in
|
|
12
|
+
* {@link QaIntegrationService}; this file owns bytes, encodings and status
|
|
13
|
+
* codes and nothing else.
|
|
14
|
+
*
|
|
15
|
+
* Method checking happens inside each handler rather than by registering one
|
|
16
|
+
* route per verb: a `GET /qa/api/ask` must answer 405 with an `Allow` header,
|
|
17
|
+
* and a route that only matched POST would instead fall through to the SPA
|
|
18
|
+
* fallback and answer 200 with an HTML page.
|
|
19
|
+
*/
|
|
20
|
+
/** Raster formats the prompt content can carry inline; the rest need uploads. */
|
|
21
|
+
const INLINE_IMAGE_MEDIA_TYPES = Object.freeze([
|
|
22
|
+
"image/png",
|
|
23
|
+
"image/jpeg",
|
|
24
|
+
"image/webp",
|
|
25
|
+
"image/gif",
|
|
26
|
+
]);
|
|
27
|
+
/** The bridge's own ceiling: five attachments per question. */
|
|
28
|
+
export const QA_INTEGRATION_MAX_FILES = 5;
|
|
29
|
+
/**
|
|
30
|
+
* Register the integration routes on the host web server.
|
|
31
|
+
* @param webServer - the route table owner.
|
|
32
|
+
* @param options - resolved config, the service and the plugin logger.
|
|
33
|
+
* @returns the disposer removing every route this call registered.
|
|
34
|
+
*/
|
|
35
|
+
export function registerQaIntegrationRoutes(webServer, options) {
|
|
36
|
+
const base = options.config.integration.basePath;
|
|
37
|
+
const disposers = [
|
|
38
|
+
webServer.register({
|
|
39
|
+
kind: "exact",
|
|
40
|
+
path: `${base}/ask`,
|
|
41
|
+
handler: (request, response) => handleAsk(request, response, options).catch(() => sendRefusal(response, new QaIntegrationError("unavailable", "the request could not be answered"))),
|
|
42
|
+
}),
|
|
43
|
+
webServer.register({
|
|
44
|
+
kind: "exact",
|
|
45
|
+
path: `${base}/session`,
|
|
46
|
+
handler: (request, response) => handleSession(request, response, options).catch(() => sendRefusal(response, new QaIntegrationError("unavailable", "the conversation could not be read"))),
|
|
47
|
+
}),
|
|
48
|
+
webServer.register({
|
|
49
|
+
kind: "exact",
|
|
50
|
+
path: `${base}/health`,
|
|
51
|
+
handler: (request, response) => handleHealth(request, response, options).catch(() => sendRefusal(response, new QaIntegrationError("unavailable", "health could not be answered"))),
|
|
52
|
+
}),
|
|
53
|
+
];
|
|
54
|
+
return () => {
|
|
55
|
+
for (const dispose of disposers)
|
|
56
|
+
dispose();
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
async function handleAsk(request, response, options) {
|
|
60
|
+
if (request.method !== "POST") {
|
|
61
|
+
sendMethodNotAllowed(response, "POST");
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
try {
|
|
65
|
+
const body = await readBody(request, options.config.integration.maxRequestBytes);
|
|
66
|
+
const parsed = parseAskBody(body, contentTypeOf(request), options.config);
|
|
67
|
+
const answer = await options.service.ask(headerOf(request, "authorization"), parsed, clientSignal(response));
|
|
68
|
+
sendJson(response, 200, answerPayload(answer));
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
sendRefusal(response, error);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
/** The page size a caller gets when it does not ask for one. */
|
|
75
|
+
export const QA_INTEGRATION_DEFAULT_TRANSCRIPT_LIMIT = 50;
|
|
76
|
+
/**
|
|
77
|
+
* Read one conversation back, for the application that owns it.
|
|
78
|
+
*
|
|
79
|
+
* `GET {base}/session?chat_id=…&after=…&limit=…`: the chat id is the required
|
|
80
|
+
* part, `after` is the caller's own cursor (the `last_seq` of its previous
|
|
81
|
+
* read) and `limit` bounds the page. Path parameters were avoided on purpose —
|
|
82
|
+
* one exact route per endpoint is what this table is good at, and a chat id in
|
|
83
|
+
* a query string never has to be unescaped out of a path.
|
|
84
|
+
*/
|
|
85
|
+
async function handleSession(request, response, options) {
|
|
86
|
+
if (request.method !== "GET" && request.method !== "HEAD") {
|
|
87
|
+
sendMethodNotAllowed(response, "GET, HEAD");
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
try {
|
|
91
|
+
const query = queryOf(request);
|
|
92
|
+
const chatId = (query.get("chat_id") ?? "").trim();
|
|
93
|
+
if (chatId === "") {
|
|
94
|
+
throw new QaIntegrationError("invalid-request", "chat_id is required");
|
|
95
|
+
}
|
|
96
|
+
const after = integerParameter(query, "after", 0);
|
|
97
|
+
if (after < 0) {
|
|
98
|
+
throw new QaIntegrationError("invalid-request", "after must not be negative");
|
|
99
|
+
}
|
|
100
|
+
// A page size is a preference, not a contract: a caller that asks for more
|
|
101
|
+
// than the ceiling gets the ceiling rather than a refusal, because the
|
|
102
|
+
// window it needs is still in the answer, just shorter.
|
|
103
|
+
const requested = integerParameter(query, "limit", QA_INTEGRATION_DEFAULT_TRANSCRIPT_LIMIT);
|
|
104
|
+
if (requested <= 0) {
|
|
105
|
+
throw new QaIntegrationError("invalid-request", "limit must be positive");
|
|
106
|
+
}
|
|
107
|
+
const transcript = await options.service.session(headerOf(request, "authorization"), {
|
|
108
|
+
chatId,
|
|
109
|
+
after,
|
|
110
|
+
limit: Math.min(requested, QA_INTEGRATION_MAX_TRANSCRIPT_MESSAGES),
|
|
111
|
+
});
|
|
112
|
+
sendJson(response, 200, {
|
|
113
|
+
chat_id: transcript.chatId,
|
|
114
|
+
messages: transcript.messages.map((message) => ({
|
|
115
|
+
seq: message.seq,
|
|
116
|
+
role: message.role,
|
|
117
|
+
text: message.text,
|
|
118
|
+
at: message.at ?? null,
|
|
119
|
+
})),
|
|
120
|
+
last_seq: transcript.lastSeq,
|
|
121
|
+
truncated: transcript.truncated,
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
catch (error) {
|
|
125
|
+
sendRefusal(response, error);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
/** The query string of a request, decoded once into a lookup. */
|
|
129
|
+
function queryOf(request) {
|
|
130
|
+
const raw = request.url?.split("?")[1] ?? "";
|
|
131
|
+
const query = new Map();
|
|
132
|
+
for (const pair of raw.split("&")) {
|
|
133
|
+
if (pair === "")
|
|
134
|
+
continue;
|
|
135
|
+
const separator = pair.indexOf("=");
|
|
136
|
+
const key = decodeURIComponent(separator === -1 ? pair : pair.slice(0, separator));
|
|
137
|
+
const value = decodeURIComponent(separator === -1 ? "" : pair.slice(separator + 1));
|
|
138
|
+
if (!query.has(key))
|
|
139
|
+
query.set(key, value);
|
|
140
|
+
}
|
|
141
|
+
return query;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* One numeric query parameter, refused rather than coerced when it is not a
|
|
145
|
+
* number: a cursor the caller did not mean is worse than a clear refusal.
|
|
146
|
+
*/
|
|
147
|
+
function integerParameter(query, name, fallback) {
|
|
148
|
+
const raw = query.get(name)?.trim() ?? "";
|
|
149
|
+
if (raw === "")
|
|
150
|
+
return fallback;
|
|
151
|
+
if (!/^\d+$/u.test(raw)) {
|
|
152
|
+
throw new QaIntegrationError("invalid-request", `${name} must be a whole number`);
|
|
153
|
+
}
|
|
154
|
+
return Number(raw);
|
|
155
|
+
}
|
|
156
|
+
async function handleHealth(request, response, options) {
|
|
157
|
+
if (request.method !== "GET" && request.method !== "HEAD") {
|
|
158
|
+
sendMethodNotAllowed(response, "GET, HEAD");
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
try {
|
|
162
|
+
const health = await options.service.health(headerOf(request, "authorization"));
|
|
163
|
+
// The bridge reads snake_case here (its own field names), unlike the ask
|
|
164
|
+
// response, which it also defines — the contract is reproduced exactly.
|
|
165
|
+
sendJson(response, 200, {
|
|
166
|
+
ok: health.ok,
|
|
167
|
+
version: health.version,
|
|
168
|
+
models: health.models,
|
|
169
|
+
uptime_s: health.uptimeS,
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
catch (error) {
|
|
173
|
+
sendRefusal(response, error);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
/** The `{chat_id, answer, …}` body the bridge publishes from. */
|
|
177
|
+
function answerPayload(answer) {
|
|
178
|
+
return {
|
|
179
|
+
chat_id: answer.chatId,
|
|
180
|
+
answer: answer.answer,
|
|
181
|
+
sources: answer.sources,
|
|
182
|
+
confidence: answer.confidence,
|
|
183
|
+
escalate: answer.escalate,
|
|
184
|
+
reason: answer.reason,
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Parse one `POST /ask` body out of whichever encoding carried it.
|
|
189
|
+
*
|
|
190
|
+
* JSON is the primary form. Multipart exists because the bridge sends the
|
|
191
|
+
* ticket's attachments through it, and images ride a prompt inline in this
|
|
192
|
+
* harness — so an image-only multipart request is answered like a JSON one. A
|
|
193
|
+
* non-image attachment has nowhere to go: files reach a prompt as a receipt
|
|
194
|
+
* minted by the browser upload path, which an external caller has no session
|
|
195
|
+
* to mint. That request is refused with 415, which is exactly the signal the
|
|
196
|
+
* bridge's own fallback waits for: it repeats the question without
|
|
197
|
+
* attachments rather than failing.
|
|
198
|
+
*
|
|
199
|
+
* @param body - the raw request body.
|
|
200
|
+
* @param contentType - the request's content type, parameters included.
|
|
201
|
+
* @param config - resolved config, for the attachment ceilings.
|
|
202
|
+
* @returns the normalized request.
|
|
203
|
+
*/
|
|
204
|
+
export function parseAskBody(body, contentType, config) {
|
|
205
|
+
const media = (contentType ?? "").split(";")[0]?.trim().toLowerCase() ?? "";
|
|
206
|
+
if (media === "application/json" || media === "") {
|
|
207
|
+
return parseJsonAsk(body);
|
|
208
|
+
}
|
|
209
|
+
if (media === "multipart/form-data") {
|
|
210
|
+
const boundary = boundaryOf(contentType);
|
|
211
|
+
if (boundary === null) {
|
|
212
|
+
throw new QaIntegrationError("invalid-request", "multipart/form-data without a boundary parameter");
|
|
213
|
+
}
|
|
214
|
+
return parseMultipartAsk(parseMultipart(body, boundary), config);
|
|
215
|
+
}
|
|
216
|
+
throw new QaIntegrationError("unsupported-media", `unsupported content type ${media}`);
|
|
217
|
+
}
|
|
218
|
+
function parseJsonAsk(body) {
|
|
219
|
+
let parsed;
|
|
220
|
+
try {
|
|
221
|
+
parsed = JSON.parse(body.toString("utf8"));
|
|
222
|
+
}
|
|
223
|
+
catch {
|
|
224
|
+
throw new QaIntegrationError("invalid-request", "the body is not valid JSON");
|
|
225
|
+
}
|
|
226
|
+
return fromFields(record(parsed), null);
|
|
227
|
+
}
|
|
228
|
+
const MAX_MESSAGE_CHARS = 200_000;
|
|
229
|
+
const MAX_CONTEXT_CHARS = 4_000;
|
|
230
|
+
function parseMultipartAsk(multipart, config) {
|
|
231
|
+
const attachments = [];
|
|
232
|
+
for (const file of multipart.files) {
|
|
233
|
+
const media = file.mediaType.split(";")[0]?.trim().toLowerCase() ?? "";
|
|
234
|
+
if (file.bytes.length > config.integration.maxAttachmentBytes) {
|
|
235
|
+
throw new QaIntegrationError("payload-too-large", `attachment ${file.filename} exceeds the configured limit`);
|
|
236
|
+
}
|
|
237
|
+
if (INLINE_IMAGE_MEDIA_TYPES.includes(media)) {
|
|
238
|
+
// An image is the one attachment the prompt carries as bytes.
|
|
239
|
+
attachments.push(Object.freeze({
|
|
240
|
+
kind: "image",
|
|
241
|
+
mediaType: media,
|
|
242
|
+
data: file.bytes.toString("base64"),
|
|
243
|
+
...(file.filename === "" ? {} : { name: file.filename }),
|
|
244
|
+
}));
|
|
245
|
+
continue;
|
|
246
|
+
}
|
|
247
|
+
if (!isIntegrationTextMediaType(media) &&
|
|
248
|
+
!isIntegrationDocumentMediaType(media)) {
|
|
249
|
+
// Deliberate 415: it makes the bridge send the question again without
|
|
250
|
+
// attachments, publishing an answer instead of failing the ticket. The
|
|
251
|
+
// accepted families are the caller's own filter (text, PDF, OOXML);
|
|
252
|
+
// archives, executables and media never get here from the bridge, and a
|
|
253
|
+
// caller that sends them gets the fallback rather than a prompt full of
|
|
254
|
+
// bytes the model cannot read.
|
|
255
|
+
throw new QaIntegrationError("unsupported-media", `unsupported attachment type ${media}; repeat the request without attachments`);
|
|
256
|
+
}
|
|
257
|
+
// A document is read on the Host — decoded when its bytes are the content,
|
|
258
|
+
// extracted through the document pipeline otherwise — and joins the prompt
|
|
259
|
+
// as text. Nothing is stored, so the bytes are all this layer keeps.
|
|
260
|
+
attachments.push(Object.freeze({
|
|
261
|
+
kind: "file",
|
|
262
|
+
mediaType: media,
|
|
263
|
+
// A file name has to survive being a file name: a media type carries a
|
|
264
|
+
// slash, which a temporary file on Windows cannot.
|
|
265
|
+
name: file.filename === ""
|
|
266
|
+
? `attachment.${media.replace("/", ".")}`
|
|
267
|
+
: file.filename,
|
|
268
|
+
bytes: file.bytes,
|
|
269
|
+
}));
|
|
270
|
+
}
|
|
271
|
+
const context = parseContextField(multipart.fields.get("context"));
|
|
272
|
+
return fromFields({
|
|
273
|
+
message: multipart.fields.get("message"),
|
|
274
|
+
version: emptyToNull(multipart.fields.get("version")),
|
|
275
|
+
session_id: emptyToNull(multipart.fields.get("session_id")),
|
|
276
|
+
context: {
|
|
277
|
+
ticket_key: context.ticketKey,
|
|
278
|
+
reporter: context.reporter,
|
|
279
|
+
reporter_name: context.reporterName,
|
|
280
|
+
},
|
|
281
|
+
}, attachments);
|
|
282
|
+
}
|
|
283
|
+
/**
|
|
284
|
+
* Normalize the fields both encodings share into one request, refusing what a
|
|
285
|
+
* turn cannot be opened with.
|
|
286
|
+
* @param fields - the request as an object, however it arrived.
|
|
287
|
+
* @param attachments - inline images, or null for the JSON encoding.
|
|
288
|
+
* @returns the validated request.
|
|
289
|
+
*/
|
|
290
|
+
function fromFields(fields, attachments) {
|
|
291
|
+
const message = typeof fields?.message === "string" ? fields.message : "";
|
|
292
|
+
if (message.trim() === "") {
|
|
293
|
+
throw new QaIntegrationError("invalid-request", "message is required");
|
|
294
|
+
}
|
|
295
|
+
if (message.length > MAX_MESSAGE_CHARS) {
|
|
296
|
+
throw new QaIntegrationError("payload-too-large", "message is longer than the accepted maximum");
|
|
297
|
+
}
|
|
298
|
+
const context = fields === undefined ? undefined : record(fields.context);
|
|
299
|
+
return Object.freeze({
|
|
300
|
+
message,
|
|
301
|
+
version: stringOrNull(fields?.version),
|
|
302
|
+
sessionId: stringOrNull(fields?.session_id ?? fields?.sessionId),
|
|
303
|
+
context: context === undefined
|
|
304
|
+
? EMPTY_CONTEXT
|
|
305
|
+
: Object.freeze({
|
|
306
|
+
ticketKey: stringOrNull(context.ticket_key ?? context.ticketKey),
|
|
307
|
+
reporter: stringOrNull(context.reporter),
|
|
308
|
+
reporterName: stringOrNull(context.reporter_name ?? context.reporterName),
|
|
309
|
+
}),
|
|
310
|
+
attachments: Object.freeze([...(attachments ?? [])]),
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
const EMPTY_CONTEXT = Object.freeze({
|
|
314
|
+
ticketKey: null,
|
|
315
|
+
reporter: null,
|
|
316
|
+
reporterName: null,
|
|
317
|
+
});
|
|
318
|
+
/** The `context` field of a multipart form: a JSON string, not an object. */
|
|
319
|
+
function parseContextField(raw) {
|
|
320
|
+
const value = raw === undefined ? "" : raw.trim();
|
|
321
|
+
if (value === "")
|
|
322
|
+
return EMPTY_CONTEXT;
|
|
323
|
+
if (value.length > MAX_CONTEXT_CHARS) {
|
|
324
|
+
throw new QaIntegrationError("invalid-request", "the context field is too long");
|
|
325
|
+
}
|
|
326
|
+
let parsed;
|
|
327
|
+
try {
|
|
328
|
+
parsed = JSON.parse(value);
|
|
329
|
+
}
|
|
330
|
+
catch {
|
|
331
|
+
throw new QaIntegrationError("invalid-request", "the context field is not valid JSON");
|
|
332
|
+
}
|
|
333
|
+
const entry = record(parsed) ?? {};
|
|
334
|
+
return Object.freeze({
|
|
335
|
+
ticketKey: stringOrNull(entry.ticket_key ?? entry.ticketKey),
|
|
336
|
+
reporter: stringOrNull(entry.reporter),
|
|
337
|
+
reporterName: stringOrNull(entry.reporter_name ?? entry.reporterName),
|
|
338
|
+
});
|
|
339
|
+
}
|
|
340
|
+
/**
|
|
341
|
+
* Split a multipart body into its text fields and files.
|
|
342
|
+
*
|
|
343
|
+
* Hand-written and deliberately minimal: one request shape (a flat form of
|
|
344
|
+
* scalar fields and `files` parts), one boundary, no nested multiparts. The
|
|
345
|
+
* body is already bounded by the caller, so no part can grow without limit.
|
|
346
|
+
*
|
|
347
|
+
* @param body - the raw request body.
|
|
348
|
+
* @param boundary - the boundary parameter of the content type.
|
|
349
|
+
* @returns text fields and file parts, in the order they appeared.
|
|
350
|
+
*/
|
|
351
|
+
export function parseMultipart(body, boundary) {
|
|
352
|
+
const delimiter = Buffer.from(`--${boundary}`);
|
|
353
|
+
const fields = new Map();
|
|
354
|
+
const files = [];
|
|
355
|
+
let cursor = body.indexOf(delimiter);
|
|
356
|
+
if (cursor === -1) {
|
|
357
|
+
throw new QaIntegrationError("invalid-request", "the multipart body does not contain its boundary");
|
|
358
|
+
}
|
|
359
|
+
while (cursor !== -1) {
|
|
360
|
+
const start = cursor + delimiter.length;
|
|
361
|
+
// A closing delimiter is "--" right after the boundary.
|
|
362
|
+
if (body.subarray(start, start + 2).toString("latin1") === "--")
|
|
363
|
+
break;
|
|
364
|
+
const next = body.indexOf(delimiter, start);
|
|
365
|
+
if (next === -1) {
|
|
366
|
+
throw new QaIntegrationError("invalid-request", "the multipart body is truncated");
|
|
367
|
+
}
|
|
368
|
+
// Each part is "\r\n" headers "\r\n\r\n" content "\r\n".
|
|
369
|
+
const raw = body.subarray(start, next);
|
|
370
|
+
const split = raw.indexOf("\r\n\r\n");
|
|
371
|
+
if (split === -1) {
|
|
372
|
+
// A part without its header/content separator is malformed, and skipping
|
|
373
|
+
// it would silently drop what the caller sent — a text field, or an
|
|
374
|
+
// attachment the question would then be answered without. That is the
|
|
375
|
+
// one outcome this contract refuses to publish, so the body is refused
|
|
376
|
+
// instead.
|
|
377
|
+
throw new QaIntegrationError("invalid-request", "the multipart body has a part without headers");
|
|
378
|
+
}
|
|
379
|
+
const headers = raw.subarray(0, split).toString("utf8");
|
|
380
|
+
const content = raw.subarray(split + 4);
|
|
381
|
+
const trimmed = content.subarray(0, content.length >= 2 &&
|
|
382
|
+
content[content.length - 2] === 0x0d &&
|
|
383
|
+
content[content.length - 1] === 0x0a
|
|
384
|
+
? content.length - 2
|
|
385
|
+
: content.length);
|
|
386
|
+
const part = parsePartHeaders(headers);
|
|
387
|
+
if (part !== null) {
|
|
388
|
+
if (part.filename === null) {
|
|
389
|
+
fields.set(part.name, trimmed.toString("utf8"));
|
|
390
|
+
}
|
|
391
|
+
else {
|
|
392
|
+
files.push(Object.freeze({
|
|
393
|
+
filename: part.filename,
|
|
394
|
+
mediaType: part.contentType ?? "application/octet-stream",
|
|
395
|
+
bytes: Buffer.from(trimmed),
|
|
396
|
+
}));
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
cursor = next;
|
|
400
|
+
}
|
|
401
|
+
if (files.length > QA_INTEGRATION_MAX_FILES) {
|
|
402
|
+
throw new QaIntegrationError("invalid-request", `at most ${String(QA_INTEGRATION_MAX_FILES)} attachments are accepted`);
|
|
403
|
+
}
|
|
404
|
+
return Object.freeze({ fields, files: Object.freeze(files) });
|
|
405
|
+
}
|
|
406
|
+
function parsePartHeaders(headers) {
|
|
407
|
+
let name = null;
|
|
408
|
+
let filename = null;
|
|
409
|
+
let contentType;
|
|
410
|
+
for (const line of headers.split("\r\n")) {
|
|
411
|
+
const colon = line.indexOf(":");
|
|
412
|
+
if (colon === -1)
|
|
413
|
+
continue;
|
|
414
|
+
const key = line.slice(0, colon).trim().toLowerCase();
|
|
415
|
+
const value = line.slice(colon + 1).trim();
|
|
416
|
+
if (key === "content-disposition") {
|
|
417
|
+
name = parameterOf(value, "name");
|
|
418
|
+
filename = filenameOf(value);
|
|
419
|
+
}
|
|
420
|
+
else if (key === "content-type") {
|
|
421
|
+
contentType = value;
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
if (name === null)
|
|
425
|
+
return null;
|
|
426
|
+
return { name, filename, contentType };
|
|
427
|
+
}
|
|
428
|
+
/**
|
|
429
|
+
* The `filename` of one `content-disposition`, in either of its two forms.
|
|
430
|
+
*
|
|
431
|
+
* A file name is what tells a part apart from a text field, so reading only the
|
|
432
|
+
* plain form loses attachments: a caller that sends a non-ASCII name — what
|
|
433
|
+
* browsers and several HTTP clients do — puts it in the RFC 5987 extended form
|
|
434
|
+
* (`filename*=UTF-8''%D0%94...`), where the plain parameter is absent. Read as
|
|
435
|
+
* a field, the file would be dropped and the question answered without the
|
|
436
|
+
* material it was asked about.
|
|
437
|
+
*
|
|
438
|
+
* @param value - the header value.
|
|
439
|
+
* @returns the decoded name, or null when neither form is present.
|
|
440
|
+
*/
|
|
441
|
+
function filenameOf(value) {
|
|
442
|
+
const plain = parameterOf(value, "filename");
|
|
443
|
+
if (plain !== null)
|
|
444
|
+
return plain;
|
|
445
|
+
const extended = /filename\*=("[^"]*"|[^;\s]+)/iu.exec(value)?.[1];
|
|
446
|
+
if (extended === undefined)
|
|
447
|
+
return null;
|
|
448
|
+
const unquoted = extended.replace(/^"|"$/gu, "");
|
|
449
|
+
// "charset'language'percent-encoded", per RFC 5987/8187. The charset is not
|
|
450
|
+
// honoured: a name the caller encoded as raw bytes is not worth a decoder,
|
|
451
|
+
// and a decode failure falls back to the field it would otherwise have been.
|
|
452
|
+
const encoded = unquoted.replace(/^[^']*'[^']*'/u, "");
|
|
453
|
+
try {
|
|
454
|
+
return decodeURIComponent(encoded);
|
|
455
|
+
}
|
|
456
|
+
catch {
|
|
457
|
+
return null;
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
/** One quoted parameter of a header value, or null when it is absent. */
|
|
461
|
+
function parameterOf(value, key) {
|
|
462
|
+
const match = new RegExp(`${key}="([^"]*)"`, "iu").exec(value);
|
|
463
|
+
return match?.[1] ?? null;
|
|
464
|
+
}
|
|
465
|
+
function boundaryOf(contentType) {
|
|
466
|
+
if (typeof contentType !== "string")
|
|
467
|
+
return null;
|
|
468
|
+
const match = /boundary=(?:"([^"]+)"|([^;\s]+))/iu.exec(contentType);
|
|
469
|
+
const boundary = match?.[1] ?? match?.[2];
|
|
470
|
+
return boundary === undefined || boundary === "" ? null : boundary;
|
|
471
|
+
}
|
|
472
|
+
/**
|
|
473
|
+
* Read the whole request body under a byte ceiling.
|
|
474
|
+
* @param request - the incoming request.
|
|
475
|
+
* @param limit - accepted body size in bytes.
|
|
476
|
+
* @returns the body.
|
|
477
|
+
*/
|
|
478
|
+
export async function readBody(request, limit) {
|
|
479
|
+
const declared = Number(headerOf(request, "content-length"));
|
|
480
|
+
if (Number.isFinite(declared) && declared > limit) {
|
|
481
|
+
throw new QaIntegrationError("payload-too-large", "the request body is larger than the configured limit");
|
|
482
|
+
}
|
|
483
|
+
const chunks = [];
|
|
484
|
+
let total = 0;
|
|
485
|
+
for await (const chunk of request) {
|
|
486
|
+
const buffer = Buffer.isBuffer(chunk)
|
|
487
|
+
? chunk
|
|
488
|
+
: Buffer.from(chunk);
|
|
489
|
+
total += buffer.length;
|
|
490
|
+
if (total > limit) {
|
|
491
|
+
throw new QaIntegrationError("payload-too-large", "the request body is larger than the configured limit");
|
|
492
|
+
}
|
|
493
|
+
chunks.push(buffer);
|
|
494
|
+
}
|
|
495
|
+
return Buffer.concat(chunks);
|
|
496
|
+
}
|
|
497
|
+
function contentTypeOf(request) {
|
|
498
|
+
return headerOf(request, "content-type");
|
|
499
|
+
}
|
|
500
|
+
function headerOf(request, name) {
|
|
501
|
+
const value = request.headers?.[name];
|
|
502
|
+
if (typeof value === "string")
|
|
503
|
+
return value;
|
|
504
|
+
return Array.isArray(value) ? value[0] : undefined;
|
|
505
|
+
}
|
|
506
|
+
/**
|
|
507
|
+
* The caller's own lifetime: a dropped connection stops the turn's wait.
|
|
508
|
+
*
|
|
509
|
+
* Watched on the *response*, not the request. A request's `close` fires as
|
|
510
|
+
* soon as its body has been consumed — which is before the turn even starts —
|
|
511
|
+
* so watching it would abort every request that was read successfully. The
|
|
512
|
+
* response's `close` fires when the exchange is over, and
|
|
513
|
+
* `writableFinished` says which way it ended: a finished response was
|
|
514
|
+
* delivered, an unfinished one was abandoned by the client.
|
|
515
|
+
* @param response - the response being written.
|
|
516
|
+
* @returns a signal aborted only when the client goes away.
|
|
517
|
+
*/
|
|
518
|
+
function clientSignal(response) {
|
|
519
|
+
const controller = new AbortController();
|
|
520
|
+
response.once("close", () => {
|
|
521
|
+
if (!response.writableFinished) {
|
|
522
|
+
controller.abort(new Error("the client disconnected"));
|
|
523
|
+
}
|
|
524
|
+
});
|
|
525
|
+
return controller.signal;
|
|
526
|
+
}
|
|
527
|
+
function sendJson(response, status, payload) {
|
|
528
|
+
const body = Buffer.from(JSON.stringify(payload), "utf8");
|
|
529
|
+
response.writeHead(status, {
|
|
530
|
+
"content-type": "application/json; charset=utf-8",
|
|
531
|
+
"content-length": String(body.length),
|
|
532
|
+
"cache-control": "no-store",
|
|
533
|
+
});
|
|
534
|
+
response.end(body);
|
|
535
|
+
}
|
|
536
|
+
/**
|
|
537
|
+
* One refusal, mapped onto its status.
|
|
538
|
+
*
|
|
539
|
+
* An unexpected error is answered as `unavailable` rather than leaking a stack
|
|
540
|
+
* trace: the bridge retries a 5xx, and the deployment's own log holds the
|
|
541
|
+
* detail.
|
|
542
|
+
*/
|
|
543
|
+
export function sendRefusal(response, error) {
|
|
544
|
+
const refusal = error instanceof QaIntegrationError
|
|
545
|
+
? error
|
|
546
|
+
: new QaIntegrationError("unavailable", "the request could not be answered");
|
|
547
|
+
sendJson(response, refusal.status, {
|
|
548
|
+
error: refusal.message,
|
|
549
|
+
code: refusal.reason,
|
|
550
|
+
});
|
|
551
|
+
}
|
|
552
|
+
function sendMethodNotAllowed(response, allow) {
|
|
553
|
+
const body = Buffer.from(JSON.stringify({ error: "method not allowed", code: "invalid-request" }), "utf8");
|
|
554
|
+
response.writeHead(405, {
|
|
555
|
+
"content-type": "application/json; charset=utf-8",
|
|
556
|
+
"content-length": String(body.length),
|
|
557
|
+
allow,
|
|
558
|
+
"cache-control": "no-store",
|
|
559
|
+
});
|
|
560
|
+
response.end(body);
|
|
561
|
+
}
|
|
562
|
+
function record(value) {
|
|
563
|
+
return typeof value === "object" && value !== null && !Array.isArray(value)
|
|
564
|
+
? value
|
|
565
|
+
: undefined;
|
|
566
|
+
}
|
|
567
|
+
function stringOrNull(value) {
|
|
568
|
+
if (typeof value !== "string")
|
|
569
|
+
return null;
|
|
570
|
+
const trimmed = value.trim();
|
|
571
|
+
return trimmed === "" ? null : trimmed;
|
|
572
|
+
}
|
|
573
|
+
function emptyToNull(value) {
|
|
574
|
+
return value === undefined || value.trim() === "" ? null : value.trim();
|
|
575
|
+
}
|
|
576
|
+
//# sourceMappingURL=http.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.js","sourceRoot":"","sources":["../../src/integration/http.ts"],"names":[],"mappings":"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"}
|