@apifuse/provider-sdk 2.2.0-beta.5 → 2.2.0-beta.51
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/AUTHORING.md +537 -33
- package/CHANGELOG.md +205 -1
- package/README.md +83 -22
- package/SUBMISSION.md +2 -2
- package/bin/apifuse-check.ts +165 -11
- package/bin/apifuse-dev.ts +57 -13
- package/bin/apifuse-migrate-operation-declaration.ts +55 -0
- package/bin/apifuse-migrate-shape.ts +202 -0
- package/bin/apifuse-pack-check.ts +22 -2
- package/bin/apifuse-pack-smoke.ts +57 -2
- package/bin/apifuse-pack-types.ts +357 -38
- package/bin/apifuse-perf.ts +14 -13
- package/bin/apifuse-record.ts +709 -72
- package/bin/apifuse-submit-check.ts +2344 -324
- package/bin/apifuse-sync-assets.ts +117 -0
- package/bin/submit-check-delimited-text.ts +50 -0
- package/dist/auth-turn/index.d.ts +3 -3
- package/dist/auth-turn/index.js +1 -1
- package/dist/auth.d.ts +14 -0
- package/dist/auth.js +67 -0
- package/dist/ceremonies/index.d.ts +16 -0
- package/dist/ceremonies/index.js +141 -36
- package/dist/cli/commands.d.ts +1 -1
- package/dist/cli/commands.js +27 -0
- package/dist/cli/create.d.ts +4 -1
- package/dist/cli/create.js +42 -37
- package/dist/cli/migrate-operation-declaration.d.ts +59 -0
- package/dist/cli/migrate-operation-declaration.js +1249 -0
- package/dist/cli/migrate-operation-shape.d.ts +44 -0
- package/dist/cli/migrate-operation-shape.js +113 -0
- package/dist/cli/migrate-provider-shape.d.ts +52 -0
- package/dist/cli/migrate-provider-shape.js +578 -0
- package/dist/cli/prompt-assets.d.ts +80 -0
- package/dist/cli/prompt-assets.js +743 -0
- package/dist/cli/templates/provider/AGENTS.md.tpl +17 -8
- package/dist/cli/templates/provider/Dockerfile.tpl +1 -1
- package/dist/cli/templates/provider/README.md.tpl +5 -5
- package/dist/cli/templates/provider/index.ts.tpl +6 -3
- package/dist/cli/templates/provider/operations/ping.ts.tpl +4 -1
- package/dist/cli/templates/provider/provider.json.tpl +6 -0
- package/dist/config/loader.d.ts +179 -16
- package/dist/config/loader.js +435 -127
- package/dist/contract-serialization.js +4 -8
- package/dist/contract-types.d.ts +12 -5
- package/dist/contract.js +24 -10
- package/dist/declaration-validation.d.ts +33 -0
- package/dist/declaration-validation.js +266 -0
- package/dist/define.d.ts +66 -29
- package/dist/define.js +778 -69
- package/dist/dev.d.ts +3 -0
- package/dist/dev.js +1 -1
- package/dist/engine.d.ts +78 -0
- package/dist/engine.js +133 -0
- package/dist/error-observability.d.ts +7 -0
- package/dist/error-observability.js +61 -0
- package/dist/error-resolution.d.ts +4 -0
- package/dist/error-resolution.js +122 -0
- package/dist/errors.d.ts +33 -0
- package/dist/errors.js +40 -0
- package/dist/fixture-sanitization.d.ts +28 -0
- package/dist/fixture-sanitization.js +227 -0
- package/dist/health-scenario.d.ts +1842 -0
- package/dist/health-scenario.js +624 -0
- package/dist/index.d.ts +21 -10
- package/dist/index.js +12 -7
- package/dist/lint.d.ts +23 -11
- package/dist/lint.js +572 -69
- package/dist/native-address.d.ts +43 -0
- package/dist/native-address.js +281 -0
- package/dist/native-egress-policy.d.ts +31 -0
- package/dist/native-egress-policy.js +288 -0
- package/dist/observability.d.ts +5 -2
- package/dist/observability.js +48 -1
- package/dist/provider.d.ts +10 -2
- package/dist/provider.js +4 -1
- package/dist/runtime/auth-flow.d.ts +5 -1
- package/dist/runtime/auth-flow.js +6 -0
- package/dist/runtime/browser.d.ts +1 -0
- package/dist/runtime/browser.js +492 -49
- package/dist/runtime/cache.d.ts +1 -0
- package/dist/runtime/cache.js +169 -15
- package/dist/runtime/choice-wordlist.d.ts +9 -0
- package/dist/runtime/choice-wordlist.js +138 -0
- package/dist/runtime/choice.d.ts +13 -1
- package/dist/runtime/choice.js +490 -102
- package/dist/runtime/chrome149-header-order.d.ts +58 -0
- package/dist/runtime/chrome149-header-order.js +289 -0
- package/dist/runtime/env.js +12 -0
- package/dist/runtime/executor.d.ts +3 -2
- package/dist/runtime/executor.js +26 -25
- package/dist/runtime/http.d.ts +1 -0
- package/dist/runtime/http.js +515 -53
- package/dist/runtime/insights.js +2 -2
- package/dist/runtime/instrumentation.d.ts +2 -2
- package/dist/runtime/instrumentation.js +366 -8
- package/dist/runtime/native-network-errors.d.ts +33 -0
- package/dist/runtime/native-network-errors.js +69 -0
- package/dist/runtime/native-network.d.ts +96 -0
- package/dist/runtime/native-network.js +1232 -0
- package/dist/runtime/ocr.d.ts +29 -0
- package/dist/runtime/ocr.js +440 -0
- package/dist/runtime/otlp.d.ts +71 -2
- package/dist/runtime/otlp.js +397 -16
- package/dist/runtime/proxy-errors.js +6 -2
- package/dist/runtime/proxy-nodemaven.d.ts +56 -0
- package/dist/runtime/proxy-nodemaven.js +146 -0
- package/dist/runtime/proxy-telemetry.d.ts +80 -1
- package/dist/runtime/proxy-telemetry.js +154 -47
- package/dist/runtime/redirects.d.ts +29 -0
- package/dist/runtime/redirects.js +36 -0
- package/dist/runtime/redis.d.ts +1 -1
- package/dist/runtime/redis.js +4 -2
- package/dist/runtime/request-options.d.ts +68 -1
- package/dist/runtime/request-options.js +548 -0
- package/dist/runtime/resolver-config.d.ts +6 -0
- package/dist/runtime/resolver-config.js +6 -0
- package/dist/runtime/resolver-public.d.ts +1 -0
- package/dist/runtime/resolver-public.js +1 -0
- package/dist/runtime/resolver-shared.d.ts +14 -0
- package/dist/runtime/resolver-shared.js +12 -0
- package/dist/runtime/resolver-vendors/bindings.d.ts +48 -0
- package/dist/runtime/resolver-vendors/bindings.js +40 -0
- package/dist/runtime/resolver-vendors/browser.d.ts +22 -0
- package/dist/runtime/resolver-vendors/browser.js +377 -0
- package/dist/runtime/resolver-vendors/capsolver.d.ts +22 -0
- package/dist/runtime/resolver-vendors/capsolver.js +531 -0
- package/dist/runtime/resolver-vendors/hosts.d.ts +2 -0
- package/dist/runtime/resolver-vendors/hosts.js +33 -0
- package/dist/runtime/resolver-vendors/twocaptcha.d.ts +24 -0
- package/dist/runtime/resolver-vendors/twocaptcha.js +408 -0
- package/dist/runtime/resolver-vendors/types.d.ts +94 -0
- package/dist/runtime/resolver-vendors/types.js +96 -0
- package/dist/runtime/resolver.d.ts +72 -0
- package/dist/runtime/resolver.js +771 -0
- package/dist/runtime/secrets.d.ts +27 -0
- package/dist/runtime/secrets.js +51 -0
- package/dist/runtime/state.d.ts +3 -0
- package/dist/runtime/state.js +277 -71
- package/dist/runtime/stealth-cookies.d.ts +20 -0
- package/dist/runtime/stealth-cookies.js +111 -0
- package/dist/runtime/stealth.d.ts +41 -5
- package/dist/runtime/stealth.js +997 -291
- package/dist/runtime/stt.js +1 -12
- package/dist/runtime/timeout.d.ts +5 -0
- package/dist/runtime/timeout.js +12 -0
- package/dist/runtime/trace-config.d.ts +12 -0
- package/dist/runtime/trace-config.js +62 -0
- package/dist/runtime/trace.d.ts +5 -0
- package/dist/runtime/trace.js +43 -10
- package/dist/serve.d.ts +1 -1
- package/dist/serve.js +1 -1
- package/dist/server/error-observability.d.ts +1 -0
- package/dist/server/error-observability.js +1 -0
- package/dist/server/index.d.ts +5 -2
- package/dist/server/index.js +2 -2
- package/dist/server/self-test-input-tokens.d.ts +2 -1
- package/dist/server/self-test-input-tokens.js +18 -14
- package/dist/server/self-test.d.ts +14 -3
- package/dist/server/self-test.js +129 -58
- package/dist/server/serve-implementation.d.ts +230 -0
- package/dist/server/serve-implementation.js +2265 -0
- package/dist/server/serve.d.ts +1 -70
- package/dist/server/serve.js +1 -1131
- package/dist/server/trace-output.d.ts +6 -0
- package/dist/server/trace-output.js +79 -0
- package/dist/server/types.d.ts +30 -5
- package/dist/server/types.js +13 -1
- package/dist/stateful/errors.d.ts +19 -0
- package/dist/stateful/errors.js +24 -0
- package/dist/stateful/http-provider-event-emitter.d.ts +40 -0
- package/dist/stateful/http-provider-event-emitter.js +237 -0
- package/dist/stateful/http-session-owner-registry.d.ts +44 -0
- package/dist/stateful/http-session-owner-registry.js +210 -0
- package/dist/stateful/index.d.ts +18 -0
- package/dist/stateful/index.js +18 -0
- package/dist/stateful/provider-event-delivery-failures.d.ts +32 -0
- package/dist/stateful/provider-event-delivery-failures.js +43 -0
- package/dist/stateful/provider-event-pipeline-metrics.d.ts +46 -0
- package/dist/stateful/provider-event-pipeline-metrics.js +48 -0
- package/dist/stateful/provider-event-pipeline.d.ts +50 -0
- package/dist/stateful/provider-event-pipeline.js +1 -0
- package/dist/stateful/provider-events.d.ts +101 -0
- package/dist/stateful/provider-events.js +289 -0
- package/dist/stateful/session-key.d.ts +15 -0
- package/dist/stateful/session-key.js +86 -0
- package/dist/stateful/stateful-provider-adapter-context.d.ts +5 -0
- package/dist/stateful/stateful-provider-adapter-context.js +42 -0
- package/dist/stateful/stateful-provider-adapter-metrics.d.ts +15 -0
- package/dist/stateful/stateful-provider-adapter-metrics.js +21 -0
- package/dist/stateful/stateful-provider-adapter.d.ts +98 -0
- package/dist/stateful/stateful-provider-adapter.js +287 -0
- package/dist/stateful/stateful-provider-observability.d.ts +62 -0
- package/dist/stateful/stateful-provider-observability.js +161 -0
- package/dist/stateful/stateful-provider-owner-forwarder.d.ts +41 -0
- package/dist/stateful/stateful-provider-owner-forwarder.js +215 -0
- package/dist/stateful/stateful-provider-runtime-context.d.ts +32 -0
- package/dist/stateful/stateful-provider-runtime-context.js +60 -0
- package/dist/stateful/stateful-provider-runtime-executor.d.ts +34 -0
- package/dist/stateful/stateful-provider-runtime-executor.js +52 -0
- package/dist/stateful/stateful-provider-session-routing.d.ts +67 -0
- package/dist/stateful/stateful-provider-session-routing.js +345 -0
- package/dist/stateful/stateful-provider-session-runtime.d.ts +98 -0
- package/dist/stateful/stateful-provider-session-runtime.js +245 -0
- package/dist/stateful-signing.d.ts +18 -0
- package/dist/stateful-signing.js +27 -0
- package/dist/stealth/profiles.d.ts +9 -4
- package/dist/stealth/profiles.js +160 -211
- package/dist/stream-evidence.d.ts +74 -0
- package/dist/stream-evidence.js +785 -0
- package/dist/stream.js +7 -1
- package/dist/testing/index.d.ts +2 -1
- package/dist/testing/index.js +2 -1
- package/dist/testing/run.d.ts +32 -2
- package/dist/testing/run.js +489 -21
- package/dist/trace-sanitization.d.ts +5 -0
- package/dist/trace-sanitization.js +45 -0
- package/dist/types.d.ts +673 -131
- package/dist/types.js +1 -0
- package/package.json +45 -5
- package/src/auth-turn/index.ts +1 -1
- package/src/auth.ts +118 -0
- package/src/ceremonies/index.ts +189 -46
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/approval-override.ts.txt +6 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/codemod-syntax.ts.txt +3 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/connection-precedence.ts.txt +10 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/docs-conflict.ts.txt +8 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/examples-hoisted-array-spread.ts.txt +15 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/examples-imported-array-spread.ts.txt +9 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/examples-map.ts.txt +5 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/examples-mixed-array-spread.ts.txt +24 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/examples-operation.ts.txt +16 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/factory-map.ts.txt +3 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/hoist-all.ts.txt +31 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/hoisted-const.ts.txt +11 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/imported-spread.ts.txt +11 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/inline-map.ts.txt +11 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/inline-spread-cast-tail.ts.txt +21 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/inline-spread-ekitan.ts.txt +11 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/inline-spread-override.ts.txt +14 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/missing-english-locale.ts.txt +7 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/no-safety.ts.txt +6 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/non-literal.ts.txt +7 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/redundant-approval.ts.txt +6 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/safety-conflict.ts.txt +7 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/stream.ts.txt +7 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/tool-router-spread.ts.txt +15 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/unparseable.ts.txt +4 -0
- package/src/cli/__tests__/fixtures/migrate-operation-declaration/verbatim-template.ts.txt +12 -0
- package/src/cli/commands.ts +33 -0
- package/src/cli/create.ts +50 -37
- package/src/cli/migrate-operation-declaration.ts +1751 -0
- package/src/cli/migrate-operation-shape.ts +184 -0
- package/src/cli/migrate-provider-shape.ts +772 -0
- package/src/cli/prompt-assets.ts +865 -0
- package/src/cli/templates/provider/AGENTS.md.tpl +17 -8
- package/src/cli/templates/provider/Dockerfile.tpl +1 -1
- package/src/cli/templates/provider/README.md.tpl +5 -5
- package/src/cli/templates/provider/index.ts.tpl +6 -3
- package/src/cli/templates/provider/operations/ping.ts.tpl +4 -1
- package/src/cli/templates/provider/provider.json.tpl +6 -0
- package/src/config/loader.ts +690 -163
- package/src/contract-serialization.ts +5 -7
- package/src/contract-types.ts +12 -5
- package/src/contract.ts +24 -10
- package/src/declaration-validation.ts +330 -0
- package/src/define.ts +1048 -131
- package/src/dev.ts +4 -1
- package/src/engine.ts +279 -0
- package/src/error-observability.ts +64 -0
- package/src/error-resolution.ts +127 -0
- package/src/errors.ts +68 -0
- package/src/fixture-sanitization.ts +264 -0
- package/src/health-scenario.ts +875 -0
- package/src/index.ts +220 -13
- package/src/lint.ts +698 -90
- package/src/native-address.ts +340 -0
- package/src/native-egress-policy.ts +358 -0
- package/src/observability.ts +51 -1
- package/src/provider.ts +161 -3
- package/src/runtime/auth-flow.ts +12 -0
- package/src/runtime/browser.ts +661 -63
- package/src/runtime/cache.ts +189 -14
- package/src/runtime/choice-wordlist.ts +145 -0
- package/src/runtime/choice.ts +631 -120
- package/src/runtime/chrome149-header-order.ts +330 -0
- package/src/runtime/env.ts +13 -0
- package/src/runtime/executor.ts +43 -31
- package/src/runtime/http.ts +641 -61
- package/src/runtime/insights.ts +2 -2
- package/src/runtime/instrumentation.ts +520 -15
- package/src/runtime/native-network-errors.ts +99 -0
- package/src/runtime/native-network.ts +1605 -0
- package/src/runtime/ocr.ts +523 -0
- package/src/runtime/otlp.ts +467 -21
- package/src/runtime/proxy-errors.ts +12 -4
- package/src/runtime/proxy-nodemaven.ts +221 -0
- package/src/runtime/proxy-telemetry.ts +244 -75
- package/src/runtime/redirects.ts +66 -0
- package/src/runtime/redis.ts +7 -2
- package/src/runtime/request-options.ts +680 -1
- package/src/runtime/resolver-config.ts +6 -0
- package/src/runtime/resolver-public.ts +23 -0
- package/src/runtime/resolver-shared.ts +33 -0
- package/src/runtime/resolver-vendors/bindings.ts +56 -0
- package/src/runtime/resolver-vendors/browser.ts +533 -0
- package/src/runtime/resolver-vendors/capsolver.ts +707 -0
- package/src/runtime/resolver-vendors/hosts.ts +38 -0
- package/src/runtime/resolver-vendors/twocaptcha.ts +540 -0
- package/src/runtime/resolver-vendors/types.ts +212 -0
- package/src/runtime/resolver.ts +1157 -0
- package/src/runtime/secrets.ts +64 -0
- package/src/runtime/state.ts +394 -77
- package/src/runtime/stealth-cookies.ts +132 -0
- package/src/runtime/stealth.ts +1280 -336
- package/src/runtime/stt.ts +1 -19
- package/src/runtime/timeout.ts +18 -0
- package/src/runtime/trace-config.ts +78 -0
- package/src/runtime/trace.ts +57 -17
- package/src/serve.ts +6 -1
- package/src/server/error-observability.ts +1 -0
- package/src/server/index.ts +34 -2
- package/src/server/self-test-input-tokens.ts +29 -14
- package/src/server/self-test.ts +191 -68
- package/src/server/serve-implementation.ts +3378 -0
- package/src/server/serve.ts +1 -1632
- package/src/server/trace-output.ts +129 -0
- package/src/server/types.ts +13 -1
- package/src/stateful/README.md +146 -0
- package/src/stateful/errors.ts +35 -0
- package/src/stateful/http-provider-event-emitter.ts +314 -0
- package/src/stateful/http-session-owner-registry.ts +306 -0
- package/src/stateful/index.ts +18 -0
- package/src/stateful/provider-event-delivery-failures.ts +80 -0
- package/src/stateful/provider-event-pipeline-metrics.ts +95 -0
- package/src/stateful/provider-event-pipeline.ts +61 -0
- package/src/stateful/provider-events.ts +462 -0
- package/src/stateful/session-key.ts +111 -0
- package/src/stateful/stateful-provider-adapter-context.ts +59 -0
- package/src/stateful/stateful-provider-adapter-metrics.ts +48 -0
- package/src/stateful/stateful-provider-adapter.ts +562 -0
- package/src/stateful/stateful-provider-observability.ts +261 -0
- package/src/stateful/stateful-provider-owner-forwarder.ts +287 -0
- package/src/stateful/stateful-provider-runtime-context.ts +92 -0
- package/src/stateful/stateful-provider-runtime-executor.ts +96 -0
- package/src/stateful/stateful-provider-session-routing.ts +546 -0
- package/src/stateful/stateful-provider-session-runtime.ts +403 -0
- package/src/stateful-signing.ts +46 -0
- package/src/stealth/profiles.ts +202 -231
- package/src/stream-evidence.ts +988 -0
- package/src/stream.ts +8 -1
- package/src/testing/index.ts +10 -1
- package/src/testing/run.ts +658 -15
- package/src/trace-sanitization.ts +63 -0
- package/src/types.ts +788 -174
- package/dist/cli/templates/provider/CLAUDE.md.tpl +0 -1
- package/src/cli/templates/provider/CLAUDE.md.tpl +0 -1
- /package/dist/cli/templates/provider/{skills → .agents/skills}/fixtures-and-recording/SKILL.md.tpl +0 -0
- /package/dist/cli/templates/provider/{skills → .agents/skills}/health-checks-and-fail-closed/SKILL.md.tpl +0 -0
- /package/dist/cli/templates/provider/{skills → .agents/skills}/normalization-standards/SKILL.md.tpl +0 -0
- /package/dist/cli/templates/provider/{skills → .agents/skills}/pagination-and-counts/SKILL.md.tpl +0 -0
- /package/dist/cli/templates/provider/{skills → .agents/skills}/upstream-contract-verification/SKILL.md.tpl +0 -0
- /package/dist/cli/templates/provider/{skills → .agents/skills}/upstream-notes/README.md.tpl +0 -0
- /package/src/cli/templates/provider/{skills → .agents/skills}/fixtures-and-recording/SKILL.md.tpl +0 -0
- /package/src/cli/templates/provider/{skills → .agents/skills}/health-checks-and-fail-closed/SKILL.md.tpl +0 -0
- /package/src/cli/templates/provider/{skills → .agents/skills}/normalization-standards/SKILL.md.tpl +0 -0
- /package/src/cli/templates/provider/{skills → .agents/skills}/pagination-and-counts/SKILL.md.tpl +0 -0
- /package/src/cli/templates/provider/{skills → .agents/skills}/upstream-contract-verification/SKILL.md.tpl +0 -0
- /package/src/cli/templates/provider/{skills → .agents/skills}/upstream-notes/README.md.tpl +0 -0
package/dist/server/self-test.js
CHANGED
|
@@ -115,25 +115,15 @@ export function computeSelfTestPlanDigest(provider) {
|
|
|
115
115
|
}
|
|
116
116
|
/**
|
|
117
117
|
* Fail-closed read-only classification: an operation may self-test only when
|
|
118
|
-
* its
|
|
119
|
-
* toolRouter.riskClass "read") and nothing marks it side-effecting. Unclassified
|
|
120
|
-
* operations are refused so the endpoint cannot become a mutation oracle.
|
|
118
|
+
* its authored safety source of truth classifies it as read-only.
|
|
121
119
|
*/
|
|
122
120
|
export function isSelfTestReadOnlyOperation(operation) {
|
|
123
|
-
|
|
124
|
-
if (annotations?.readOnly === false)
|
|
125
|
-
return false;
|
|
126
|
-
if (annotations?.destructive === true)
|
|
127
|
-
return false;
|
|
128
|
-
const riskClass = operation.toolRouter?.riskClass;
|
|
129
|
-
if (riskClass !== undefined && riskClass !== "read")
|
|
130
|
-
return false;
|
|
131
|
-
return annotations?.readOnly === true || riskClass === "read";
|
|
121
|
+
return operation.riskClass === "read";
|
|
132
122
|
}
|
|
133
123
|
/** Binds the self-test executor to a tenant app's /v1 pipeline in-process. */
|
|
134
124
|
export function createSelfTestInvoke(app) {
|
|
135
|
-
return async ({ operationId, input, connection, requestId }) => {
|
|
136
|
-
const
|
|
125
|
+
return async ({ operationId, input, connection, requestId, signal }) => {
|
|
126
|
+
const responsePromise = Promise.resolve(app.request(`/v1/${encodeURIComponent(operationId)}`, {
|
|
137
127
|
method: "POST",
|
|
138
128
|
headers: { "content-type": "application/json" },
|
|
139
129
|
body: JSON.stringify({
|
|
@@ -141,7 +131,14 @@ export function createSelfTestInvoke(app) {
|
|
|
141
131
|
input: input ?? {},
|
|
142
132
|
...(connection ? { connection } : {}),
|
|
143
133
|
}),
|
|
144
|
-
|
|
134
|
+
...(signal ? { signal } : {}),
|
|
135
|
+
}));
|
|
136
|
+
const response = await responsePromise;
|
|
137
|
+
if (signal?.aborted) {
|
|
138
|
+
await cancelSelfTestResponse(response);
|
|
139
|
+
signal.throwIfAborted();
|
|
140
|
+
}
|
|
141
|
+
// An abort after body consumption starts may let response.text() finish.
|
|
145
142
|
const text = await response.text();
|
|
146
143
|
let body = text;
|
|
147
144
|
try {
|
|
@@ -161,9 +158,36 @@ export function createSelfTestInvoke(app) {
|
|
|
161
158
|
return { status: response.status, data: body };
|
|
162
159
|
};
|
|
163
160
|
}
|
|
161
|
+
async function cancelSelfTestResponse(response) {
|
|
162
|
+
await response.body?.cancel().catch(() => undefined);
|
|
163
|
+
}
|
|
164
|
+
function selfTestAbortReason(reason, sensitiveValues) {
|
|
165
|
+
const text = reason instanceof Error
|
|
166
|
+
? reason.message || reason.name
|
|
167
|
+
: reason === undefined
|
|
168
|
+
? "aborted"
|
|
169
|
+
: String(reason);
|
|
170
|
+
return redactSelfTestText(text, sensitiveValues);
|
|
171
|
+
}
|
|
172
|
+
function logSelfTestCancellation(provider, options, requestId, selected, signal, sensitiveValues) {
|
|
173
|
+
const event = {
|
|
174
|
+
level: "info",
|
|
175
|
+
event: "self_test_run_cancelled",
|
|
176
|
+
providerId: provider.id,
|
|
177
|
+
requestId,
|
|
178
|
+
operationId: selected.operationId,
|
|
179
|
+
caseName: selected.healthCase.name,
|
|
180
|
+
reason: selfTestAbortReason(signal.reason, sensitiveValues),
|
|
181
|
+
};
|
|
182
|
+
if (options.logger) {
|
|
183
|
+
options.logger(event);
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
console.log(JSON.stringify(event));
|
|
187
|
+
}
|
|
164
188
|
/** Binds the self-test auth-flow driver to a tenant app's /auth pipeline in-process. */
|
|
165
189
|
export function createSelfTestAuthFlowInvoke(app) {
|
|
166
|
-
return async ({ route, requestId, flowId, connectionId, externalRef, input, context }) => {
|
|
190
|
+
return async ({ route, requestId, flowId, connectionId, externalRef, input, context, signal, }) => {
|
|
167
191
|
const response = await app.request(`/auth/${route}`, {
|
|
168
192
|
method: "POST",
|
|
169
193
|
headers: { "content-type": "application/json" },
|
|
@@ -175,6 +199,7 @@ export function createSelfTestAuthFlowInvoke(app) {
|
|
|
175
199
|
...(input ? { input } : {}),
|
|
176
200
|
...(context ? { context } : {}),
|
|
177
201
|
}),
|
|
202
|
+
...(signal ? { signal } : {}),
|
|
178
203
|
});
|
|
179
204
|
const text = await response.text();
|
|
180
205
|
let body = text;
|
|
@@ -193,19 +218,32 @@ class SelfTestCaseTimeoutError extends Error {
|
|
|
193
218
|
this.name = "SelfTestCaseTimeoutError";
|
|
194
219
|
}
|
|
195
220
|
}
|
|
196
|
-
async function withCaseTimeout(run, timeoutMs) {
|
|
221
|
+
async function withCaseTimeout(run, timeoutMs, controller) {
|
|
197
222
|
let timer;
|
|
223
|
+
let onAbort;
|
|
198
224
|
try {
|
|
199
225
|
return await Promise.race([
|
|
200
226
|
run(),
|
|
201
227
|
new Promise((_, reject) => {
|
|
202
|
-
timer = setTimeout(() =>
|
|
228
|
+
timer = setTimeout(() => {
|
|
229
|
+
const error = new SelfTestCaseTimeoutError(timeoutMs);
|
|
230
|
+
controller.abort(error);
|
|
231
|
+
reject(error);
|
|
232
|
+
}, timeoutMs);
|
|
233
|
+
}),
|
|
234
|
+
new Promise((_, reject) => {
|
|
235
|
+
onAbort = () => reject(controller.signal.reason);
|
|
236
|
+
controller.signal.addEventListener("abort", onAbort, { once: true });
|
|
237
|
+
if (controller.signal.aborted)
|
|
238
|
+
onAbort();
|
|
203
239
|
}),
|
|
204
240
|
]);
|
|
205
241
|
}
|
|
206
242
|
finally {
|
|
207
243
|
if (timer !== undefined)
|
|
208
244
|
clearTimeout(timer);
|
|
245
|
+
if (onAbort)
|
|
246
|
+
controller.signal.removeEventListener("abort", onAbort);
|
|
209
247
|
}
|
|
210
248
|
}
|
|
211
249
|
function objectProperty(value, key) {
|
|
@@ -389,6 +427,7 @@ async function materializeFlowCredential(execution, inputs, options = {}) {
|
|
|
389
427
|
flowId,
|
|
390
428
|
...(options.connectionId ? { connectionId: options.connectionId } : {}),
|
|
391
429
|
...(options.externalRef ? { externalRef: options.externalRef } : {}),
|
|
430
|
+
...(options.signal ? { signal: options.signal } : {}),
|
|
392
431
|
}));
|
|
393
432
|
if (!started.ok) {
|
|
394
433
|
return { kind: "flow_error", code: started.code, message: started.message };
|
|
@@ -460,6 +499,7 @@ async function materializeFlowCredential(execution, inputs, options = {}) {
|
|
|
460
499
|
...(options.externalRef ? { externalRef: options.externalRef } : {}),
|
|
461
500
|
input: submitInputs,
|
|
462
501
|
...(Object.keys(flowContext).length > 0 ? { context: flowContext } : {}),
|
|
502
|
+
...(options.signal ? { signal: options.signal } : {}),
|
|
463
503
|
}));
|
|
464
504
|
if (!continued.ok) {
|
|
465
505
|
// Providers built with defineCredentialsAuth cannot return a retry
|
|
@@ -613,6 +653,7 @@ async function resolveSelfTestConnection(execution, operationId, suite, options
|
|
|
613
653
|
...(options.isAbandoned !== undefined ? { isAbandoned: options.isAbandoned } : {}),
|
|
614
654
|
connectionId,
|
|
615
655
|
externalRef: `${execution.provider.id}-${operationId}-self-test`,
|
|
656
|
+
...(options.signal ? { signal: options.signal } : {}),
|
|
616
657
|
});
|
|
617
658
|
if (!("credential" in materialized)) {
|
|
618
659
|
// Only the multi-turn SKIP is negative-cached. Flow ERRORS
|
|
@@ -632,10 +673,9 @@ async function resolveSelfTestConnection(execution, operationId, suite, options
|
|
|
632
673
|
}
|
|
633
674
|
return materialized;
|
|
634
675
|
}
|
|
635
|
-
//
|
|
636
|
-
//
|
|
637
|
-
//
|
|
638
|
-
// reuse a login whose latency just failed the case, hiding the failure.
|
|
676
|
+
// Abort is cooperative: a flow may still complete after the case deadline
|
|
677
|
+
// if provider code ignores the signal. Never cache that late credential or
|
|
678
|
+
// let the next probe hide the timed-out login.
|
|
639
679
|
if (options.isAbandoned?.() === true) {
|
|
640
680
|
return {
|
|
641
681
|
kind: "flow_error",
|
|
@@ -659,7 +699,7 @@ async function resolveSelfTestConnection(execution, operationId, suite, options
|
|
|
659
699
|
function isAuthFailureCaseResult(result) {
|
|
660
700
|
return result.status === "failed" && (result.httpStatus === 401 || result.httpStatus === 403);
|
|
661
701
|
}
|
|
662
|
-
async function executeSelfTestCase(execution, operationId, suite, healthCase) {
|
|
702
|
+
async function executeSelfTestCase(execution, operationId, suite, healthCase, caseController) {
|
|
663
703
|
const { provider, invoke } = execution;
|
|
664
704
|
// execution.sensitiveValues may grow while the case runs (flow-issued
|
|
665
705
|
// secrets); redact always reads the live array.
|
|
@@ -671,6 +711,7 @@ async function executeSelfTestCase(execution, operationId, suite, healthCase) {
|
|
|
671
711
|
// a 30s case must never take ~4×30s across its stages.
|
|
672
712
|
const caseDeadlineAtMs = performance.now() + timeoutMs;
|
|
673
713
|
const remainingCaseTimeoutMs = () => Math.max(1, Math.ceil(caseDeadlineAtMs - performance.now()));
|
|
714
|
+
const runWithCaseTimeout = (run, remainingMs) => withCaseTimeout(run, remainingMs, caseController);
|
|
674
715
|
const beginCase = () => {
|
|
675
716
|
const startedAt = new Date().toISOString();
|
|
676
717
|
const startedAtMs = performance.now();
|
|
@@ -695,14 +736,15 @@ async function executeSelfTestCase(execution, operationId, suite, healthCase) {
|
|
|
695
736
|
});
|
|
696
737
|
}
|
|
697
738
|
const resolveConnection = async (forceLogin) => {
|
|
698
|
-
// The
|
|
699
|
-
//
|
|
700
|
-
//
|
|
739
|
+
// The deadline aborts the in-process flow request. Keep the abandonment
|
|
740
|
+
// guard as a backstop for provider code that ignores cancellation so a
|
|
741
|
+
// late completion still cannot write the session cache.
|
|
701
742
|
let abandoned = false;
|
|
702
743
|
try {
|
|
703
|
-
return await
|
|
744
|
+
return await runWithCaseTimeout(() => resolveSelfTestConnection(execution, operationId, suite, {
|
|
704
745
|
forceLogin,
|
|
705
746
|
isAbandoned: () => abandoned,
|
|
747
|
+
signal: caseController.signal,
|
|
706
748
|
}), remainingCaseTimeoutMs());
|
|
707
749
|
}
|
|
708
750
|
catch (error) {
|
|
@@ -739,7 +781,10 @@ async function executeSelfTestCase(execution, operationId, suite, healthCase) {
|
|
|
739
781
|
// operation attempt, or a slow login reads as a fast healthy case.
|
|
740
782
|
const { startedAtMs, finish } = caseScope;
|
|
741
783
|
try {
|
|
742
|
-
return await
|
|
784
|
+
return await runWithCaseTimeout(async () => {
|
|
785
|
+
if (healthCase.assertions === undefined) {
|
|
786
|
+
throw new Error(`Self-test cannot execute declarative health-check case "${healthCase.name}"; run its scenario through the health monitor.`);
|
|
787
|
+
}
|
|
743
788
|
const resolvedInput = resolveHealthCheckInputDateTokens(healthCase.input);
|
|
744
789
|
const preparedInput = healthCase.prepareInput
|
|
745
790
|
? await healthCase.prepareInput({
|
|
@@ -758,6 +803,7 @@ async function executeSelfTestCase(execution, operationId, suite, healthCase) {
|
|
|
758
803
|
input: gatewayInput,
|
|
759
804
|
connection,
|
|
760
805
|
requestId: `${execution.requestId}-prepare-${randomUUID()}`,
|
|
806
|
+
signal: caseController.signal,
|
|
761
807
|
});
|
|
762
808
|
if (executed.status === 401 || executed.status === 403) {
|
|
763
809
|
prepareAuthStatus = executed.status;
|
|
@@ -777,6 +823,7 @@ async function executeSelfTestCase(execution, operationId, suite, healthCase) {
|
|
|
777
823
|
input: preparedInput,
|
|
778
824
|
connection,
|
|
779
825
|
requestId: `${execution.requestId}-${randomUUID()}`,
|
|
826
|
+
signal: caseController.signal,
|
|
780
827
|
});
|
|
781
828
|
const durationMs = performance.now() - startedAtMs;
|
|
782
829
|
if (executed.status < 200 || executed.status >= 300) {
|
|
@@ -1054,41 +1101,65 @@ export function createSelfTestApp(provider, options) {
|
|
|
1054
1101
|
};
|
|
1055
1102
|
const deadline = performance.now() + requestBudgetMs;
|
|
1056
1103
|
const results = [];
|
|
1104
|
+
const runSignal = c.req.raw.signal;
|
|
1105
|
+
let interruptedCase;
|
|
1057
1106
|
// Sequential execution (parallelism 1): self-tests run on serving pods
|
|
1058
1107
|
// and must never compete with themselves for upstream quota.
|
|
1059
1108
|
for (const selected of selection.cases) {
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1109
|
+
const caseController = new AbortController();
|
|
1110
|
+
const abortFromRun = () => caseController.abort(runSignal.reason);
|
|
1111
|
+
runSignal.addEventListener("abort", abortFromRun, { once: true });
|
|
1112
|
+
if (runSignal.aborted)
|
|
1113
|
+
abortFromRun();
|
|
1114
|
+
try {
|
|
1115
|
+
if (runSignal.aborted) {
|
|
1116
|
+
interruptedCase = selected;
|
|
1117
|
+
break;
|
|
1118
|
+
}
|
|
1119
|
+
if (performance.now() >= deadline) {
|
|
1120
|
+
const now = new Date().toISOString();
|
|
1121
|
+
results.push({
|
|
1122
|
+
operationId: selected.operationId,
|
|
1123
|
+
caseName: selected.healthCase.name,
|
|
1124
|
+
status: "skipped",
|
|
1125
|
+
label: selected.healthCase.name,
|
|
1126
|
+
responseTimeMs: 0,
|
|
1127
|
+
skipReason: "budget_exhausted",
|
|
1128
|
+
startedAt: now,
|
|
1129
|
+
finishedAt: now,
|
|
1130
|
+
});
|
|
1131
|
+
continue;
|
|
1132
|
+
}
|
|
1133
|
+
if (!isSelfTestReadOnlyOperation(selected.operation)) {
|
|
1134
|
+
const now = new Date().toISOString();
|
|
1135
|
+
results.push({
|
|
1136
|
+
operationId: selected.operationId,
|
|
1137
|
+
caseName: selected.healthCase.name,
|
|
1138
|
+
status: "error",
|
|
1139
|
+
label: selected.healthCase.name,
|
|
1140
|
+
responseTimeMs: 0,
|
|
1141
|
+
error: {
|
|
1142
|
+
code: "operation_not_read_only",
|
|
1143
|
+
message: `Operation "${selected.operationId}" is not classified read-only; self-test refuses to execute it.`,
|
|
1144
|
+
},
|
|
1145
|
+
startedAt: now,
|
|
1146
|
+
finishedAt: now,
|
|
1147
|
+
});
|
|
1148
|
+
continue;
|
|
1149
|
+
}
|
|
1150
|
+
results.push(await executeSelfTestCase(execution, selected.operationId, selected.suite, selected.healthCase, caseController));
|
|
1151
|
+
if (runSignal.aborted) {
|
|
1152
|
+
interruptedCase = selected;
|
|
1153
|
+
break;
|
|
1154
|
+
}
|
|
1073
1155
|
}
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
operationId: selected.operationId,
|
|
1078
|
-
caseName: selected.healthCase.name,
|
|
1079
|
-
status: "error",
|
|
1080
|
-
label: selected.healthCase.name,
|
|
1081
|
-
responseTimeMs: 0,
|
|
1082
|
-
error: {
|
|
1083
|
-
code: "operation_not_read_only",
|
|
1084
|
-
message: `Operation "${selected.operationId}" is not classified read-only; self-test refuses to execute it.`,
|
|
1085
|
-
},
|
|
1086
|
-
startedAt: now,
|
|
1087
|
-
finishedAt: now,
|
|
1088
|
-
});
|
|
1089
|
-
continue;
|
|
1156
|
+
finally {
|
|
1157
|
+
runSignal.removeEventListener("abort", abortFromRun);
|
|
1158
|
+
caseController.abort();
|
|
1090
1159
|
}
|
|
1091
|
-
|
|
1160
|
+
}
|
|
1161
|
+
if (interruptedCase) {
|
|
1162
|
+
logSelfTestCancellation(provider, options, request.requestId, interruptedCase, runSignal, execution.sensitiveValues);
|
|
1092
1163
|
}
|
|
1093
1164
|
const singleCase = request.operationId !== undefined && request.caseName !== undefined;
|
|
1094
1165
|
const response = {
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
import { Hono } from "hono";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { type ProviderEngine } from "../engine.js";
|
|
4
|
+
import { type ProviderErrorObservability } from "../errors.js";
|
|
5
|
+
import { type ProviderErrorCategory } from "../observability.js";
|
|
6
|
+
import { type ProxyTelemetryLogPayload } from "../runtime/proxy-telemetry.js";
|
|
7
|
+
import type { OcrContext, ProviderContext, ProviderDefinition, ProviderFilesContext, ProviderRuntimeState, ResolverContext, SttContext } from "../types.js";
|
|
8
|
+
import type { SelfTestCancellationLogEvent } from "./self-test.js";
|
|
9
|
+
import { type AuthFlowRequest, type OperationRequest } from "./types.js";
|
|
10
|
+
/** Compact SDK-owned error classification emitted separately from the public response body. */
|
|
11
|
+
export declare const ERROR_OBSERVABILITY_HEADER = "X-ApiFuse-Error-Observability";
|
|
12
|
+
export type ErrorObservabilityDetails = {
|
|
13
|
+
category: ProviderErrorCategory;
|
|
14
|
+
taxonomyVersion: string;
|
|
15
|
+
retryable: boolean;
|
|
16
|
+
upstreamStatus?: number;
|
|
17
|
+
providerObservability?: ProviderErrorObservability;
|
|
18
|
+
};
|
|
19
|
+
export declare const ProviderServerStatefulForwardEnvelopeSchema: z.ZodObject<{
|
|
20
|
+
requestId: z.ZodString;
|
|
21
|
+
providerId: z.ZodString;
|
|
22
|
+
operationId: z.ZodString;
|
|
23
|
+
sessionKey: z.ZodString;
|
|
24
|
+
connectionId: z.ZodString;
|
|
25
|
+
serviceAccountId: z.ZodString;
|
|
26
|
+
ownerPodId: z.ZodString;
|
|
27
|
+
generation: z.ZodNumber;
|
|
28
|
+
sourcePodId: z.ZodString;
|
|
29
|
+
forwardedAt: z.ZodString;
|
|
30
|
+
deadlineAt: z.ZodOptional<z.ZodString>;
|
|
31
|
+
idempotencyKey: z.ZodOptional<z.ZodString>;
|
|
32
|
+
operationRequest: z.ZodObject<{
|
|
33
|
+
requestId: z.ZodString;
|
|
34
|
+
input: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
35
|
+
connectionId: z.ZodOptional<z.ZodString>;
|
|
36
|
+
headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
37
|
+
trace: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
38
|
+
connection: z.ZodOptional<z.ZodObject<{
|
|
39
|
+
id: z.ZodString;
|
|
40
|
+
mode: z.ZodEnum<{
|
|
41
|
+
credentials: "credentials";
|
|
42
|
+
none: "none";
|
|
43
|
+
oauth2: "oauth2";
|
|
44
|
+
"platform-managed": "platform-managed";
|
|
45
|
+
oauth2_proxied: "oauth2_proxied";
|
|
46
|
+
}>;
|
|
47
|
+
secrets: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
48
|
+
scopes: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
49
|
+
metadata: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
50
|
+
externalRef: z.ZodString;
|
|
51
|
+
}, z.core.$strict>>;
|
|
52
|
+
}, z.core.$strict>;
|
|
53
|
+
}, z.core.$strict>;
|
|
54
|
+
export type ProviderServerStatefulForwardEnvelope = Readonly<z.infer<typeof ProviderServerStatefulForwardEnvelopeSchema>>;
|
|
55
|
+
export type ProviderServerStatefulOwnerFence = Readonly<Pick<ProviderServerStatefulForwardEnvelope, "providerId" | "sessionKey" | "ownerPodId" | "generation" | "sourcePodId" | "forwardedAt" | "requestId" | "idempotencyKey">>;
|
|
56
|
+
export type ProviderServerStatefulOwnerFenceValidator = (fence: ProviderServerStatefulOwnerFence, signal: AbortSignal) => boolean | Promise<boolean>;
|
|
57
|
+
export type ProviderServerOperationExecutorInput<TContext extends Partial<ProviderContext> = ProviderContext> = {
|
|
58
|
+
readonly provider: ProviderDefinition<TContext>;
|
|
59
|
+
readonly operationId: string;
|
|
60
|
+
readonly ctx: TContext;
|
|
61
|
+
readonly request: OperationRequest & {
|
|
62
|
+
readonly deadlineAt?: string;
|
|
63
|
+
};
|
|
64
|
+
readonly signal?: AbortSignal;
|
|
65
|
+
readonly internalStatefulForward?: ProviderServerStatefulForwardEnvelope;
|
|
66
|
+
};
|
|
67
|
+
export type ProviderServerOperationExecutor<TContext extends Partial<ProviderContext> = ProviderContext> = (input: ProviderServerOperationExecutorInput<TContext>) => Promise<unknown>;
|
|
68
|
+
export declare function resolveProviderProxyAffinityKey(provider: ProviderDefinition, request: OperationRequest, operationId: string): string;
|
|
69
|
+
export declare function resolveProviderResolverIdentityScope(provider: ProviderDefinition, affinityKey: string, contextId: string): string;
|
|
70
|
+
export declare function resolveAuthFlowProxyAffinityKey(provider: ProviderDefinition, request: Pick<AuthFlowRequest, "connection" | "connectionId" | "externalRef" | "tenantId" | "providerId">): string;
|
|
71
|
+
type ProviderRequestCost = {
|
|
72
|
+
durationMs: number;
|
|
73
|
+
cpuUserMicros: number;
|
|
74
|
+
cpuSystemMicros: number;
|
|
75
|
+
cpuTotalMicros: number;
|
|
76
|
+
};
|
|
77
|
+
type ProviderServerLogEventBase = ProviderRequestCost & {
|
|
78
|
+
providerId: string;
|
|
79
|
+
kind: "operation" | "auth";
|
|
80
|
+
route: string;
|
|
81
|
+
requestId?: string;
|
|
82
|
+
status: number;
|
|
83
|
+
proxy?: ProxyTelemetryLogPayload;
|
|
84
|
+
};
|
|
85
|
+
export type ProviderServerLogEvent = (ProviderServerLogEventBase & {
|
|
86
|
+
level: "info";
|
|
87
|
+
event: "provider_request_completed";
|
|
88
|
+
}) | (ProviderServerLogEventBase & {
|
|
89
|
+
level: "warn" | "error";
|
|
90
|
+
event: "provider_request_failed";
|
|
91
|
+
code: string;
|
|
92
|
+
errorClass: string;
|
|
93
|
+
message: string;
|
|
94
|
+
upstreamStatus?: number;
|
|
95
|
+
errorCategory?: ProviderErrorCategory;
|
|
96
|
+
taxonomyVersion?: string;
|
|
97
|
+
retryable?: boolean;
|
|
98
|
+
providerObservability?: ProviderErrorObservability;
|
|
99
|
+
causeChain?: ProviderErrorCauseFrame[];
|
|
100
|
+
signal?: "unregistered_provider_error_code";
|
|
101
|
+
signalFix?: string;
|
|
102
|
+
issues?: Array<{
|
|
103
|
+
path: string;
|
|
104
|
+
code: string;
|
|
105
|
+
message: string;
|
|
106
|
+
}>;
|
|
107
|
+
}) | {
|
|
108
|
+
level: "warn";
|
|
109
|
+
event: "provider_secrets_missing";
|
|
110
|
+
providerId: string;
|
|
111
|
+
missingSecrets: string[];
|
|
112
|
+
} | {
|
|
113
|
+
level: "info";
|
|
114
|
+
event: "provider_choice_token";
|
|
115
|
+
providerId: string;
|
|
116
|
+
purpose: string;
|
|
117
|
+
operation: "parse" | "consume";
|
|
118
|
+
format: "word" | "legacy";
|
|
119
|
+
outcome: "success" | "not-found" | "invalid" | "unsupported" | "error";
|
|
120
|
+
consumeMode: "never" | "on-parse" | "explicit";
|
|
121
|
+
consumed: boolean;
|
|
122
|
+
replay: boolean;
|
|
123
|
+
} | {
|
|
124
|
+
level: "warn";
|
|
125
|
+
event: "provider_cleanup_failed";
|
|
126
|
+
providerId: string;
|
|
127
|
+
kind: "operation" | "auth";
|
|
128
|
+
route: string;
|
|
129
|
+
requestId?: string;
|
|
130
|
+
resource: "browser" | "stealth";
|
|
131
|
+
errorClass: string;
|
|
132
|
+
message: string;
|
|
133
|
+
} | {
|
|
134
|
+
level: "error";
|
|
135
|
+
event: "provider_shutdown_hook_failed";
|
|
136
|
+
providerId: string;
|
|
137
|
+
hookIndex: number;
|
|
138
|
+
errorClass: string;
|
|
139
|
+
message: string;
|
|
140
|
+
} | SelfTestCancellationLogEvent;
|
|
141
|
+
export type ProviderServerLogger = (event: ProviderServerLogEvent) => void;
|
|
142
|
+
export type ProviderServerOptions<TContext extends Partial<ProviderContext> = ProviderContext> = {
|
|
143
|
+
logger?: ProviderServerLogger;
|
|
144
|
+
/** Capability attachment boundary. Defaults to the local in-process engine. */
|
|
145
|
+
engine?: ProviderEngine;
|
|
146
|
+
/** Request-file resolver supplied by the engine host when `files` is declared. */
|
|
147
|
+
files?: ProviderFilesContext;
|
|
148
|
+
/** Optional provider-specific operation executor. Stateful providers use this to preserve provider-local runtime semantics. */
|
|
149
|
+
operationExecutor?: ProviderServerOperationExecutor<TContext>;
|
|
150
|
+
/** Optional signed internal executor for stateful owner forwarding. */
|
|
151
|
+
internalOperationExecutor?: ProviderServerOperationExecutor<TContext>;
|
|
152
|
+
statefulForwarding?: {
|
|
153
|
+
readonly secret: string;
|
|
154
|
+
readonly maxSkewMs?: number;
|
|
155
|
+
readonly replayCacheMaxEntries?: number;
|
|
156
|
+
/** Required fail-closed check against the SDK/runtime owner registry. */
|
|
157
|
+
readonly validateOwnerFence: ProviderServerStatefulOwnerFenceValidator;
|
|
158
|
+
};
|
|
159
|
+
/** Optional STT override for tests or custom hosts; local/prod normally resolves from env. */
|
|
160
|
+
stt?: SttContext;
|
|
161
|
+
/** Optional OCR override for tests or custom hosts; local/prod normally resolves from env. */
|
|
162
|
+
ocr?: OcrContext;
|
|
163
|
+
/** Optional resolver override for tests or custom hosts; local/prod normally resolves from env. */
|
|
164
|
+
resolver?: ResolverContext;
|
|
165
|
+
/** Optional runtime state override for tests or custom hosts. Production resolves Redis from env and fails closed when unavailable. */
|
|
166
|
+
state?: ProviderRuntimeState;
|
|
167
|
+
/** Allow process-local runtime state only for local development and tests. */
|
|
168
|
+
allowMemoryStateFallback?: boolean;
|
|
169
|
+
/**
|
|
170
|
+
* Graceful process shutdown. Hooks run in declaration order after listeners stop accepting work.
|
|
171
|
+
*
|
|
172
|
+
* @example
|
|
173
|
+
* ```ts
|
|
174
|
+
* await serve(provider, {
|
|
175
|
+
* shutdown: {
|
|
176
|
+
* hooks: [
|
|
177
|
+
* async () => { await emitter.flush(); },
|
|
178
|
+
* async () => { await sessionManager.closeAll("server-shutdown"); },
|
|
179
|
+
* async () => { await lease.release(); },
|
|
180
|
+
* async () => { await router.close(); },
|
|
181
|
+
* ],
|
|
182
|
+
* },
|
|
183
|
+
* });
|
|
184
|
+
* ```
|
|
185
|
+
*/
|
|
186
|
+
shutdown?: {
|
|
187
|
+
readonly hooks?: Array<() => Promise<void>>;
|
|
188
|
+
readonly signals?: boolean | NodeJS.Signals[];
|
|
189
|
+
readonly timeoutMs?: number;
|
|
190
|
+
};
|
|
191
|
+
};
|
|
192
|
+
export type ProviderErrorCauseFrame = {
|
|
193
|
+
errorClass: string;
|
|
194
|
+
code?: string;
|
|
195
|
+
message: string;
|
|
196
|
+
messageLength: number;
|
|
197
|
+
messageFingerprint: string;
|
|
198
|
+
providerObservability?: ProviderErrorObservability;
|
|
199
|
+
};
|
|
200
|
+
/**
|
|
201
|
+
* Primary, cross-runtime app factory. Declared capability ESM is preloaded
|
|
202
|
+
* asynchronously, so this path works on Bun and every supported Node release.
|
|
203
|
+
*/
|
|
204
|
+
export declare function createServerAppAsync<TContext extends Partial<ProviderContext> = ProviderContext>(provider: ProviderDefinition<TContext>, options?: ProviderServerOptions<TContext>): Promise<Hono>;
|
|
205
|
+
/**
|
|
206
|
+
* Synchronous compatibility factory. Standard providers remain synchronous on
|
|
207
|
+
* every runtime because they load no capability modules. Providers declaring a
|
|
208
|
+
* capability require Bun or Node >=22.12; older Node releases receive an
|
|
209
|
+
* actionable error directing them to createServerAppAsync().
|
|
210
|
+
*/
|
|
211
|
+
export declare function createServerApp<TContext extends Partial<ProviderContext> = ProviderContext>(provider: ProviderDefinition<TContext>, options?: ProviderServerOptions<TContext>): Hono;
|
|
212
|
+
export type ProviderServerCloseOptions = {
|
|
213
|
+
readonly timeoutMs?: number;
|
|
214
|
+
};
|
|
215
|
+
export type ProviderServerHandle = {
|
|
216
|
+
readonly port: number;
|
|
217
|
+
close(options?: ProviderServerCloseOptions): Promise<void>;
|
|
218
|
+
};
|
|
219
|
+
export interface ServeOptions<TContext extends Partial<ProviderContext> = ProviderContext> extends ProviderServerOptions<TContext> {
|
|
220
|
+
host?: string;
|
|
221
|
+
port?: number;
|
|
222
|
+
/**
|
|
223
|
+
* Port for the internal self-test listener (default 3001 or
|
|
224
|
+
* APIFUSE__PROVIDER_RUNTIME__SELF_TEST_PORT). The listener only starts
|
|
225
|
+
* when APIFUSE__PROVIDER_RUNTIME__SELF_TEST_MASTER_SECRET is present.
|
|
226
|
+
*/
|
|
227
|
+
selfTestPort?: number;
|
|
228
|
+
}
|
|
229
|
+
export declare function serve<TContext extends Partial<ProviderContext> = ProviderContext>(provider: ProviderDefinition<TContext>, options?: ServeOptions<TContext>): Promise<ProviderServerHandle>;
|
|
230
|
+
export {};
|