diff --git a/src/server/db/schemaContract.ts b/src/server/db/schemaContract.ts index b241e84..00303a8 100644 --- a/src/server/db/schemaContract.ts +++ b/src/server/db/schemaContract.ts @@ -9,6 +9,8 @@ import { type LogicalColumnType, } from './schemaMetadata.js'; +export type { LogicalColumnType } from './schemaMetadata.js'; + export interface SchemaContractColumn { logicalType: LogicalColumnType; notNull: boolean; diff --git a/src/server/proxy-core/surfaces/sharedSurface.ts b/src/server/proxy-core/surfaces/sharedSurface.ts index f1f91b9..efad78b 100644 --- a/src/server/proxy-core/surfaces/sharedSurface.ts +++ b/src/server/proxy-core/surfaces/sharedSurface.ts @@ -59,8 +59,23 @@ type SurfaceOauthRefreshContext = { }; type SurfaceSuccessSelectedChannel = SurfaceSelectedChannel & { - account: Record & { id: number }; - site: Record; + account: Record & { + id: number; + username?: string | null; + accessToken?: string | null; + apiToken?: string | null; + extraConfig?: string | null; + platformUserId?: number | null; + }; + site: Record & { + id: number; + url: string; + platform: string; + apiKey?: string | null; + useSystemProxy?: boolean | null; + proxyUrl?: string | null; + name?: string | null; + }; tokenValue: string; tokenName?: string | null; }; @@ -69,6 +84,18 @@ type SurfaceUsageSummary = { promptTokens: number; completionTokens: number; totalTokens: number; + cacheReadTokens: number; + cacheCreationTokens: number; + promptTokensIncludeCache: boolean | null; +}; + +type SurfaceResolvedUsageSummary = { + promptTokens: number; + completionTokens: number; + totalTokens: number; + recoveredFromSelfLog: boolean; + estimatedCostFromQuota: number; + selfLogBillingMeta: import('../../services/proxyUsageFallbackService.js').SelfLogBillingMeta | null; }; export async function selectSurfaceChannelForAttempt(input: { @@ -251,11 +278,18 @@ export async function recordSurfaceSuccess(input: { bestEffortMetrics?: { errorLabel: string; }; -}) { - let resolvedUsage = { +}): Promise<{ + resolvedUsage: SurfaceResolvedUsageSummary; + estimatedCost: number; + billingDetails: unknown; +}> { + let resolvedUsage: SurfaceResolvedUsageSummary = { promptTokens: input.parsedUsage.promptTokens, completionTokens: input.parsedUsage.completionTokens, totalTokens: input.parsedUsage.totalTokens, + recoveredFromSelfLog: false, + estimatedCostFromQuota: 0, + selfLogBillingMeta: null, }; let estimatedCost = 0; let billingDetails: unknown = null; diff --git a/src/web/pages/ModelTester.tsx b/src/web/pages/ModelTester.tsx index f3ae2d5..e017b27 100644 --- a/src/web/pages/ModelTester.tsx +++ b/src/web/pages/ModelTester.tsx @@ -53,6 +53,7 @@ import { isConversationUploadedFileSupported, resolveConversationFileCapability, } from './helpers/conversationFileCapabilities.js'; +import ConversationComposer from './model-tester/ConversationComposer.js'; import DebugPanel from './model-tester/DebugPanel.js'; import ModernSelect from '../components/ModernSelect.js'; import { useAnimatedVisibility } from '../components/useAnimatedVisibility.js'; @@ -2859,163 +2860,25 @@ export default function ModelTester() { )} {inputs.mode === 'conversation' ? ( -
-
-
- { - void handleConversationFilesChange(event.target.files); - event.target.value = ''; - }} - /> -
- - - {customRequestMode - ? '自定义请求模式不会自动上传这些附件;关闭自定义模式后可走标准 /v1/files 链路。' - : !conversationFileSupported - ? (conversationFileCapability.reason || '当前协议暂不支持会话附件注入。') - : conversationFileHint} - -
- {conversationFiles.length > 0 && ( -
- {conversationFiles.map((file) => { - const statusText = file.status === 'uploading' - ? '上传中' - : file.status === 'uploaded' - ? '已上传' - : file.status === 'error' - ? '失败' - : '待上传'; - const statusColor = file.status === 'error' - ? 'var(--color-danger)' - : file.status === 'uploaded' - ? 'var(--color-success)' - : file.status === 'uploading' - ? 'var(--color-warning)' - : 'var(--color-text-muted)'; - - return ( - - 📎 - - {file.name} - - · {statusText} - {!sending && ( - - )} - - ); - })} -
- )} -
- -