@superblocksteam/vite-plugin-file-sync 2.0.69 → 2.0.70-next.1
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/dist/ai-service/agent/middleware.d.ts +6 -0
- package/dist/ai-service/agent/middleware.d.ts.map +1 -1
- package/dist/ai-service/agent/middleware.js +11 -0
- package/dist/ai-service/agent/middleware.js.map +1 -1
- package/dist/ai-service/agent/prompts/build-base-system-prompt.d.ts.map +1 -1
- package/dist/ai-service/agent/prompts/build-base-system-prompt.js +50 -6
- package/dist/ai-service/agent/prompts/build-base-system-prompt.js.map +1 -1
- package/dist/ai-service/agent/subagents/types.d.ts.map +1 -1
- package/dist/ai-service/agent/subagents/types.js +1 -0
- package/dist/ai-service/agent/subagents/types.js.map +1 -1
- package/dist/ai-service/agent/tool-message-utils.d.ts +2 -0
- package/dist/ai-service/agent/tool-message-utils.d.ts.map +1 -1
- package/dist/ai-service/agent/tool-message-utils.js +48 -0
- package/dist/ai-service/agent/tool-message-utils.js.map +1 -1
- package/dist/ai-service/agent/tools/apis/api-validation-orchestrator.js +3 -7
- package/dist/ai-service/agent/tools/apis/api-validation-orchestrator.js.map +1 -1
- package/dist/ai-service/agent/tools/apis/build-api-artifact.d.ts.map +1 -1
- package/dist/ai-service/agent/tools/apis/build-api-artifact.js +3 -6
- package/dist/ai-service/agent/tools/apis/build-api-artifact.js.map +1 -1
- package/dist/ai-service/agent/tools/apis/get-api-docs.d.ts.map +1 -1
- package/dist/ai-service/agent/tools/apis/get-api-docs.js +24 -0
- package/dist/ai-service/agent/tools/apis/get-api-docs.js.map +1 -1
- package/dist/ai-service/agent/tools/apis/sample-json.d.ts +2 -0
- package/dist/ai-service/agent/tools/apis/sample-json.d.ts.map +1 -0
- package/dist/ai-service/agent/tools/apis/sample-json.js +16 -0
- package/dist/ai-service/agent/tools/apis/sample-json.js.map +1 -0
- package/dist/ai-service/agent/tools/apis/test-api.d.ts +4 -4
- package/dist/ai-service/agent/tools/apis/test-api.d.ts.map +1 -1
- package/dist/ai-service/agent/tools/apis/test-api.js +17 -6
- package/dist/ai-service/agent/tools/apis/test-api.js.map +1 -1
- package/dist/ai-service/agent/tools/build-capture-screenshot.d.ts +10 -0
- package/dist/ai-service/agent/tools/build-capture-screenshot.d.ts.map +1 -0
- package/dist/ai-service/agent/tools/build-capture-screenshot.js +103 -0
- package/dist/ai-service/agent/tools/build-capture-screenshot.js.map +1 -0
- package/dist/ai-service/agent/tools/build-install-packages.d.ts.map +1 -1
- package/dist/ai-service/agent/tools/build-install-packages.js +36 -29
- package/dist/ai-service/agent/tools/build-install-packages.js.map +1 -1
- package/dist/ai-service/agent/tools/build-multi-edit-file.d.ts +1 -1
- package/dist/ai-service/agent/tools/build-reload-file.d.ts +8 -0
- package/dist/ai-service/agent/tools/build-reload-file.d.ts.map +1 -0
- package/dist/ai-service/agent/tools/build-reload-file.js +57 -0
- package/dist/ai-service/agent/tools/build-reload-file.js.map +1 -0
- package/dist/ai-service/agent/tools/debug-cache.js.map +1 -1
- package/dist/ai-service/agent/tools/get-console-logs.d.ts +23 -0
- package/dist/ai-service/agent/tools/get-console-logs.d.ts.map +1 -0
- package/dist/ai-service/agent/tools/get-console-logs.js +84 -0
- package/dist/ai-service/agent/tools/get-console-logs.js.map +1 -0
- package/dist/ai-service/agent/tools/get-runtime-errors.d.ts +13 -0
- package/dist/ai-service/agent/tools/get-runtime-errors.d.ts.map +1 -0
- package/dist/ai-service/agent/tools/get-runtime-errors.js +59 -0
- package/dist/ai-service/agent/tools/get-runtime-errors.js.map +1 -0
- package/dist/ai-service/agent/tools/index.d.ts +4 -0
- package/dist/ai-service/agent/tools/index.d.ts.map +1 -1
- package/dist/ai-service/agent/tools/index.js +4 -0
- package/dist/ai-service/agent/tools/index.js.map +1 -1
- package/dist/ai-service/agent/tools/integrations/execute-request.d.ts +5 -2
- package/dist/ai-service/agent/tools/integrations/execute-request.d.ts.map +1 -1
- package/dist/ai-service/agent/tools/integrations/execute-request.js +5 -3
- package/dist/ai-service/agent/tools/integrations/execute-request.js.map +1 -1
- package/dist/ai-service/agent/tools/integrations/internal.d.ts +4 -1
- package/dist/ai-service/agent/tools/integrations/internal.d.ts.map +1 -1
- package/dist/ai-service/agent/tools/integrations/internal.js +45 -3
- package/dist/ai-service/agent/tools/integrations/internal.js.map +1 -1
- package/dist/ai-service/agent/tools/integrations/metadata.d.ts.map +1 -1
- package/dist/ai-service/agent/tools/integrations/metadata.js +5 -1
- package/dist/ai-service/agent/tools/integrations/metadata.js.map +1 -1
- package/dist/ai-service/agent/tools/integrations/run-code.d.ts +4 -1
- package/dist/ai-service/agent/tools/integrations/run-code.d.ts.map +1 -1
- package/dist/ai-service/agent/tools/integrations/run-code.js +1 -1
- package/dist/ai-service/agent/tools/shared-helpers.d.ts +35 -0
- package/dist/ai-service/agent/tools/shared-helpers.d.ts.map +1 -1
- package/dist/ai-service/agent/tools/shared-helpers.js +89 -0
- package/dist/ai-service/agent/tools/shared-helpers.js.map +1 -1
- package/dist/ai-service/agent/tools.d.ts.map +1 -1
- package/dist/ai-service/agent/tools.js +11 -5
- package/dist/ai-service/agent/tools.js.map +1 -1
- package/dist/ai-service/agent/tools2/access-control.d.ts +1 -23
- package/dist/ai-service/agent/tools2/access-control.d.ts.map +1 -1
- package/dist/ai-service/agent/tools2/access-control.js +10 -67
- package/dist/ai-service/agent/tools2/access-control.js.map +1 -1
- package/dist/ai-service/agent/tools2/registry.d.ts.map +1 -1
- package/dist/ai-service/agent/tools2/registry.js +3 -3
- package/dist/ai-service/agent/tools2/registry.js.map +1 -1
- package/dist/ai-service/agent/tools2/tools/exit-plan-mode.d.ts.map +1 -1
- package/dist/ai-service/agent/tools2/tools/exit-plan-mode.js +38 -10
- package/dist/ai-service/agent/tools2/tools/exit-plan-mode.js.map +1 -1
- package/dist/ai-service/agent/tools2/types.d.ts +11 -1
- package/dist/ai-service/agent/tools2/types.d.ts.map +1 -1
- package/dist/ai-service/agent/tools2/types.js +1 -0
- package/dist/ai-service/agent/tools2/types.js.map +1 -1
- package/dist/ai-service/agent/utils.d.ts.map +1 -1
- package/dist/ai-service/agent/utils.js +33 -1
- package/dist/ai-service/agent/utils.js.map +1 -1
- package/dist/ai-service/app-interface/shell.d.ts.map +1 -1
- package/dist/ai-service/app-interface/shell.js +30 -15
- package/dist/ai-service/app-interface/shell.js.map +1 -1
- package/dist/ai-service/chat/chat-session-store.d.ts.map +1 -1
- package/dist/ai-service/chat/chat-session-store.js +71 -0
- package/dist/ai-service/chat/chat-session-store.js.map +1 -1
- package/dist/ai-service/chat/extract-history.d.ts.map +1 -1
- package/dist/ai-service/chat/extract-history.js +0 -2
- package/dist/ai-service/chat/extract-history.js.map +1 -1
- package/dist/ai-service/chat/utils.d.ts +2 -0
- package/dist/ai-service/chat/utils.d.ts.map +1 -0
- package/dist/ai-service/chat/utils.js +8 -0
- package/dist/ai-service/chat/utils.js.map +1 -0
- package/dist/ai-service/clark-provider/clark-language-model.d.ts.map +1 -1
- package/dist/ai-service/clark-provider/clark-language-model.js +6 -0
- package/dist/ai-service/clark-provider/clark-language-model.js.map +1 -1
- package/dist/ai-service/clark-provider/clark-provider.d.ts +2 -1
- package/dist/ai-service/clark-provider/clark-provider.d.ts.map +1 -1
- package/dist/ai-service/clark-provider/clark-provider.js.map +1 -1
- package/dist/ai-service/features.d.ts +4 -0
- package/dist/ai-service/features.d.ts.map +1 -1
- package/dist/ai-service/features.js +4 -0
- package/dist/ai-service/features.js.map +1 -1
- package/dist/ai-service/index.d.ts +7 -1
- package/dist/ai-service/index.d.ts.map +1 -1
- package/dist/ai-service/index.js +129 -10
- package/dist/ai-service/index.js.map +1 -1
- package/dist/ai-service/integration-validator.d.ts.map +1 -1
- package/dist/ai-service/integration-validator.js +1 -1
- package/dist/ai-service/integration-validator.js.map +1 -1
- package/dist/ai-service/integrations/store.d.ts +4 -3
- package/dist/ai-service/integrations/store.d.ts.map +1 -1
- package/dist/ai-service/integrations/store.js +43 -41
- package/dist/ai-service/integrations/store.js.map +1 -1
- package/dist/ai-service/judge/integration/mcp-client.d.ts +13 -0
- package/dist/ai-service/judge/integration/mcp-client.d.ts.map +1 -1
- package/dist/ai-service/judge/integration/mcp-client.js +15 -0
- package/dist/ai-service/judge/integration/mcp-client.js.map +1 -1
- package/dist/ai-service/judge/tools/playwright-action.d.ts +1 -1
- package/dist/ai-service/llm/client.d.ts +12 -1
- package/dist/ai-service/llm/client.d.ts.map +1 -1
- package/dist/ai-service/llm/client.js +20 -2
- package/dist/ai-service/llm/client.js.map +1 -1
- package/dist/ai-service/llm/context/context.d.ts.map +1 -1
- package/dist/ai-service/llm/context/context.js +1 -1
- package/dist/ai-service/llm/context/context.js.map +1 -1
- package/dist/ai-service/llm/context/utils/message-utils.d.ts +3 -0
- package/dist/ai-service/llm/context/utils/message-utils.d.ts.map +1 -1
- package/dist/ai-service/llm/context/utils/message-utils.js +53 -1
- package/dist/ai-service/llm/context/utils/message-utils.js.map +1 -1
- package/dist/ai-service/llm/error.d.ts +10 -2
- package/dist/ai-service/llm/error.d.ts.map +1 -1
- package/dist/ai-service/llm/error.js +22 -0
- package/dist/ai-service/llm/error.js.map +1 -1
- package/dist/ai-service/llm/interaction/adapters/vercel.js.map +1 -1
- package/dist/ai-service/llm/interaction/index.d.ts +1 -1
- package/dist/ai-service/llm/interaction/index.d.ts.map +1 -1
- package/dist/ai-service/llm/interaction/index.js.map +1 -1
- package/dist/ai-service/llm/interaction/middlewares/stream-retry.d.ts +30 -36
- package/dist/ai-service/llm/interaction/middlewares/stream-retry.d.ts.map +1 -1
- package/dist/ai-service/llm/interaction/middlewares/stream-retry.js +126 -223
- package/dist/ai-service/llm/interaction/middlewares/stream-retry.js.map +1 -1
- package/dist/ai-service/llm/interaction/middlewares/utils/abort.d.ts +41 -0
- package/dist/ai-service/llm/interaction/middlewares/utils/abort.d.ts.map +1 -0
- package/dist/ai-service/llm/interaction/middlewares/utils/abort.js +74 -0
- package/dist/ai-service/llm/interaction/middlewares/utils/abort.js.map +1 -0
- package/dist/ai-service/llm/interaction/middlewares/utils/fallback-chain.d.ts +61 -0
- package/dist/ai-service/llm/interaction/middlewares/utils/fallback-chain.d.ts.map +1 -0
- package/dist/ai-service/llm/interaction/middlewares/utils/fallback-chain.js +116 -0
- package/dist/ai-service/llm/interaction/middlewares/utils/fallback-chain.js.map +1 -0
- package/dist/ai-service/llm/interaction/middlewares/utils/retries.d.ts +47 -0
- package/dist/ai-service/llm/interaction/middlewares/utils/retries.d.ts.map +1 -0
- package/dist/ai-service/llm/interaction/middlewares/utils/retries.js +131 -0
- package/dist/ai-service/llm/interaction/middlewares/utils/retries.js.map +1 -0
- package/dist/ai-service/llm/interaction/middlewares/utils/stall-detector.d.ts +30 -0
- package/dist/ai-service/llm/interaction/middlewares/utils/stall-detector.d.ts.map +1 -0
- package/dist/ai-service/llm/interaction/middlewares/utils/stall-detector.js +36 -0
- package/dist/ai-service/llm/interaction/middlewares/utils/stall-detector.js.map +1 -0
- package/dist/ai-service/llm/interaction/middlewares/utils/streams.d.ts +42 -0
- package/dist/ai-service/llm/interaction/middlewares/utils/streams.d.ts.map +1 -0
- package/dist/ai-service/llm/interaction/middlewares/utils/streams.js +208 -0
- package/dist/ai-service/llm/interaction/middlewares/utils/streams.js.map +1 -0
- package/dist/ai-service/llm/interaction/provider.d.ts +2 -0
- package/dist/ai-service/llm/interaction/provider.d.ts.map +1 -1
- package/dist/ai-service/llm/interaction/stream-lifecycle.d.ts.map +1 -1
- package/dist/ai-service/llm/interaction/stream-lifecycle.js +21 -3
- package/dist/ai-service/llm/interaction/stream-lifecycle.js.map +1 -1
- package/dist/ai-service/llm/provider.d.ts.map +1 -1
- package/dist/ai-service/llm/provider.js +4 -3
- package/dist/ai-service/llm/provider.js.map +1 -1
- package/dist/ai-service/llmobs/middleware/stream-text.d.ts.map +1 -1
- package/dist/ai-service/llmobs/middleware/stream-text.js +17 -4
- package/dist/ai-service/llmobs/middleware/stream-text.js.map +1 -1
- package/dist/ai-service/mcp/adapter/index.d.ts +8 -0
- package/dist/ai-service/mcp/adapter/index.d.ts.map +1 -0
- package/dist/ai-service/mcp/adapter/index.js +10 -0
- package/dist/ai-service/mcp/adapter/index.js.map +1 -0
- package/dist/ai-service/mcp/adapter/json-schema-to-zod.d.ts +44 -0
- package/dist/ai-service/mcp/adapter/json-schema-to-zod.d.ts.map +1 -0
- package/dist/ai-service/mcp/adapter/json-schema-to-zod.js +231 -0
- package/dist/ai-service/mcp/adapter/json-schema-to-zod.js.map +1 -0
- package/dist/ai-service/mcp/adapter/mcp-tool-adapter.d.ts +118 -0
- package/dist/ai-service/mcp/adapter/mcp-tool-adapter.d.ts.map +1 -0
- package/dist/ai-service/mcp/adapter/mcp-tool-adapter.js +254 -0
- package/dist/ai-service/mcp/adapter/mcp-tool-adapter.js.map +1 -0
- package/dist/ai-service/mcp/index.d.ts +11 -0
- package/dist/ai-service/mcp/index.d.ts.map +1 -0
- package/dist/ai-service/mcp/index.js +11 -0
- package/dist/ai-service/mcp/index.js.map +1 -0
- package/dist/ai-service/mcp/playwright-server.d.ts.map +1 -1
- package/dist/ai-service/mcp/playwright-server.js.map +1 -1
- package/dist/ai-service/mcp/types.d.ts +94 -0
- package/dist/ai-service/mcp/types.d.ts.map +1 -0
- package/dist/ai-service/mcp/types.js +7 -0
- package/dist/ai-service/mcp/types.js.map +1 -0
- package/dist/ai-service/state-machine/clark-fsm.d.ts +6 -1
- package/dist/ai-service/state-machine/clark-fsm.d.ts.map +1 -1
- package/dist/ai-service/state-machine/clark-fsm.js +13 -0
- package/dist/ai-service/state-machine/clark-fsm.js.map +1 -1
- package/dist/ai-service/state-machine/handlers/agent-planning.d.ts.map +1 -1
- package/dist/ai-service/state-machine/handlers/agent-planning.js +2 -4
- package/dist/ai-service/state-machine/handlers/agent-planning.js.map +1 -1
- package/dist/ai-service/state-machine/handlers/idle.d.ts.map +1 -1
- package/dist/ai-service/state-machine/handlers/idle.js +4 -0
- package/dist/ai-service/state-machine/handlers/idle.js.map +1 -1
- package/dist/ai-service/state-machine/handlers/llm-generating.d.ts.map +1 -1
- package/dist/ai-service/state-machine/handlers/llm-generating.js +26 -2
- package/dist/ai-service/state-machine/handlers/llm-generating.js.map +1 -1
- package/dist/ai-service/state-machine/helpers/file-read-tracker.d.ts.map +1 -1
- package/dist/ai-service/state-machine/helpers/file-read-tracker.js +12 -3
- package/dist/ai-service/state-machine/helpers/file-read-tracker.js.map +1 -1
- package/dist/ai-service/template-renderer.d.ts.map +1 -1
- package/dist/ai-service/template-renderer.js +4 -2
- package/dist/ai-service/template-renderer.js.map +1 -1
- package/dist/ai-service/test-utils/error-mocks.d.ts.map +1 -1
- package/dist/ai-service/test-utils/error-mocks.js +9 -4
- package/dist/ai-service/test-utils/error-mocks.js.map +1 -1
- package/dist/ai-service/transform/shared.js +1 -1
- package/dist/ai-service/transform/shared.js.map +1 -1
- package/dist/ai-service/util/backoff-strategy.d.ts.map +1 -1
- package/dist/ai-service/util/backoff-strategy.js +14 -1
- package/dist/ai-service/util/backoff-strategy.js.map +1 -1
- package/dist/clark-log-forwarder.d.ts +15 -0
- package/dist/clark-log-forwarder.d.ts.map +1 -0
- package/dist/clark-log-forwarder.js +31 -0
- package/dist/clark-log-forwarder.js.map +1 -0
- package/dist/components-manager.js +1 -1
- package/dist/components-manager.js.map +1 -1
- package/dist/file-sync-vite-plugin.d.ts.map +1 -1
- package/dist/file-sync-vite-plugin.js +11 -0
- package/dist/file-sync-vite-plugin.js.map +1 -1
- package/dist/file-system-manager.d.ts.map +1 -1
- package/dist/file-system-manager.js +3 -3
- package/dist/file-system-manager.js.map +1 -1
- package/dist/socket-manager.d.ts +3 -0
- package/dist/socket-manager.d.ts.map +1 -1
- package/dist/socket-manager.js +23 -0
- package/dist/socket-manager.js.map +1 -1
- package/dist/source-tracker.d.ts.map +1 -1
- package/dist/source-tracker.js +8 -0
- package/dist/source-tracker.js.map +1 -1
- package/dist/util/logger.d.ts +5 -10
- package/dist/util/logger.d.ts.map +1 -1
- package/dist/util/logger.js +6 -7
- package/dist/util/logger.js.map +1 -1
- package/dist/util.d.ts.map +1 -1
- package/dist/util.js +0 -2
- package/dist/util.js.map +1 -1
- package/package.json +11 -11
|
@@ -1,22 +1,24 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Retry middleware for StreamText operations.
|
|
2
|
+
* Retry middleware for StreamText operations with integrated provider fallback.
|
|
3
3
|
*
|
|
4
4
|
* This middleware wraps entire streamText() calls to handle failures during
|
|
5
|
-
* stream consumption. When a stream fails mid-consumption (e.g., network timeout
|
|
6
|
-
* this middleware retries the entire streamText call with
|
|
7
|
-
* from successful steps preserved via Context.
|
|
5
|
+
* stream consumption. When a stream fails mid-consumption (e.g., network timeout,
|
|
6
|
+
* stall, or no output), this middleware retries the entire streamText call with
|
|
7
|
+
* accumulated messages from successful steps preserved via Context.
|
|
8
8
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
9
|
+
* ## Provider Fallback
|
|
10
|
+
*
|
|
11
|
+
* When fallback is enabled, the middleware cycles through provider/model combinations:
|
|
12
|
+
* - vertex/opus → bedrock/opus → vertex/sonnet → bedrock/sonnet
|
|
12
13
|
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* -
|
|
16
|
-
* - Phase 2 can retry up to 3 times (4 total attempts to consume stream)
|
|
17
|
-
* - Maximum total attempts: 4 (phase 1) + 4 (phase 2) = 8
|
|
14
|
+
* On mid-stream failure (error, stall, or no_output):
|
|
15
|
+
* - Advances to next provider/model in chain
|
|
16
|
+
* - Stays on last provider (sonnet) once chain is exhausted
|
|
18
17
|
*
|
|
19
|
-
*
|
|
18
|
+
* ## Two-phase retry architecture
|
|
19
|
+
*
|
|
20
|
+
* 1. **Initial call retry**: Retries errors when calling streamText() to get metadata
|
|
21
|
+
* 2. **Stream consumption retry**: Retries mid-stream errors during stream consumption
|
|
20
22
|
*
|
|
21
23
|
* ## Why at StreamText Level?
|
|
22
24
|
*
|
|
@@ -32,44 +34,34 @@
|
|
|
32
34
|
* - Step 1 succeeds → Context.endStep() records messages
|
|
33
35
|
* - Step 2 fails → No endStep() call, empty step array remains
|
|
34
36
|
* - Retry → Context.getMessages() provides Step 1's messages
|
|
35
|
-
* - Fresh streamText() call receives those messages and continues from Step 2
|
|
36
|
-
*
|
|
37
|
-
* ## Multi-Step Scenarios
|
|
38
|
-
*
|
|
39
|
-
* For multi-step flows (e.g., tool calling):
|
|
40
|
-
* - Step 1 (tool call) succeeds
|
|
41
|
-
* - Step 2 (continuation) fails
|
|
42
|
-
* - Retry receives Step 1's messages (including tool-results)
|
|
43
|
-
* - Vercel SDK sees tool-results and continues to Step 2
|
|
44
|
-
* - Does NOT re-execute Step 1's tools (already have results)
|
|
37
|
+
* - Fresh streamText() call receives those messages and continues from Step 2
|
|
45
38
|
*
|
|
46
39
|
* @example
|
|
47
40
|
* ```typescript
|
|
48
41
|
* const middleware = createStreamRetryMiddleware({
|
|
49
42
|
* maxRetries: 3,
|
|
50
43
|
* maxTotalRetryTimeMs: 120000,
|
|
51
|
-
*
|
|
44
|
+
* fallback: {
|
|
45
|
+
* enabled: true,
|
|
46
|
+
* initialProvider: 'vertex',
|
|
47
|
+
* initialCoreModel: 'claude-opus-4-5',
|
|
48
|
+
* stallTimeoutMs: 30000,
|
|
49
|
+
* }
|
|
52
50
|
* });
|
|
53
|
-
*
|
|
54
|
-
* const provider = applyMiddleware(baseProvider, middleware);
|
|
55
|
-
* const result = await provider.streamText({ model, messages, tools });
|
|
56
|
-
* // Automatically retries on stream consumption failures
|
|
57
51
|
* ```
|
|
58
52
|
*/
|
|
59
|
-
import {
|
|
60
|
-
import { ExponentialBackoff
|
|
53
|
+
import { getPrefixedLogger } from "../../../../util/logger.js";
|
|
54
|
+
import { ExponentialBackoff } from "../../../util/backoff-strategy.js";
|
|
61
55
|
import { LLMProviderError } from "../../error.js";
|
|
56
|
+
import { createFallbackState, getCurrentFallback, advanceFallback, applyFallbackToOptions, } from "./utils/fallback-chain.js";
|
|
57
|
+
import { wrapError, defaultIsRetryable, handleRetryAttempt, } from "./utils/retries.js";
|
|
58
|
+
import { createRetryingAsyncIterable } from "./utils/streams.js";
|
|
62
59
|
/**
|
|
63
|
-
* Creates a middleware that retries streamText calls on failure
|
|
64
|
-
*
|
|
65
|
-
* This middleware wraps the entire streamText operation, catching errors during
|
|
66
|
-
* both the initial call and stream consumption. Retries with accumulated messages from Context.
|
|
67
|
-
*
|
|
68
|
-
* @param options - Configuration for retry behavior
|
|
69
|
-
* @returns A StreamTextMiddleware
|
|
60
|
+
* Creates a middleware that retries streamText calls on failure,
|
|
61
|
+
* with optional provider fallback for mid-stream errors.
|
|
70
62
|
*/
|
|
71
63
|
export function createStreamRetryMiddleware(options = {}) {
|
|
72
|
-
const { maxRetries = Infinity, initialDelayMs = 500, maxDelayMs = 10000, backoffMultiplier = 2, maxTotalRetryTimeMs, isRetryable = defaultIsRetryable, onRetry, abortSignal, logger = getPrefixedLogger("[
|
|
64
|
+
const { maxRetries = Infinity, initialDelayMs = 500, maxDelayMs = 10000, backoffMultiplier = 2, maxTotalRetryTimeMs, isRetryable = defaultIsRetryable, onRetry, abortSignal, logger = getPrefixedLogger("[retry]"), fallback, } = options;
|
|
73
65
|
const backoffStrategy = options.backoffStrategy ??
|
|
74
66
|
new ExponentialBackoff({
|
|
75
67
|
initialDelayMs,
|
|
@@ -77,23 +69,55 @@ export function createStreamRetryMiddleware(options = {}) {
|
|
|
77
69
|
backoffMultiplier,
|
|
78
70
|
});
|
|
79
71
|
const maxRetriesDisplay = maxRetries === Infinity ? "unlimited" : String(maxRetries);
|
|
72
|
+
// Initialize fallback state if enabled
|
|
73
|
+
const fallbackState = createFallbackState(fallback);
|
|
74
|
+
const stallTimeoutMs = fallback?.stallTimeoutMs ?? 40_000;
|
|
75
|
+
let retryOnStall = fallback?.retryOnStall ?? true;
|
|
80
76
|
return {
|
|
81
77
|
wrap(provider) {
|
|
82
78
|
return {
|
|
83
79
|
async streamText(streamOptions) {
|
|
84
|
-
//
|
|
80
|
+
// Extract lifecycle callbacks - the retry middleware owns these.
|
|
81
|
+
// We can't pass them to individual attempts because:
|
|
82
|
+
// 1. We use per-attempt abort controllers to stop previous streams on retry
|
|
83
|
+
// 2. Aborting a stream triggers Vercel SDK's onAbort/onError callbacks
|
|
84
|
+
// 3. This would incorrectly release resources mid-retry
|
|
85
|
+
// ˢᵒᵐᵉᵒⁿᵉ ᵖˡᵉᵃˢᵉ ᶠᶦˣ ᵗʰᶦˢ ʷʰᵒˡᵉ ᶠᶦˡᵉ ᶦᵗˢ ᵏᶦˡˡᶦⁿᵍ ᵐᵉ
|
|
86
|
+
//
|
|
87
|
+
// Instead, we only call the original callbacks when we're actually done:
|
|
88
|
+
// - onAbort: when the user actually aborts the request (external abort signal)
|
|
89
|
+
// - onError: when all retries are exhausted and we're giving up
|
|
90
|
+
const { onAbort: originalOnAbort, onError: originalOnError, ...optionsWithoutLifecycle } = streamOptions;
|
|
91
|
+
const getOptionsForAttempt = () => {
|
|
92
|
+
const baseOptions = optionsWithoutLifecycle;
|
|
93
|
+
return fallbackState
|
|
94
|
+
? applyFallbackToOptions(baseOptions, fallbackState, logger)
|
|
95
|
+
: baseOptions;
|
|
96
|
+
};
|
|
97
|
+
if (fallbackState) {
|
|
98
|
+
const current = getCurrentFallback(fallbackState);
|
|
99
|
+
logger.info(`Starting stream: provider=${current.provider} model=${current.coreModel} index=${fallbackState.currentIndex}/${fallbackState.chain.length - 1}`);
|
|
100
|
+
}
|
|
101
|
+
// Phase 1: Retry initial streamText call (HTTP-level errors)
|
|
85
102
|
let httpAttempt = 0;
|
|
86
103
|
let totalRetryTime = 0;
|
|
87
104
|
const overallStartTime = Date.now();
|
|
88
105
|
let initialResult;
|
|
89
106
|
while (true) {
|
|
90
107
|
try {
|
|
91
|
-
initialResult = await provider.streamText(
|
|
108
|
+
initialResult = await provider.streamText(getOptionsForAttempt());
|
|
92
109
|
break; // Success!
|
|
93
110
|
}
|
|
94
111
|
catch (err) {
|
|
95
112
|
httpAttempt++;
|
|
96
113
|
const error = wrapError(err);
|
|
114
|
+
if (fallbackState) {
|
|
115
|
+
const reason = error.type === "no_output" ? "no_output" : "error";
|
|
116
|
+
const advanced = advanceFallback(fallbackState, reason, logger);
|
|
117
|
+
if (!advanced) {
|
|
118
|
+
retryOnStall = false;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
97
121
|
const delay = await handleRetryAttempt(error, httpAttempt, totalRetryTime, {
|
|
98
122
|
maxRetries,
|
|
99
123
|
maxRetriesDisplay,
|
|
@@ -109,12 +133,49 @@ export function createStreamRetryMiddleware(options = {}) {
|
|
|
109
133
|
totalRetryTime += delay;
|
|
110
134
|
}
|
|
111
135
|
}
|
|
136
|
+
if (abortSignal?.aborted) {
|
|
137
|
+
await originalOnAbort?.();
|
|
138
|
+
return initialResult;
|
|
139
|
+
}
|
|
112
140
|
// Phase 2: Wrap streams to handle consumption errors
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
141
|
+
let responseSettled = false;
|
|
142
|
+
if (initialResult.response) {
|
|
143
|
+
// Suppress unhandled rejection on response promise, we are retrying the stream
|
|
144
|
+
// below
|
|
145
|
+
initialResult.response.catch(() => { });
|
|
146
|
+
}
|
|
147
|
+
const handleStreamComplete = async () => {
|
|
148
|
+
if (responseSettled)
|
|
149
|
+
return;
|
|
150
|
+
responseSettled = true;
|
|
151
|
+
};
|
|
152
|
+
const handleStreamFailed = async (error) => {
|
|
153
|
+
if (responseSettled)
|
|
154
|
+
return;
|
|
155
|
+
responseSettled = true;
|
|
156
|
+
if (LLMProviderError.isInstance(error) &&
|
|
157
|
+
error.type === "aborted") {
|
|
158
|
+
await originalOnAbort?.();
|
|
159
|
+
}
|
|
160
|
+
else {
|
|
161
|
+
// Only call onError when we're actually giving up (retries exhausted)
|
|
162
|
+
const normalizedError = error instanceof Error ? error : new Error(String(error));
|
|
163
|
+
await originalOnError?.(normalizedError);
|
|
164
|
+
}
|
|
165
|
+
};
|
|
166
|
+
const retryingFullStream = createRetryingAsyncIterable((isInitial, attemptAbortSignal) => {
|
|
167
|
+
if (isInitial) {
|
|
168
|
+
return Promise.resolve(initialResult.fullStream);
|
|
169
|
+
}
|
|
170
|
+
return provider
|
|
171
|
+
.streamText({
|
|
172
|
+
...getOptionsForAttempt(),
|
|
173
|
+
abortSignal: attemptAbortSignal,
|
|
174
|
+
})
|
|
175
|
+
.then((res) => {
|
|
176
|
+
return res.fullStream;
|
|
177
|
+
});
|
|
178
|
+
}, {
|
|
118
179
|
maxRetries,
|
|
119
180
|
maxRetriesDisplay,
|
|
120
181
|
maxTotalRetryTimeMs,
|
|
@@ -124,12 +185,23 @@ export function createStreamRetryMiddleware(options = {}) {
|
|
|
124
185
|
onRetry,
|
|
125
186
|
abortSignal,
|
|
126
187
|
logger,
|
|
188
|
+
fallbackState,
|
|
189
|
+
fallbackConfig: fallback,
|
|
190
|
+
stallTimeoutMs,
|
|
191
|
+
retryOnStall,
|
|
192
|
+
onStreamComplete: handleStreamComplete,
|
|
193
|
+
onStreamFailed: handleStreamFailed,
|
|
127
194
|
});
|
|
128
|
-
const retryingTextStream = createRetryingAsyncIterable((isInitial) => isInitial
|
|
195
|
+
const retryingTextStream = createRetryingAsyncIterable((isInitial, attemptAbortSignal) => isInitial
|
|
129
196
|
? Promise.resolve(initialResult.textStream)
|
|
130
197
|
: provider
|
|
131
|
-
.streamText(
|
|
132
|
-
|
|
198
|
+
.streamText({
|
|
199
|
+
...getOptionsForAttempt(),
|
|
200
|
+
abortSignal: attemptAbortSignal,
|
|
201
|
+
})
|
|
202
|
+
.then((res) => {
|
|
203
|
+
return res.textStream;
|
|
204
|
+
}), {
|
|
133
205
|
maxRetries,
|
|
134
206
|
maxRetriesDisplay,
|
|
135
207
|
maxTotalRetryTimeMs,
|
|
@@ -139,8 +211,13 @@ export function createStreamRetryMiddleware(options = {}) {
|
|
|
139
211
|
onRetry,
|
|
140
212
|
abortSignal,
|
|
141
213
|
logger,
|
|
214
|
+
fallbackState: null,
|
|
215
|
+
fallbackConfig: fallback,
|
|
216
|
+
stallTimeoutMs,
|
|
217
|
+
retryOnStall: false,
|
|
218
|
+
onStreamComplete: handleStreamComplete,
|
|
219
|
+
onStreamFailed: handleStreamFailed,
|
|
142
220
|
});
|
|
143
|
-
// Return result with retrying streams
|
|
144
221
|
return {
|
|
145
222
|
...initialResult,
|
|
146
223
|
fullStream: retryingFullStream,
|
|
@@ -151,178 +228,4 @@ export function createStreamRetryMiddleware(options = {}) {
|
|
|
151
228
|
},
|
|
152
229
|
};
|
|
153
230
|
}
|
|
154
|
-
/**
|
|
155
|
-
* Creates an AsyncIterableStream that retries on consumption errors.
|
|
156
|
-
*/
|
|
157
|
-
function createRetryingAsyncIterable(getStream, config) {
|
|
158
|
-
// Create an AsyncIterable that implements the retry logic
|
|
159
|
-
const retryingIterable = {
|
|
160
|
-
async *[Symbol.asyncIterator]() {
|
|
161
|
-
let consumptionAttempt = 0;
|
|
162
|
-
let totalRetryTimeMs = 0;
|
|
163
|
-
let isFirstAttempt = true;
|
|
164
|
-
while (true) {
|
|
165
|
-
try {
|
|
166
|
-
// Get stream for current attempt
|
|
167
|
-
const iterator = (await getStream(isFirstAttempt))[Symbol.asyncIterator]();
|
|
168
|
-
isFirstAttempt = false;
|
|
169
|
-
// Iterate through chunks
|
|
170
|
-
while (true) {
|
|
171
|
-
const { value: chunk, done } = await iterator.next();
|
|
172
|
-
if (done) {
|
|
173
|
-
return; // Success!
|
|
174
|
-
}
|
|
175
|
-
// Check for error chunks
|
|
176
|
-
if (typeof chunk !== "string" && chunk.type === "error") {
|
|
177
|
-
throw wrapError(chunk.error);
|
|
178
|
-
}
|
|
179
|
-
// Normal chunk - yield it
|
|
180
|
-
yield chunk;
|
|
181
|
-
if (isProgressChunk(chunk)) {
|
|
182
|
-
consumptionAttempt = 0;
|
|
183
|
-
totalRetryTimeMs = 0;
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
catch (err) {
|
|
188
|
-
const error = wrapError(err);
|
|
189
|
-
// Handle error - check if we should retry
|
|
190
|
-
consumptionAttempt++;
|
|
191
|
-
try {
|
|
192
|
-
const delay = await handleRetryAttempt(error, consumptionAttempt, totalRetryTimeMs, {
|
|
193
|
-
...config,
|
|
194
|
-
errorContext: "Stream error",
|
|
195
|
-
});
|
|
196
|
-
totalRetryTimeMs += delay;
|
|
197
|
-
// Loop continues - will try again with fresh stream
|
|
198
|
-
}
|
|
199
|
-
catch (finalError) {
|
|
200
|
-
// Exhausted or non-retryable - yield error and exit
|
|
201
|
-
yield {
|
|
202
|
-
type: "error",
|
|
203
|
-
error: finalError,
|
|
204
|
-
};
|
|
205
|
-
return;
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
},
|
|
210
|
-
};
|
|
211
|
-
// Convert AsyncIterable to ReadableStream
|
|
212
|
-
const readableStream = new ReadableStream({
|
|
213
|
-
async start(controller) {
|
|
214
|
-
try {
|
|
215
|
-
for await (const chunk of retryingIterable) {
|
|
216
|
-
controller.enqueue(chunk);
|
|
217
|
-
}
|
|
218
|
-
controller.close();
|
|
219
|
-
}
|
|
220
|
-
catch (error) {
|
|
221
|
-
controller.error(error);
|
|
222
|
-
}
|
|
223
|
-
},
|
|
224
|
-
});
|
|
225
|
-
// Return as AsyncIterableStream (ReadableStream with async iteration support)
|
|
226
|
-
return readableStream;
|
|
227
|
-
}
|
|
228
|
-
/**
|
|
229
|
-
* Wraps an error in LLMProviderError if it isn't already.
|
|
230
|
-
*/
|
|
231
|
-
function wrapError(err, provider) {
|
|
232
|
-
if (err instanceof LLMProviderError) {
|
|
233
|
-
return err;
|
|
234
|
-
}
|
|
235
|
-
// Provider is optional here since we may not know it at this level
|
|
236
|
-
return new LLMProviderError({
|
|
237
|
-
provider: provider,
|
|
238
|
-
cause: err,
|
|
239
|
-
});
|
|
240
|
-
}
|
|
241
|
-
/**
|
|
242
|
-
* Checks if retry is allowed and executes retry logic.
|
|
243
|
-
* Returns the delay in milliseconds if a retry should be attempted.
|
|
244
|
-
* Throws if no retry is possible.
|
|
245
|
-
*/
|
|
246
|
-
async function handleRetryAttempt(error, attempt, totalRetryTimeMs, config) {
|
|
247
|
-
config.logger.debug(`totalRetryTimeMs: ${totalRetryTimeMs}`);
|
|
248
|
-
// Check abort signal
|
|
249
|
-
if (config.abortSignal?.aborted) {
|
|
250
|
-
const abortError = new LLMProviderError({
|
|
251
|
-
provider: error.provider,
|
|
252
|
-
message: "Request aborted",
|
|
253
|
-
type: "aborted",
|
|
254
|
-
isRetryable: false,
|
|
255
|
-
});
|
|
256
|
-
config.logger.info("Request aborted, stopping retry attempts");
|
|
257
|
-
throw abortError;
|
|
258
|
-
}
|
|
259
|
-
// Check retry conditions
|
|
260
|
-
const withinMaxRetries = attempt <= config.maxRetries;
|
|
261
|
-
const withinTimeLimit = !config.maxTotalRetryTimeMs ||
|
|
262
|
-
totalRetryTimeMs < config.maxTotalRetryTimeMs;
|
|
263
|
-
const errorIsRetryable = config.isRetryable(error);
|
|
264
|
-
const canRetry = errorIsRetryable && withinMaxRetries && withinTimeLimit;
|
|
265
|
-
if (!canRetry) {
|
|
266
|
-
if (errorIsRetryable) {
|
|
267
|
-
const reason = !withinMaxRetries
|
|
268
|
-
? `after ${config.maxRetriesDisplay} retries`
|
|
269
|
-
: `total retry time exceeded ${config.maxTotalRetryTimeMs}ms`;
|
|
270
|
-
config.logger.error(`Exceeded retry limits: ${reason}`, getErrorMeta(error));
|
|
271
|
-
throw new LLMProviderError({
|
|
272
|
-
provider: error.provider,
|
|
273
|
-
message: `${config.errorContext} ${reason}`,
|
|
274
|
-
type: "retries_exhausted",
|
|
275
|
-
isRetryable: false,
|
|
276
|
-
cause: error,
|
|
277
|
-
});
|
|
278
|
-
}
|
|
279
|
-
config.logger.error("Non-retryable error encountered", getErrorMeta(error));
|
|
280
|
-
throw error;
|
|
281
|
-
}
|
|
282
|
-
// Calculate backoff delay
|
|
283
|
-
const delay = config.backoffStrategy.getNextDelay(attempt);
|
|
284
|
-
config.logger.warn(`${config.errorContext} (type: ${error.type}). Attempt ${attempt}/${config.maxRetriesDisplay}. Retrying in ${delay}ms... Error: ${JSON.stringify(error)}`);
|
|
285
|
-
// Call onRetry callback
|
|
286
|
-
if (config.onRetry) {
|
|
287
|
-
await config.onRetry(error, attempt, delay, totalRetryTimeMs);
|
|
288
|
-
}
|
|
289
|
-
// Wait before retry
|
|
290
|
-
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
291
|
-
return delay;
|
|
292
|
-
}
|
|
293
|
-
function defaultIsRetryable(error) {
|
|
294
|
-
if (LLMProviderError.isInstance(error)) {
|
|
295
|
-
return error.isRetryable;
|
|
296
|
-
}
|
|
297
|
-
// For thrown errors or unstructured errors, be permissive and retry
|
|
298
|
-
// These might be network issues, timeouts, or other transient problems
|
|
299
|
-
return true;
|
|
300
|
-
}
|
|
301
|
-
/**
|
|
302
|
-
* Chunk types that indicate meaningful progress from the LLM.
|
|
303
|
-
* These warrant resetting the retry counter because we're making real progress.
|
|
304
|
-
*
|
|
305
|
-
* Excluded chunk types (don't reset retry):
|
|
306
|
-
* - Start markers: text-start, reasoning-start, tool-input-start, start-step, start
|
|
307
|
-
* - End markers without content: text-end, reasoning-end, tool-input-end
|
|
308
|
-
* - Errors: error, tool-error, abort
|
|
309
|
-
* - Unknown: raw
|
|
310
|
-
*/
|
|
311
|
-
const PROGRESS_CHUNK_TYPES = new Set([
|
|
312
|
-
"text-delta",
|
|
313
|
-
"reasoning-delta",
|
|
314
|
-
"tool-input-delta",
|
|
315
|
-
"tool-call",
|
|
316
|
-
"tool-result",
|
|
317
|
-
"source",
|
|
318
|
-
"file",
|
|
319
|
-
"finish-step",
|
|
320
|
-
"finish",
|
|
321
|
-
]);
|
|
322
|
-
function isProgressChunk(chunk) {
|
|
323
|
-
if (typeof chunk === "string") {
|
|
324
|
-
return true;
|
|
325
|
-
}
|
|
326
|
-
return PROGRESS_CHUNK_TYPES.has(chunk.type);
|
|
327
|
-
}
|
|
328
231
|
//# sourceMappingURL=stream-retry.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stream-retry.js","sourceRoot":"","sources":["../../../../../src/ai-service/llm/interaction/middlewares/stream-retry.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"stream-retry.js","sourceRoot":"","sources":["../../../../../src/ai-service/llm/interaction/middlewares/stream-retry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Chains multiple abort signals into a single signal that aborts when any input aborts.
|
|
3
|
+
*
|
|
4
|
+
* This is used to combine:
|
|
5
|
+
* - External abort signal (user cancellation)
|
|
6
|
+
* - Per-attempt abort controller (to cancel previous attempts on retry)
|
|
7
|
+
*
|
|
8
|
+
* When either signal aborts, the combined signal also aborts with the same reason.
|
|
9
|
+
*
|
|
10
|
+
* @param signals - Abort signals to chain (undefined signals are ignored)
|
|
11
|
+
* @returns A combined abort signal that aborts when any input aborts
|
|
12
|
+
*/
|
|
13
|
+
export declare function chainAbortSignals(...signals: (AbortSignal | undefined)[]): AbortSignal;
|
|
14
|
+
/**
|
|
15
|
+
* Manages per-attempt abort controllers for retrying operations.
|
|
16
|
+
*
|
|
17
|
+
* Each retry attempt gets its own abort controller so we can cancel
|
|
18
|
+
* the previous attempt before starting a new one. This prevents resource
|
|
19
|
+
* leaks and ensures clean handoff between attempts.
|
|
20
|
+
*/
|
|
21
|
+
export declare class AttemptAbortManager {
|
|
22
|
+
private currentController;
|
|
23
|
+
private readonly externalSignal;
|
|
24
|
+
constructor(externalSignal?: AbortSignal);
|
|
25
|
+
/**
|
|
26
|
+
* Checks if the external abort signal has been triggered.
|
|
27
|
+
*/
|
|
28
|
+
isExternallyAborted(): boolean;
|
|
29
|
+
/**
|
|
30
|
+
* Aborts the current attempt (if any) and creates a new abort controller.
|
|
31
|
+
* Returns a signal that aborts when either the external signal or the
|
|
32
|
+
* per-attempt controller aborts.
|
|
33
|
+
*/
|
|
34
|
+
startNewAttempt(): AbortSignal;
|
|
35
|
+
/**
|
|
36
|
+
* Aborts the current attempt due to an error or stall.
|
|
37
|
+
* Call this before starting retry logic.
|
|
38
|
+
*/
|
|
39
|
+
abortCurrentAttempt(): void;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=abort.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"abort.d.ts","sourceRoot":"","sources":["../../../../../../src/ai-service/llm/interaction/middlewares/utils/abort.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,wBAAgB,iBAAiB,CAC/B,GAAG,OAAO,EAAE,CAAC,WAAW,GAAG,SAAS,CAAC,EAAE,GACtC,WAAW,CAmBb;AAED;;;;;;GAMG;AACH,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,iBAAiB,CAAgC;IACzD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAA0B;gBAE7C,cAAc,CAAC,EAAE,WAAW;IAIxC;;OAEG;IACH,mBAAmB,IAAI,OAAO;IAI9B;;;;OAIG;IACH,eAAe,IAAI,WAAW;IAgB9B;;;OAGG;IACH,mBAAmB,IAAI,IAAI;CAK5B"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Chains multiple abort signals into a single signal that aborts when any input aborts.
|
|
3
|
+
*
|
|
4
|
+
* This is used to combine:
|
|
5
|
+
* - External abort signal (user cancellation)
|
|
6
|
+
* - Per-attempt abort controller (to cancel previous attempts on retry)
|
|
7
|
+
*
|
|
8
|
+
* When either signal aborts, the combined signal also aborts with the same reason.
|
|
9
|
+
*
|
|
10
|
+
* @param signals - Abort signals to chain (undefined signals are ignored)
|
|
11
|
+
* @returns A combined abort signal that aborts when any input aborts
|
|
12
|
+
*/
|
|
13
|
+
export function chainAbortSignals(...signals) {
|
|
14
|
+
const controller = new AbortController();
|
|
15
|
+
for (const signal of signals) {
|
|
16
|
+
if (!signal)
|
|
17
|
+
continue;
|
|
18
|
+
// If already aborted, immediately abort the combined signal
|
|
19
|
+
if (signal.aborted) {
|
|
20
|
+
controller.abort(signal.reason);
|
|
21
|
+
return controller.signal;
|
|
22
|
+
}
|
|
23
|
+
// Forward abort events from source to combined signal
|
|
24
|
+
signal.addEventListener("abort", () => controller.abort(signal.reason), {
|
|
25
|
+
once: true,
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
return controller.signal;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Manages per-attempt abort controllers for retrying operations.
|
|
32
|
+
*
|
|
33
|
+
* Each retry attempt gets its own abort controller so we can cancel
|
|
34
|
+
* the previous attempt before starting a new one. This prevents resource
|
|
35
|
+
* leaks and ensures clean handoff between attempts.
|
|
36
|
+
*/
|
|
37
|
+
export class AttemptAbortManager {
|
|
38
|
+
currentController = null;
|
|
39
|
+
externalSignal;
|
|
40
|
+
constructor(externalSignal) {
|
|
41
|
+
this.externalSignal = externalSignal;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Checks if the external abort signal has been triggered.
|
|
45
|
+
*/
|
|
46
|
+
isExternallyAborted() {
|
|
47
|
+
return this.externalSignal?.aborted ?? false;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Aborts the current attempt (if any) and creates a new abort controller.
|
|
51
|
+
* Returns a signal that aborts when either the external signal or the
|
|
52
|
+
* per-attempt controller aborts.
|
|
53
|
+
*/
|
|
54
|
+
startNewAttempt() {
|
|
55
|
+
// Abort previous attempt if exists
|
|
56
|
+
if (this.currentController) {
|
|
57
|
+
this.currentController.abort();
|
|
58
|
+
}
|
|
59
|
+
// Create new controller for this attempt
|
|
60
|
+
this.currentController = new AbortController();
|
|
61
|
+
// Chain with external signal
|
|
62
|
+
return chainAbortSignals(this.externalSignal, this.currentController.signal);
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Aborts the current attempt due to an error or stall.
|
|
66
|
+
* Call this before starting retry logic.
|
|
67
|
+
*/
|
|
68
|
+
abortCurrentAttempt() {
|
|
69
|
+
if (this.currentController) {
|
|
70
|
+
this.currentController.abort();
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=abort.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"abort.js","sourceRoot":"","sources":["../../../../../../src/ai-service/llm/interaction/middlewares/utils/abort.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,iBAAiB,CAC/B,GAAG,OAAoC;IAEvC,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;IAEzC,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,IAAI,CAAC,MAAM;YAAE,SAAS;QAEtB,4DAA4D;QAC5D,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACnB,UAAU,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YAChC,OAAO,UAAU,CAAC,MAAM,CAAC;QAC3B,CAAC;QAED,sDAAsD;QACtD,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE;YACtE,IAAI,EAAE,IAAI;SACX,CAAC,CAAC;IACL,CAAC;IAED,OAAO,UAAU,CAAC,MAAM,CAAC;AAC3B,CAAC;AAED;;;;;;GAMG;AACH,MAAM,OAAO,mBAAmB;IACtB,iBAAiB,GAA2B,IAAI,CAAC;IACxC,cAAc,CAA0B;IAEzD,YAAY,cAA4B;QACtC,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC;IACvC,CAAC;IAED;;OAEG;IACH,mBAAmB;QACjB,OAAO,IAAI,CAAC,cAAc,EAAE,OAAO,IAAI,KAAK,CAAC;IAC/C,CAAC;IAED;;;;OAIG;IACH,eAAe;QACb,mCAAmC;QACnC,IAAI,IAAI,CAAC,iBAAiB,EAAE,CAAC;YAC3B,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,CAAC;QACjC,CAAC;QAED,yCAAyC;QACzC,IAAI,CAAC,iBAAiB,GAAG,IAAI,eAAe,EAAE,CAAC;QAE/C,6BAA6B;QAC7B,OAAO,iBAAiB,CACtB,IAAI,CAAC,cAAc,EACnB,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAC9B,CAAC;IACJ,CAAC;IAED;;;OAGG;IACH,mBAAmB;QACjB,IAAI,IAAI,CAAC,iBAAiB,EAAE,CAAC;YAC3B,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,CAAC;QACjC,CAAC;IACH,CAAC;CACF"}
|