@apifuse/provider-sdk 2.2.0-beta.40 → 2.2.0-beta.42

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.
Files changed (47) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/bin/apifuse-check.ts +61 -0
  3. package/bin/apifuse-migrate-shape.ts +202 -0
  4. package/bin/apifuse-submit-check.ts +1773 -222
  5. package/dist/cli/commands.d.ts +1 -1
  6. package/dist/cli/commands.js +8 -0
  7. package/dist/cli/create.js +6 -0
  8. package/dist/cli/migrate-operation-shape.d.ts +44 -0
  9. package/dist/cli/migrate-operation-shape.js +113 -0
  10. package/dist/cli/migrate-provider-shape.d.ts +52 -0
  11. package/dist/cli/migrate-provider-shape.js +578 -0
  12. package/dist/cli/templates/provider/provider.json.tpl +6 -0
  13. package/dist/contract.js +1 -0
  14. package/dist/define.js +22 -1
  15. package/dist/error-observability.d.ts +7 -0
  16. package/dist/error-observability.js +61 -0
  17. package/dist/errors.d.ts +15 -0
  18. package/dist/fixture-sanitization.js +13 -3
  19. package/dist/index.d.ts +1 -1
  20. package/dist/provider.d.ts +1 -1
  21. package/dist/runtime/executor.js +11 -1
  22. package/dist/server/error-observability.d.ts +1 -0
  23. package/dist/server/error-observability.js +1 -0
  24. package/dist/server/index.d.ts +2 -1
  25. package/dist/server/self-test.js +3 -0
  26. package/dist/server/serve-implementation.d.ts +12 -0
  27. package/dist/server/serve-implementation.js +174 -66
  28. package/dist/types.d.ts +18 -10
  29. package/package.json +1 -1
  30. package/src/cli/commands.ts +10 -0
  31. package/src/cli/create.ts +6 -0
  32. package/src/cli/migrate-operation-shape.ts +184 -0
  33. package/src/cli/migrate-provider-shape.ts +772 -0
  34. package/src/cli/templates/provider/provider.json.tpl +6 -0
  35. package/src/contract.ts +1 -0
  36. package/src/define.ts +33 -1
  37. package/src/error-observability.ts +64 -0
  38. package/src/errors.ts +16 -0
  39. package/src/fixture-sanitization.ts +19 -3
  40. package/src/index.ts +1 -0
  41. package/src/provider.ts +1 -0
  42. package/src/runtime/executor.ts +13 -1
  43. package/src/server/error-observability.ts +1 -0
  44. package/src/server/index.ts +2 -0
  45. package/src/server/self-test.ts +5 -0
  46. package/src/server/serve-implementation.ts +214 -84
  47. package/src/types.ts +38 -27
