Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 44 additions & 1 deletion apps/electron/src/main/ipc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
*/

import { ipcMain, nativeTheme, shell, dialog, BrowserWindow } from 'electron'
import { IPC_CHANNELS, CHANNEL_IPC_CHANNELS, CHAT_IPC_CHANNELS, AGENT_IPC_CHANNELS, ENVIRONMENT_IPC_CHANNELS, PROXY_IPC_CHANNELS, GITHUB_RELEASE_IPC_CHANNELS } from '@proma/shared'
import { IPC_CHANNELS, CHANNEL_IPC_CHANNELS, CHAT_IPC_CHANNELS, AGENT_IPC_CHANNELS, ENVIRONMENT_IPC_CHANNELS, PROXY_IPC_CHANNELS, GITHUB_RELEASE_IPC_CHANNELS, USAGE_IPC_CHANNELS } from '@proma/shared'
import { USER_PROFILE_IPC_CHANNELS, SETTINGS_IPC_CHANNELS } from '../types'
import type {
RuntimeStatus,
Expand Down Expand Up @@ -44,6 +44,9 @@ import type {
SystemProxyDetectResult,
GitHubRelease,
GitHubReleaseListOptions,
UsageStats,
ConversationUsage,
UsageSettings,
} from '@proma/shared'
import type { UserProfile, AppSettings } from '../types'
import { getRuntimeStatus, getGitRepoStatus } from './lib/runtime-init'
Expand Down Expand Up @@ -109,6 +112,12 @@ import {
listReleases as listGitHubReleases,
getReleaseByTag,
} from './lib/github-release-service'
import {
getUsageStats,
getConversationUsage,
getUsageSettings,
updateUsageSettings,
} from './lib/usage-service'

/**
* 注册 IPC 处理器
Expand Down Expand Up @@ -860,6 +869,40 @@ export function registerIpcHandlers(): void {
}
)

// ===== 使用统计相关 =====

// 获取使用量统计总览
ipcMain.handle(
USAGE_IPC_CHANNELS.GET_USAGE_STATS,
async (_, days: number = 30): Promise<UsageStats> => {
return getUsageStats(days)
}
)

// 获取指定对话的使用量详情
ipcMain.handle(
USAGE_IPC_CHANNELS.GET_CONVERSATION_USAGE,
async (_, conversationId: string): Promise<ConversationUsage | null> => {
return getConversationUsage(conversationId)
}
)

// 获取使用统计设置
ipcMain.handle(
USAGE_IPC_CHANNELS.GET_USAGE_SETTINGS,
async (): Promise<UsageSettings> => {
return getUsageSettings()
}
)

// 更新使用统计设置
ipcMain.handle(
USAGE_IPC_CHANNELS.UPDATE_USAGE_SETTINGS,
async (_, settings: UsageSettings): Promise<UsageSettings> => {
return updateUsageSettings(settings)
}
)

console.log('[IPC] IPC 处理器注册完成')

// 注册更新 IPC 处理器
Expand Down
10 changes: 8 additions & 2 deletions apps/electron/src/main/lib/chat-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
import { randomUUID } from 'node:crypto'
import type { WebContents } from 'electron'
import { CHAT_IPC_CHANNELS } from '@proma/shared'
import type { ChatSendInput, ChatMessage, GenerateTitleInput, FileAttachment } from '@proma/shared'
import type { ChatSendInput, ChatMessage, GenerateTitleInput, FileAttachment, TokenUsage } from '@proma/shared'
import {
getAdapter,
streamSSE,
Expand Down Expand Up @@ -238,6 +238,7 @@ export async function sendMessage(
// 在 try 外累积流式内容,abort 时 catch 块仍可访问
let accumulatedContent = ''
let accumulatedReasoning = ''
let usage: TokenUsage | undefined

try {
// 7. 获取适配器 + 构建请求 + 执行流式 SSE
Expand All @@ -257,7 +258,7 @@ export async function sendMessage(
const proxyUrl = await getEffectiveProxyUrl()
const fetchFn = getFetchFn(proxyUrl)

const { content, reasoning } = await streamSSE({
const { content, reasoning, usage: streamUsage } = await streamSSE({
request,
adapter,
signal: controller.signal,
Expand All @@ -283,6 +284,9 @@ export async function sendMessage(
},
})

// 保存 usage 数据
usage = streamUsage

// 8. 保存 assistant 消息(空内容不保存)
const assistantMsgId = randomUUID()
if (content.trim()) {
Expand All @@ -293,6 +297,7 @@ export async function sendMessage(
createdAt: Date.now(),
model: modelId,
reasoning: reasoning || undefined,
usage: usage || undefined,
}
appendMessage(conversationId, assistantMsg)

Expand Down Expand Up @@ -327,6 +332,7 @@ export async function sendMessage(
model: modelId,
reasoning: accumulatedReasoning || undefined,
stopped: true,
usage: usage || undefined,
}
appendMessage(conversationId, partialMsg)

Expand Down
Loading
Loading