@knights-eye-chess/ai-analysis 0.0.0-stage → 0.1.0-dev.17
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 +235 -0
- package/LICENSING.md +26 -0
- package/NOTICE +5 -0
- package/NPM-PUBLISHING.md +28 -0
- package/README.md +139 -2
- package/SOURCE-ORIGIN.json +16 -0
- package/THIRD_PARTY_NOTICES.md +18 -0
- package/build.mjs +22 -0
- package/dist/answer-pipeline.test.mjs +375 -0
- package/dist/chunk-PLKNJRPF.js +10662 -0
- package/dist/chunk-XQDZJOYD.js +2515 -0
- package/dist/index.js +146 -0
- package/dist/owner-tests/chess-reasoning-compact-search-preparation.test.mjs +963 -0
- package/dist/owner-tests/mechanism-encoding.test.mjs +529 -0
- package/dist/owner-tests/move-mechanism-facts.test.mjs +396 -0
- package/dist/owner-tests/pipeline-host-preparation.test.mjs +10556 -0
- package/dist/owner-tests/position-preparation.test.mjs +625 -0
- package/dist/owner-tests/preparation-consolidation.test.mjs +1052 -0
- package/dist/owner-tests/prose-reference-admission.test.mjs +1770 -0
- package/dist/owner-tests/score-comparison-notices.test.mjs +240 -0
- package/dist/owner-tests/simple-engine-presentation.test.mjs +233 -0
- package/dist/owner-tests/tool-input-loop-guard.test.mjs +78 -0
- package/dist/research.js +2274 -0
- package/dist/runtime-closure.json +103 -0
- package/dist/shared-runtime-closure.json +39 -0
- package/dist/shared.js +152 -0
- package/dist/types/ai-request-failure.d.ts +14 -0
- package/dist/types/ai-request-limits.d.ts +4 -0
- package/dist/types/ai-routing-diagnostics.d.ts +14 -0
- package/dist/types/chess-reasoning/ablation-adaptive-evidence-loop.d.ts +127 -0
- package/dist/types/chess-reasoning/ablation-adaptive-runtime.d.ts +178 -0
- package/dist/types/chess-reasoning/ablation-direct-synthesis.d.ts +1030 -0
- package/dist/types/chess-reasoning/ablation-evidence-bundle.d.ts +185 -0
- package/dist/types/chess-reasoning/ablation-evidence-capture.d.ts +37 -0
- package/dist/types/chess-reasoning/ablation-lean-direct-runtime.d.ts +193 -0
- package/dist/types/chess-reasoning/ablation-model-facing-evidence.d.ts +38 -0
- package/dist/types/chess-reasoning/ablation-transport-correction.d.ts +13 -0
- package/dist/types/chess-reasoning/ai-sdk-runtime-support.d.ts +93 -0
- package/dist/types/chess-reasoning/answer-host-contracts.d.ts +59 -0
- package/dist/types/chess-reasoning/answer-model-connector.d.ts +68 -0
- package/dist/types/chess-reasoning/answer-pipeline-exports.d.ts +98 -0
- package/dist/types/chess-reasoning/answer-pipeline.d.ts +41 -0
- package/dist/types/chess-reasoning/answer-reference-validation.d.ts +40 -0
- package/dist/types/chess-reasoning/answer-tool-host.d.ts +8 -0
- package/dist/types/chess-reasoning/branch-expansion-policy.d.ts +13 -0
- package/dist/types/chess-reasoning/branch-expansion.d.ts +39 -0
- package/dist/types/chess-reasoning/causal-claim-checks.d.ts +21 -0
- package/dist/types/chess-reasoning/chess-reference-dictionary.d.ts +13 -0
- package/dist/types/chess-reasoning/classification-question-target.d.ts +22 -0
- package/dist/types/chess-reasoning/classification-reassessment.d.ts +31 -0
- package/dist/types/chess-reasoning/compact-search-preparation.d.ts +7 -0
- package/dist/types/chess-reasoning/concept-registry.d.ts +99 -0
- package/dist/types/chess-reasoning/conversation-context.d.ts +12 -0
- package/dist/types/chess-reasoning/engine-search-failure.d.ts +7 -0
- package/dist/types/chess-reasoning/evidence-citation-normalization.d.ts +9 -0
- package/dist/types/chess-reasoning/evidence-licenses.d.ts +57 -0
- package/dist/types/chess-reasoning/evidence-selector-contract.d.ts +5 -0
- package/dist/types/chess-reasoning/existing-analysis-context.d.ts +104 -0
- package/dist/types/chess-reasoning/fact-observation-provider.d.ts +15 -0
- package/dist/types/chess-reasoning/fact-provider.d.ts +111 -0
- package/dist/types/chess-reasoning/fresh-engine-pv-witnesses.d.ts +67 -0
- package/dist/types/chess-reasoning/historical-prose.d.ts +23 -0
- package/dist/types/chess-reasoning/idea-graph.d.ts +34 -0
- package/dist/types/chess-reasoning/initial-search-plan.d.ts +37 -0
- package/dist/types/chess-reasoning/lossless-evidence-sharing.d.ts +18 -0
- package/dist/types/chess-reasoning/matched-comparison.d.ts +10 -0
- package/dist/types/chess-reasoning/material-accounting.d.ts +80 -0
- package/dist/types/chess-reasoning/material-format.d.ts +4 -0
- package/dist/types/chess-reasoning/mechanical-fact-provider.d.ts +33 -0
- package/dist/types/chess-reasoning/mechanical-ray-facts.d.ts +19 -0
- package/dist/types/chess-reasoning/mechanism-presentation.d.ts +9 -0
- package/dist/types/chess-reasoning/move-mechanism-facts.d.ts +45 -0
- package/dist/types/chess-reasoning/native-answer-connector.d.ts +4 -0
- package/dist/types/chess-reasoning/opening-source-contracts.d.ts +54 -0
- package/dist/types/chess-reasoning/opening-source-credits.d.ts +16 -0
- package/dist/types/chess-reasoning/opponent-threat-preparation.d.ts +7 -0
- package/dist/types/chess-reasoning/piece-identities.d.ts +11 -0
- package/dist/types/chess-reasoning/poc-contracts.d.ts +1026 -0
- package/dist/types/chess-reasoning/poc-hypotheses.d.ts +74 -0
- package/dist/types/chess-reasoning/poc-move-witnesses.d.ts +13 -0
- package/dist/types/chess-reasoning/poc-observations.d.ts +23 -0
- package/dist/types/chess-reasoning/poc-piece-refs.d.ts +12 -0
- package/dist/types/chess-reasoning/poc-plan-model.d.ts +45 -0
- package/dist/types/chess-reasoning/poc-semantic-text.d.ts +8 -0
- package/dist/types/chess-reasoning/poc-tools.d.ts +81 -0
- package/dist/types/chess-reasoning/portable-answer-runtime.d.ts +291 -0
- package/dist/types/chess-reasoning/position-analysis-contracts.d.ts +31 -0
- package/dist/types/chess-reasoning/position-analysis-scope.d.ts +3 -0
- package/dist/types/chess-reasoning/preparation-consolidation.d.ts +21 -0
- package/dist/types/chess-reasoning/production-observation-provider.d.ts +16 -0
- package/dist/types/chess-reasoning/question-routing.d.ts +326 -0
- package/dist/types/chess-reasoning/recorded-main-line.d.ts +37 -0
- package/dist/types/chess-reasoning/recorded-position-tools.d.ts +11 -0
- package/dist/types/chess-reasoning/recorded-reference-context.d.ts +13 -0
- package/dist/types/chess-reasoning/recorded-selected-classification.d.ts +36 -0
- package/dist/types/chess-reasoning/reference-limits.d.ts +2 -0
- package/dist/types/chess-reasoning/research-exports.d.ts +197 -0
- package/dist/types/chess-reasoning/saved-score-presentation.d.ts +14 -0
- package/dist/types/chess-reasoning/score-comparison-notices.d.ts +33 -0
- package/dist/types/chess-reasoning/server-simple-policy.d.ts +31 -0
- package/dist/types/chess-reasoning/simple-agent-config.d.ts +73 -0
- package/dist/types/chess-reasoning/simple-board-analysis.d.ts +85 -0
- package/dist/types/chess-reasoning/simple-compact-evidence.d.ts +7 -0
- package/dist/types/chess-reasoning/simple-completion.d.ts +23 -0
- package/dist/types/chess-reasoning/simple-engine-presentation.d.ts +3 -0
- package/dist/types/chess-reasoning/simple-evidence-preparation.d.ts +17 -0
- package/dist/types/chess-reasoning/simple-evidence-view.d.ts +17 -0
- package/dist/types/chess-reasoning/simple-explanation-coverage.d.ts +90 -0
- package/dist/types/chess-reasoning/simple-fact-delivery.d.ts +43 -0
- package/dist/types/chess-reasoning/simple-fallback-premise.d.ts +5 -0
- package/dist/types/chess-reasoning/simple-prose-references.d.ts +108 -0
- package/dist/types/chess-reasoning/simple-runtime-version.d.ts +1 -0
- package/dist/types/chess-reasoning/stable.d.ts +2 -0
- package/dist/types/chess-reasoning/tool-input-loop-guard.d.ts +5 -0
- package/dist/types/chess-reasoning/types.d.ts +180 -0
- package/dist/types/chess-reasoning/visible-support-lines.d.ts +12 -0
- package/dist/types/chess-reasoning/wikibooks-index.d.ts +30 -0
- package/dist/types/chess-reasoning/wikibooks-tool-context.d.ts +10 -0
- package/dist/types/player-perspective.d.ts +16 -0
- package/dist/types/shared-exports.d.ts +22 -0
- package/docs/API.md +82 -0
- package/docs/OWNERSHIP-ADOPTION.md +35 -0
- package/docs/OWNERSHIP-DRIFT.json +55 -0
- package/docs/RESEARCH-API.md +28 -0
- package/licenses/third-party/INVENTORY.json +202 -0
- package/licenses/third-party/ai-7.0.85/LICENSE +13 -0
- package/licenses/third-party/ai-sdk--gateway-4.0.69/LICENSE +13 -0
- package/licenses/third-party/ai-sdk--provider-4.0.9/LICENSE +13 -0
- package/licenses/third-party/ai-sdk--provider-utils-5.0.34/APACHE-2.0.txt +73 -0
- package/licenses/third-party/ai-sdk--provider-utils-5.0.34/src/to-json-schema/zod3-to-json-schema/LICENSE +16 -0
- package/licenses/third-party/chess.js-1.4.0/LICENSE +23 -0
- package/licenses/third-party/eventsource-parser-3.1.1/LICENSE +21 -0
- package/licenses/third-party/json-schema-0.4.0/LICENSE +195 -0
- package/licenses/third-party/standard-schema--spec-1.1.0/LICENSE +21 -0
- package/licenses/third-party/types--json-schema-7.0.15/LICENSE +21 -0
- package/licenses/third-party/types--node-22.19.19/LICENSE +21 -0
- package/licenses/third-party/undici-7.30.0/LICENSE +21 -0
- package/licenses/third-party/undici-7.30.0/lib/web/fetch/LICENSE +21 -0
- package/licenses/third-party/undici-types-6.21.0/LICENSE +21 -0
- package/licenses/third-party/vercel--oidc-3.2.0/LICENSE +202 -0
- package/licenses/third-party/workflow--serde-4.1.0/APACHE-2.0.txt +73 -0
- package/licenses/third-party/workflow--serde-4.1.0/LICENSE.md +3 -0
- package/licenses/third-party/zod-4.6.5/LICENSE +21 -0
- package/npm-release.json +5 -0
- package/package.json +72 -4
- package/scripts/check-release-tooling.mjs +22 -0
- package/scripts/pack.mjs +68 -0
- package/scripts/publish-reviewed.mjs +85 -0
- package/scripts/release-tooling.json +13 -0
- package/scripts/update-dependency.mjs +44 -0
- package/scripts/verify-release.mjs +52 -0
- package/src/ai-request-failure.ts +34 -0
- package/src/ai-request-limits.ts +4 -0
- package/src/ai-routing-diagnostics.ts +33 -0
- package/src/chess-reasoning/ablation-adaptive-evidence-loop.ts +515 -0
- package/src/chess-reasoning/ablation-adaptive-runtime.ts +924 -0
- package/src/chess-reasoning/ablation-direct-synthesis.ts +1128 -0
- package/src/chess-reasoning/ablation-evidence-bundle.ts +726 -0
- package/src/chess-reasoning/ablation-evidence-capture.ts +513 -0
- package/src/chess-reasoning/ablation-lean-direct-runtime.ts +670 -0
- package/src/chess-reasoning/ablation-model-facing-evidence.ts +212 -0
- package/src/chess-reasoning/ablation-transport-correction.ts +106 -0
- package/src/chess-reasoning/ai-sdk-runtime-support.ts +381 -0
- package/src/chess-reasoning/answer-host-contracts.ts +10 -0
- package/src/chess-reasoning/answer-model-connector.ts +83 -0
- package/src/chess-reasoning/answer-pipeline-exports.ts +98 -0
- package/src/chess-reasoning/answer-pipeline.ts +195 -0
- package/src/chess-reasoning/answer-reference-validation.ts +124 -0
- package/src/chess-reasoning/answer-tool-host.ts +10 -0
- package/src/chess-reasoning/branch-expansion-policy.ts +32 -0
- package/src/chess-reasoning/branch-expansion.ts +80 -0
- package/src/chess-reasoning/causal-claim-checks.ts +256 -0
- package/src/chess-reasoning/chess-reference-dictionary.ts +21 -0
- package/src/chess-reasoning/classification-question-target.ts +30 -0
- package/src/chess-reasoning/classification-reassessment.ts +34 -0
- package/src/chess-reasoning/compact-search-preparation.ts +125 -0
- package/src/chess-reasoning/concept-registry.ts +275 -0
- package/src/chess-reasoning/conversation-context.ts +29 -0
- package/src/chess-reasoning/engine-search-failure.ts +11 -0
- package/src/chess-reasoning/evidence-citation-normalization.ts +15 -0
- package/src/chess-reasoning/evidence-licenses.ts +166 -0
- package/src/chess-reasoning/evidence-selector-contract.ts +5 -0
- package/src/chess-reasoning/existing-analysis-context.ts +544 -0
- package/src/chess-reasoning/fact-observation-provider.ts +134 -0
- package/src/chess-reasoning/fact-provider.ts +250 -0
- package/src/chess-reasoning/fresh-engine-pv-witnesses.ts +128 -0
- package/src/chess-reasoning/historical-prose.ts +116 -0
- package/src/chess-reasoning/idea-graph.ts +224 -0
- package/src/chess-reasoning/initial-search-plan.ts +115 -0
- package/src/chess-reasoning/lossless-evidence-sharing.ts +135 -0
- package/src/chess-reasoning/matched-comparison.ts +40 -0
- package/src/chess-reasoning/material-accounting.ts +55 -0
- package/src/chess-reasoning/material-format.ts +47 -0
- package/src/chess-reasoning/mechanical-fact-provider.ts +1602 -0
- package/src/chess-reasoning/mechanical-ray-facts.ts +123 -0
- package/src/chess-reasoning/mechanism-presentation.ts +94 -0
- package/src/chess-reasoning/move-mechanism-facts.ts +185 -0
- package/src/chess-reasoning/native-answer-connector.ts +13 -0
- package/src/chess-reasoning/opening-source-contracts.ts +47 -0
- package/src/chess-reasoning/opening-source-credits.ts +53 -0
- package/src/chess-reasoning/opponent-threat-preparation.ts +98 -0
- package/src/chess-reasoning/piece-identities.ts +159 -0
- package/src/chess-reasoning/poc-contracts.ts +1097 -0
- package/src/chess-reasoning/poc-hypotheses.ts +759 -0
- package/src/chess-reasoning/poc-move-witnesses.ts +170 -0
- package/src/chess-reasoning/poc-observations.ts +611 -0
- package/src/chess-reasoning/poc-piece-refs.ts +62 -0
- package/src/chess-reasoning/poc-plan-model.ts +345 -0
- package/src/chess-reasoning/poc-semantic-text.ts +10 -0
- package/src/chess-reasoning/poc-tools.ts +978 -0
- package/src/chess-reasoning/portable-answer-runtime.ts +684 -0
- package/src/chess-reasoning/position-analysis-contracts.ts +88 -0
- package/src/chess-reasoning/position-analysis-scope.ts +20 -0
- package/src/chess-reasoning/preparation-consolidation.ts +91 -0
- package/src/chess-reasoning/production-observation-provider.ts +41 -0
- package/src/chess-reasoning/question-routing.ts +332 -0
- package/src/chess-reasoning/recorded-main-line.ts +55 -0
- package/src/chess-reasoning/recorded-position-tools.ts +78 -0
- package/src/chess-reasoning/recorded-reference-context.ts +44 -0
- package/src/chess-reasoning/recorded-selected-classification.ts +54 -0
- package/src/chess-reasoning/reference-limits.ts +2 -0
- package/src/chess-reasoning/research-exports.ts +197 -0
- package/src/chess-reasoning/saved-score-presentation.ts +6 -0
- package/src/chess-reasoning/score-comparison-notices.ts +115 -0
- package/src/chess-reasoning/server-simple-policy.ts +75 -0
- package/src/chess-reasoning/simple-agent-config.ts +58 -0
- package/src/chess-reasoning/simple-board-analysis.ts +57 -0
- package/src/chess-reasoning/simple-compact-evidence.ts +79 -0
- package/src/chess-reasoning/simple-completion.ts +37 -0
- package/src/chess-reasoning/simple-engine-presentation.ts +95 -0
- package/src/chess-reasoning/simple-evidence-preparation.ts +32 -0
- package/src/chess-reasoning/simple-evidence-view.ts +69 -0
- package/src/chess-reasoning/simple-explanation-coverage.ts +118 -0
- package/src/chess-reasoning/simple-fact-delivery.ts +52 -0
- package/src/chess-reasoning/simple-fallback-premise.ts +65 -0
- package/src/chess-reasoning/simple-prose-references.ts +528 -0
- package/src/chess-reasoning/simple-runtime-version.ts +2 -0
- package/src/chess-reasoning/stable.ts +18 -0
- package/src/chess-reasoning/tool-input-loop-guard.ts +38 -0
- package/src/chess-reasoning/types.ts +195 -0
- package/src/chess-reasoning/visible-support-lines.ts +44 -0
- package/src/chess-reasoning/wikibooks-index.ts +56 -0
- package/src/chess-reasoning/wikibooks-tool-context.ts +91 -0
- package/src/player-perspective.ts +41 -0
- package/src/shared-exports.ts +23 -0
- package/test/answer-pipeline.test.mjs +375 -0
- package/test/owner/chess-reasoning-compact-search-preparation.test.mjs +111 -0
- package/test/owner/mechanism-encoding.test.mjs +78 -0
- package/test/owner/move-mechanism-facts.test.mjs +105 -0
- package/test/owner/pipeline-host-preparation.test.mjs +115 -0
- package/test/owner/position-preparation.test.mjs +22 -0
- package/test/owner/preparation-consolidation.test.mjs +74 -0
- package/test/owner/prose-reference-admission.test.mjs +26 -0
- package/test/owner/score-comparison-notices.test.mjs +116 -0
- package/test/owner/simple-engine-presentation.test.mjs +50 -0
- package/test/owner/tool-input-loop-guard.test.mjs +25 -0
- package/test-types.mts +23 -0
- package/tsconfig.json +22 -0
|
@@ -0,0 +1,381 @@
|
|
|
1
|
+
import { NoOutputGeneratedError, RetryError } from "ai";
|
|
2
|
+
import { APICallError, EmptyResponseBodyError, NoContentGeneratedError } from "@ai-sdk/provider";
|
|
3
|
+
import type { ModelMessage } from "@ai-sdk/provider-utils";
|
|
4
|
+
import type { ReasoningRuntimeDiagnostic } from "./poc-contracts";
|
|
5
|
+
|
|
6
|
+
export type SanitizedHttpAttempt = {
|
|
7
|
+
status: number | null;
|
|
8
|
+
requestId: string | null;
|
|
9
|
+
latencyMs: number;
|
|
10
|
+
aborted: boolean;
|
|
11
|
+
requestBytes?: number | null;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export type ObservableLlmTraceEvent = {
|
|
15
|
+
stage: string;
|
|
16
|
+
direction: "input" | "output" | "error";
|
|
17
|
+
model: string;
|
|
18
|
+
providerRoute: string;
|
|
19
|
+
reasoningEffort: string;
|
|
20
|
+
payload: Record<string, unknown>;
|
|
21
|
+
excluded: string[];
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export type ObservableLlmTraceSink = (event: ObservableLlmTraceEvent) => void;
|
|
25
|
+
|
|
26
|
+
export const AI_SDK_REASONING_RUNTIME = "ai-sdk-tool-loop-agent/99";
|
|
27
|
+
export const AI_SDK_HYPOTHESIS_RUNTIME = "ai-sdk-hypothesis-provider/31";
|
|
28
|
+
export const AI_SDK_PURPOSE_PROBE_RUNTIME = "ai-sdk-future-purpose-probe/1";
|
|
29
|
+
export const AI_SDK_CRITIC_RUNTIME = "ai-sdk-reasoning-critic/32";
|
|
30
|
+
export const AI_SDK_TERMINAL_REVIEW_RUNTIME = "ai-sdk-terminal-reasoning-review/7";
|
|
31
|
+
export const AI_SDK_RESOLUTION_AUDIT_RUNTIME = "ai-sdk-critic-resolution-audit/4";
|
|
32
|
+
export const AI_SDK_GRAPH_SELECTION_RUNTIME = "ai-sdk-graph-selector/8";
|
|
33
|
+
export const AI_SDK_ANSWER_OBLIGATION_RUNTIME = "ai-sdk-answer-obligation-audit/4";
|
|
34
|
+
export const AI_SDK_GRAPH_PLANNING_RUNTIME = "ai-sdk-answer-obligation-and-graph-selector/3";
|
|
35
|
+
export const AI_SDK_DISCOURSE_RUNTIME = "ai-sdk-discourse-planner/3";
|
|
36
|
+
export const DETERMINISTIC_DISCOURSE_RUNTIME = "harness-discourse-aggregator/3";
|
|
37
|
+
export const AI_SDK_RENDER_RUNTIME = "ai-sdk-checkpoint-render/24";
|
|
38
|
+
export const AI_SDK_REPAIR_RUNTIME = "ai-sdk-semantic-draft-repair/13";
|
|
39
|
+
|
|
40
|
+
const encoder = new TextEncoder();
|
|
41
|
+
|
|
42
|
+
export function bytes(value: unknown): number {
|
|
43
|
+
if (typeof value === "string") return encoder.encode(value).byteLength;
|
|
44
|
+
if (value == null) return 0;
|
|
45
|
+
try {
|
|
46
|
+
return encoder.encode(JSON.stringify(value)).byteLength;
|
|
47
|
+
} catch {
|
|
48
|
+
return 0;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const OBSERVABLE_TRACE_EXCLUSIONS = Object.freeze([
|
|
53
|
+
"provider credentials and authorization headers",
|
|
54
|
+
"raw HTTP request and response bodies",
|
|
55
|
+
"hidden chain-of-thought and provider reasoning details",
|
|
56
|
+
]);
|
|
57
|
+
|
|
58
|
+
function traceSafeValue(value: unknown): unknown {
|
|
59
|
+
if (Array.isArray(value)) return value.map(traceSafeValue);
|
|
60
|
+
if (!value || typeof value !== "object") return value;
|
|
61
|
+
const record = value as Record<string, unknown>;
|
|
62
|
+
if (record.type === "reasoning") {
|
|
63
|
+
return { type: "reasoning", omitted: true, byteCount: bytes(record.text) };
|
|
64
|
+
}
|
|
65
|
+
const result: Record<string, unknown> = {};
|
|
66
|
+
for (const [key, item] of Object.entries(record)) {
|
|
67
|
+
if (key === "providerMetadata" || key === "providerOptions" || key === "reasoning_details" || key === "reasoningDetails") {
|
|
68
|
+
result[`${key}Omitted`] = true;
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
result[key] = traceSafeValue(item);
|
|
72
|
+
}
|
|
73
|
+
return result;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export function observableTraceMessages(messages: readonly ModelMessage[]): unknown[] {
|
|
77
|
+
return messages.map((message) => traceSafeValue(message));
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export function emitObservableTrace(
|
|
81
|
+
sink: ObservableLlmTraceSink | undefined,
|
|
82
|
+
event: Omit<ObservableLlmTraceEvent, "excluded">,
|
|
83
|
+
) {
|
|
84
|
+
if (!sink) return;
|
|
85
|
+
sink({
|
|
86
|
+
...event,
|
|
87
|
+
payload: traceSafeValue(event.payload) as Record<string, unknown>,
|
|
88
|
+
excluded: [...OBSERVABLE_TRACE_EXCLUSIONS],
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export function reasoningMetrics(content: readonly unknown[]) {
|
|
93
|
+
let reasoningPartCount = 0;
|
|
94
|
+
let reasoningBytes = 0;
|
|
95
|
+
let reasoningDetailsPresent = false;
|
|
96
|
+
for (const value of content) {
|
|
97
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) continue;
|
|
98
|
+
const part = value as Record<string, unknown>;
|
|
99
|
+
if (part.type === "reasoning") {
|
|
100
|
+
reasoningPartCount += 1;
|
|
101
|
+
reasoningBytes += bytes(part.text);
|
|
102
|
+
}
|
|
103
|
+
const metadata = (part.providerMetadata || part.providerOptions) as Record<string, unknown> | undefined;
|
|
104
|
+
const openrouter = metadata?.openrouter as Record<string, unknown> | undefined;
|
|
105
|
+
const details = openrouter?.reasoning_details;
|
|
106
|
+
if (Array.isArray(details) && details.length) {
|
|
107
|
+
reasoningDetailsPresent = true;
|
|
108
|
+
reasoningBytes += bytes(details);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
return { reasoningPartCount, reasoningBytes, reasoningDetailsPresent };
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export function numericUsage(value: unknown): number | null {
|
|
115
|
+
if (typeof value === "number") return value;
|
|
116
|
+
if (value && typeof value === "object" && typeof (value as { total?: unknown }).total === "number") {
|
|
117
|
+
return (value as { total: number }).total;
|
|
118
|
+
}
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export function requestId(headers?: Record<string, string>, fallback?: string): string | null {
|
|
123
|
+
return headers?.["request-id"] || headers?.["x-request-id"] || headers?.["openai-request-id"] || fallback || null;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export class ReasoningWorkflowFailure extends Error {
|
|
127
|
+
readonly code: "continuation-coverage-unavailable" | "response-coverage-unavailable";
|
|
128
|
+
|
|
129
|
+
constructor(code: ReasoningWorkflowFailure["code"]) {
|
|
130
|
+
super(code === "continuation-coverage-unavailable"
|
|
131
|
+
? "The required continuation coverage remained unavailable after the bounded forced probe."
|
|
132
|
+
: "The required response coverage remained unavailable after the bounded forced probe.");
|
|
133
|
+
this.name = "ReasoningWorkflowFailure";
|
|
134
|
+
this.code = code;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
function classifyRuntimeError(error: unknown): string {
|
|
139
|
+
if (error instanceof ReasoningWorkflowFailure) return error.code;
|
|
140
|
+
if (RetryError.isInstance(error)) return `retry-${error.reason}`;
|
|
141
|
+
if (APICallError.isInstance(error)) return "provider-api-call";
|
|
142
|
+
if (EmptyResponseBodyError.isInstance(error)) return "empty-response-body";
|
|
143
|
+
if (NoContentGeneratedError.isInstance(error)) return "no-provider-content";
|
|
144
|
+
if (NoOutputGeneratedError.isInstance(error)) return "no-structured-output";
|
|
145
|
+
const name = error instanceof Error ? error.name : "unknown";
|
|
146
|
+
const message = error instanceof Error ? error.message : String(error || "");
|
|
147
|
+
if (/timeout|timed out|wall-time budget/i.test(`${name} ${message}`)) return "timeout";
|
|
148
|
+
if (/schema|validation/i.test(name)) return "structured-output-schema";
|
|
149
|
+
if (/parse|json/i.test(name)) return "structured-output-parse";
|
|
150
|
+
if (/abort/i.test(name)) return "aborted";
|
|
151
|
+
return "runtime-unknown";
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
export function classifyRuntimeFailure(
|
|
155
|
+
error: unknown,
|
|
156
|
+
lastStep?: Pick<ReasoningRuntimeDiagnostic, "finishReason" | "structuredOutputBytes" | "toolCallCount">
|
|
157
|
+
& Partial<Pick<ReasoningRuntimeDiagnostic, "lastHarnessPhase" | "sdkRuntime">>,
|
|
158
|
+
): string {
|
|
159
|
+
if (lastStep?.structuredOutputBytes === 0 && lastStep.toolCallCount === 0 && lastStep.finishReason) {
|
|
160
|
+
const rendering = lastStep.lastHarnessPhase === "draft-render"
|
|
161
|
+
|| lastStep.lastHarnessPhase === "draft-generated"
|
|
162
|
+
|| lastStep.lastHarnessPhase === "draft-repair";
|
|
163
|
+
if (lastStep.finishReason === "length") {
|
|
164
|
+
if (lastStep.lastHarnessPhase === "hypothesis-submission-required") return "hypothesis-submission-truncated";
|
|
165
|
+
if (/reasoning-critic/.test(lastStep.sdkRuntime || "")) return "critic-output-truncated";
|
|
166
|
+
if (/terminal-reasoning-review/.test(lastStep.sdkRuntime || "")) return "terminal-review-output-truncated";
|
|
167
|
+
if (/critic-resolution-audit/.test(lastStep.sdkRuntime || "")) return "critic-resolution-audit-output-truncated";
|
|
168
|
+
return rendering || !lastStep.lastHarnessPhase
|
|
169
|
+
? "structured-output-truncated"
|
|
170
|
+
: "required-tool-call-truncated";
|
|
171
|
+
}
|
|
172
|
+
if (lastStep.lastHarnessPhase === "hypothesis-submission-required") return "hypothesis-submission-missing";
|
|
173
|
+
if (/reasoning-critic/.test(lastStep.sdkRuntime || "")) return "critic-output-missing";
|
|
174
|
+
if (/terminal-reasoning-review/.test(lastStep.sdkRuntime || "")) return "terminal-review-output-missing";
|
|
175
|
+
if (/critic-resolution-audit/.test(lastStep.sdkRuntime || "")) return "critic-resolution-audit-output-missing";
|
|
176
|
+
if (!rendering && lastStep.lastHarnessPhase) return "required-tool-call-missing";
|
|
177
|
+
}
|
|
178
|
+
if (lastStep?.lastHarnessPhase === "hypothesis-submission-required" && (lastStep.structuredOutputBytes || 0) > 0) {
|
|
179
|
+
return "hypothesis-submission-invalid";
|
|
180
|
+
}
|
|
181
|
+
return classifyRuntimeError(error);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
export function deepestError(error: unknown): unknown {
|
|
185
|
+
if (RetryError.isInstance(error)) return error.lastError;
|
|
186
|
+
if (error instanceof Error && "cause" in error && error.cause) return deepestError(error.cause);
|
|
187
|
+
return error;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
export function abortSource(
|
|
191
|
+
signal: AbortSignal | undefined,
|
|
192
|
+
error: unknown,
|
|
193
|
+
): ReasoningRuntimeDiagnostic["abortSource"] {
|
|
194
|
+
const reason = signal?.aborted ? String(signal.reason instanceof Error ? signal.reason.message : signal.reason || "") : "";
|
|
195
|
+
if (/wall-time budget/i.test(reason)) return "wall-time";
|
|
196
|
+
if (signal?.aborted) return "external";
|
|
197
|
+
if (RetryError.isInstance(error) && error.reason === "abort") return "provider";
|
|
198
|
+
return null;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
export type HypothesisRejection = {
|
|
202
|
+
stage: NonNullable<ReasoningRuntimeDiagnostic["hypothesisRejectionStage"]>;
|
|
203
|
+
code: NonNullable<ReasoningRuntimeDiagnostic["hypothesisRejectionCode"]>;
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
export class HypothesisProviderRuntimeFailure extends Error {
|
|
207
|
+
readonly diagnostics: ReasoningRuntimeDiagnostic[];
|
|
208
|
+
readonly usage: { inputTokens: number | null; outputTokens: number | null };
|
|
209
|
+
|
|
210
|
+
constructor(diagnostics: ReasoningRuntimeDiagnostic[], usage: { inputTokens: number | null; outputTokens: number | null }) {
|
|
211
|
+
super("The hypothesis provider failed before returning a valid batch");
|
|
212
|
+
this.name = "HypothesisProviderRuntimeFailure";
|
|
213
|
+
this.diagnostics = diagnostics.map((item) => ({ ...item }));
|
|
214
|
+
this.usage = { ...usage };
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
export class HypothesisHarnessRejection extends Error {
|
|
219
|
+
readonly rejection: HypothesisRejection;
|
|
220
|
+
|
|
221
|
+
constructor(rejection: HypothesisRejection) {
|
|
222
|
+
super("The hypothesis batch failed Harness validation");
|
|
223
|
+
this.name = "HypothesisHarnessRejection";
|
|
224
|
+
this.rejection = rejection;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
export class ReasoningCriticHarnessRejection extends Error {
|
|
229
|
+
readonly code: string;
|
|
230
|
+
|
|
231
|
+
constructor(code: string) {
|
|
232
|
+
super("The independent critic decision failed Harness validation");
|
|
233
|
+
this.name = "ReasoningCriticHarnessRejection";
|
|
234
|
+
this.code = code;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
export class CriticResolutionAuditHarnessRejection extends Error {
|
|
239
|
+
readonly code: string;
|
|
240
|
+
|
|
241
|
+
constructor(code: string) {
|
|
242
|
+
super("The independent critic-resolution audit did not approve every finding resolution");
|
|
243
|
+
this.name = "CriticResolutionAuditHarnessRejection";
|
|
244
|
+
this.code = code;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
export class GraphSelectionHarnessRejection extends Error {
|
|
249
|
+
readonly code: string;
|
|
250
|
+
|
|
251
|
+
constructor(code: string) {
|
|
252
|
+
super("The dedicated graph selection failed Harness validation");
|
|
253
|
+
this.name = "GraphSelectionHarnessRejection";
|
|
254
|
+
this.code = code;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
export class HypothesisReviewHarnessRejection extends Error {
|
|
259
|
+
readonly code: string;
|
|
260
|
+
|
|
261
|
+
constructor(code: string) {
|
|
262
|
+
super("Terminal hypothesis review failed after its bounded correction path");
|
|
263
|
+
this.name = "HypothesisReviewHarnessRejection";
|
|
264
|
+
this.code = code;
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
export class TerminalReviewHarnessRejection extends Error {
|
|
269
|
+
readonly code: string;
|
|
270
|
+
|
|
271
|
+
constructor(code: string) {
|
|
272
|
+
super("The dedicated terminal reasoning review failed Harness validation");
|
|
273
|
+
this.name = "TerminalReviewHarnessRejection";
|
|
274
|
+
this.code = code;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
export function classifyProviderHypothesisRejection(error: unknown): HypothesisRejection {
|
|
279
|
+
const category = classifyRuntimeError(deepestError(error));
|
|
280
|
+
if (category === "structured-output-schema") return { stage: "schema-validation", code: "schema" };
|
|
281
|
+
if (category === "structured-output-parse") return { stage: "provider-structured-output", code: "parse" };
|
|
282
|
+
return { stage: "provider-structured-output", code: "no-output" };
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
export function classifyHypothesisHarnessRejection(error: unknown): HypothesisRejection {
|
|
286
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
287
|
+
if (/empty hypothesis batch/i.test(message)) return { stage: "harness-validation", code: "empty-batch" };
|
|
288
|
+
if (/Unknown concept key/i.test(message)) return { stage: "harness-validation", code: "unsupported-concept" };
|
|
289
|
+
if (/overstates available proof/i.test(message)) return { stage: "harness-validation", code: "proof-overstatement" };
|
|
290
|
+
if (/requires an accepted hypothesis before explain_plan/i.test(message)) return { stage: "harness-validation", code: "used-observation-orphaned" };
|
|
291
|
+
if (/Superseding hypothesis .* preserve lineage/i.test(message)) return { stage: "harness-validation", code: "supersession-lineage" };
|
|
292
|
+
if (/Critic finding .* (?:cites missing, old, or non-grounding new evidence|is not resolved by compatible existing evidence)|criticFindingResolutions\[\d+\] cites unknown evidence/i.test(message)) {
|
|
293
|
+
return { stage: "harness-validation", code: "critic-resolution-evidence" };
|
|
294
|
+
}
|
|
295
|
+
if (/Critic finding .* requires|criticFindingResolutions.*(?:does not match|incompatible|unknown or duplicate finding)|Every critic finding requires/i.test(message)) {
|
|
296
|
+
return { stage: "harness-validation", code: "critic-resolution-incompatibility" };
|
|
297
|
+
}
|
|
298
|
+
if (/\banchor\b|\bowner\b|refinement|parent hypothesis|lineage/i.test(message)) return { stage: "harness-validation", code: "anchor-incompatibility" };
|
|
299
|
+
if (/lacks evidence licensed|evidence licen[cs]e|license ceiling|unlicensed/i.test(message)) return { stage: "harness-validation", code: "evidence-license" };
|
|
300
|
+
if (/observation|evidence|reference|missing or stale/i.test(message)) return { stage: "harness-validation", code: "unknown-reference-or-evidence" };
|
|
301
|
+
if (/is malformed|attributes key|must be (?:a |an )?(?:non-empty|string|array|object)|invalid/i.test(message)) return { stage: "harness-validation", code: "malformed-structure" };
|
|
302
|
+
if (/relation|budget|duplicate|repeats an existing/i.test(message)) return { stage: "harness-validation", code: "relation-or-budget" };
|
|
303
|
+
return { stage: "harness-validation", code: "harness-validation" };
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
export function classifyReasoningCriticHarnessRejection(error: unknown): string {
|
|
307
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
308
|
+
if (/causal evidence audits must cover the exact bounded comparison set/i.test(message)) return "causal-evidence-incomplete";
|
|
309
|
+
if (/root assessments must cover the exact compared roots/i.test(message)) return "causal-root-incomplete";
|
|
310
|
+
if (/continuation activity audits must cover the exact indexed evidence set/i.test(message)) return "continuation-activity-evidence-incomplete";
|
|
311
|
+
if (/continuation activity root assessments must cover the exact indexed roots/i.test(message)) return "continuation-activity-root-incomplete";
|
|
312
|
+
if (/continuation activity assessments must cover every exact indexed piece route/i.test(message)) return "continuation-activity-incomplete";
|
|
313
|
+
if (/continuation activity (?:contact assessments must cover every exact indexed contact|root requires every indexed contact assessment)/i.test(message)) return "continuation-activity-contact-incomplete";
|
|
314
|
+
if (/(?:causal evidence audit|continuation activity (?:audit|root assessment|assessment)|continuation contact assessment) (?:is )?malformed/i.test(message)) return "malformed-audit-item";
|
|
315
|
+
if (/(?:causal evidence audit|root assessment|continuation activity assessment|continuation contact assessment|hypothesisFindings\[\d+\]) references an unknown hypothesis/i.test(message)) return "unknown-hypothesis-or-reference";
|
|
316
|
+
if (/priority omission audits must cover the exact high-salience exact observation set/i.test(message)) return "missing-link-contract";
|
|
317
|
+
if (/material priority omission gap(?: without an existing hypothesis)? requires|material priority omission gap against an existing hypothesis requires/i.test(message)) return "missing-link-contract";
|
|
318
|
+
if (/(?:material causal comparison|material continuation activity) gap requires a missing-link finding and one bounded revision/i.test(message)) return "missing-link-contract";
|
|
319
|
+
if (/complete current set|complete audit|unknown or unpresented observation/i.test(message)) return "incomplete-audit";
|
|
320
|
+
if (/must not contain duplicates/i.test(message)) return "duplicate-id";
|
|
321
|
+
if (/contains duplicate or unknown hypotheses/i.test(message)) return "unknown-or-duplicate-representation";
|
|
322
|
+
if (/Only a reopened non-used observation may name existing representing hypotheses/i.test(message)) return "nonused-retain-has-representation";
|
|
323
|
+
if (/Reopened non-used observation .* may name only source-linked hypotheses/i.test(message)) return "nonused-representation-not-source-linked";
|
|
324
|
+
if (/Retained used observation .* must retain its representing hypotheses/i.test(message)) return "retain-used-missing-representation";
|
|
325
|
+
if (/requires a missingLink/i.test(message)) return "reopen-missing-link";
|
|
326
|
+
if (/cannot claim a missingLink/i.test(message)) return "retain-has-missing-link";
|
|
327
|
+
if (/must record that omission weakens/i.test(message)) return "retain-used-impact";
|
|
328
|
+
if (/must preserve the conclusion/i.test(message)) return "retain-nonused-impact";
|
|
329
|
+
if (/must weaken or leave uncertainty/i.test(message)) return "reopen-preserves-impact";
|
|
330
|
+
if (/Uncertain omission impact must reopen/i.test(message)) return "retain-uncertain-impact";
|
|
331
|
+
if (/representedHypothesisIds must be a string array/i.test(message)) return "invalid-representation-set";
|
|
332
|
+
if (/\.omissionImpact is invalid/i.test(message)) return "invalid-omission-impact";
|
|
333
|
+
if (/\.action is invalid/i.test(message)) return "invalid-action";
|
|
334
|
+
if (/novelHypothesisNeeded must be boolean/i.test(message)) return "invalid-novelty-decision";
|
|
335
|
+
if (/is malformed/i.test(message)) return "malformed-audit-item";
|
|
336
|
+
if (/omission|preserve the conclusion|missingLink|reopen/i.test(message)) return "omission-contract";
|
|
337
|
+
if (/terminal observation review|already been completed/i.test(message)) return "stale-phase";
|
|
338
|
+
if (/requires at least one recorded hypothesis|must be a string array|must be a non-empty string/i.test(message)) return "malformed-audit";
|
|
339
|
+
return "challenge-validation";
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
export function classifyGraphSelectionHarnessRejection(error: unknown): string {
|
|
343
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
344
|
+
if (/requires an accepted hypothesis before explain_plan/i.test(message)) return "used-observation-orphaned";
|
|
345
|
+
if (/must include every hypothesis marked used/i.test(message)) return "missing-required";
|
|
346
|
+
if (/Unknown hypothesis selected/i.test(message)) return "unknown-hypothesis";
|
|
347
|
+
if (/Only accepted hypotheses/i.test(message)) return "unaccepted-hypothesis";
|
|
348
|
+
if (/Unknown hypothesis relation/i.test(message)) return "unknown-relation";
|
|
349
|
+
if (/relation .* leaves the selected hypothesis set/i.test(message)) return "relation-closure";
|
|
350
|
+
if (/Selected endpoint .* is not in hypothesisIds|Selected entity .* does not exist/i.test(message)) return "endpoint-selection";
|
|
351
|
+
if (/No connected (?:plan subgraph|primary explanation chain)|disconnected optional component/i.test(message)) return "disconnected";
|
|
352
|
+
if (/lost required realization anchor/i.test(message)) return "entity-anchor-missing";
|
|
353
|
+
if (/has missing parent/i.test(message)) return "parent-missing";
|
|
354
|
+
if (/contradicts parent owner/i.test(message)) return "parent-owner-conflict";
|
|
355
|
+
if (/changes parent concepts/i.test(message)) return "parent-concept-change";
|
|
356
|
+
if (/drops parent realization anchor/i.test(message)) return "parent-anchor-dropped";
|
|
357
|
+
if (/anchor|parent|refinement|owner/i.test(message)) return "realization";
|
|
358
|
+
if (/hypotheses\.relations.*evidenceIds must contain|Relation hypothesis .* requires compatible evidence/i.test(message)) return "relation-evidence-missing";
|
|
359
|
+
if (/overstates available proof/i.test(message)) return "proof-overstatement";
|
|
360
|
+
if (/missing, stale, or incompatible evidence|cites missing evidence/i.test(message)) return "evidence-compatibility";
|
|
361
|
+
if (/evidence|proof/i.test(message)) return "evidence";
|
|
362
|
+
if (/budget|maxEntities|at least two|invalid number of values/i.test(message)) return "selection-budget";
|
|
363
|
+
return "validation";
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
export function classifyGraphSelectionRuntimeFailure(
|
|
367
|
+
error: unknown,
|
|
368
|
+
lastStep?: Pick<ReasoningRuntimeDiagnostic, "finishReason" | "structuredOutputBytes" | "toolCallCount">,
|
|
369
|
+
): string {
|
|
370
|
+
if (lastStep?.structuredOutputBytes === 0 && lastStep.toolCallCount === 0) {
|
|
371
|
+
if (lastStep.finishReason === "length") return "graph-selection-output-truncated";
|
|
372
|
+
if (lastStep.finishReason) return "graph-selection-output-missing";
|
|
373
|
+
}
|
|
374
|
+
const category = classifyRuntimeError(error);
|
|
375
|
+
if (category === "no-structured-output" || category === "no-provider-content" || category === "empty-response-body") {
|
|
376
|
+
return "graph-selection-output-missing";
|
|
377
|
+
}
|
|
378
|
+
if (category === "structured-output-schema") return "graph-selection-output-schema";
|
|
379
|
+
if (category === "structured-output-parse") return "graph-selection-output-parse";
|
|
380
|
+
return category;
|
|
381
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ReasoningPositionContext } from './poc-contracts';
|
|
2
|
+
import type { QuestionRoutingDecision } from './question-routing';
|
|
3
|
+
import type { WikibooksContextResult, WikibooksTarget } from './opening-source-contracts';
|
|
4
|
+
export type RecordedMoveAnalysis = { version: string; fenBefore: string; fenAfter: string; moveUci: string; engine: string; actualDepth: number; requestedDepth: number; classifierVersion: number; classification: string; beforeCp: number | null; afterCp: number | null; lossCp: number | null; mateBefore: number | null; mateAfter: number | null };
|
|
5
|
+
export type RecordedMainLine = { selectedAtStart?: boolean; startFen: string; moves: Array<{ uci: string; san: string; edgeId: string; analysis?: RecordedMoveAnalysis }>; selectedIndex: number; totalPlies: number; truncated: boolean; };
|
|
6
|
+
|
|
7
|
+
export type AnswerSelection = {deliveryId:string;selectionKey:string;edgeId:string;context:ReasoningPositionContext;existingAnalysis:unknown};
|
|
8
|
+
export type AnswerRoutingPreparation = {decision:QuestionRoutingDecision;mainLine?:RecordedMainLine;omitSelectedContext:boolean;elapsedMs:number;question:string;selectionKey:string;deliveryId:string};
|
|
9
|
+
export type AnswerHistoryPort = {getMainLine?:(selected:AnswerSelection,signal?:AbortSignal)=>Promise<RecordedMainLine>;refreshContext?:(selected:AnswerSelection,signal?:AbortSignal)=>Promise<{existingAnalysis:unknown}>};
|
|
10
|
+
export type AnswerOpeningSession = {initial:(signal?:AbortSignal)=>Promise<WikibooksContextResult>;gameReview:(line:RecordedMainLine,signal?:AbortSignal)=>Promise<WikibooksContextResult>;lookup:(targets:WikibooksTarget[],signal?:AbortSignal,root?:ReasoningPositionContext)=>Promise<WikibooksContextResult>};
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import type { ModelMessage, ToolSet, JSONValue, jsonSchema, ToolModelMessage } from 'ai';
|
|
2
|
+
import { asSchema } from '@ai-sdk/provider-utils';
|
|
3
|
+
|
|
4
|
+
/** A single resumable model turn. No HTTP, account, storage or agent executor assumption. */
|
|
5
|
+
export type AnswerTurnRequest = {
|
|
6
|
+
system?: string;
|
|
7
|
+
messages: ModelMessage[];
|
|
8
|
+
tools: Array<{name:string; description?:string; inputSchema: Parameters<typeof jsonSchema>[0]}>;
|
|
9
|
+
toolChoice: 'auto' | 'none';
|
|
10
|
+
maxOutputTokens: number;
|
|
11
|
+
signal?: AbortSignal;
|
|
12
|
+
effort: string;
|
|
13
|
+
};
|
|
14
|
+
export type AnswerToolRequest = {toolCallId:string; toolName:string; input:Record<string,unknown>};
|
|
15
|
+
export type AnswerTurnResult = {
|
|
16
|
+
text: string;
|
|
17
|
+
toolCalls: AnswerToolRequest[];
|
|
18
|
+
finishReason: string;
|
|
19
|
+
usage: {inputTokens?:number; outputTokens?:number};
|
|
20
|
+
/** Provider continuation messages; opaque provider metadata must be preserved in memory. */
|
|
21
|
+
response: {messages:ModelMessage[]; headers?:Record<string,string>};
|
|
22
|
+
providerMetadata?: unknown;
|
|
23
|
+
};
|
|
24
|
+
export interface AnswerModelConnector {
|
|
25
|
+
readonly kind: 'model-turn';
|
|
26
|
+
readonly capabilities?: {toolRequests:boolean;toolFreeComposition:boolean;opaqueContinuation:boolean;outputTokenLimit:'enforced'|'requested'|'unavailable';usageReporting:'reported'|'optional'|'unavailable'};
|
|
27
|
+
/** Connectors propose calls; only the pipeline executes them. */
|
|
28
|
+
invoke(request: AnswerTurnRequest): Promise<AnswerTurnResult>;
|
|
29
|
+
}
|
|
30
|
+
export type ExecutableTurn = {
|
|
31
|
+
system?:string; messages:ModelMessage[]; tools?:ToolSet; toolChoice:'auto'|'none';
|
|
32
|
+
maxOutputTokens:number; maxRetries:0; abortSignal?:AbortSignal;
|
|
33
|
+
providerOptions: {openai:{store:boolean;include:string[];reasoningEffort:string}};
|
|
34
|
+
/** Fixed-evidence evaluation only: validate but discard unsolicited known calls. Never advertised or dispatched. */
|
|
35
|
+
fixedEvidenceDiscardTools?: ToolSet;
|
|
36
|
+
};
|
|
37
|
+
/** Interface admission ceiling, separate from the inherited search-batch budget. */
|
|
38
|
+
export const MAX_ANSWER_TOOL_REQUESTS_PER_TURN = 32;
|
|
39
|
+
function validateTurnResult(result:AnswerTurnResult, tools:ToolSet, previous:ModelMessage[]) {
|
|
40
|
+
if(!result || typeof result.text!=='string' || typeof result.finishReason!=='string'
|
|
41
|
+
|| !Array.isArray(result.toolCalls) || result.toolCalls.length>MAX_ANSWER_TOOL_REQUESTS_PER_TURN
|
|
42
|
+
|| !result.response || !Array.isArray(result.response.messages)
|
|
43
|
+
|| !result.usage || typeof result.usage!=='object')throw Error('invalid-model-turn-result');
|
|
44
|
+
const ids=new Set(previous.flatMap(message=>message.role==='assistant' && Array.isArray(message.content)
|
|
45
|
+
? message.content.flatMap(part=>part.type==='tool-call'?[part.toolCallId]:[]) : []));
|
|
46
|
+
// Validate the entire proposed batch before the first call has side effects.
|
|
47
|
+
for(const call of result.toolCalls) {
|
|
48
|
+
if(!call || typeof call.toolCallId!=='string' || !call.toolCallId.trim() || call.toolCallId.length>256 || ids.has(call.toolCallId))throw Error('invalid-model-tool-id');
|
|
49
|
+
ids.add(call.toolCallId);
|
|
50
|
+
if(typeof call.toolName!=='string' || !Object.hasOwn(tools,call.toolName) || !tools[call.toolName]?.execute)throw Error('unknown-model-tool');
|
|
51
|
+
if(!call.input || typeof call.input!=='object' || Array.isArray(call.input)
|
|
52
|
+
|| ![Object.prototype,null].includes(Object.getPrototypeOf(call.input)))throw Error('invalid-model-tool-input');
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
export async function invokeAnswerTurn(connector:AnswerModelConnector, request:ExecutableTurn):Promise<AnswerTurnResult> {
|
|
56
|
+
request.abortSignal?.throwIfAborted();
|
|
57
|
+
if(connector.kind!=='model-turn' || typeof connector.invoke!=='function')throw Error('invalid-model-connector');
|
|
58
|
+
const tools = request.tools ?? {};
|
|
59
|
+
const result = await connector.invoke({system:request.system,messages:request.messages,
|
|
60
|
+
tools:await Promise.all(Object.entries(tools).map(async ([name,definition])=>({name,description:typeof definition.description === "string" ? definition.description : undefined,inputSchema:await asSchema(definition.inputSchema).jsonSchema}))),
|
|
61
|
+
toolChoice:request.toolChoice,maxOutputTokens:request.maxOutputTokens,signal:request.abortSignal,effort:request.providerOptions.openai.reasoningEffort});
|
|
62
|
+
request.abortSignal?.throwIfAborted();
|
|
63
|
+
validateTurnResult(result,request.fixedEvidenceDiscardTools ?? tools,request.messages);
|
|
64
|
+
if(request.toolChoice==='none' && result.toolCalls.length) {
|
|
65
|
+
// The frozen-evidence study must remain one call with zero new evidence.
|
|
66
|
+
// Retaining the validated proposal lets its caller report no-final-answer,
|
|
67
|
+
// never treating the unsolicited tool request as a completed answer.
|
|
68
|
+
if(request.fixedEvidenceDiscardTools)return result;
|
|
69
|
+
throw Error('tools-disabled-during-composition');
|
|
70
|
+
}
|
|
71
|
+
const messages = [...result.response.messages];
|
|
72
|
+
const toolResults: ToolModelMessage["content"] = [];
|
|
73
|
+
for(const call of result.toolCalls) {
|
|
74
|
+
request.abortSignal?.throwIfAborted();
|
|
75
|
+
const definition=tools[call.toolName];
|
|
76
|
+
if(!definition?.execute)throw Error('unknown-model-tool');
|
|
77
|
+
const output=await definition.execute(call.input,{toolCallId:call.toolCallId,messages:request.messages,abortSignal:request.abortSignal,context:undefined});
|
|
78
|
+
request.abortSignal?.throwIfAborted();
|
|
79
|
+
toolResults.push({type:'tool-result',toolCallId:call.toolCallId,toolName:call.toolName,output:{type:'json',value:JSON.parse(JSON.stringify(output)) as JSONValue}});
|
|
80
|
+
}
|
|
81
|
+
if(toolResults.length)messages.push({role:'tool',content:toolResults});
|
|
82
|
+
return {...result,response:{...result.response,messages}};
|
|
83
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
export {runAnswerPipeline} from './answer-pipeline';
|
|
2
|
+
export type {AnswerPipelineResult} from './answer-pipeline';
|
|
3
|
+
export {runPreparedAnswer,SIMPLE_BUDGETS,SIMPLE_MODELS,SIMPLE_EXPANDED_BUDGETS,SIMPLE_RECOVERY_BUDGETS,validateSimpleToolInput} from './portable-answer-runtime';
|
|
4
|
+
export type {SimpleModelOption} from './portable-answer-runtime';
|
|
5
|
+
export type {AnswerModelConnector,AnswerTurnRequest,AnswerTurnResult,AnswerToolRequest} from './answer-model-connector';
|
|
6
|
+
export {createNativeAnswerConnector} from './native-answer-connector';
|
|
7
|
+
export {simpleSystemPolicy,simpleToolDescription} from './server-simple-policy';
|
|
8
|
+
export {createPocToolHost} from './answer-tool-host';
|
|
9
|
+
export type {AnswerToolHostOptions} from './answer-tool-host';
|
|
10
|
+
export type {PositionAnalysisProvider,PositionAnalysisRequest,PositionAnalysisResult,PositionAnalysisLine,PositionAnalysisSegment,CompatiblePositionAnalysisProvider,LegacyPositionAnalysisProvider,LegacyPositionAnalysisResult,LegacyPositionAnalysisLine} from './position-analysis-contracts';
|
|
11
|
+
export {toPositionAnalysis,toLegacyPositionAnalysis,toPositionAnalysisProvider,toLegacyPositionAnalysisProvider} from './position-analysis-contracts';
|
|
12
|
+
export {createProductionObservationProvider} from './production-observation-provider';
|
|
13
|
+
export {validateReasoningPositionContext,reasoningContextHash,createContextEvidence,createQueryContract,DEFAULT_REASONING_RUN_CONTROLS,REASONING_POC_VERSION} from './poc-contracts';
|
|
14
|
+
export type {ReasoningPositionContext,ReasoningToolSet,ObservationProvider,ReasoningEvidenceRecord} from './poc-contracts';
|
|
15
|
+
export {captureAblationOriginalEvidenceBundle} from './ablation-evidence-capture';
|
|
16
|
+
export {createDefaultSaliencePolicy} from './poc-observations';
|
|
17
|
+
export {planInitialSearches} from './initial-search-plan';
|
|
18
|
+
export {QUESTION_ROUTING_VERSION} from './question-routing';
|
|
19
|
+
export type {QuestionRoutingDecision} from './question-routing';
|
|
20
|
+
export type {RecordedMainLine} from './answer-host-contracts';
|
|
21
|
+
export type { AnswerRoutingPreparation, AnswerSelection, AnswerHistoryPort, AnswerOpeningSession } from './answer-host-contracts';
|
|
22
|
+
export {MAX_ANSWER_TOOL_REQUESTS_PER_TURN} from './answer-model-connector';
|
|
23
|
+
export type {ReasoningToolResult} from './poc-contracts';
|
|
24
|
+
export type {ReasoningObservation} from './poc-contracts';
|
|
25
|
+
export type {ReasoningObservationSet} from './poc-contracts';
|
|
26
|
+
export type {ReasoningRankedObservationSet} from './poc-contracts';
|
|
27
|
+
export type {ReasoningToolDescriptor} from './poc-contracts';
|
|
28
|
+
export type {ReasoningToolName} from './poc-contracts';
|
|
29
|
+
export type {ModelRuntime} from './poc-contracts';
|
|
30
|
+
export type {QueryContract} from './poc-contracts';
|
|
31
|
+
export type {ReasoningRunControls} from './poc-contracts';
|
|
32
|
+
export type {ReasoningToolExecutionContext} from './poc-contracts';
|
|
33
|
+
export type {ReasoningProviderObservationSet} from './poc-contracts';
|
|
34
|
+
export {SIMPLE_MODEL_CATALOGUE} from './simple-agent-config';
|
|
35
|
+
export {simpleEffortsForModel} from './simple-agent-config';
|
|
36
|
+
export type {SimpleAgentConfig} from './simple-agent-config';
|
|
37
|
+
export {validateSimpleAgentConfig} from './simple-agent-config';
|
|
38
|
+
export type {SimpleModelId} from './simple-agent-config';
|
|
39
|
+
export type {SimpleEffort} from './simple-agent-config';
|
|
40
|
+
export {hasSharedEvidence} from './lossless-evidence-sharing';
|
|
41
|
+
export {expandSharedEvidence} from './lossless-evidence-sharing';
|
|
42
|
+
export {EVIDENCE_SHARING_VERSION} from './lossless-evidence-sharing';
|
|
43
|
+
export {shareEvidence} from './lossless-evidence-sharing';
|
|
44
|
+
export {shareEvidenceMessages} from './lossless-evidence-sharing';
|
|
45
|
+
export {PRODUCTION_OBSERVATION_PROVIDER_VERSION} from './production-observation-provider';
|
|
46
|
+
export type {SimpleToken} from './simple-prose-references';
|
|
47
|
+
export {simpleProseReferences} from './simple-prose-references';
|
|
48
|
+
export type {SimpleReference} from './simple-prose-references';
|
|
49
|
+
export type {SimplePosition} from './simple-prose-references';
|
|
50
|
+
export {safeSimpleSourceLink} from './simple-prose-references';
|
|
51
|
+
export type {FreshEnginePvWitness} from './simple-prose-references';
|
|
52
|
+
export {SIMPLE_REFERENCE_VERSION} from './simple-prose-references';
|
|
53
|
+
export {decorateSimpleVariations} from './simple-prose-references';
|
|
54
|
+
export {repairFrozenCitationLabels} from './simple-prose-references';
|
|
55
|
+
export {stripSimpleMarkdownFences} from './simple-prose-references';
|
|
56
|
+
export {stripSimpleCitationLinks} from './simple-prose-references';
|
|
57
|
+
export type {AuthoredReferenceResult} from './simple-prose-references';
|
|
58
|
+
export type {SimpleProseReferenceOptions} from './simple-prose-references';
|
|
59
|
+
export type {SimpleReferenceGapCounts} from './simple-prose-references';
|
|
60
|
+
export type {RecordedMoveAnalysis} from './answer-host-contracts';
|
|
61
|
+
export {classifyQuestionRoutingAnswers} from './question-routing';
|
|
62
|
+
export {classifyReviewSubject} from './question-routing';
|
|
63
|
+
export {makeQuestionRoutingRequest} from './question-routing';
|
|
64
|
+
export {parseQuestionRoutingAnswers} from './question-routing';
|
|
65
|
+
export {hasMoveClassificationQuestion} from './question-routing';
|
|
66
|
+
export {moveSectionScope} from './question-routing';
|
|
67
|
+
export {REVIEW_SUBJECTS} from './question-routing';
|
|
68
|
+
export {openingTitle} from './wikibooks-index';
|
|
69
|
+
export {positionKey} from './wikibooks-index';
|
|
70
|
+
export {replayWikibooksTitle} from './wikibooks-index';
|
|
71
|
+
export {selectIndexedOpening} from './wikibooks-index';
|
|
72
|
+
export type {WikibooksIndex} from './wikibooks-index';
|
|
73
|
+
export type {IndexedSelection} from './wikibooks-index';
|
|
74
|
+
export {decodeWikibooksIndex} from './wikibooks-index';
|
|
75
|
+
export type {WikibooksTarget} from './opening-source-contracts';
|
|
76
|
+
export type {WikibooksPage} from './opening-source-contracts';
|
|
77
|
+
export type {WikibooksContextResult} from './opening-source-contracts';
|
|
78
|
+
export type {WikibooksPlan} from './opening-source-contracts';
|
|
79
|
+
export {MAX_INTERACTIVE_LINE_PLIES} from './reference-limits';
|
|
80
|
+
export {parseOpeningSourceCredits} from './opening-source-credits';
|
|
81
|
+
export type {OpeningSourceCredit} from './opening-source-credits';
|
|
82
|
+
export {openingSourceLinks} from './opening-source-credits';
|
|
83
|
+
export {OPENING_SOURCE_LICENSE_URL} from './opening-source-credits';
|
|
84
|
+
export {openingSourcesInMessages} from './opening-source-credits';
|
|
85
|
+
export type {RecordedReferenceLine} from './historical-prose';
|
|
86
|
+
export {admitFreshEnginePvWitnesses} from './fresh-engine-pv-witnesses';
|
|
87
|
+
export type {FreshEnginePvAdmissionAudit} from './fresh-engine-pv-witnesses';
|
|
88
|
+
export {MAX_FRESH_ENGINE_WITNESS_ACQUISITIONS} from './fresh-engine-pv-witnesses';
|
|
89
|
+
export {SIMPLE_TOOL_AGENT_VERSION} from './simple-runtime-version';
|
|
90
|
+
export {recordedMainLineResult} from './recorded-main-line';
|
|
91
|
+
export {classificationTargetAtSelection} from './classification-question-target';
|
|
92
|
+
export {scopePositionAnalysis} from './position-analysis-scope';
|
|
93
|
+
export {priorConversationMessages} from './conversation-context';
|
|
94
|
+
export type {PriorConversationMessage} from './conversation-context';
|
|
95
|
+
export {emitObservableTrace} from './ai-sdk-runtime-support';
|
|
96
|
+
export type {ObservableLlmTraceSink,ObservableLlmTraceEvent,SanitizedHttpAttempt} from './ai-sdk-runtime-support';
|
|
97
|
+
export {selectSimpleModel} from './simple-agent-config';
|
|
98
|
+
export {recordedNavigation} from './recorded-reference-context';
|