@cat-factory/server 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/dist/agents/CompositeAgentExecutor.d.ts +39 -0
- package/dist/agents/CompositeAgentExecutor.d.ts.map +1 -0
- package/dist/agents/CompositeAgentExecutor.js +169 -0
- package/dist/agents/CompositeAgentExecutor.js.map +1 -0
- package/dist/agents/ContainerAgentExecutor.d.ts +235 -0
- package/dist/agents/ContainerAgentExecutor.d.ts.map +1 -0
- package/dist/agents/ContainerAgentExecutor.js +825 -0
- package/dist/agents/ContainerAgentExecutor.js.map +1 -0
- package/dist/agents/ContainerRepoBootstrapper.d.ts +78 -0
- package/dist/agents/ContainerRepoBootstrapper.d.ts.map +1 -0
- package/dist/agents/ContainerRepoBootstrapper.js +279 -0
- package/dist/agents/ContainerRepoBootstrapper.js.map +1 -0
- package/dist/agents/ModelRouter.d.ts +69 -0
- package/dist/agents/ModelRouter.d.ts.map +1 -0
- package/dist/agents/ModelRouter.js +84 -0
- package/dist/agents/ModelRouter.js.map +1 -0
- package/dist/agents/RunnerJobClient.d.ts +41 -0
- package/dist/agents/RunnerJobClient.d.ts.map +1 -0
- package/dist/agents/RunnerJobClient.js +43 -0
- package/dist/agents/RunnerJobClient.js.map +1 -0
- package/dist/agents/modelProviderResolver.d.ts +33 -0
- package/dist/agents/modelProviderResolver.d.ts.map +1 -0
- package/dist/agents/modelProviderResolver.js +48 -0
- package/dist/agents/modelProviderResolver.js.map +1 -0
- package/dist/agents/providerCapabilities.d.ts +22 -0
- package/dist/agents/providerCapabilities.d.ts.map +1 -0
- package/dist/agents/providerCapabilities.js +43 -0
- package/dist/agents/providerCapabilities.js.map +1 -0
- package/dist/agents/resolveRepoTarget.d.ts +33 -0
- package/dist/agents/resolveRepoTarget.d.ts.map +1 -0
- package/dist/agents/resolveRepoTarget.js +81 -0
- package/dist/agents/resolveRepoTarget.js.map +1 -0
- package/dist/app.d.ts +12 -0
- package/dist/app.d.ts.map +1 -0
- package/dist/app.js +102 -0
- package/dist/app.js.map +1 -0
- package/dist/auth/GitHubOAuth.d.ts +39 -0
- package/dist/auth/GitHubOAuth.d.ts.map +1 -0
- package/dist/auth/GitHubOAuth.js +90 -0
- package/dist/auth/GitHubOAuth.js.map +1 -0
- package/dist/auth/GoogleOAuth.d.ts +35 -0
- package/dist/auth/GoogleOAuth.d.ts.map +1 -0
- package/dist/auth/GoogleOAuth.js +66 -0
- package/dist/auth/GoogleOAuth.js.map +1 -0
- package/dist/auth/middleware.d.ts +15 -0
- package/dist/auth/middleware.d.ts.map +1 -0
- package/dist/auth/middleware.js +63 -0
- package/dist/auth/middleware.js.map +1 -0
- package/dist/auth/signing.d.ts +50 -0
- package/dist/auth/signing.d.ts.map +1 -0
- package/dist/auth/signing.js +96 -0
- package/dist/auth/signing.js.map +1 -0
- package/dist/auth/wsTicket.d.ts +34 -0
- package/dist/auth/wsTicket.d.ts.map +1 -0
- package/dist/auth/wsTicket.js +50 -0
- package/dist/auth/wsTicket.js.map +1 -0
- package/dist/config/types.d.ts +294 -0
- package/dist/config/types.d.ts.map +1 -0
- package/dist/config/types.js +2 -0
- package/dist/config/types.js.map +1 -0
- package/dist/config/url-safety.d.ts +8 -0
- package/dist/config/url-safety.d.ts.map +1 -0
- package/dist/config/url-safety.js +11 -0
- package/dist/config/url-safety.js.map +1 -0
- package/dist/containers/ContainerSessionService.d.ts +67 -0
- package/dist/containers/ContainerSessionService.d.ts.map +1 -0
- package/dist/containers/ContainerSessionService.js +44 -0
- package/dist/containers/ContainerSessionService.js.map +1 -0
- package/dist/crypto/WebCryptoPasswordHasher.d.ts +9 -0
- package/dist/crypto/WebCryptoPasswordHasher.d.ts.map +1 -0
- package/dist/crypto/WebCryptoPasswordHasher.js +67 -0
- package/dist/crypto/WebCryptoPasswordHasher.js.map +1 -0
- package/dist/crypto/WebCryptoPersonalSecretCipher.d.ts +6 -0
- package/dist/crypto/WebCryptoPersonalSecretCipher.d.ts.map +1 -0
- package/dist/crypto/WebCryptoPersonalSecretCipher.js +57 -0
- package/dist/crypto/WebCryptoPersonalSecretCipher.js.map +1 -0
- package/dist/crypto/WebCryptoSecretCipher.d.ts +23 -0
- package/dist/crypto/WebCryptoSecretCipher.d.ts.map +1 -0
- package/dist/crypto/WebCryptoSecretCipher.js +60 -0
- package/dist/crypto/WebCryptoSecretCipher.js.map +1 -0
- package/dist/crypto/encoding.d.ts +14 -0
- package/dist/crypto/encoding.d.ts.map +1 -0
- package/dist/crypto/encoding.js +58 -0
- package/dist/crypto/encoding.js.map +1 -0
- package/dist/events/FanOutEventPublisher.d.ts +32 -0
- package/dist/events/FanOutEventPublisher.d.ts.map +1 -0
- package/dist/events/FanOutEventPublisher.js +76 -0
- package/dist/events/FanOutEventPublisher.js.map +1 -0
- package/dist/events/InAppNotificationChannel.d.ts +20 -0
- package/dist/events/InAppNotificationChannel.d.ts.map +1 -0
- package/dist/events/InAppNotificationChannel.js +23 -0
- package/dist/events/InAppNotificationChannel.js.map +1 -0
- package/dist/github/FetchGitHubClient.d.ts +72 -0
- package/dist/github/FetchGitHubClient.d.ts.map +1 -0
- package/dist/github/FetchGitHubClient.js +485 -0
- package/dist/github/FetchGitHubClient.js.map +1 -0
- package/dist/github/FetchGitHubProvisioningClient.d.ts +13 -0
- package/dist/github/FetchGitHubProvisioningClient.d.ts.map +1 -0
- package/dist/github/FetchGitHubProvisioningClient.js +59 -0
- package/dist/github/FetchGitHubProvisioningClient.js.map +1 -0
- package/dist/github/GitHubAppAuth.d.ts +30 -0
- package/dist/github/GitHubAppAuth.d.ts.map +1 -0
- package/dist/github/GitHubAppAuth.js +95 -0
- package/dist/github/GitHubAppAuth.js.map +1 -0
- package/dist/github/GitHubAppRegistry.d.ts +57 -0
- package/dist/github/GitHubAppRegistry.d.ts.map +1 -0
- package/dist/github/GitHubAppRegistry.js +51 -0
- package/dist/github/GitHubAppRegistry.js.map +1 -0
- package/dist/github/GitHubCiStatusProvider.d.ts +21 -0
- package/dist/github/GitHubCiStatusProvider.d.ts.map +1 -0
- package/dist/github/GitHubCiStatusProvider.js +39 -0
- package/dist/github/GitHubCiStatusProvider.js.map +1 -0
- package/dist/github/GitHubMergeabilityProvider.d.ts +26 -0
- package/dist/github/GitHubMergeabilityProvider.d.ts.map +1 -0
- package/dist/github/GitHubMergeabilityProvider.js +38 -0
- package/dist/github/GitHubMergeabilityProvider.js.map +1 -0
- package/dist/github/GitHubPullRequestMerger.d.ts +23 -0
- package/dist/github/GitHubPullRequestMerger.d.ts.map +1 -0
- package/dist/github/GitHubPullRequestMerger.js +38 -0
- package/dist/github/GitHubPullRequestMerger.js.map +1 -0
- package/dist/github/WebCryptoWebhookVerifier.d.ts +9 -0
- package/dist/github/WebCryptoWebhookVerifier.d.ts.map +1 -0
- package/dist/github/WebCryptoWebhookVerifier.js +40 -0
- package/dist/github/WebCryptoWebhookVerifier.js.map +1 -0
- package/dist/github/ensureWorkBranch.d.ts +26 -0
- package/dist/github/ensureWorkBranch.d.ts.map +1 -0
- package/dist/github/ensureWorkBranch.js +97 -0
- package/dist/github/ensureWorkBranch.js.map +1 -0
- package/dist/github/state.d.ts +19 -0
- package/dist/github/state.d.ts.map +1 -0
- package/dist/github/state.js +55 -0
- package/dist/github/state.js.map +1 -0
- package/dist/http/authGate.d.ts +21 -0
- package/dist/http/authGate.d.ts.map +1 -0
- package/dist/http/authGate.js +77 -0
- package/dist/http/authGate.js.map +1 -0
- package/dist/http/cors.d.ts +13 -0
- package/dist/http/cors.d.ts.map +1 -0
- package/dist/http/cors.js +30 -0
- package/dist/http/cors.js.map +1 -0
- package/dist/http/env.d.ts +68 -0
- package/dist/http/env.d.ts.map +1 -0
- package/dist/http/env.js +2 -0
- package/dist/http/env.js.map +1 -0
- package/dist/http/errorHandler.d.ts +4 -0
- package/dist/http/errorHandler.d.ts.map +1 -0
- package/dist/http/errorHandler.js +33 -0
- package/dist/http/errorHandler.js.map +1 -0
- package/dist/http/params.d.ts +8 -0
- package/dist/http/params.d.ts.map +1 -0
- package/dist/http/params.js +13 -0
- package/dist/http/params.js.map +1 -0
- package/dist/http/validation.d.ts +12 -0
- package/dist/http/validation.d.ts.map +1 -0
- package/dist/http/validation.js +21 -0
- package/dist/http/validation.js.map +1 -0
- package/dist/index.d.ts +46 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +63 -0
- package/dist/index.js.map +1 -0
- package/dist/modules/accounts/AccountController.d.ts +10 -0
- package/dist/modules/accounts/AccountController.d.ts.map +1 -0
- package/dist/modules/accounts/AccountController.js +197 -0
- package/dist/modules/accounts/AccountController.js.map +1 -0
- package/dist/modules/agentRuns/AgentRunController.d.ts +10 -0
- package/dist/modules/agentRuns/AgentRunController.d.ts.map +1 -0
- package/dist/modules/agentRuns/AgentRunController.js +65 -0
- package/dist/modules/agentRuns/AgentRunController.js.map +1 -0
- package/dist/modules/auth/AuthController.d.ts +12 -0
- package/dist/modules/auth/AuthController.d.ts.map +1 -0
- package/dist/modules/auth/AuthController.js +457 -0
- package/dist/modules/auth/AuthController.js.map +1 -0
- package/dist/modules/board/BoardController.d.ts +8 -0
- package/dist/modules/board/BoardController.d.ts.map +1 -0
- package/dist/modules/board/BoardController.js +89 -0
- package/dist/modules/board/BoardController.js.map +1 -0
- package/dist/modules/boardScan/BoardScanController.d.ts +10 -0
- package/dist/modules/boardScan/BoardScanController.d.ts.map +1 -0
- package/dist/modules/boardScan/BoardScanController.js +53 -0
- package/dist/modules/boardScan/BoardScanController.js.map +1 -0
- package/dist/modules/bootstrap/BootstrapController.d.ts +10 -0
- package/dist/modules/bootstrap/BootstrapController.d.ts.map +1 -0
- package/dist/modules/bootstrap/BootstrapController.js +75 -0
- package/dist/modules/bootstrap/BootstrapController.js.map +1 -0
- package/dist/modules/clarity/ClarityReviewController.d.ts +11 -0
- package/dist/modules/clarity/ClarityReviewController.d.ts.map +1 -0
- package/dist/modules/clarity/ClarityReviewController.js +97 -0
- package/dist/modules/clarity/ClarityReviewController.js.map +1 -0
- package/dist/modules/consensus/ConsensusController.d.ts +12 -0
- package/dist/modules/consensus/ConsensusController.d.ts.map +1 -0
- package/dist/modules/consensus/ConsensusController.js +23 -0
- package/dist/modules/consensus/ConsensusController.js.map +1 -0
- package/dist/modules/documents/DocumentSourceController.d.ts +10 -0
- package/dist/modules/documents/DocumentSourceController.d.ts.map +1 -0
- package/dist/modules/documents/DocumentSourceController.js +116 -0
- package/dist/modules/documents/DocumentSourceController.js.map +1 -0
- package/dist/modules/environments/EnvironmentController.d.ts +10 -0
- package/dist/modules/environments/EnvironmentController.d.ts.map +1 -0
- package/dist/modules/environments/EnvironmentController.js +95 -0
- package/dist/modules/environments/EnvironmentController.js.map +1 -0
- package/dist/modules/events/EventsController.d.ts +26 -0
- package/dist/modules/events/EventsController.d.ts.map +1 -0
- package/dist/modules/events/EventsController.js +56 -0
- package/dist/modules/events/EventsController.js.map +1 -0
- package/dist/modules/execution/ExecutionController.d.ts +10 -0
- package/dist/modules/execution/ExecutionController.d.ts.map +1 -0
- package/dist/modules/execution/ExecutionController.js +156 -0
- package/dist/modules/execution/ExecutionController.js.map +1 -0
- package/dist/modules/fragmentLibrary/FragmentLibraryController.d.ts +14 -0
- package/dist/modules/fragmentLibrary/FragmentLibraryController.d.ts.map +1 -0
- package/dist/modules/fragmentLibrary/FragmentLibraryController.js +128 -0
- package/dist/modules/fragmentLibrary/FragmentLibraryController.js.map +1 -0
- package/dist/modules/github/GitHubController.d.ts +12 -0
- package/dist/modules/github/GitHubController.d.ts.map +1 -0
- package/dist/modules/github/GitHubController.js +234 -0
- package/dist/modules/github/GitHubController.js.map +1 -0
- package/dist/modules/github/GitHubWebhookController.d.ts +13 -0
- package/dist/modules/github/GitHubWebhookController.d.ts.map +1 -0
- package/dist/modules/github/GitHubWebhookController.js +74 -0
- package/dist/modules/github/GitHubWebhookController.js.map +1 -0
- package/dist/modules/llmProxy/LlmProxyController.d.ts +18 -0
- package/dist/modules/llmProxy/LlmProxyController.d.ts.map +1 -0
- package/dist/modules/llmProxy/LlmProxyController.js +567 -0
- package/dist/modules/llmProxy/LlmProxyController.js.map +1 -0
- package/dist/modules/localModels/LocalModelEndpointController.d.ts +4 -0
- package/dist/modules/localModels/LocalModelEndpointController.d.ts.map +1 -0
- package/dist/modules/localModels/LocalModelEndpointController.js +58 -0
- package/dist/modules/localModels/LocalModelEndpointController.js.map +1 -0
- package/dist/modules/merge/MergePresetController.d.ts +9 -0
- package/dist/modules/merge/MergePresetController.d.ts.map +1 -0
- package/dist/modules/merge/MergePresetController.js +46 -0
- package/dist/modules/merge/MergePresetController.js.map +1 -0
- package/dist/modules/modelDefaults/ModelDefaultsController.d.ts +9 -0
- package/dist/modules/modelDefaults/ModelDefaultsController.d.ts.map +1 -0
- package/dist/modules/modelDefaults/ModelDefaultsController.js +32 -0
- package/dist/modules/modelDefaults/ModelDefaultsController.js.map +1 -0
- package/dist/modules/models/ModelController.d.ts +11 -0
- package/dist/modules/models/ModelController.d.ts.map +1 -0
- package/dist/modules/models/ModelController.js +38 -0
- package/dist/modules/models/ModelController.js.map +1 -0
- package/dist/modules/notifications/NotificationController.d.ts +13 -0
- package/dist/modules/notifications/NotificationController.d.ts.map +1 -0
- package/dist/modules/notifications/NotificationController.js +67 -0
- package/dist/modules/notifications/NotificationController.js.map +1 -0
- package/dist/modules/pipelines/PipelineController.d.ts +5 -0
- package/dist/modules/pipelines/PipelineController.d.ts.map +1 -0
- package/dist/modules/pipelines/PipelineController.js +46 -0
- package/dist/modules/pipelines/PipelineController.js.map +1 -0
- package/dist/modules/promptFragments/PromptFragmentController.d.ts +11 -0
- package/dist/modules/promptFragments/PromptFragmentController.d.ts.map +1 -0
- package/dist/modules/promptFragments/PromptFragmentController.js +18 -0
- package/dist/modules/promptFragments/PromptFragmentController.js.map +1 -0
- package/dist/modules/providers/ApiKeyController.d.ts +13 -0
- package/dist/modules/providers/ApiKeyController.d.ts.map +1 -0
- package/dist/modules/providers/ApiKeyController.js +98 -0
- package/dist/modules/providers/ApiKeyController.js.map +1 -0
- package/dist/modules/providers/PersonalSubscriptionController.d.ts +4 -0
- package/dist/modules/providers/PersonalSubscriptionController.d.ts.map +1 -0
- package/dist/modules/providers/PersonalSubscriptionController.js +48 -0
- package/dist/modules/providers/PersonalSubscriptionController.js.map +1 -0
- package/dist/modules/providers/VendorCredentialController.d.ts +4 -0
- package/dist/modules/providers/VendorCredentialController.d.ts.map +1 -0
- package/dist/modules/providers/VendorCredentialController.js +55 -0
- package/dist/modules/providers/VendorCredentialController.js.map +1 -0
- package/dist/modules/providers/personalCredentialGate.d.ts +34 -0
- package/dist/modules/providers/personalCredentialGate.d.ts.map +1 -0
- package/dist/modules/providers/personalCredentialGate.js +106 -0
- package/dist/modules/providers/personalCredentialGate.js.map +1 -0
- package/dist/modules/recurring/RecurringPipelineController.d.ts +8 -0
- package/dist/modules/recurring/RecurringPipelineController.d.ts.map +1 -0
- package/dist/modules/recurring/RecurringPipelineController.js +58 -0
- package/dist/modules/recurring/RecurringPipelineController.js.map +1 -0
- package/dist/modules/recurring/TrackerSettingsController.d.ts +8 -0
- package/dist/modules/recurring/TrackerSettingsController.d.ts.map +1 -0
- package/dist/modules/recurring/TrackerSettingsController.js +30 -0
- package/dist/modules/recurring/TrackerSettingsController.js.map +1 -0
- package/dist/modules/releaseHealth/ReleaseHealthController.d.ts +9 -0
- package/dist/modules/releaseHealth/ReleaseHealthController.d.ts.map +1 -0
- package/dist/modules/releaseHealth/ReleaseHealthController.js +58 -0
- package/dist/modules/releaseHealth/ReleaseHealthController.js.map +1 -0
- package/dist/modules/requirements/RequirementReviewController.d.ts +12 -0
- package/dist/modules/requirements/RequirementReviewController.d.ts.map +1 -0
- package/dist/modules/requirements/RequirementReviewController.js +107 -0
- package/dist/modules/requirements/RequirementReviewController.js.map +1 -0
- package/dist/modules/runners/RunnerPoolController.d.ts +10 -0
- package/dist/modules/runners/RunnerPoolController.d.ts.map +1 -0
- package/dist/modules/runners/RunnerPoolController.js +52 -0
- package/dist/modules/runners/RunnerPoolController.js.map +1 -0
- package/dist/modules/serviceFragmentDefaults/ServiceFragmentDefaultsController.d.ts +9 -0
- package/dist/modules/serviceFragmentDefaults/ServiceFragmentDefaultsController.d.ts.map +1 -0
- package/dist/modules/serviceFragmentDefaults/ServiceFragmentDefaultsController.js +32 -0
- package/dist/modules/serviceFragmentDefaults/ServiceFragmentDefaultsController.js.map +1 -0
- package/dist/modules/services/ServiceMountController.d.ts +11 -0
- package/dist/modules/services/ServiceMountController.d.ts.map +1 -0
- package/dist/modules/services/ServiceMountController.js +64 -0
- package/dist/modules/services/ServiceMountController.js.map +1 -0
- package/dist/modules/settings/WorkspaceSettingsController.d.ts +9 -0
- package/dist/modules/settings/WorkspaceSettingsController.d.ts.map +1 -0
- package/dist/modules/settings/WorkspaceSettingsController.js +32 -0
- package/dist/modules/settings/WorkspaceSettingsController.js.map +1 -0
- package/dist/modules/slack/SlackController.d.ts +17 -0
- package/dist/modules/slack/SlackController.d.ts.map +1 -0
- package/dist/modules/slack/SlackController.js +135 -0
- package/dist/modules/slack/SlackController.js.map +1 -0
- package/dist/modules/tasks/TaskSourceController.d.ts +9 -0
- package/dist/modules/tasks/TaskSourceController.d.ts.map +1 -0
- package/dist/modules/tasks/TaskSourceController.js +103 -0
- package/dist/modules/tasks/TaskSourceController.js.map +1 -0
- package/dist/modules/webSearch/WebSearchProxyController.d.ts +4 -0
- package/dist/modules/webSearch/WebSearchProxyController.d.ts.map +1 -0
- package/dist/modules/webSearch/WebSearchProxyController.js +78 -0
- package/dist/modules/webSearch/WebSearchProxyController.js.map +1 -0
- package/dist/modules/webSearch/upstreams.d.ts +50 -0
- package/dist/modules/webSearch/upstreams.d.ts.map +1 -0
- package/dist/modules/webSearch/upstreams.js +107 -0
- package/dist/modules/webSearch/upstreams.js.map +1 -0
- package/dist/modules/workspaces/WorkspaceController.d.ts +5 -0
- package/dist/modules/workspaces/WorkspaceController.d.ts.map +1 -0
- package/dist/modules/workspaces/WorkspaceController.js +167 -0
- package/dist/modules/workspaces/WorkspaceController.js.map +1 -0
- package/dist/observability/logger.d.ts +9 -0
- package/dist/observability/logger.d.ts.map +1 -0
- package/dist/observability/logger.js +39 -0
- package/dist/observability/logger.js.map +1 -0
- package/dist/persistence/mappers.d.ts +101 -0
- package/dist/persistence/mappers.d.ts.map +1 -0
- package/dist/persistence/mappers.js +260 -0
- package/dist/persistence/mappers.js.map +1 -0
- package/dist/runtime/escalateNotifications.d.ts +12 -0
- package/dist/runtime/escalateNotifications.d.ts.map +1 -0
- package/dist/runtime/escalateNotifications.js +25 -0
- package/dist/runtime/escalateNotifications.js.map +1 -0
- package/dist/runtime/gateways.d.ts +159 -0
- package/dist/runtime/gateways.d.ts.map +1 -0
- package/dist/runtime/gateways.js +2 -0
- package/dist/runtime/gateways.js.map +1 -0
- package/package.json +44 -0
|
@@ -0,0 +1,567 @@
|
|
|
1
|
+
import { Hono } from 'hono';
|
|
2
|
+
import { cachedTokensFromUsage, promptCacheParams } from '@cat-factory/agents';
|
|
3
|
+
import { isLocalRunner } from '@cat-factory/contracts';
|
|
4
|
+
import { contextWindowFor } from '@cat-factory/kernel';
|
|
5
|
+
import { ContainerSessionService } from '../../containers/ContainerSessionService.js';
|
|
6
|
+
import { logger } from '../../observability/logger.js';
|
|
7
|
+
// The OpenAI Chat Completions-compatible proxy that implementation containers
|
|
8
|
+
// point Pi at. It is the seam that keeps provider secrets out of the container:
|
|
9
|
+
// the container authenticates with a short-lived, model-locked session token
|
|
10
|
+
// (no API key), and the facade injects the real upstream key and forwards the
|
|
11
|
+
// request. It is also the single spend-metering point for container runs.
|
|
12
|
+
//
|
|
13
|
+
// This controller is runtime-neutral: session verification, the spend gate,
|
|
14
|
+
// request hardening, the OpenAI-compatible HTTP forward and the streaming metering
|
|
15
|
+
// all live here. The runtime-specific bits — resolving an OpenAI-compatible
|
|
16
|
+
// upstream (base URL + key) and the optional in-process path for binding-reached
|
|
17
|
+
// providers (Cloudflare Workers AI) — are delegated to the `llmUpstream` gateway.
|
|
18
|
+
/**
|
|
19
|
+
* Output-token floor applied to every container-agent call on a `workers-ai` provider
|
|
20
|
+
* (native `@cf/...` and AI-catalog slugs both): `max_tokens = max(asked, this)`.
|
|
21
|
+
*
|
|
22
|
+
* This is the EFFECTIVE per-call output ceiling, not a mere safety net. Production
|
|
23
|
+
* telemetry showed every workers-ai call recording exactly 16384 — Pi does NOT forward
|
|
24
|
+
* its model-entry `maxTokens` (the harness `PI_MAX_OUTPUT_TOKENS`) as the request
|
|
25
|
+
* `max_tokens`, so `asked` is always ≤ this floor and the floor governs. Raising the
|
|
26
|
+
* harness ceiling alone therefore does nothing; this is the value to change. Keep it in
|
|
27
|
+
* step with the harness `PI_MAX_OUTPUT_TOKENS` (32k). A ceiling, not a target — unused
|
|
28
|
+
* tokens are not billed. It is itself capped per-call against the model's context window
|
|
29
|
+
* below: a small-window model (e.g. qwen3-30b-a3b-fp8 at 32K total) does NOT clamp a
|
|
30
|
+
* too-large output request, it rejects the whole call (error 8007 → HTTP 502).
|
|
31
|
+
*/
|
|
32
|
+
const PI_MIN_OUTPUT_TOKENS = 32_768;
|
|
33
|
+
/**
|
|
34
|
+
* Chars-per-token used to estimate a prompt's input-token cost from its serialized
|
|
35
|
+
* length when capping the output request against a model's context window. Kept LOW (a
|
|
36
|
+
* dense-JSON ratio) on purpose so the estimate runs HIGH and the cap stays conservative:
|
|
37
|
+
* over-reserving input room only trims output a little, while under-reserving risks the
|
|
38
|
+
* very overflow the cap exists to prevent.
|
|
39
|
+
*/
|
|
40
|
+
const PROMPT_CHARS_PER_TOKEN = 3;
|
|
41
|
+
/**
|
|
42
|
+
* Tokens held back from the context window beyond the estimated input — covers role/
|
|
43
|
+
* formatting overhead the char estimate misses and the model's own generation headroom.
|
|
44
|
+
*/
|
|
45
|
+
const CONTEXT_WINDOW_MARGIN = 512;
|
|
46
|
+
/**
|
|
47
|
+
* The output-token ceiling for a workers-ai container call: Pi's asked value floored to
|
|
48
|
+
* {@link PI_MIN_OUTPUT_TOKENS}, then capped so input + output fits the model's context
|
|
49
|
+
* window (when the catalog declares one). A small-window model rejects the WHOLE request
|
|
50
|
+
* (Workers AI error 8007 → HTTP 502) when the output request alone fills the window, so we
|
|
51
|
+
* reserve room for the prompt: estimate its input-token cost from the serialized
|
|
52
|
+
* prompt + tool definitions (`inputChars`) and hold that back. The cap only NARROWS the
|
|
53
|
+
* floor; an unknown window or ample room leaves it untouched. Pure + exported for testing.
|
|
54
|
+
*/
|
|
55
|
+
export function workersAiOutputCeiling(args) {
|
|
56
|
+
let ceiling = Math.max(args.asked, PI_MIN_OUTPUT_TOKENS);
|
|
57
|
+
if (args.contextWindow) {
|
|
58
|
+
const estimatedInputTokens = Math.ceil(args.inputChars / PROMPT_CHARS_PER_TOKEN);
|
|
59
|
+
const outputRoom = args.contextWindow - estimatedInputTokens - CONTEXT_WINDOW_MARGIN;
|
|
60
|
+
if (outputRoom > 0 && outputRoom < ceiling)
|
|
61
|
+
ceiling = outputRoom;
|
|
62
|
+
}
|
|
63
|
+
return ceiling;
|
|
64
|
+
}
|
|
65
|
+
/** Pull the bearer token from the Authorization header. */
|
|
66
|
+
function bearer(header) {
|
|
67
|
+
if (!header)
|
|
68
|
+
return null;
|
|
69
|
+
const match = /^Bearer\s+(.+)$/i.exec(header.trim());
|
|
70
|
+
return match ? match[1].trim() : null;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Schedule post-response work. On the Worker the runtime exposes `executionCtx.waitUntil`
|
|
74
|
+
* (keeps the isolate alive past the response); on Node there is no such context, so we
|
|
75
|
+
* fall back to fire-and-forget (the process is long-lived).
|
|
76
|
+
*/
|
|
77
|
+
function makeWaitUntil(c) {
|
|
78
|
+
return (p) => {
|
|
79
|
+
try {
|
|
80
|
+
c.executionCtx.waitUntil(p);
|
|
81
|
+
}
|
|
82
|
+
catch {
|
|
83
|
+
void p.catch(() => { });
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
export function llmProxyController() {
|
|
88
|
+
const app = new Hono();
|
|
89
|
+
app.post('/v1/chat/completions', async (c) => {
|
|
90
|
+
// Proxy-entry clock: everything from here to the upstream dispatch (and after the
|
|
91
|
+
// response) is transport overhead; the slice spent waiting on the model is the
|
|
92
|
+
// actual execution. The two are split in the observability sink.
|
|
93
|
+
const t0 = Date.now();
|
|
94
|
+
const { config, spendService, gateways, llmObservability, executionEventPublisher, apiKeys, localModelEndpoints, } = c.get('container');
|
|
95
|
+
const secret = config.auth.sessionSecret;
|
|
96
|
+
if (!secret) {
|
|
97
|
+
logger.error({ scope: 'llmProxy' }, 'llm proxy: session secret not configured');
|
|
98
|
+
return c.json({ error: { message: 'LLM proxy is not configured' } }, 503);
|
|
99
|
+
}
|
|
100
|
+
const sessions = new ContainerSessionService({ secret });
|
|
101
|
+
const session = await sessions.verify(bearer(c.req.header('authorization')));
|
|
102
|
+
if (!session) {
|
|
103
|
+
logger.warn({ scope: 'llmProxy' }, 'llm proxy: invalid or expired session token');
|
|
104
|
+
return c.json({ error: { message: 'Invalid or expired session token' } }, 401);
|
|
105
|
+
}
|
|
106
|
+
// Parse + harden the request: lock the model to the session's, and ask for
|
|
107
|
+
// usage on the final streamed chunk so we can always meter. Parsed before the
|
|
108
|
+
// spend gate so a refusal is still recorded with its prompt/shape for analysis.
|
|
109
|
+
let payload;
|
|
110
|
+
try {
|
|
111
|
+
payload = (await c.req.json());
|
|
112
|
+
}
|
|
113
|
+
catch {
|
|
114
|
+
return c.json({ error: { message: 'Invalid JSON body' } }, 400);
|
|
115
|
+
}
|
|
116
|
+
payload.model = session.model;
|
|
117
|
+
// Prompt caching: route this conversation's calls to the same cached prefix on
|
|
118
|
+
// providers that support it (keyed on the execution id, stable across the run's
|
|
119
|
+
// turns). A no-op for providers that cache automatically on the prefix or not at
|
|
120
|
+
// all — see `promptCacheParams`.
|
|
121
|
+
Object.assign(payload, promptCacheParams(session.provider, session.executionId));
|
|
122
|
+
const streaming = payload.stream === true;
|
|
123
|
+
const toolCount = Array.isArray(payload.tools) ? payload.tools.length : 0;
|
|
124
|
+
const messageCount = Array.isArray(payload.messages) ? payload.messages.length : 0;
|
|
125
|
+
// The EFFECTIVE output ceiling: updated below if the proxy overrides max_tokens
|
|
126
|
+
// (e.g. the Workers AI floor), so the recorded metric reflects what actually
|
|
127
|
+
// applied, not just what the client asked for.
|
|
128
|
+
let requestMaxTokens = typeof payload.max_tokens === 'number' ? payload.max_tokens : null;
|
|
129
|
+
const promptText = JSON.stringify(payload.messages ?? []);
|
|
130
|
+
// Correlate every proxied call with its run so a bootstrap/execution can be
|
|
131
|
+
// traced end to end. We log the tool count explicitly: an agent (Pi) that gets
|
|
132
|
+
// no tools back can't edit files, so a toolless call is the signature of a no-op.
|
|
133
|
+
const log = logger.child({
|
|
134
|
+
scope: 'llmProxy',
|
|
135
|
+
workspaceId: session.workspaceId,
|
|
136
|
+
executionId: session.executionId,
|
|
137
|
+
agentKind: session.agentKind,
|
|
138
|
+
provider: session.provider,
|
|
139
|
+
model: session.model,
|
|
140
|
+
});
|
|
141
|
+
log.info({ streaming, toolCount }, 'llm proxy: forwarding chat completion');
|
|
142
|
+
const waitUntil = makeWaitUntil(c);
|
|
143
|
+
// One id per proxied call, minted here so the SAME id rides both the live
|
|
144
|
+
// `llmCall` activity event and the persisted metric row — the drill-down panel
|
|
145
|
+
// keys its lazy body-load by it, and a live-appended summary row reconciles with
|
|
146
|
+
// the stored row on reload instead of duplicating.
|
|
147
|
+
const callId = `llm_${crypto.randomUUID()}`;
|
|
148
|
+
// Per-call observation handling, off the response path: (1) push a COMPACT live
|
|
149
|
+
// activity event (no prompt/response bodies) so an open "Model activity" panel
|
|
150
|
+
// updates in real time, independent of the durable driver — the proxy records
|
|
151
|
+
// calls even while the run's poll loop is evicted; (2) persist the full metric to
|
|
152
|
+
// the observability sink when it is wired. `upstreamMs` is supplied by whichever
|
|
153
|
+
// path made the call; `totalMs` is the proxy's end-to-end time. Both are
|
|
154
|
+
// best-effort and must never break the proxy.
|
|
155
|
+
const observe = (obs) => {
|
|
156
|
+
const promptTokens = obs.usage?.prompt_tokens ?? 0;
|
|
157
|
+
const completionTokens = obs.usage?.completion_tokens ?? 0;
|
|
158
|
+
const cachedPromptTokens = obs.cachedPromptTokens ?? cachedTokensFromUsage(obs.usage);
|
|
159
|
+
const totalMs = Date.now() - t0;
|
|
160
|
+
// Live activity event — emitted regardless of whether the persistence sink is
|
|
161
|
+
// wired, so the live view works even on a deployment that does not retain
|
|
162
|
+
// metrics. This fires on EVERY observed outcome, including refusals/errors (spend
|
|
163
|
+
// exhausted, unavailable provider, upstream non-2xx) where no model work ran:
|
|
164
|
+
// surfacing those live (with `ok:false`) is intentional and matches what the sink
|
|
165
|
+
// persists. Best-effort: a publish failure (no subscribers, transient hub error)
|
|
166
|
+
// must not break metering.
|
|
167
|
+
waitUntil(Promise.resolve(
|
|
168
|
+
// `?.` on the publisher itself, not just the method: a minimal container
|
|
169
|
+
// (e.g. the harness's real-proxy acceptance test) may omit it, and the live
|
|
170
|
+
// emit is best-effort — a missing publisher must never break metering.
|
|
171
|
+
executionEventPublisher?.llmCallObserved?.(session.workspaceId, {
|
|
172
|
+
id: callId,
|
|
173
|
+
workspaceId: session.workspaceId,
|
|
174
|
+
executionId: session.executionId,
|
|
175
|
+
agentKind: session.agentKind,
|
|
176
|
+
provider: session.provider,
|
|
177
|
+
model: session.model,
|
|
178
|
+
createdAt: Date.now(),
|
|
179
|
+
streaming,
|
|
180
|
+
messageCount,
|
|
181
|
+
toolCount,
|
|
182
|
+
requestMaxTokens,
|
|
183
|
+
promptTokens,
|
|
184
|
+
cachedPromptTokens,
|
|
185
|
+
completionTokens,
|
|
186
|
+
totalTokens: promptTokens + completionTokens,
|
|
187
|
+
finishReason: obs.finishReason,
|
|
188
|
+
upstreamMs: obs.upstreamMs,
|
|
189
|
+
overheadMs: Math.max(0, totalMs - obs.upstreamMs),
|
|
190
|
+
totalMs,
|
|
191
|
+
ok: obs.ok,
|
|
192
|
+
httpStatus: obs.httpStatus,
|
|
193
|
+
errorMessage: obs.errorMessage,
|
|
194
|
+
})).catch(() => { }));
|
|
195
|
+
if (!llmObservability)
|
|
196
|
+
return;
|
|
197
|
+
waitUntil(llmObservability
|
|
198
|
+
.record({
|
|
199
|
+
id: callId,
|
|
200
|
+
workspaceId: session.workspaceId,
|
|
201
|
+
executionId: session.executionId,
|
|
202
|
+
agentKind: session.agentKind,
|
|
203
|
+
provider: session.provider,
|
|
204
|
+
model: session.model,
|
|
205
|
+
streaming,
|
|
206
|
+
messageCount,
|
|
207
|
+
toolCount,
|
|
208
|
+
requestMaxTokens,
|
|
209
|
+
promptTokens,
|
|
210
|
+
cachedPromptTokens,
|
|
211
|
+
completionTokens,
|
|
212
|
+
totalTokens: promptTokens + completionTokens,
|
|
213
|
+
finishReason: obs.finishReason,
|
|
214
|
+
totalMs,
|
|
215
|
+
upstreamMs: obs.upstreamMs,
|
|
216
|
+
ok: obs.ok,
|
|
217
|
+
httpStatus: obs.httpStatus,
|
|
218
|
+
errorMessage: obs.errorMessage,
|
|
219
|
+
promptText,
|
|
220
|
+
responseText: obs.responseText,
|
|
221
|
+
reasoningText: obs.reasoningText ?? '',
|
|
222
|
+
})
|
|
223
|
+
// Observability must never break the proxy.
|
|
224
|
+
.catch((err) => log.warn({ err: err instanceof Error ? err.message : String(err) }, 'llm proxy: failed to record metric')));
|
|
225
|
+
};
|
|
226
|
+
// Spend gate: refuse once the monthly budget is exhausted, mirroring the
|
|
227
|
+
// engine's pre-step check so a container can't keep spending.
|
|
228
|
+
if (await spendService.isOverBudget()) {
|
|
229
|
+
logger.warn({ scope: 'llmProxy', workspaceId: session.workspaceId, executionId: session.executionId }, 'llm proxy: spend budget exhausted — refusing call');
|
|
230
|
+
observe({
|
|
231
|
+
usage: null,
|
|
232
|
+
finishReason: null,
|
|
233
|
+
responseText: '',
|
|
234
|
+
ok: false,
|
|
235
|
+
httpStatus: 402,
|
|
236
|
+
errorMessage: 'Spend budget exhausted',
|
|
237
|
+
upstreamMs: 0,
|
|
238
|
+
});
|
|
239
|
+
return c.json({ error: { message: 'Spend budget exhausted' } }, 402);
|
|
240
|
+
}
|
|
241
|
+
// Give container agents (Pi) generous output room for in-process Workers AI models
|
|
242
|
+
// (which clamp to their large ceilings gracefully). Other providers keep Pi's value
|
|
243
|
+
// to respect their stricter upstream output caps.
|
|
244
|
+
if (session.provider === 'workers-ai') {
|
|
245
|
+
const asked = typeof payload.max_tokens === 'number' ? payload.max_tokens : 0;
|
|
246
|
+
const toolsText = Array.isArray(payload.tools) ? JSON.stringify(payload.tools) : '';
|
|
247
|
+
const floored = workersAiOutputCeiling({
|
|
248
|
+
asked,
|
|
249
|
+
contextWindow: contextWindowFor({ provider: session.provider, model: session.model }),
|
|
250
|
+
inputChars: promptText.length + toolsText.length,
|
|
251
|
+
});
|
|
252
|
+
payload.max_tokens = floored;
|
|
253
|
+
// Record the ceiling we actually applied, not the (often absent) asked value.
|
|
254
|
+
requestMaxTokens = floored;
|
|
255
|
+
}
|
|
256
|
+
// The pooled API key leased for this call (non-binding providers), so usage can be
|
|
257
|
+
// folded back into its rolling-window rotation counters when the call completes.
|
|
258
|
+
let leasedApiKeyId = null;
|
|
259
|
+
const record = (usage) => {
|
|
260
|
+
if (!usage)
|
|
261
|
+
return Promise.resolve(0);
|
|
262
|
+
const inputTokens = usage.prompt_tokens ?? 0;
|
|
263
|
+
const outputTokens = usage.completion_tokens ?? 0;
|
|
264
|
+
// Fold usage into the leased key's rotation counters (best-effort, off the meter).
|
|
265
|
+
if (leasedApiKeyId && apiKeys) {
|
|
266
|
+
void apiKeys.recordUsage(leasedApiKeyId, { inputTokens, outputTokens }).catch(() => { });
|
|
267
|
+
}
|
|
268
|
+
return spendService.record({
|
|
269
|
+
workspaceId: session.workspaceId,
|
|
270
|
+
executionId: session.executionId,
|
|
271
|
+
agentKind: session.agentKind,
|
|
272
|
+
model: `${session.provider}:${session.model}`,
|
|
273
|
+
usage: { inputTokens, outputTokens },
|
|
274
|
+
});
|
|
275
|
+
};
|
|
276
|
+
// Workers AI (and any binding-reached provider) has no external upstream: run it
|
|
277
|
+
// in-process via the facade's gateway. Null means this runtime can't (e.g. Node) →
|
|
278
|
+
// the provider is unavailable.
|
|
279
|
+
if (session.provider === 'workers-ai') {
|
|
280
|
+
// The in-process gateway reports its own observation via `recordMetric` (it
|
|
281
|
+
// owns the model timing). We only record here when the dispatch itself fails.
|
|
282
|
+
const dispatchAt = Date.now();
|
|
283
|
+
const inProcess = gateways.llmUpstream.runInProcess({
|
|
284
|
+
model: session.model,
|
|
285
|
+
payload,
|
|
286
|
+
streaming,
|
|
287
|
+
record,
|
|
288
|
+
recordMetric: observe,
|
|
289
|
+
waitUntil,
|
|
290
|
+
log,
|
|
291
|
+
});
|
|
292
|
+
if (!inProcess) {
|
|
293
|
+
log.error('llm proxy: in-process provider is not available in this runtime');
|
|
294
|
+
observe({
|
|
295
|
+
usage: null,
|
|
296
|
+
finishReason: null,
|
|
297
|
+
responseText: '',
|
|
298
|
+
ok: false,
|
|
299
|
+
httpStatus: 502,
|
|
300
|
+
errorMessage: `Provider '${session.provider}' is not available`,
|
|
301
|
+
upstreamMs: 0,
|
|
302
|
+
});
|
|
303
|
+
return c.json({ error: { message: `Provider '${session.provider}' is not available` } }, 502);
|
|
304
|
+
}
|
|
305
|
+
try {
|
|
306
|
+
return await inProcess;
|
|
307
|
+
}
|
|
308
|
+
catch (err) {
|
|
309
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
310
|
+
log.error({ err: message }, 'llm proxy: in-process call failed');
|
|
311
|
+
observe({
|
|
312
|
+
usage: null,
|
|
313
|
+
finishReason: null,
|
|
314
|
+
responseText: '',
|
|
315
|
+
ok: false,
|
|
316
|
+
httpStatus: 502,
|
|
317
|
+
errorMessage: message,
|
|
318
|
+
upstreamMs: Date.now() - dispatchAt,
|
|
319
|
+
});
|
|
320
|
+
return c.json({ error: { message: `In-process call failed for model '${session.model}': ${message}` } }, 502);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
// Resolve the upstream base URL + bearer key. Two paths:
|
|
324
|
+
// - LOCAL runners (Ollama / LM Studio / …): the endpoint is configured PER USER, so
|
|
325
|
+
// resolve it by the run INITIATOR (`session.userId`) and use its optional key
|
|
326
|
+
// directly — NO DB key lease (these runners are keyless by default; a placeholder
|
|
327
|
+
// bearer is harmless). `leasedApiKeyId` stays undefined so no spend key is attributed.
|
|
328
|
+
// - Cloud providers: resolve the base URL from the gateway and lease the key from the
|
|
329
|
+
// DB-backed pool (workspace + account + initiator).
|
|
330
|
+
let baseURL;
|
|
331
|
+
let apiKey;
|
|
332
|
+
if (isLocalRunner(session.provider)) {
|
|
333
|
+
const resolved = session.userId && localModelEndpoints
|
|
334
|
+
? await localModelEndpoints.resolve(session.userId, session.provider)
|
|
335
|
+
: null;
|
|
336
|
+
if (!resolved) {
|
|
337
|
+
log.error('llm proxy: no local runner endpoint configured for the run initiator');
|
|
338
|
+
observe({
|
|
339
|
+
usage: null,
|
|
340
|
+
finishReason: null,
|
|
341
|
+
responseText: '',
|
|
342
|
+
ok: false,
|
|
343
|
+
httpStatus: 502,
|
|
344
|
+
errorMessage: `No local runner '${session.provider}' configured for this run`,
|
|
345
|
+
upstreamMs: 0,
|
|
346
|
+
});
|
|
347
|
+
return c.json({ error: { message: `No local runner '${session.provider}' configured for this run` } }, 502);
|
|
348
|
+
}
|
|
349
|
+
baseURL = resolved.baseUrl.replace(/\/+$/, '');
|
|
350
|
+
// Most local runners ignore auth; the SDK/fetch still emit an Authorization header.
|
|
351
|
+
apiKey = resolved.apiKey || 'local';
|
|
352
|
+
}
|
|
353
|
+
else {
|
|
354
|
+
const upstream = gateways.llmUpstream.resolveOpenAiCompatible(session.provider);
|
|
355
|
+
if (!upstream) {
|
|
356
|
+
log.error('llm proxy: provider is not available (no base URL resolved)');
|
|
357
|
+
observe({
|
|
358
|
+
usage: null,
|
|
359
|
+
finishReason: null,
|
|
360
|
+
responseText: '',
|
|
361
|
+
ok: false,
|
|
362
|
+
httpStatus: 502,
|
|
363
|
+
errorMessage: `Provider '${session.provider}' is not available`,
|
|
364
|
+
upstreamMs: 0,
|
|
365
|
+
});
|
|
366
|
+
return c.json({ error: { message: `Provider '${session.provider}' is not available` } }, 502);
|
|
367
|
+
}
|
|
368
|
+
// Lease the API key for this provider from the DB-backed pool (workspace + owning
|
|
369
|
+
// account + the run initiator), scoped from the signed session claims. Keys are no
|
|
370
|
+
// longer env-baked: an empty pool means the provider is not configured.
|
|
371
|
+
if (!apiKeys) {
|
|
372
|
+
log.error('llm proxy: API-key store is not configured');
|
|
373
|
+
observe({
|
|
374
|
+
usage: null,
|
|
375
|
+
finishReason: null,
|
|
376
|
+
responseText: '',
|
|
377
|
+
ok: false,
|
|
378
|
+
httpStatus: 502,
|
|
379
|
+
errorMessage: 'API-key store is not configured',
|
|
380
|
+
upstreamMs: 0,
|
|
381
|
+
});
|
|
382
|
+
return c.json({ error: { message: 'API-key store is not configured' } }, 502);
|
|
383
|
+
}
|
|
384
|
+
try {
|
|
385
|
+
const leased = await apiKeys.lease(session.workspaceId, session.provider, {
|
|
386
|
+
accountId: session.accountId,
|
|
387
|
+
userId: session.userId,
|
|
388
|
+
});
|
|
389
|
+
leasedApiKeyId = leased.keyId;
|
|
390
|
+
apiKey = leased.secret;
|
|
391
|
+
}
|
|
392
|
+
catch (err) {
|
|
393
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
394
|
+
log.error({ err: message }, 'llm proxy: no API key configured for provider');
|
|
395
|
+
observe({
|
|
396
|
+
usage: null,
|
|
397
|
+
finishReason: null,
|
|
398
|
+
responseText: '',
|
|
399
|
+
ok: false,
|
|
400
|
+
httpStatus: 502,
|
|
401
|
+
errorMessage: message,
|
|
402
|
+
upstreamMs: 0,
|
|
403
|
+
});
|
|
404
|
+
return c.json({ error: { message: `No API key configured for provider '${session.provider}'` } }, 502);
|
|
405
|
+
}
|
|
406
|
+
baseURL = upstream.baseURL;
|
|
407
|
+
}
|
|
408
|
+
if (streaming) {
|
|
409
|
+
payload.stream_options = { include_usage: true };
|
|
410
|
+
}
|
|
411
|
+
// Upstream-dispatch clock: the slice between here and the response is the model's
|
|
412
|
+
// execution; the rest of the proxy's time is transport overhead.
|
|
413
|
+
const dispatchAt = Date.now();
|
|
414
|
+
const upstreamRes = await fetch(`${baseURL}/chat/completions`, {
|
|
415
|
+
method: 'POST',
|
|
416
|
+
headers: {
|
|
417
|
+
authorization: `Bearer ${apiKey}`,
|
|
418
|
+
'content-type': 'application/json',
|
|
419
|
+
},
|
|
420
|
+
body: JSON.stringify(payload),
|
|
421
|
+
});
|
|
422
|
+
// Non-2xx: pass the upstream error straight back, nothing to meter.
|
|
423
|
+
if (!upstreamRes.ok || !upstreamRes.body) {
|
|
424
|
+
log.error({ status: upstreamRes.status }, 'llm proxy: upstream returned non-2xx');
|
|
425
|
+
observe({
|
|
426
|
+
usage: null,
|
|
427
|
+
finishReason: null,
|
|
428
|
+
responseText: '',
|
|
429
|
+
ok: false,
|
|
430
|
+
httpStatus: upstreamRes.status,
|
|
431
|
+
errorMessage: `Upstream returned ${upstreamRes.status}`,
|
|
432
|
+
upstreamMs: Date.now() - dispatchAt,
|
|
433
|
+
});
|
|
434
|
+
return new Response(upstreamRes.body, {
|
|
435
|
+
status: upstreamRes.status,
|
|
436
|
+
headers: { 'content-type': upstreamRes.headers.get('content-type') ?? 'application/json' },
|
|
437
|
+
});
|
|
438
|
+
}
|
|
439
|
+
if (streaming) {
|
|
440
|
+
// Tee the SSE stream so we can scrape the trailing `usage` chunk + finish
|
|
441
|
+
// reason + assistant text without buffering the response, then meter spend and
|
|
442
|
+
// record the observation (off the response path) once it ends.
|
|
443
|
+
const body = upstreamRes.body.pipeThrough(observationStream(dispatchAt, (obs) => {
|
|
444
|
+
waitUntil(record(obs.usage));
|
|
445
|
+
observe(obs);
|
|
446
|
+
}));
|
|
447
|
+
return new Response(body, {
|
|
448
|
+
status: upstreamRes.status,
|
|
449
|
+
headers: { 'content-type': 'text/event-stream' },
|
|
450
|
+
});
|
|
451
|
+
}
|
|
452
|
+
// Buffered JSON: read usage, meter, record the observation, and relay verbatim.
|
|
453
|
+
const json = (await upstreamRes.json());
|
|
454
|
+
const upstreamMs = Date.now() - dispatchAt;
|
|
455
|
+
await record(json.usage ?? null);
|
|
456
|
+
observe({
|
|
457
|
+
usage: json.usage ?? null,
|
|
458
|
+
finishReason: json.choices?.[0]?.finish_reason ?? null,
|
|
459
|
+
responseText: assistantTextFromCompletion(json),
|
|
460
|
+
reasoningText: reasoningTextFromCompletion(json),
|
|
461
|
+
ok: true,
|
|
462
|
+
httpStatus: upstreamRes.status,
|
|
463
|
+
errorMessage: null,
|
|
464
|
+
upstreamMs,
|
|
465
|
+
});
|
|
466
|
+
return c.json(json);
|
|
467
|
+
});
|
|
468
|
+
return app;
|
|
469
|
+
}
|
|
470
|
+
/** Pull the assistant text out of a buffered completion (empty when tool-only). */
|
|
471
|
+
function assistantTextFromCompletion(json) {
|
|
472
|
+
const content = json.choices?.[0]?.message?.content;
|
|
473
|
+
return typeof content === 'string' ? content : '';
|
|
474
|
+
}
|
|
475
|
+
/**
|
|
476
|
+
* Pull the reasoning/"thinking" trace out of a buffered completion, across the field
|
|
477
|
+
* names OpenAI-compatible providers use (`reasoning_content` on DeepSeek, `reasoning`
|
|
478
|
+
* on OpenRouter and others). Empty for non-reasoning models.
|
|
479
|
+
*/
|
|
480
|
+
function reasoningTextFromCompletion(json) {
|
|
481
|
+
const message = json.choices?.[0]?.message;
|
|
482
|
+
const reasoning = message?.reasoning_content ?? message?.reasoning;
|
|
483
|
+
return typeof reasoning === 'string' ? reasoning : '';
|
|
484
|
+
}
|
|
485
|
+
/**
|
|
486
|
+
* A passthrough TransformStream that scans OpenAI SSE chunks, accumulating the
|
|
487
|
+
* assistant text, the final `usage` and the finish reason, and reports the full
|
|
488
|
+
* observation once the stream ends — so the proxy can meter spend AND record the
|
|
489
|
+
* observability metric without buffering the response. `dispatchAt` anchors the
|
|
490
|
+
* model-execution slice (`upstreamMs` = stream end − dispatch). OpenAI emits usage
|
|
491
|
+
* in the last `data:` event when `stream_options.include_usage` is set.
|
|
492
|
+
*
|
|
493
|
+
* Caveat: for a streamed call `upstreamMs` is measured at `flush`, which fires when
|
|
494
|
+
* the upstream closes after chunks have drained downstream — so a slow consumer can
|
|
495
|
+
* fold some client-drain time into the "model execution" slice. Container readers
|
|
496
|
+
* (Pi) drain fast, so the transport-vs-execution split stays a good approximation;
|
|
497
|
+
* exact per-chunk attribution would need first-byte/last-byte timestamps.
|
|
498
|
+
*
|
|
499
|
+
* Two further limitations are accepted deliberately to keep the response unbuffered:
|
|
500
|
+
* - `responseText` captures the assistant *text* deltas only (not tool-call argument
|
|
501
|
+
* deltas), matching the buffered path — a tool-only turn records empty text.
|
|
502
|
+
* - `flush` only runs on a clean close, so a stream the upstream *errors* mid-flight
|
|
503
|
+
* is not recorded here; the error still propagates to the client. (The in-process
|
|
504
|
+
* Workers-AI path, which owns its generation, does record stream failures.)
|
|
505
|
+
* Recording either would require buffering/teeing the body, which this seam exists to
|
|
506
|
+
* avoid; revisit only if streaming-error observability becomes a real need.
|
|
507
|
+
*/
|
|
508
|
+
function observationStream(dispatchAt, report) {
|
|
509
|
+
const decoder = new TextDecoder();
|
|
510
|
+
let buffer = '';
|
|
511
|
+
let lastUsage = null;
|
|
512
|
+
let finishReason = null;
|
|
513
|
+
let text = '';
|
|
514
|
+
let reasoning = '';
|
|
515
|
+
const scan = (input) => {
|
|
516
|
+
buffer += input;
|
|
517
|
+
let nl;
|
|
518
|
+
while ((nl = buffer.indexOf('\n')) !== -1) {
|
|
519
|
+
const line = buffer.slice(0, nl).trim();
|
|
520
|
+
buffer = buffer.slice(nl + 1);
|
|
521
|
+
if (!line.startsWith('data:'))
|
|
522
|
+
continue;
|
|
523
|
+
const data = line.slice(5).trim();
|
|
524
|
+
if (data === '' || data === '[DONE]')
|
|
525
|
+
continue;
|
|
526
|
+
try {
|
|
527
|
+
const parsed = JSON.parse(data);
|
|
528
|
+
if (parsed.usage)
|
|
529
|
+
lastUsage = parsed.usage;
|
|
530
|
+
const choice = parsed.choices?.[0];
|
|
531
|
+
if (choice) {
|
|
532
|
+
const delta = choice.delta?.content;
|
|
533
|
+
if (typeof delta === 'string')
|
|
534
|
+
text += delta;
|
|
535
|
+
const reasoningDelta = choice.delta?.reasoning_content ?? choice.delta?.reasoning;
|
|
536
|
+
if (typeof reasoningDelta === 'string')
|
|
537
|
+
reasoning += reasoningDelta;
|
|
538
|
+
if (choice.finish_reason)
|
|
539
|
+
finishReason = choice.finish_reason;
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
catch {
|
|
543
|
+
// Partial/non-JSON keep-alive line; ignore.
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
};
|
|
547
|
+
return new TransformStream({
|
|
548
|
+
transform(chunk, controller) {
|
|
549
|
+
scan(decoder.decode(chunk, { stream: true }));
|
|
550
|
+
controller.enqueue(chunk);
|
|
551
|
+
},
|
|
552
|
+
flush() {
|
|
553
|
+
scan(decoder.decode());
|
|
554
|
+
report({
|
|
555
|
+
usage: lastUsage,
|
|
556
|
+
finishReason,
|
|
557
|
+
responseText: text,
|
|
558
|
+
reasoningText: reasoning,
|
|
559
|
+
ok: true,
|
|
560
|
+
httpStatus: 200,
|
|
561
|
+
errorMessage: null,
|
|
562
|
+
upstreamMs: Date.now() - dispatchAt,
|
|
563
|
+
});
|
|
564
|
+
},
|
|
565
|
+
});
|
|
566
|
+
}
|
|
567
|
+
//# sourceMappingURL=LlmProxyController.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LlmProxyController.js","sourceRoot":"","sources":["../../../src/modules/llmProxy/LlmProxyController.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LocalModelEndpointController.d.ts","sourceRoot":"","sources":["../../../src/modules/localModels/LocalModelEndpointController.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAE3B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAkB/C,wBAAgB,4BAA4B,IAAI,IAAI,CAAC,MAAM,CAAC,CA8C3D"}
|