UNPKG

@sema-agent/core

Version:

Stateless, task-oriented AI agent core

187 lines (186 loc) • 8.02 kB
import { MODEL_OUTPUT_INVALID_CAUSES } from "../../internal/llm.js"; import { isProviderEchoShape } from "../../brain/errors.js"; import { isProviderCondition, isProviderConditionSource } from "../../brain/provider-dialect.js"; import { admittedRequestRoute } from "../../brain/request-route.js"; import { readMember } from "../thrown-value.js"; import { egressText } from "../untrusted-egress.js"; import { isSensitiveName, looksLikeCredentialValue } from "../secret-env.js"; import { isSensitiveRecordKey } from "../credential-vocabulary.js"; export function providerVerdictOf(final) { const condition = readMember(final, "providerCondition"); const source = readMember(final, "providerConditionSource"); if (!isProviderCondition(condition) || !isProviderConditionSource(source)) return {}; const resetAtMs = readMember(final, "providerResetAtMs"); return { providerCondition: condition, providerConditionSource: source, ...(typeof resetAtMs === "number" && Number.isFinite(resetAtMs) ? { providerResetAtMs: resetAtMs } : {}) }; } export function requestRouteOfMessage(final) { return admittedRequestRoute(readMember(final, "apiErrorRoute")); } const MODEL_OUTPUT_INVALID_CAUSE_SET = new Set(MODEL_OUTPUT_INVALID_CAUSES); const countOf = (v) => (typeof v === "number" && Number.isInteger(v) && v >= 0 ? v : undefined); export function modelOutputInvalidOfMessage(final) { const account = readMember(final, "modelOutputInvalid"); const cause = readMember(account, "cause"); if (!MODEL_OUTPUT_INVALID_CAUSE_SET.has(cause)) return undefined; const limit = cause === "truncated" ? readMember(account, "outputLimit") : undefined; const capStop = readMember(limit, "capStop"); if (typeof capStop !== "boolean") return { cause: cause }; const outputTokens = countOf(readMember(limit, "outputTokens")); const capTokens = countOf(readMember(limit, "capTokens")); const outputLimit = { capStop, ...(outputTokens !== undefined ? { outputTokens } : {}), ...(capTokens !== undefined ? { capTokens } : {}) }; return { cause: cause, outputLimit }; } const CODED_DETAIL_DEPTH = 4; const CODED_DETAIL_ENTRIES = 64; const CODED_DETAIL_STRING = 4_096; const CODED_DETAIL_VALUES = 256; const CODED_DETAIL_CHARS = 16_384; const REDACTED = "[redacted]"; const INDEX_KEY_RE = /^(?:0|[1-9][0-9]*)$/; function carriesCredential(text) { return looksLikeCredentialValue(text) || egressText("same-principal", text) !== text; } const NAME_CHARS = 128; function namesCredential(name) { return name.length <= NAME_CHARS && (isSensitiveName(name) || isSensitiveRecordKey(name)); } const NAME_POSITION_KEYS = new Set(["name", "key", "header", "field"]); const VALUE_POSITION_KEYS = new Set(["value", "val"]); function charge(budget, chars) { if (budget.values >= CODED_DETAIL_VALUES || budget.chars + chars > CODED_DETAIL_CHARS) return false; budget.values++; budget.chars += chars; return true; } function leafOf(keyContext, read, depth, budget) { if (keyContext !== undefined && namesCredential(keyContext)) return charge(budget, REDACTED.length) ? REDACTED : undefined; const value = read(); if (value === null || typeof value === "boolean" || (typeof value === "number" && Number.isFinite(value))) return charge(budget, 0) ? value : undefined; if (typeof value === "string") { if (value.length > CODED_DETAIL_STRING) return undefined; const shown = carriesCredential(value) ? REDACTED : value; return charge(budget, shown.length) ? shown : undefined; } if (typeof value !== "object" || depth >= CODED_DETAIL_DEPTH) return undefined; let isArray; try { if (ArrayBuffer.isView(value)) return undefined; isArray = Array.isArray(value); } catch { return undefined; } if (!isArray) return recordOf(value, depth, budget); const length = readMember(value, "length"); if (typeof length !== "number" || !Number.isInteger(length) || length < 0 || length > CODED_DETAIL_ENTRIES) return undefined; if (!charge(budget, 0)) return undefined; const items = []; const handed = Array.from({ length }, (_, i) => readMember(value, String(i))); for (let i = 0; i < length; i++) { const before = handed[i - 1]; const item = leafOf(typeof before === "string" && namesCredential(before) ? before : keyContext, () => handed[i], depth + 1, budget); if (item === undefined) return undefined; items.push(item); } return items; } function pairedNameOf(value, keys, read) { if (!keys.some((k) => VALUE_POSITION_KEYS.has(k.toLowerCase()))) return undefined; let named; for (const key of keys) { if (!NAME_POSITION_KEYS.has(key.toLowerCase())) continue; const name = readMember(value, key); read.set(key, name); if (named === undefined && typeof name === "string" && namesCredential(name)) named = name; } return named; } function recordOf(value, depth, budget) { let keys; try { keys = Object.keys(value); } catch { return undefined; } if (keys.length > CODED_DETAIL_ENTRIES || (keys.length > 0 && keys.every((k) => INDEX_KEY_RE.test(k))) || !charge(budget, 0)) return undefined; const nameMembers = new Map(); const paired = pairedNameOf(value, keys, nameMembers); const out = {}; for (const key of keys) { if (!isProviderEchoShape(key) || carriesCredential(key) || budget.chars + key.length > CODED_DETAIL_CHARS) continue; const charsBefore = budget.chars; budget.chars += key.length; const context = paired !== undefined && VALUE_POSITION_KEYS.has(key.toLowerCase()) ? paired : key; const admitted = leafOf(context, () => (nameMembers.has(key) ? nameMembers.get(key) : readMember(value, key)), depth + 1, budget); if (admitted === undefined) budget.chars = charsBefore; else Object.defineProperty(out, key, { value: admitted, enumerable: true, writable: true, configurable: true }); } return Object.keys(out).length > 0 ? out : undefined; } function detailRecordOf(detail) { try { if (detail === null || typeof detail !== "object" || Array.isArray(detail) || ArrayBuffer.isView(detail)) return undefined; } catch { return undefined; } return recordOf(detail, 0, { values: 0, chars: 0 }); } function codedFailureDetailOf(link) { const detail = detailRecordOf(readMember(link, "detail")); return detail === undefined ? undefined : { kind: "coded", detail }; } export function errorCodeOf(err) { return codedLinkOf(err)?.code; } function codedLinkOf(err) { let cur = err; let fallback; for (let depth = 0; cur !== null && cur !== undefined && typeof cur === "object" && depth < 8; depth++) { const code = readMember(cur, "code"); if (typeof code === "string" && code) { if (code !== "unknown") { return { code, link: cur }; } fallback ??= { code, link: cur }; } cur = readMember(cur, "cause"); } return fallback; } export function thrownFailureOf(err, text) { const message = egressText("same-principal", text); const coded = codedLinkOf(err); if (coded === undefined) return { message }; const detail = codedFailureDetailOf(coded.link); return { code: coded.code, message, ...(detail !== undefined ? { detail } : {}) }; } export function completedTerminalOf(final) { const finishReasonUnknown = readMember(final, "finishReasonUnknown"); return typeof finishReasonUnknown === "string" && isProviderEchoShape(finishReasonUnknown) ? { kind: "completed", detail: { kind: "finish_reason_unknown", finishReasonUnknown } } : { kind: "completed" }; }