Files
pikasTech-HWLAB/internal/cloud/server-http-utils.ts
T
Codex 6a8e9b3d79 feat(agentrun): inject owner HWLAB_API_KEY into runner transient env
- submitAgentRunChatTurn resolves owner user API key via accessController.store.findActiveDefaultApiKeyForUser
- buildAgentRunRunnerJobInput accepts ownerApiKey; when present, removes HWLAB_DEVICE_POD_API_KEY and adds HWLAB_API_KEY as sensitive
- buildAgentRunTransientEnv no longer emits HWLAB_DEVICE_POD_API_KEY
- codex-stdio child env now reads HWLAB_API_KEY (not HWLAB_DEVICE_POD_API_KEY)
- server-code-agent-http codeAgentAuthEnv looks up user default API key; URL env vars still set unconditionally
- tests: code-agent-session-registry Codex child env carries only device-pod API key now checks HWLAB_API_KEY
- tests: server-agent-chat delegates v0.2 turns removes HWLAB_DEVICE_POD_API_KEY assertion
- 58 pass / 4 pre-existing fail
2026-06-04 15:01:30 +08:00

79 lines
2.2 KiB
TypeScript

const DEFAULT_BODY_LIMIT_BYTES = 1024 * 1024;
export function readBody(request, limitBytes = DEFAULT_BODY_LIMIT_BYTES) {
const limit = Number.isInteger(limitBytes) && limitBytes > 0 ? limitBytes : DEFAULT_BODY_LIMIT_BYTES;
return new Promise((resolve, reject) => {
let body = "";
request.setEncoding("utf8");
request.on("data", (chunk) => {
body += chunk;
if (Buffer.byteLength(body, "utf8") > limit) {
request.destroy(new Error(`request body exceeds ${limit} bytes`));
}
});
request.on("end", () => resolve(body));
request.on("error", reject);
});
}
export function sendJson(response, statusCode, body) {
response.writeHead(statusCode, {
"content-type": "application/json; charset=utf-8",
"cache-control": "no-store"
});
response.end(JSON.stringify(body) + "\n");
}
export function getHeader(request, name) {
const value = request.headers[name.toLowerCase()];
if (Array.isArray(value)) return value[0];
return value;
}
export function firstHeaderValue(request, name) {
return getHeader(request, name);
}
export function truthyFlag(value) {
return /^(?:1|true|yes|on|enabled)$/iu.test(String(value ?? "").trim());
}
export function safeTraceId(value) {
const text = String(value ?? "").trim();
return /^trc_[A-Za-z0-9_.:-]+$/u.test(text) ? text : null;
}
export function safeSessionId(value) {
const text = String(value ?? "").trim();
return /^ses_[A-Za-z0-9_.:-]+$/u.test(text) ? text : null;
}
export function safeConversationId(value) {
const text = String(value ?? "").trim();
return /^cnv_[A-Za-z0-9_.:-]+$/u.test(text) ? text : null;
}
export function safeOpaqueId(value) {
const text = String(value ?? "").trim();
return /^[A-Za-z0-9_.:-]{3,180}$/u.test(text) ? text : null;
}
export function parsePositiveInteger(value, fallback) {
const parsed = Number.parseInt(value ?? "", 10);
return Number.isInteger(parsed) && parsed > 0 ? parsed : fallback;
}
export function positiveInteger(value, fallback) {
const parsed = Number.parseInt(value ?? "", 10);
return Number.isInteger(parsed) && parsed > 0 ? parsed : fallback;
}
export function text(value) {
if (value === null || value === undefined) return "";
return String(value);
}