@@ -0,0 +1,61 @@
1
+ import { isProviderError } from "./errors.js";
2
+ const PROVIDER_OBSERVABILITY_TOKEN_PATTERN = /^[A-Za-z0-9_.-]{1,64}$/;
3
+ const PROVIDER_OBSERVABILITY_FINGERPRINT_PATTERN = /^[A-Fa-f0-9]{12}$/;
4
+ const MAX_PROVIDER_OBSERVABILITY_MESSAGE_LENGTH = 10_000_000;
5
+ /**
6
+ * Extracts only own data properties from branded provider errors. In
7
+ * particular, descriptor reads reject options/observability accessors without
8
+ * invoking provider-controlled getters.
9
+ */
10
+ export function safeProviderErrorObservability(error) {
11
+ if (!isProviderError(error))
12
+ return undefined;
13
+ let candidate;
14
+ let reason;
15
+ let fingerprint;
16
+ let messageLength;
17
+ try {
18
+ const optionsDescriptor = Object.getOwnPropertyDescriptor(error, "options");
19
+ if (optionsDescriptor === undefined || !Object.hasOwn(optionsDescriptor, "value")) {
20
+ return undefined;
21
+ }
22
+ const options = optionsDescriptor.value;
23
+ if (options === null || typeof options !== "object" || Array.isArray(options)) {
24
+ return undefined;
25
+ }
26
+ const observabilityDescriptor = Object.getOwnPropertyDescriptor(options, "observability");
27
+ if (observabilityDescriptor === undefined || !Object.hasOwn(observabilityDescriptor, "value")) {
28
+ return undefined;
29
+ }
30
+ candidate = observabilityDescriptor.value;
31
+ if (candidate === null || typeof candidate !== "object" || Array.isArray(candidate)) {
32
+ return undefined;
33
+ }
34
+ const ownValue = (key) => {
35
+ const descriptor = Object.getOwnPropertyDescriptor(candidate, key);
36
+ return descriptor && Object.hasOwn(descriptor, "value") ? descriptor.value : undefined;
37
+ };
38
+ reason = ownValue("reason");
39
+ fingerprint = ownValue("fingerprint");
40
+ messageLength = ownValue("messageLength");
41
+ }
42
+ catch {
43
+ return undefined;
44
+ }
45
+ const safe = {
46
+ ...(typeof reason === "string" && PROVIDER_OBSERVABILITY_TOKEN_PATTERN.test(reason)
47
+ ? { reason }
48
+ : {}),
49
+ ...(typeof fingerprint === "string" &&
50
+ PROVIDER_OBSERVABILITY_FINGERPRINT_PATTERN.test(fingerprint)
51
+ ? { fingerprint }
52
+ : {}),
53
+ ...(typeof messageLength === "number" &&
54
+ Number.isInteger(messageLength) &&
55
+ messageLength >= 0 &&
56
+ messageLength <= MAX_PROVIDER_OBSERVABILITY_MESSAGE_LENGTH
57
+ ? { messageLength }
58
+ : {}),
59
+ };
60
+ return Object.keys(safe).length > 0 ? safe : undefined;
61
+ }
package/dist/errors.d.ts CHANGED
@@ -7,6 +7,21 @@ export type ProviderErrorOptions = {
7
7
  cause?: Error;
8
8
  category?: ProviderErrorCategory;
9
9
  retryable?: boolean;
10
+ /** Provider-authored, bounded metadata safe for operational logs and error headers. */
11
+ observability?: ProviderErrorObservability;
12
+ };
13
+ /**
14
+ * Provider-authored error diagnostics whose runtime values are validated before emission.
15
+ * Classification tokens such as `reason` are source literals, not runtime user input or
16
+ * credentials. The gateway removes the observability header from tenant responses.
17
+ */
18
+ export type ProviderErrorObservability = {
19
+ /** A 1-64 character `[A-Za-z0-9_.-]` classification token, for example `LOGIN_COMPLETE_FAILED`. */
20
+ reason?: string;
21
+ /** A provider-computed 12-hex-character fingerprint of private diagnostic input. */
22
+ fingerprint?: string;
23
+ /** The non-negative length of the private diagnostic input, capped at 10,000,000. */
24
+ messageLength?: number;
10
25
  };
