@superblocksteam/vite-plugin-file-sync 2.0.70 → 2.0.71-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/prompts/build-base-system-prompt.js +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.map +1 -1
- package/dist/ai-service/agent/tool-message-utils.js +5 -0
- package/dist/ai-service/agent/tool-message-utils.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 +2 -1
- package/dist/ai-service/agent/tools/apis/build-api-artifact.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 +16 -5
- package/dist/ai-service/agent/tools/apis/test-api.js.map +1 -1
- package/dist/ai-service/agent/tools/build-capture-screenshot.d.ts +35 -0
- package/dist/ai-service/agent/tools/build-capture-screenshot.d.ts.map +1 -1
- package/dist/ai-service/agent/tools/build-capture-screenshot.js +90 -15
- package/dist/ai-service/agent/tools/build-capture-screenshot.js.map +1 -1
- package/dist/ai-service/agent/tools/build-validate-icons.d.ts +3 -18
- package/dist/ai-service/agent/tools/build-validate-icons.d.ts.map +1 -1
- package/dist/ai-service/agent/tools/build-validate-icons.js +12 -50
- package/dist/ai-service/agent/tools/build-validate-icons.js.map +1 -1
- package/dist/ai-service/agent/tools/debug-cache.js.map +1 -1
- package/dist/ai-service/agent/tools/integrations/execute-request.d.ts +1 -1
- package/dist/ai-service/agent/tools/shared-helpers.d.ts +0 -35
- package/dist/ai-service/agent/tools/shared-helpers.d.ts.map +1 -1
- package/dist/ai-service/agent/tools/shared-helpers.js +0 -89
- package/dist/ai-service/agent/tools/shared-helpers.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 +3 -68
- 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 +16 -5
- package/dist/ai-service/agent/tools2/registry.js.map +1 -1
- package/dist/ai-service/agent/tools2/tools/bash.d.ts.map +1 -1
- package/dist/ai-service/agent/tools2/tools/bash.js +2 -1
- package/dist/ai-service/agent/tools2/tools/bash.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 +10 -2
- package/dist/ai-service/agent/tools2/tools/exit-plan-mode.js.map +1 -1
- package/dist/ai-service/agent/tools2/tools/grep.d.ts.map +1 -1
- package/dist/ai-service/agent/tools2/tools/grep.js +2 -1
- package/dist/ai-service/agent/tools2/tools/grep.js.map +1 -1
- package/dist/ai-service/agent/tools2/tools/ls.d.ts.map +1 -1
- package/dist/ai-service/agent/tools2/tools/ls.js +3 -1
- package/dist/ai-service/agent/tools2/tools/ls.js.map +1 -1
- package/dist/ai-service/agent/tools2/types.d.ts +2 -1
- package/dist/ai-service/agent/tools2/types.d.ts.map +1 -1
- package/dist/ai-service/agent/tools2/types.js +31 -11
- 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 +5 -10
- package/dist/ai-service/agent/utils.js.map +1 -1
- package/dist/ai-service/clark-provider/clark-chat-settings.d.ts +2 -1
- package/dist/ai-service/clark-provider/clark-chat-settings.d.ts.map +1 -1
- package/dist/ai-service/clark-provider/clark-chat-settings.js +1 -0
- package/dist/ai-service/clark-provider/clark-chat-settings.js.map +1 -1
- package/dist/ai-service/index.d.ts.map +1 -1
- package/dist/ai-service/index.js +7 -4
- package/dist/ai-service/index.js.map +1 -1
- package/dist/ai-service/integrations/store.d.ts +1 -0
- package/dist/ai-service/integrations/store.d.ts.map +1 -1
- package/dist/ai-service/integrations/store.js +1 -0
- package/dist/ai-service/integrations/store.js.map +1 -1
- package/dist/ai-service/llm/client.d.ts +14 -117
- package/dist/ai-service/llm/client.d.ts.map +1 -1
- package/dist/ai-service/llm/client.js +57 -149
- package/dist/ai-service/llm/client.js.map +1 -1
- package/dist/ai-service/llm/error.d.ts +7 -2
- package/dist/ai-service/llm/error.d.ts.map +1 -1
- package/dist/ai-service/llm/error.js +17 -17
- package/dist/ai-service/llm/error.js.map +1 -1
- package/dist/ai-service/llm/impl/anthropic.d.ts.map +1 -1
- package/dist/ai-service/llm/impl/anthropic.js +2 -1
- package/dist/ai-service/llm/impl/anthropic.js.map +1 -1
- package/dist/ai-service/llm/impl/clark.d.ts.map +1 -1
- package/dist/ai-service/llm/impl/clark.js +2 -1
- package/dist/ai-service/llm/impl/clark.js.map +1 -1
- package/dist/ai-service/llm/interaction/index.d.ts +0 -64
- package/dist/ai-service/llm/interaction/index.d.ts.map +1 -1
- package/dist/ai-service/llm/interaction/index.js +0 -65
- package/dist/ai-service/llm/interaction/index.js.map +1 -1
- package/dist/ai-service/llm/provider.d.ts.map +1 -1
- package/dist/ai-service/llm/provider.js +2 -6
- package/dist/ai-service/llm/provider.js.map +1 -1
- package/dist/ai-service/llm/stream/config.d.ts +56 -0
- package/dist/ai-service/llm/stream/config.d.ts.map +1 -0
- package/dist/ai-service/llm/stream/config.js +41 -0
- package/dist/ai-service/llm/stream/config.js.map +1 -0
- package/dist/ai-service/llm/stream/errors.d.ts +16 -0
- package/dist/ai-service/llm/stream/errors.d.ts.map +1 -0
- package/dist/ai-service/llm/stream/errors.js +68 -0
- package/dist/ai-service/llm/stream/errors.js.map +1 -0
- package/dist/ai-service/llm/stream/event-bus.d.ts +68 -0
- package/dist/ai-service/llm/stream/event-bus.d.ts.map +1 -0
- package/dist/ai-service/llm/stream/event-bus.js +51 -0
- package/dist/ai-service/llm/stream/event-bus.js.map +1 -0
- package/dist/ai-service/llm/stream/index.d.ts +49 -0
- package/dist/ai-service/llm/stream/index.d.ts.map +1 -0
- package/dist/ai-service/llm/stream/index.js +46 -0
- package/dist/ai-service/llm/stream/index.js.map +1 -0
- package/dist/ai-service/llm/stream/managed-stream.d.ts +25 -0
- package/dist/ai-service/llm/stream/managed-stream.d.ts.map +1 -0
- package/dist/ai-service/llm/stream/managed-stream.js +68 -0
- package/dist/ai-service/llm/stream/managed-stream.js.map +1 -0
- package/dist/ai-service/llm/stream/observer.d.ts +34 -0
- package/dist/ai-service/llm/stream/observer.d.ts.map +1 -0
- package/dist/ai-service/llm/stream/observer.js +2 -0
- package/dist/ai-service/llm/stream/observer.js.map +1 -0
- package/dist/ai-service/llm/stream/observers/context.d.ts +40 -0
- package/dist/ai-service/llm/stream/observers/context.d.ts.map +1 -0
- package/dist/ai-service/llm/stream/observers/context.js +55 -0
- package/dist/ai-service/llm/stream/observers/context.js.map +1 -0
- package/dist/ai-service/llm/stream/observers/index.d.ts +8 -0
- package/dist/ai-service/llm/stream/observers/index.d.ts.map +1 -0
- package/dist/ai-service/llm/stream/observers/index.js +8 -0
- package/dist/ai-service/llm/stream/observers/index.js.map +1 -0
- package/dist/ai-service/llm/stream/observers/llmobs.d.ts +78 -0
- package/dist/ai-service/llm/stream/observers/llmobs.d.ts.map +1 -0
- package/dist/ai-service/llm/stream/observers/llmobs.js +504 -0
- package/dist/ai-service/llm/stream/observers/llmobs.js.map +1 -0
- package/dist/ai-service/llm/stream/observers/logging.d.ts +46 -0
- package/dist/ai-service/llm/stream/observers/logging.d.ts.map +1 -0
- package/dist/ai-service/llm/stream/observers/logging.js +296 -0
- package/dist/ai-service/llm/stream/observers/logging.js.map +1 -0
- package/dist/ai-service/llm/stream/observers/retry-notification.d.ts +17 -0
- package/dist/ai-service/llm/stream/observers/retry-notification.d.ts.map +1 -0
- package/dist/ai-service/llm/stream/observers/retry-notification.js +36 -0
- package/dist/ai-service/llm/stream/observers/retry-notification.js.map +1 -0
- package/dist/ai-service/llm/stream/orchestrator.d.ts +73 -0
- package/dist/ai-service/llm/stream/orchestrator.d.ts.map +1 -0
- package/dist/ai-service/llm/stream/orchestrator.js +285 -0
- package/dist/ai-service/llm/stream/orchestrator.js.map +1 -0
- package/dist/ai-service/llm/stream/retry-engine.d.ts +58 -0
- package/dist/ai-service/llm/stream/retry-engine.d.ts.map +1 -0
- package/dist/ai-service/llm/stream/retry-engine.js +151 -0
- package/dist/ai-service/llm/stream/retry-engine.js.map +1 -0
- package/dist/ai-service/llm/stream/session.d.ts +58 -0
- package/dist/ai-service/llm/stream/session.d.ts.map +1 -0
- package/dist/ai-service/llm/stream/session.js +116 -0
- package/dist/ai-service/llm/stream/session.js.map +1 -0
- package/dist/ai-service/llm/stream/tests/helpers/mock-provider.d.ts +129 -0
- package/dist/ai-service/llm/stream/tests/helpers/mock-provider.d.ts.map +1 -0
- package/dist/ai-service/llm/stream/tests/helpers/mock-provider.js +508 -0
- package/dist/ai-service/llm/stream/tests/helpers/mock-provider.js.map +1 -0
- package/dist/ai-service/llm/stream/types.d.ts +15 -0
- package/dist/ai-service/llm/stream/types.d.ts.map +1 -0
- package/dist/ai-service/llm/stream/types.js +2 -0
- package/dist/ai-service/llm/stream/types.js.map +1 -0
- package/dist/ai-service/llm/types.d.ts +1 -1
- package/dist/ai-service/llm/types.d.ts.map +1 -1
- package/dist/ai-service/llmobs/helpers.d.ts +0 -19
- package/dist/ai-service/llmobs/helpers.d.ts.map +1 -1
- package/dist/ai-service/llmobs/helpers.js +0 -23
- package/dist/ai-service/llmobs/helpers.js.map +1 -1
- package/dist/ai-service/llmobs/tracer.d.ts +1 -0
- package/dist/ai-service/llmobs/tracer.d.ts.map +1 -1
- package/dist/ai-service/llmobs/tracer.js +1 -0
- package/dist/ai-service/llmobs/tracer.js.map +1 -1
- package/dist/ai-service/llmobs/types.d.ts +2 -0
- package/dist/ai-service/llmobs/types.d.ts.map +1 -1
- package/dist/ai-service/llmobs/utils.d.ts.map +1 -1
- package/dist/ai-service/llmobs/utils.js +8 -0
- package/dist/ai-service/llmobs/utils.js.map +1 -1
- 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/state-machine/clark-fsm.d.ts +1 -3
- package/dist/ai-service/state-machine/clark-fsm.d.ts.map +1 -1
- package/dist/ai-service/state-machine/clark-fsm.js +6 -28
- 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 +9 -11
- package/dist/ai-service/state-machine/handlers/agent-planning.js.map +1 -1
- package/dist/ai-service/state-machine/handlers/awaiting-user.d.ts.map +1 -1
- package/dist/ai-service/state-machine/handlers/awaiting-user.js +3 -2
- package/dist/ai-service/state-machine/handlers/awaiting-user.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 +18 -4
- package/dist/ai-service/state-machine/handlers/llm-generating.js.map +1 -1
- package/dist/ai-service/state-machine/traced-fsm.d.ts +5 -4
- package/dist/ai-service/state-machine/traced-fsm.d.ts.map +1 -1
- package/dist/ai-service/state-machine/traced-fsm.js +25 -25
- package/dist/ai-service/state-machine/traced-fsm.js.map +1 -1
- package/dist/ai-service/types.d.ts +3 -3
- package/dist/ai-service/types.d.ts.map +1 -1
- package/dist/ai-service/types.js +10 -10
- package/dist/ai-service/types.js.map +1 -1
- package/dist/socket-manager.d.ts.map +1 -1
- package/dist/socket-manager.js +10 -3
- 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/sync-service/index.d.ts +7 -2
- package/dist/sync-service/index.d.ts.map +1 -1
- package/dist/sync-service/index.js +16 -9
- package/dist/sync-service/index.js.map +1 -1
- package/package.json +11 -11
- package/dist/ai-service/llm/interaction/compose.d.ts +0 -71
- package/dist/ai-service/llm/interaction/compose.d.ts.map +0 -1
- package/dist/ai-service/llm/interaction/compose.js +0 -88
- package/dist/ai-service/llm/interaction/compose.js.map +0 -1
- package/dist/ai-service/llm/interaction/middleware.d.ts +0 -52
- package/dist/ai-service/llm/interaction/middleware.d.ts.map +0 -1
- package/dist/ai-service/llm/interaction/middleware.js +0 -17
- package/dist/ai-service/llm/interaction/middleware.js.map +0 -1
- package/dist/ai-service/llm/interaction/middlewares/llmobs.d.ts +0 -45
- package/dist/ai-service/llm/interaction/middlewares/llmobs.d.ts.map +0 -1
- package/dist/ai-service/llm/interaction/middlewares/llmobs.js +0 -85
- package/dist/ai-service/llm/interaction/middlewares/llmobs.js.map +0 -1
- package/dist/ai-service/llm/interaction/middlewares/logging.d.ts +0 -88
- package/dist/ai-service/llm/interaction/middlewares/logging.d.ts.map +0 -1
- package/dist/ai-service/llm/interaction/middlewares/logging.js +0 -238
- package/dist/ai-service/llm/interaction/middlewares/logging.js.map +0 -1
- package/dist/ai-service/llm/interaction/middlewares/profiler.d.ts +0 -47
- package/dist/ai-service/llm/interaction/middlewares/profiler.d.ts.map +0 -1
- package/dist/ai-service/llm/interaction/middlewares/profiler.js +0 -183
- package/dist/ai-service/llm/interaction/middlewares/profiler.js.map +0 -1
- package/dist/ai-service/llm/interaction/middlewares/stream-retry.d.ts +0 -115
- package/dist/ai-service/llm/interaction/middlewares/stream-retry.d.ts.map +0 -1
- package/dist/ai-service/llm/interaction/middlewares/stream-retry.js +0 -231
- package/dist/ai-service/llm/interaction/middlewares/stream-retry.js.map +0 -1
- package/dist/ai-service/llm/interaction/middlewares/utils/abort.d.ts +0 -41
- package/dist/ai-service/llm/interaction/middlewares/utils/abort.d.ts.map +0 -1
- package/dist/ai-service/llm/interaction/middlewares/utils/abort.js +0 -74
- package/dist/ai-service/llm/interaction/middlewares/utils/abort.js.map +0 -1
- package/dist/ai-service/llm/interaction/middlewares/utils/fallback-chain.d.ts +0 -61
- package/dist/ai-service/llm/interaction/middlewares/utils/fallback-chain.d.ts.map +0 -1
- package/dist/ai-service/llm/interaction/middlewares/utils/fallback-chain.js +0 -116
- package/dist/ai-service/llm/interaction/middlewares/utils/fallback-chain.js.map +0 -1
- package/dist/ai-service/llm/interaction/middlewares/utils/retries.d.ts +0 -47
- package/dist/ai-service/llm/interaction/middlewares/utils/retries.d.ts.map +0 -1
- package/dist/ai-service/llm/interaction/middlewares/utils/retries.js +0 -141
- package/dist/ai-service/llm/interaction/middlewares/utils/retries.js.map +0 -1
- package/dist/ai-service/llm/interaction/middlewares/utils/stall-detector.d.ts +0 -30
- package/dist/ai-service/llm/interaction/middlewares/utils/stall-detector.d.ts.map +0 -1
- package/dist/ai-service/llm/interaction/middlewares/utils/stall-detector.js +0 -36
- package/dist/ai-service/llm/interaction/middlewares/utils/stall-detector.js.map +0 -1
- package/dist/ai-service/llm/interaction/middlewares/utils/streams.d.ts +0 -42
- package/dist/ai-service/llm/interaction/middlewares/utils/streams.d.ts.map +0 -1
- package/dist/ai-service/llm/interaction/middlewares/utils/streams.js +0 -208
- package/dist/ai-service/llm/interaction/middlewares/utils/streams.js.map +0 -1
- package/dist/ai-service/llmobs/middleware/stream-text.d.ts +0 -56
- package/dist/ai-service/llmobs/middleware/stream-text.d.ts.map +0 -1
- package/dist/ai-service/llmobs/middleware/stream-text.js +0 -597
- package/dist/ai-service/llmobs/middleware/stream-text.js.map +0 -1
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Retry middleware for StreamText operations with integrated provider fallback.
|
|
3
|
-
*
|
|
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
|
-
* stall, or no output), this middleware retries the entire streamText call with
|
|
7
|
-
* accumulated messages from successful steps preserved via Context.
|
|
8
|
-
*
|
|
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
|
|
13
|
-
*
|
|
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
|
|
17
|
-
*
|
|
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
|
|
22
|
-
*
|
|
23
|
-
* ## Why at StreamText Level?
|
|
24
|
-
*
|
|
25
|
-
* Retrying at the streamText level (vs model.doStream level) ensures:
|
|
26
|
-
* 1. **Fresh Vercel SDK state**: Each retry gets a new eventProcessor with no
|
|
27
|
-
* partial chunk pollution from failed attempts
|
|
28
|
-
* 2. **Correct message sequences**: No orphaned content IDs or invalid message structures
|
|
29
|
-
* 3. **Natural continuation**: Vercel SDK's built-in logic handles multi-step resumption
|
|
30
|
-
*
|
|
31
|
-
* ## How It Works with Context
|
|
32
|
-
*
|
|
33
|
-
* The Context system provides the accumulated messages for retry:
|
|
34
|
-
* - Step 1 succeeds → Context.endStep() records messages
|
|
35
|
-
* - Step 2 fails → No endStep() call, empty step array remains
|
|
36
|
-
* - Retry → Context.getMessages() provides Step 1's messages
|
|
37
|
-
* - Fresh streamText() call receives those messages and continues from Step 2
|
|
38
|
-
*
|
|
39
|
-
* @example
|
|
40
|
-
* ```typescript
|
|
41
|
-
* const middleware = createStreamRetryMiddleware({
|
|
42
|
-
* maxRetries: 3,
|
|
43
|
-
* maxTotalRetryTimeMs: 120000,
|
|
44
|
-
* fallback: {
|
|
45
|
-
* enabled: true,
|
|
46
|
-
* initialProvider: 'vertex',
|
|
47
|
-
* initialCoreModel: 'claude-opus-4-5',
|
|
48
|
-
* stallTimeoutMs: 30000,
|
|
49
|
-
* }
|
|
50
|
-
* });
|
|
51
|
-
* ```
|
|
52
|
-
*/
|
|
53
|
-
import { type Logger } from "../../../../util/logger.js";
|
|
54
|
-
import type { FallbackConfig } from "./utils/fallback-chain.js";
|
|
55
|
-
import type { BackoffStrategy } from "../../../util/backoff-strategy.js";
|
|
56
|
-
import type { StreamTextMiddleware } from "../middleware.js";
|
|
57
|
-
export type { FallbackConfig } from "./utils/fallback-chain.js";
|
|
58
|
-
export type { ProviderType, CoreModelType } from "./utils/fallback-chain.js";
|
|
59
|
-
export interface StreamRetryOptions {
|
|
60
|
-
/**
|
|
61
|
-
* Maximum number of retry attempts per phase (not including the initial attempt).
|
|
62
|
-
* Each phase (initial call, stream consumption) gets its own retry budget.
|
|
63
|
-
* Default: Infinity (unlimited)
|
|
64
|
-
*/
|
|
65
|
-
maxRetries?: number;
|
|
66
|
-
/**
|
|
67
|
-
* Custom backoff strategy for calculating retry delays.
|
|
68
|
-
* If not provided, uses ExponentialBackoff.
|
|
69
|
-
*/
|
|
70
|
-
backoffStrategy?: BackoffStrategy;
|
|
71
|
-
/**
|
|
72
|
-
* Initial delay in milliseconds before the first retry.
|
|
73
|
-
* Default: 500 (0.5 seconds)
|
|
74
|
-
*/
|
|
75
|
-
initialDelayMs?: number;
|
|
76
|
-
/**
|
|
77
|
-
* Maximum delay in milliseconds for exponential backoff.
|
|
78
|
-
* Default: 5000 (5 seconds)
|
|
79
|
-
*/
|
|
80
|
-
maxDelayMs?: number;
|
|
81
|
-
/**
|
|
82
|
-
* Backoff multiplier for exponential backoff.
|
|
83
|
-
* Default: 2
|
|
84
|
-
*/
|
|
85
|
-
backoffMultiplier?: number;
|
|
86
|
-
/**
|
|
87
|
-
* Maximum total time in milliseconds for all retry attempts.
|
|
88
|
-
* Default: undefined (no time limit)
|
|
89
|
-
*/
|
|
90
|
-
maxTotalRetryTimeMs?: number;
|
|
91
|
-
/**
|
|
92
|
-
* Function to determine if an error is retryable.
|
|
93
|
-
* Default: checks for timeout and connection errors
|
|
94
|
-
*/
|
|
95
|
-
isRetryable?: (error: unknown) => boolean;
|
|
96
|
-
/**
|
|
97
|
-
* Callback invoked before each retry attempt.
|
|
98
|
-
*/
|
|
99
|
-
onRetry?: (error: unknown, attempt: number, delayMs: number, totalRetryTimeMs: number) => void | Promise<void>;
|
|
100
|
-
/**
|
|
101
|
-
* Optional abort signal to cancel retry attempts.
|
|
102
|
-
* When the signal is aborted, no further retries will be attempted.
|
|
103
|
-
*/
|
|
104
|
-
abortSignal?: AbortSignal;
|
|
105
|
-
/** Logger instance for retry operations */
|
|
106
|
-
logger?: Logger;
|
|
107
|
-
/** Provider fallback configuration */
|
|
108
|
-
fallback?: FallbackConfig;
|
|
109
|
-
}
|
|
110
|
-
/**
|
|
111
|
-
* Creates a middleware that retries streamText calls on failure,
|
|
112
|
-
* with optional provider fallback for mid-stream errors.
|
|
113
|
-
*/
|
|
114
|
-
export declare function createStreamRetryMiddleware(options?: StreamRetryOptions): StreamTextMiddleware;
|
|
115
|
-
//# sourceMappingURL=stream-retry.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"stream-retry.d.ts","sourceRoot":"","sources":["../../../../../src/ai-service/llm/interaction/middlewares/stream-retry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmDG;AAEH,OAAO,EAAE,KAAK,MAAM,EAAqB,MAAM,4BAA4B,CAAC;AAe5E,OAAO,KAAK,EAAE,cAAc,EAAiB,MAAM,2BAA2B,CAAC;AAE/E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAC;AACzE,OAAO,KAAK,EACV,oBAAoB,EAIrB,MAAM,kBAAkB,CAAC;AAG1B,YAAY,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAChE,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAE7E,MAAM,WAAW,kBAAkB;IACjC;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;;OAGG;IACH,eAAe,CAAC,EAAE,eAAe,CAAC;IAElC;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAE3B;;;OAGG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAE7B;;;OAGG;IACH,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC;IAE1C;;OAEG;IACH,OAAO,CAAC,EAAE,CACR,KAAK,EAAE,OAAO,EACd,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,gBAAgB,EAAE,MAAM,KACrB,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE1B;;;OAGG;IACH,WAAW,CAAC,EAAE,WAAW,CAAC;IAE1B,2CAA2C;IAC3C,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,sCAAsC;IACtC,QAAQ,CAAC,EAAE,cAAc,CAAC;CAC3B;AAED;;;GAGG;AACH,wBAAgB,2BAA2B,CACzC,OAAO,GAAE,kBAAuB,GAC/B,oBAAoB,CA8NtB"}
|
|
@@ -1,231 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Retry middleware for StreamText operations with integrated provider fallback.
|
|
3
|
-
*
|
|
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
|
-
* stall, or no output), this middleware retries the entire streamText call with
|
|
7
|
-
* accumulated messages from successful steps preserved via Context.
|
|
8
|
-
*
|
|
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
|
|
13
|
-
*
|
|
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
|
|
17
|
-
*
|
|
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
|
|
22
|
-
*
|
|
23
|
-
* ## Why at StreamText Level?
|
|
24
|
-
*
|
|
25
|
-
* Retrying at the streamText level (vs model.doStream level) ensures:
|
|
26
|
-
* 1. **Fresh Vercel SDK state**: Each retry gets a new eventProcessor with no
|
|
27
|
-
* partial chunk pollution from failed attempts
|
|
28
|
-
* 2. **Correct message sequences**: No orphaned content IDs or invalid message structures
|
|
29
|
-
* 3. **Natural continuation**: Vercel SDK's built-in logic handles multi-step resumption
|
|
30
|
-
*
|
|
31
|
-
* ## How It Works with Context
|
|
32
|
-
*
|
|
33
|
-
* The Context system provides the accumulated messages for retry:
|
|
34
|
-
* - Step 1 succeeds → Context.endStep() records messages
|
|
35
|
-
* - Step 2 fails → No endStep() call, empty step array remains
|
|
36
|
-
* - Retry → Context.getMessages() provides Step 1's messages
|
|
37
|
-
* - Fresh streamText() call receives those messages and continues from Step 2
|
|
38
|
-
*
|
|
39
|
-
* @example
|
|
40
|
-
* ```typescript
|
|
41
|
-
* const middleware = createStreamRetryMiddleware({
|
|
42
|
-
* maxRetries: 3,
|
|
43
|
-
* maxTotalRetryTimeMs: 120000,
|
|
44
|
-
* fallback: {
|
|
45
|
-
* enabled: true,
|
|
46
|
-
* initialProvider: 'vertex',
|
|
47
|
-
* initialCoreModel: 'claude-opus-4-5',
|
|
48
|
-
* stallTimeoutMs: 30000,
|
|
49
|
-
* }
|
|
50
|
-
* });
|
|
51
|
-
* ```
|
|
52
|
-
*/
|
|
53
|
-
import { getPrefixedLogger } from "../../../../util/logger.js";
|
|
54
|
-
import { ExponentialBackoff } from "../../../util/backoff-strategy.js";
|
|
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";
|
|
59
|
-
/**
|
|
60
|
-
* Creates a middleware that retries streamText calls on failure,
|
|
61
|
-
* with optional provider fallback for mid-stream errors.
|
|
62
|
-
*/
|
|
63
|
-
export function createStreamRetryMiddleware(options = {}) {
|
|
64
|
-
const { maxRetries = Infinity, initialDelayMs = 500, maxDelayMs = 10000, backoffMultiplier = 2, maxTotalRetryTimeMs, isRetryable = defaultIsRetryable, onRetry, abortSignal, logger = getPrefixedLogger("[retry]"), fallback, } = options;
|
|
65
|
-
const backoffStrategy = options.backoffStrategy ??
|
|
66
|
-
new ExponentialBackoff({
|
|
67
|
-
initialDelayMs,
|
|
68
|
-
maxDelayMs,
|
|
69
|
-
backoffMultiplier,
|
|
70
|
-
});
|
|
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;
|
|
76
|
-
return {
|
|
77
|
-
wrap(provider) {
|
|
78
|
-
return {
|
|
79
|
-
async streamText(streamOptions) {
|
|
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)
|
|
102
|
-
let httpAttempt = 0;
|
|
103
|
-
let totalRetryTime = 0;
|
|
104
|
-
const overallStartTime = Date.now();
|
|
105
|
-
let initialResult;
|
|
106
|
-
while (true) {
|
|
107
|
-
try {
|
|
108
|
-
initialResult = await provider.streamText(getOptionsForAttempt());
|
|
109
|
-
break; // Success!
|
|
110
|
-
}
|
|
111
|
-
catch (err) {
|
|
112
|
-
httpAttempt++;
|
|
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
|
-
}
|
|
121
|
-
const delay = await handleRetryAttempt(error, httpAttempt, totalRetryTime, {
|
|
122
|
-
maxRetries,
|
|
123
|
-
maxRetriesDisplay,
|
|
124
|
-
maxTotalRetryTimeMs,
|
|
125
|
-
overallStartTime,
|
|
126
|
-
backoffStrategy,
|
|
127
|
-
isRetryable,
|
|
128
|
-
onRetry,
|
|
129
|
-
abortSignal,
|
|
130
|
-
logger,
|
|
131
|
-
errorContext: "HTTP error",
|
|
132
|
-
});
|
|
133
|
-
totalRetryTime += delay;
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
if (abortSignal?.aborted) {
|
|
137
|
-
await originalOnAbort?.();
|
|
138
|
-
return initialResult;
|
|
139
|
-
}
|
|
140
|
-
// Phase 2: Wrap streams to handle consumption errors
|
|
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
|
-
}, {
|
|
179
|
-
maxRetries,
|
|
180
|
-
maxRetriesDisplay,
|
|
181
|
-
maxTotalRetryTimeMs,
|
|
182
|
-
overallStartTime,
|
|
183
|
-
backoffStrategy,
|
|
184
|
-
isRetryable,
|
|
185
|
-
onRetry,
|
|
186
|
-
abortSignal,
|
|
187
|
-
logger,
|
|
188
|
-
fallbackState,
|
|
189
|
-
fallbackConfig: fallback,
|
|
190
|
-
stallTimeoutMs,
|
|
191
|
-
retryOnStall,
|
|
192
|
-
onStreamComplete: handleStreamComplete,
|
|
193
|
-
onStreamFailed: handleStreamFailed,
|
|
194
|
-
});
|
|
195
|
-
const retryingTextStream = createRetryingAsyncIterable((isInitial, attemptAbortSignal) => isInitial
|
|
196
|
-
? Promise.resolve(initialResult.textStream)
|
|
197
|
-
: provider
|
|
198
|
-
.streamText({
|
|
199
|
-
...getOptionsForAttempt(),
|
|
200
|
-
abortSignal: attemptAbortSignal,
|
|
201
|
-
})
|
|
202
|
-
.then((res) => {
|
|
203
|
-
return res.textStream;
|
|
204
|
-
}), {
|
|
205
|
-
maxRetries,
|
|
206
|
-
maxRetriesDisplay,
|
|
207
|
-
maxTotalRetryTimeMs,
|
|
208
|
-
overallStartTime,
|
|
209
|
-
backoffStrategy,
|
|
210
|
-
isRetryable,
|
|
211
|
-
onRetry,
|
|
212
|
-
abortSignal,
|
|
213
|
-
logger,
|
|
214
|
-
fallbackState: null,
|
|
215
|
-
fallbackConfig: fallback,
|
|
216
|
-
stallTimeoutMs,
|
|
217
|
-
retryOnStall: false,
|
|
218
|
-
onStreamComplete: handleStreamComplete,
|
|
219
|
-
onStreamFailed: handleStreamFailed,
|
|
220
|
-
});
|
|
221
|
-
return {
|
|
222
|
-
...initialResult,
|
|
223
|
-
fullStream: retryingFullStream,
|
|
224
|
-
textStream: retryingTextStream,
|
|
225
|
-
};
|
|
226
|
-
},
|
|
227
|
-
};
|
|
228
|
-
},
|
|
229
|
-
};
|
|
230
|
-
}
|
|
231
|
-
//# sourceMappingURL=stream-retry.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"stream-retry.js","sourceRoot":"","sources":["../../../../../src/ai-service/llm/interaction/middlewares/stream-retry.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,41 +0,0 @@
|
|
|
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
|
|
@@ -1 +0,0 @@
|
|
|
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"}
|
|
@@ -1,74 +0,0 @@
|
|
|
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
|
|
@@ -1 +0,0 @@
|
|
|
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"}
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Provider fallback chain management for stream retry middleware.
|
|
3
|
-
*
|
|
4
|
-
* Manages the state and logic for cycling through provider/model combinations
|
|
5
|
-
* when stream errors occur. The chain order is:
|
|
6
|
-
* - If starting with opus: provider1/opus → provider2/opus → provider1/sonnet → provider2/sonnet
|
|
7
|
-
* - If starting with sonnet: provider1/sonnet → provider2/sonnet
|
|
8
|
-
*/
|
|
9
|
-
import { type Logger } from "../../../../../util/logger.js";
|
|
10
|
-
import type { Tool } from "../../../../agent/tools2/types.js";
|
|
11
|
-
import type { StreamTextOptions } from "../../middleware.js";
|
|
12
|
-
export type ProviderType = "vertex" | "bedrock";
|
|
13
|
-
export type CoreModelType = "claude-sonnet-4-5" | "claude-opus-4-5";
|
|
14
|
-
export interface FallbackAttempt {
|
|
15
|
-
provider: ProviderType;
|
|
16
|
-
coreModel: CoreModelType;
|
|
17
|
-
}
|
|
18
|
-
export interface FallbackConfig {
|
|
19
|
-
enabled?: boolean;
|
|
20
|
-
initialProvider?: ProviderType;
|
|
21
|
-
initialCoreModel?: CoreModelType;
|
|
22
|
-
stallTimeoutMs?: number;
|
|
23
|
-
retryOnStall?: boolean;
|
|
24
|
-
}
|
|
25
|
-
/** Mutable fallback state tracked across retries */
|
|
26
|
-
export interface FallbackState {
|
|
27
|
-
currentIndex: number;
|
|
28
|
-
chain: FallbackAttempt[];
|
|
29
|
-
}
|
|
30
|
-
/**
|
|
31
|
-
* Builds the full fallback chain based on initial provider/model.
|
|
32
|
-
*
|
|
33
|
-
* Chain construction:
|
|
34
|
-
* - Provider order is determined by initialProvider (that provider first, then the other)
|
|
35
|
-
* - If using opus, try opus on all providers first, then sonnet on all providers
|
|
36
|
-
* - If using sonnet, each provider only gets sonnet
|
|
37
|
-
*/
|
|
38
|
-
export declare function buildFallbackChain(initialProvider: ProviderType, initialCoreModel: CoreModelType): FallbackAttempt[];
|
|
39
|
-
/**
|
|
40
|
-
* Creates initial fallback state from config.
|
|
41
|
-
* Returns null if fallback is not enabled.
|
|
42
|
-
*/
|
|
43
|
-
export declare function createFallbackState(config: FallbackConfig | undefined, logger?: Logger): FallbackState | null;
|
|
44
|
-
/**
|
|
45
|
-
* Gets the current fallback attempt from state.
|
|
46
|
-
*/
|
|
47
|
-
export declare function getCurrentFallback(state: FallbackState): FallbackAttempt;
|
|
48
|
-
/**
|
|
49
|
-
* Advances to the next provider/model in the fallback chain.
|
|
50
|
-
* If already at the end, stays on the last provider (for continued retries) and returns false.
|
|
51
|
-
*/
|
|
52
|
-
export declare function advanceFallback(state: FallbackState, reason: "error" | "stall" | "no_output", logger: Logger): boolean;
|
|
53
|
-
/**
|
|
54
|
-
* Modifies stream options with current fallback state.
|
|
55
|
-
* Sets forceProvider and coreModel to explicitly tell the server which provider/model to use.
|
|
56
|
-
*
|
|
57
|
-
* On the first attempt (index 0), we don't force anything - let the server use its defaults.
|
|
58
|
-
* On retries (index > 0), we explicitly force the provider and model.
|
|
59
|
-
*/
|
|
60
|
-
export declare function applyFallbackToOptions<TOOLS extends Record<string, Tool>>(options: StreamTextOptions<TOOLS>, state: FallbackState, logger: Logger): StreamTextOptions<TOOLS>;
|
|
61
|
-
//# sourceMappingURL=fallback-chain.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"fallback-chain.d.ts","sourceRoot":"","sources":["../../../../../../src/ai-service/llm/interaction/middlewares/utils/fallback-chain.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAqB,KAAK,MAAM,EAAE,MAAM,+BAA+B,CAAC;AAC/E,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,mCAAmC,CAAC;AAC9D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAE7D,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,SAAS,CAAC;AAChD,MAAM,MAAM,aAAa,GAAG,mBAAmB,GAAG,iBAAiB,CAAC;AAEpE,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,YAAY,CAAC;IACvB,SAAS,EAAE,aAAa,CAAC;CAC1B;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,eAAe,CAAC,EAAE,YAAY,CAAC;IAC/B,gBAAgB,CAAC,EAAE,aAAa,CAAC;IACjC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,oDAAoD;AACpD,MAAM,WAAW,aAAa;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,eAAe,EAAE,CAAC;CAC1B;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAChC,eAAe,EAAE,YAAY,EAC7B,gBAAgB,EAAE,aAAa,GAC9B,eAAe,EAAE,CAwBnB;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,cAAc,GAAG,SAAS,EAClC,MAAM,SAAsC,GAC3C,aAAa,GAAG,IAAI,CAkBtB;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,aAAa,GAAG,eAAe,CAGxE;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,aAAa,EACpB,MAAM,EAAE,OAAO,GAAG,OAAO,GAAG,WAAW,EACvC,MAAM,EAAE,MAAM,GACb,OAAO,CAqBT;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,EACvE,OAAO,EAAE,iBAAiB,CAAC,KAAK,CAAC,EACjC,KAAK,EAAE,aAAa,EACpB,MAAM,EAAE,MAAM,GACb,iBAAiB,CAAC,KAAK,CAAC,CA0B1B"}
|
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Provider fallback chain management for stream retry middleware.
|
|
3
|
-
*
|
|
4
|
-
* Manages the state and logic for cycling through provider/model combinations
|
|
5
|
-
* when stream errors occur. The chain order is:
|
|
6
|
-
* - If starting with opus: provider1/opus → provider2/opus → provider1/sonnet → provider2/sonnet
|
|
7
|
-
* - If starting with sonnet: provider1/sonnet → provider2/sonnet
|
|
8
|
-
*/
|
|
9
|
-
import { getPrefixedLogger } from "../../../../../util/logger.js";
|
|
10
|
-
/**
|
|
11
|
-
* Builds the full fallback chain based on initial provider/model.
|
|
12
|
-
*
|
|
13
|
-
* Chain construction:
|
|
14
|
-
* - Provider order is determined by initialProvider (that provider first, then the other)
|
|
15
|
-
* - If using opus, try opus on all providers first, then sonnet on all providers
|
|
16
|
-
* - If using sonnet, each provider only gets sonnet
|
|
17
|
-
*/
|
|
18
|
-
export function buildFallbackChain(initialProvider, initialCoreModel) {
|
|
19
|
-
const isOpus = initialCoreModel === "claude-opus-4-5";
|
|
20
|
-
const providerOrder = initialProvider === "bedrock"
|
|
21
|
-
? ["bedrock", "vertex"]
|
|
22
|
-
: ["vertex", "bedrock"];
|
|
23
|
-
const chain = [];
|
|
24
|
-
if (isOpus) {
|
|
25
|
-
// First try opus on all providers
|
|
26
|
-
for (const provider of providerOrder) {
|
|
27
|
-
chain.push({ provider, coreModel: "claude-opus-4-5" });
|
|
28
|
-
}
|
|
29
|
-
// Then try sonnet on all providers
|
|
30
|
-
for (const provider of providerOrder) {
|
|
31
|
-
chain.push({ provider, coreModel: "claude-sonnet-4-5" });
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
else {
|
|
35
|
-
// Sonnet only: try on all providers
|
|
36
|
-
for (const provider of providerOrder) {
|
|
37
|
-
chain.push({ provider, coreModel: "claude-sonnet-4-5" });
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
return chain;
|
|
41
|
-
}
|
|
42
|
-
/**
|
|
43
|
-
* Creates initial fallback state from config.
|
|
44
|
-
* Returns null if fallback is not enabled.
|
|
45
|
-
*/
|
|
46
|
-
export function createFallbackState(config, logger = getPrefixedLogger("fallback-chain")) {
|
|
47
|
-
if (!config?.enabled) {
|
|
48
|
-
return null;
|
|
49
|
-
}
|
|
50
|
-
const chain = buildFallbackChain(config.initialProvider ?? "vertex", config.initialCoreModel ?? "claude-sonnet-4-5");
|
|
51
|
-
logger.info(`current chain: ${chain.map((c) => `${c.provider}/${c.coreModel}`).join(" -> ")}`);
|
|
52
|
-
return {
|
|
53
|
-
currentIndex: 0,
|
|
54
|
-
chain,
|
|
55
|
-
};
|
|
56
|
-
}
|
|
57
|
-
/**
|
|
58
|
-
* Gets the current fallback attempt from state.
|
|
59
|
-
*/
|
|
60
|
-
export function getCurrentFallback(state) {
|
|
61
|
-
const index = Math.min(state.currentIndex, state.chain.length - 1);
|
|
62
|
-
return state.chain[index];
|
|
63
|
-
}
|
|
64
|
-
/**
|
|
65
|
-
* Advances to the next provider/model in the fallback chain.
|
|
66
|
-
* If already at the end, stays on the last provider (for continued retries) and returns false.
|
|
67
|
-
*/
|
|
68
|
-
export function advanceFallback(state, reason, logger) {
|
|
69
|
-
const currentIndex = Math.min(state.currentIndex, state.chain.length - 1);
|
|
70
|
-
const current = state.chain[currentIndex];
|
|
71
|
-
const nextIndex = Math.min(currentIndex + 1, state.chain.length - 1);
|
|
72
|
-
const next = state.chain[nextIndex];
|
|
73
|
-
const isAdvancing = nextIndex > currentIndex;
|
|
74
|
-
state.currentIndex = nextIndex;
|
|
75
|
-
if (isAdvancing) {
|
|
76
|
-
logger.warn(`Switching provider: ${current.provider}/${current.coreModel} -> ${next.provider}/${next.coreModel} | reason=${reason}`);
|
|
77
|
-
return true;
|
|
78
|
-
}
|
|
79
|
-
else {
|
|
80
|
-
logger.warn(`Retrying same provider (chain exhausted): ${current.provider}/${current.coreModel} | reason=${reason}`);
|
|
81
|
-
return false;
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
/**
|
|
85
|
-
* Modifies stream options with current fallback state.
|
|
86
|
-
* Sets forceProvider and coreModel to explicitly tell the server which provider/model to use.
|
|
87
|
-
*
|
|
88
|
-
* On the first attempt (index 0), we don't force anything - let the server use its defaults.
|
|
89
|
-
* On retries (index > 0), we explicitly force the provider and model.
|
|
90
|
-
*/
|
|
91
|
-
export function applyFallbackToOptions(options, state, logger) {
|
|
92
|
-
const currentIndex = Math.min(state.currentIndex, state.chain.length - 1);
|
|
93
|
-
const current = state.chain[currentIndex];
|
|
94
|
-
if (!current) {
|
|
95
|
-
logger.error("No current fallback attempt found");
|
|
96
|
-
return options;
|
|
97
|
-
}
|
|
98
|
-
return {
|
|
99
|
-
...options,
|
|
100
|
-
providerOptions: {
|
|
101
|
-
...options.providerOptions,
|
|
102
|
-
unified: {
|
|
103
|
-
...(options.providerOptions?.unified ||
|
|
104
|
-
{}),
|
|
105
|
-
// On retry (index > 0), explicitly force the provider and model
|
|
106
|
-
...(currentIndex > 0
|
|
107
|
-
? {
|
|
108
|
-
forceProvider: current.provider,
|
|
109
|
-
coreModel: current.coreModel,
|
|
110
|
-
}
|
|
111
|
-
: {}),
|
|
112
|
-
},
|
|
113
|
-
},
|
|
114
|
-
};
|
|
115
|
-
}
|
|
116
|
-
//# sourceMappingURL=fallback-chain.js.map
|