11
26
  export declare class ProviderError extends Error {
12
27
  readonly options?: ProviderErrorOptions | undefined;
@@ -2,6 +2,9 @@ export const REDACTED_FIXTURE_VALUE = "[REDACTED]";
2
2
  const OPAQUE_TOKEN = /^[A-Za-z0-9_+/=.:~-]+$/;
3
3
  const OPAQUE_TOKEN_RUN = /[A-Za-z0-9_+/=.:~-]{24,}/g;
4
4
  const URL_RUN = /https?:\/\/[^\s"'<>]+/gi;
5
+ const EMAIL_ADDRESS_RUN = /\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}\b/gi;
6
+ const DIAGNOSTIC_URL_SENTINEL_DELIMITER = String.fromCodePoint(0);
7
+ const DIAGNOSTIC_URL_SENTINEL_RUN = new RegExp(`${DIAGNOSTIC_URL_SENTINEL_DELIMITER}APIFUSE_URL(\\d+)${DIAGNOSTIC_URL_SENTINEL_DELIMITER}`, "g");
5
8
  const PEM_PRIVATE_KEY = /-----BEGIN (?:[A-Z0-9 ]+ )?PRIVATE KEY-----[\s\S]*?-----END (?:[A-Z0-9 ]+ )?PRIVATE KEY-----/g;
6
9
  /** Matches credential field names without treating benign prefixes such as `author` as `auth`. */
7
10
  export function isSensitiveFixtureKey(key) {
@@ -125,9 +128,15 @@ export function requestPathForFixture(value) {
125
128
  }
126
129
  /** Scrubs secrets and terminal/log control characters before diagnostic text is emitted. */
127
130
  export function sanitizeDiagnosticText(value) {
128
- let sanitized = value
129
- .replace(URL_RUN, (url) => sanitizeUrlForLogs(url))
130
- .replace(/\bBearer\s+[A-Za-z0-9._~+/=-]+/gi, `Bearer ${REDACTED_FIXTURE_VALUE}`);
131
+ const retainedUrls = [];
132
+ // Remove attacker-controlled NUL delimiters before introducing internal URL sentinels.
133
+ let sanitized = encodeDiagnosticControls(value)
134
+ .replace(URL_RUN, (url) => {
135
+ const index = retainedUrls.push(sanitizeUrlForLogs(url)) - 1;
136
+ return `${DIAGNOSTIC_URL_SENTINEL_DELIMITER}APIFUSE_URL${index}${DIAGNOSTIC_URL_SENTINEL_DELIMITER}`;
137
+ })
138
+ .replace(/\bBearer\s+[A-Za-z0-9._~+/=-]+/gi, `Bearer ${REDACTED_FIXTURE_VALUE}`)
139
+ .replace(EMAIL_ADDRESS_RUN, REDACTED_FIXTURE_VALUE);
131
140
  sanitized = redactSensitiveAssignments(sanitized);
132
141
  sanitized = sanitized.replace(OPAQUE_TOKEN_RUN, (candidate, offset, source) => {
133
142
  if (/^(?:request|trace|correlation)[-_]?id[:=]/i.test(candidate))
@@ -137,6 +146,7 @@ export function sanitizeDiagnosticText(value) {
137
146
  return candidate;
138
147
  return isSensitiveFixtureValue(candidate) ? REDACTED_FIXTURE_VALUE : candidate;
139
148
  });
149
+ sanitized = sanitized.replace(DIAGNOSTIC_URL_SENTINEL_RUN, (_match, index) => retainedUrls[Number(index)] ?? REDACTED_FIXTURE_VALUE);
140
150
  return encodeDiagnosticControls(sanitized);
141
151
  }
142
152
  function redactSensitiveAssignments(value) {
package/dist/index.d.ts CHANGED
@@ -42,7 +42,7 @@ export { APIFUSE__OCR__API_KEY_ENV, APIFUSE__OCR__BACKEND_ENV, APIFUSE__OCR__BAS
42
42
  export { APIFUSE__STT__BACKEND_ENV, APIFUSE__STT__CLOUDFLARE_API_TOKEN_ENV, APIFUSE__STT__MODEL_ENV, createSttClientFromEnv, createUnsupportedSttClient, extractVerificationCode, resolveSttPrompt, } from "./runtime/stt.js";
43
43
  export { type CreateTraceContextOptions, createTraceContext, type Span, type TraceContext, } from "./runtime/trace.js";
44
44
  export { APIFUSE_DESCRIPTION_KEY_META_KEY, APIFUSE_REDACTION_MARKER, APIFUSE_SENSITIVE_KIND_META_KEY, APIFUSE_SENSITIVE_META_KEY, collectSensitivePaths, describeKey, field, fields, isSensitiveSchema, redactPayload, type SensitiveFieldKind, type SensitiveFieldOptions, type SensitivePath, sensitive, z, } from "./schema.js";
45
- export { createServerApp, createServerAppAsync, ERROR_OBSERVABILITY_HEADER, type ServeOptions, serve, } from "./server/serve.js";
45
+ export { createServerApp, createServerAppAsync, ERROR_OBSERVABILITY_HEADER, type ProviderErrorCauseFrame, type ServeOptions, serve, } from "./server/serve.js";
46
46
  export { getStealthProfile, listStealthProfiles } from "./stealth/profiles.js";
47
47
  export * from "./stream.js";
48
48
  export type { ApiFuseResponse, AuthConfig, AuthContext, AuthFlowDefinition, AuthFlowInputHandler, AuthFlowStartHandler, AuthMode, AuthTurn, Bcp47Locale, BrowserCookie, BrowserEngine, BrowserOptions, BrowserResourceBody, BrowserResourceDecision, BrowserResourceMethod, BrowserResourcePolicy, BrowserResourceRequest, BrowserResourceRoute, ChallengeSolution, ConnectionMode, ContextDeclaration, CookieJar, ContextScratchpad, CredentialContext, CredentialDeclaration, E164PhoneNumber, EnvContext, FlowContext, FlowContextStore, HealthCheckAssertionContext, HealthCheckCase, HealthCheckCaseResult, HealthCheckSuite, HealthCheckUnsupported, HealthJourneyDefinition, HealthJourneyEventContext, HealthJourneyGatewayContext, HealthJourneyJournalContext, HealthJourneyManualTriggerPolicy, HealthJourneyRunContext, HealthJourneyRunResult, HealthJourneySchedule, HealthScheduleRandomization, HealthJourneySmsContext, HealthJourneyStep, HttpClient, HttpMethod, HttpRedirectFailureReason, HttpRedirectPolicy, HttpRedirectPolicyMode, HttpResponse, HttpRetryOptions, HttpRetrySummary, HttpStreamResponse, IanaTimeZone, InferSchemaOutput, Iso3166Alpha2CountryCode, Iso4217CurrencyCode, Iso8601Duration, NativeContext, NativeNetworkClient, NativeNetworkCloseReason, NativeNetworkConnection, NativeNetworkConnectInput, NativeNetworkConnectOptions, NativeNetworkDynamicGrantOptions, NativeNetworkEgressGrant, NativeProviderConfig, NativeProxyDrainHandler, NativeProxyEgressInfo, NativeProxyExpiringEvent, NativeProxyExpiringReason, NativeTcpDynamicEgressRule, NativeTcpEgressGrant, NativeTcpEgressRule, NativeTcpPortRange, NativeTcpTlsMode, NativeTlsConnectOptions, OcrCaptchaCandidate, OcrCaptchaOptions, OcrCaptchaResult, OcrContext, OcrImageInput, OcrRecognizeRequest, OcrResult, OcrWarning, OperationAnnotations, OperationApprovalPolicy, OperationContractMetadata, OperationDefinition, OperationDeprecationMetadata, OperationDocMeta, OperationErrorCode, ProviderErrorStatus, OperationHandlerResult, OperationInputExample, OperationLifecycle, OperationObservabilityConfig, OperationObservabilitySensitiveConfig, OperationRelationships, OperationRiskClass, OperationSensitivePath, OperationToolRouterMetadata, OperationTransport, OperationTransportKind, ProbeInterval, ProviderAccessConfig, ProviderAccessVisibility, ProviderCache, ProviderCacheGetOrSetOptions, ProviderCacheKeyOptions, ProviderCacheLookupMeta, ProviderCacheResponseMeta, ProviderCacheResult, ProviderChoiceBindingOptions, ProviderChoiceConsumeMode, ProviderChoiceConsumeResult, ProviderChoiceContext, ProviderChoiceExplicitParseResult, ProviderChoiceIssueOptions, ProviderChoiceParseOptions, ProviderChallenge, ProviderChallengeKind, ProviderContext, ProviderContextFor, ProviderDefinition, ProviderDeploymentOverrides, ProviderFileRef, ProviderFilesContext, ProviderHealthMonitorConfig, ProviderHealthProbeConfig, ProviderLocale, ProviderLocaleKey, ProviderLocaleKeyInput, ProviderLogoProfile, ProviderLogoSource, ProviderMeta, ProviderOcrConfig, ProviderProxyConfig, ProviderProxyMode, ProviderProxyPolicy, ProxiedOAuthConfig, ProviderProxyProvider, ProviderProxySessionAffinity, ProviderPublicConnectionMode, ProviderPublicProfile, ProviderReviewed, ProviderResolvedFile, ProviderResolverConfig, ProviderResolverVendor, ProviderRuntimeState, ProviderSecretDeclaration, ProviderStateDurationString, ProviderStateNamespace, ProviderStreamEvent, ProviderSttConfig, ProviderSttMode, ProviderSupportLevel, RequestOptions, RedirectRunReason, ResolverContext, Rfc3339Instant, SchemaLike, SmsOrigin, SmsOtpExtractionPattern, SmsOtpMatcherDefinition, SseMessage, StandardSchemaV1, StateCasResult, StateNamespaceOptions, StateNamespaceScope, StateValue, StateWriteOptions, StealthClient, StealthCookieStore, StealthCookieStoreV1, StealthFetchOptions, StealthPlatform, StealthProfile, StealthRedirectHop, StealthRedirectRunOptions, StealthRedirectRunResult, StealthResponse, StealthSession, StealthSessionCookies, SttAudioInput, SttContext, SttPromptPolicy, SttSegment, SttTranscribeMode, SttTranscribeRequest, SttTranscript, SttUnsupportedOptionPolicy, SttUsage, SttVerificationCodeOptions, SttWarning, TraceConfig, TraceSpan, VerificationCodeCandidate, VerificationCodeCandidateSource, VerificationCodeExtractionResult, } from "./types.js";
@@ -7,7 +7,7 @@ export type { ProviderBuilder, ProviderContextOf, ProviderDeclaration, } from ".
7
7
  export type { JsonPrimitive, JsonValue } from "./contract-json.js";
8
8
  export { AssertionExpressionSchema, AssertionPredicateSchema, AssertStepSchema, BoundedJsonPathSchema, CandidateBlockSchema, CandidatePolicySchema, CredentialRefDeclarationSchema, defineHealthScenario, HealthScenarioSchema, HealthStepSchema, ExtractStepSchema, FindFirstSchema, GuardStepSchema, JournalPolicySchema, JsonTemplateSchema, ManualTriggerPolicySchema, OperandSchema, OperationStepSchema, QuantifierSchema, ReferenceSchema, RetryPolicySchema, SafeRegexSchema, ScopedAssertionExpressionSchema, ScopedAssertionPredicateSchema, ScopedItemReferenceSchema, ScopedOperandSchema, StepReferenceSchema, RelativeDateNodeSchema, ValueTypeSchema, } from "./health-scenario.js";
9
9
  export type { AssertionExpression, AssertionPredicate, AttemptReference, AssertResult, AssertStep, BoundedJsonPath, CandidateBlock, CandidatePolicy, CandidateReference, CredentialReference, CredentialRefDeclaration, EstablishedConnectionReference, ExtractStep, FindFirst, GuardAttribution, GuardReasonCode, GuardResult, GuardStep, HealthScenario, HealthStep, JsonTemplate, JournalPolicy, ManualTriggerPolicy, NonEmpty, OperationResult, OperationStep, Operand, Quantifier, ReferenceNode, Reference, RelativeDateNode, RetryPolicy, SafeRegex, ScopedAssertionExpression, ScopedAssertionPredicate, ScopedItemReference, ScopedOperand, StepBase, StepReference, ExtractResult, ValueType, } from "./health-scenario.js";
10
- export { AuthError, HttpRedirectError, isProviderError, isSessionExpiredError, isTransportError, ProviderError, SessionExpiredError, TransportError, ValidationError, } from "./errors.js";
10
+ export { AuthError, HttpRedirectError, isProviderError, isSessionExpiredError, isTransportError, ProviderError, type ProviderErrorObservability, SessionExpiredError, TransportError, ValidationError, } from "./errors.js";
11
11
  export { getProviderLocalePath, providerLocaleKey, qualifyProviderLocaleKey, } from "./i18n/index.js";
12
12
  export { type CreateProviderChoiceContextOptions, createProviderChoiceContext, createTestProviderChoiceContext, PROVIDER_RUNTIME_CHOICE_TOKEN_MASTER_SECRET_ENV, } from "./runtime/choice.js";
13
13
  export { APIFUSE_DESCRIPTION_KEY_META_KEY, APIFUSE_REDACTION_MARKER, APIFUSE_SENSITIVE_KIND_META_KEY, APIFUSE_SENSITIVE_META_KEY, collectSensitivePaths, describeKey, field, fields, isSensitiveSchema, redactPayload, type SensitiveFieldKind, type SensitiveFieldOptions, type SensitivePath, sensitive, z, } from "./schema.js";
@@ -1,3 +1,4 @@
1
+ import { safeProviderErrorObservability } from "../error-observability.js";
1
2
  import { isSessionExpiredError, isValidationError, ProviderError, SessionExpiredError, ValidationError, } from "../errors.js";
2
3
  import { z } from "zod";
3
4
  import { parseSchema } from "../schema.js";
@@ -6,6 +7,12 @@ export function isStreamingOperation(provider, operationId) {
6
7
  const kind = provider.operations[operationId]?.transport?.kind ?? "json";
7
8
  return kind !== "json";
8
9
  }
10
+ function preservedSessionExpiredOptions(error) {
11
+ const observability = safeProviderErrorObservability(error);
12
+ return observability
13
+ ? { observability, retryable: true }
14
+ : { retryable: true };
15
+ }
9
16
  /**
10
17
  * Execute a provider operation by calling its handler.
11
18
  *
@@ -55,7 +62,10 @@ export async function executeOperation(provider, operationId, ctx, input, _optio
55
62
  // executor's, which `instanceof` would miss — dropping the retryable
56
63
  // upgrade and stranding an operation that opted into auth refresh.
57
64
  if (isSessionExpiredError(error) && operation.retryOnAuthRefresh) {
58
- throw new SessionExpiredError(error.message, { retryable: true });
65
+ // Preserve provider-authored safe metadata while forcing the retry signal.
66
+ // `cause` intentionally remains dropped, matching the pre-existing
67
+ // reconstruction semantics.
68
+ throw new SessionExpiredError(error.message, preservedSessionExpiredOptions(error));
59
69
  }
60
70
  throw error;
61
71
  }
@@ -0,0 +1 @@
1
+ export { safeProviderErrorObservability } from "../error-observability.js";
@@ -0,0 +1 @@
1
+ export { safeProviderErrorObservability } from "../error-observability.js";
@@ -1,6 +1,7 @@
1
1
  export type { ProxyCacheStatus, ProxyProtocol, ProxyUserAgentSource, ProxyVendorName, SmartproxyAllocatorBodyClass, } from "../config/loader.js";
2
2
  export type { ProxyTelemetryLogPayload, ProxyTelemetryResolvedPayload, ProxyTelemetryUnresolvedPayload, } from "../runtime/proxy-telemetry.js";
3
- export { createServerApp, createServerAppAsync, ERROR_OBSERVABILITY_HEADER, type ErrorObservabilityDetails, type ProviderServerCloseOptions, type ProviderServerHandle, type ProviderServerLogEvent, type ProviderServerLogger, type ProviderServerOperationExecutor, type ProviderServerOperationExecutorInput, type ProviderServerOptions, type ProviderServerStatefulForwardEnvelope, type ServeOptions, serve, } from "./serve.js";
3
+ export { createServerApp, createServerAppAsync, ERROR_OBSERVABILITY_HEADER, type ErrorObservabilityDetails, type ProviderServerCloseOptions, type ProviderServerHandle, type ProviderErrorCauseFrame, type ProviderServerLogEvent, type ProviderServerLogger, type ProviderServerOperationExecutor, type ProviderServerOperationExecutorInput, type ProviderServerOptions, type ProviderServerStatefulForwardEnvelope, type ServeOptions, serve, } from "./serve.js";
4
+ export type { ProviderErrorObservability } from "../errors.js";
4
5
  export { computeSelfTestPlanDigest, createSelfTestApp, createSelfTestAuthFlowInvoke, createSelfTestInvoke, DEFAULT_SELF_TEST_REQUEST_BUDGET_MS, isSelfTestReadOnlyOperation, PROVIDER_RUNTIME_SELF_TEST_REQUEST_BUDGET_MS_ENV, resolveSelfTestPort, SELF_TEST_AUTH_FLOW_MULTI_TURN_SKIP_REASON, SELF_TEST_AUTH_FLOW_REJECTED_SKIP_REASON, SELF_TEST_HEALTHZ_PATH, SELF_TEST_PATH, SELF_TEST_SCHEMA_VERSION, type SelfTestAppOptions, type SelfTestAuthFlowInvoke, type SelfTestAuthFlowRoute, type SelfTestCaseResult, type SelfTestCaseStatus, type SelfTestOperationInvoke, type SelfTestRequest, SelfTestRequestSchema, type SelfTestResponse, } from "./self-test.js";
5
6
  export { type InputDateTokenCalendar, resolveHealthCheckInputDateTokens, } from "./self-test-input-tokens.js";
6
7
  export { collectSelfTestSensitiveValues, redactSelfTestText, SELF_TEST_MAX_TEXT_LENGTH, SELF_TEST_REDACTED_PLACEHOLDER, } from "./self-test-redaction.js";
@@ -792,6 +792,9 @@ async function executeSelfTestCase(execution, operationId, suite, healthCase, ca
792
792
  const { startedAtMs, finish } = caseScope;
793
793
  try {
794
794
  return await runWithCaseTimeout(async () => {
795
+ if (healthCase.assertions === undefined) {
796
+ throw new Error(`Self-test cannot execute declarative health-check case "${healthCase.name}"; run its scenario through the health monitor.`);
797
+ }
795
798
  const resolvedInput = resolveHealthCheckInputDateTokens(healthCase.input);
796
799
  const preparedInput = healthCase.prepareInput
797
800
  ? await healthCase.prepareInput({
@@ -1,5 +1,6 @@
1
1
  import { Hono } from "hono";
2
2
  import { z } from "zod";
3
+ import { type ProviderErrorObservability } from "../errors.js";
3
4
  import { type ProviderErrorCategory } from "../observability.js";
4
5
  import { type ProxyTelemetryLogPayload } from "../runtime/proxy-telemetry.js";
5
6
  import type { OcrContext, ProviderContext, ProviderDefinition, ProviderRuntimeState, ResolverContext, SttContext } from "../types.js";
@@ -12,6 +13,7 @@ export type ErrorObservabilityDetails = {
12
13
  taxonomyVersion: string;
13
14
  retryable: boolean;
14
15
  upstreamStatus?: number;
16
+ providerObservability?: ProviderErrorObservability;
15
17
  };
16
18
  export declare const ProviderServerStatefulForwardEnvelopeSchema: z.ZodObject<{
17
19
  requestId: z.ZodString;
@@ -92,6 +94,8 @@ export type ProviderServerLogEvent = (ProviderServerLogEventBase & {
92
94
  errorCategory?: ProviderErrorCategory;
93
95
  taxonomyVersion?: string;
94
96
  retryable?: boolean;
97
+ providerObservability?: ProviderErrorObservability;
98
+ causeChain?: ProviderErrorCauseFrame[];
95
99
  signal?: "unregistered_provider_error_code";
96
100
  signalFix?: string;
97
101
  issues?: Array<{
@@ -180,6 +184,14 @@ export type ProviderServerOptions = {
180
184
  readonly timeoutMs?: number;
181
185
  };
182
186
  };
187
+ export type ProviderErrorCauseFrame = {
188
+ errorClass: string;
189
+ code?: string;
190
+ message: string;
191
+ messageLength: number;
192
+ messageFingerprint: string;
193
+ providerObservability?: ProviderErrorObservability;
194
+ };
183
195
  /**
184
196
  * Primary, cross-runtime app factory. Declared capability ESM is preloaded
185
197
  * asynchronously, so this path works on Bun and every supported Node release.