mirror of
https://wget.la/https://github.com/Wxw-Gu/WechatExplorer
synced 2026-10-05 12:34:35 +08:00
Merge pull request #35 from huangzhenhao90/fix/opencode-go-session-header
fix(ai): 修复 OpenCode Go 缺少会话 header 导致日报生成失败
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
import { randomUUID } from 'crypto'
|
||||
import type { Contact, Message } from '../../shared/types'
|
||||
import type { GroupDailyReport, GroupReportMetadata } from '../../shared/group-report'
|
||||
import { exportGroupReport } from '../group-report-service'
|
||||
@@ -120,12 +121,13 @@ export async function generateAgentGroupReport(
|
||||
|
||||
const input = await buildGroupReportInput(messages, contact as Contact, true, 'full')
|
||||
const runtime = aiProvider.getRuntimeConfig()
|
||||
const sessionId = randomUUID()
|
||||
const ai = await aiProvider.chat(
|
||||
[
|
||||
{ role: 'system', content: GROUP_REPORT_SYSTEM_PROMPT },
|
||||
{ role: 'user', content: input.prompt }
|
||||
],
|
||||
{ timeoutMs: Math.max(30, Math.min(1800, request.timeoutSeconds || 300)) * 1000 }
|
||||
{ sessionId, timeoutMs: Math.max(30, Math.min(1800, request.timeoutSeconds || 300)) * 1000 }
|
||||
)
|
||||
if (!ai.success || !ai.data) {
|
||||
return {
|
||||
@@ -153,7 +155,7 @@ export async function generateAgentGroupReport(
|
||||
{ role: 'system', content: GROUP_REPORT_JSON_REPAIR_SYSTEM_PROMPT },
|
||||
{ role: 'user', content: ai.data }
|
||||
],
|
||||
{ timeoutMs: Math.max(30, Math.min(1800, request.timeoutSeconds || 300)) * 1000 }
|
||||
{ sessionId, timeoutMs: Math.max(30, Math.min(1800, request.timeoutSeconds || 300)) * 1000 }
|
||||
)
|
||||
if (!repaired.success || !repaired.data) {
|
||||
const cause = parseError instanceof Error ? parseError.message : String(parseError)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { app } from 'electron'
|
||||
import { randomUUID } from 'crypto'
|
||||
import fs from 'fs-extra'
|
||||
import path from 'path'
|
||||
import type {
|
||||
@@ -486,7 +487,8 @@ export class AIProviderService {
|
||||
messages,
|
||||
testing,
|
||||
signal,
|
||||
onDelta
|
||||
onDelta,
|
||||
options?.sessionId
|
||||
)
|
||||
}
|
||||
|
||||
@@ -514,14 +516,15 @@ export class AIProviderService {
|
||||
onDelta?: AIChatDeltaHandler
|
||||
): Promise<AIRequestResult> {
|
||||
const provider = deepSeekProvider(options.baseURL, options.model)
|
||||
return requestOpenAICompatible(
|
||||
return requestProvider(
|
||||
provider,
|
||||
options.apiKey || '',
|
||||
options.model || provider.defaultModel,
|
||||
messages,
|
||||
false,
|
||||
signal,
|
||||
onDelta
|
||||
onDelta,
|
||||
options?.sessionId
|
||||
)
|
||||
}
|
||||
|
||||
@@ -736,8 +739,21 @@ function requestProvider(
|
||||
messages: AIMessage[],
|
||||
testing = false,
|
||||
signal?: AbortSignal,
|
||||
onDelta?: AIChatDeltaHandler
|
||||
onDelta?: AIChatDeltaHandler,
|
||||
sessionId?: string
|
||||
): Promise<AIRequestResult> {
|
||||
// Match the endpoint, not the editable provider name or model name.
|
||||
const url = new URL(provider.baseUrl)
|
||||
if (url.hostname === 'opencode.ai' && /^\/zen\/go(?:\/|$)/.test(url.pathname)) {
|
||||
const extraHeaders = Object.fromEntries(
|
||||
Object.entries(provider.advanced.extraHeaders).filter(
|
||||
([name]) => name.toLowerCase() !== 'x-opencode-session'
|
||||
)
|
||||
)
|
||||
extraHeaders['x-opencode-session'] = sessionId?.trim() || randomUUID()
|
||||
if (!hasHeader(extraHeaders, 'user-agent')) extraHeaders['user-agent'] = 'TraceMemo'
|
||||
provider = { ...provider, advanced: { ...provider.advanced, extraHeaders } }
|
||||
}
|
||||
if (provider.type === 'anthropic-messages') {
|
||||
return requestAnthropic(provider, apiKey, model, messages, testing, signal)
|
||||
}
|
||||
|
||||
@@ -95,6 +95,7 @@ interface UseGroupReportGenerationArgs {
|
||||
}
|
||||
|
||||
interface PreparedReportContext {
|
||||
sessionId: string
|
||||
input: Awaited<ReturnType<typeof buildGroupReportInput>>
|
||||
startedAt: number
|
||||
logs: ReportGenerationLog[]
|
||||
@@ -507,6 +508,7 @@ export function useGroupReportGeneration({
|
||||
const result = await trackStep(`AI 生成(${selectedModel.model})`, () =>
|
||||
withTimeout(
|
||||
window.api.aiChat(aiMessages, {
|
||||
sessionId: context.sessionId,
|
||||
providerId: selectedModel.providerId,
|
||||
modelId: selectedModel.model,
|
||||
timeoutMs: reportTimeoutSeconds * 1000
|
||||
@@ -560,6 +562,7 @@ export function useGroupReportGeneration({
|
||||
const repairResult = await trackStep(`AI 修复 JSON(${selectedModel.model})`, () =>
|
||||
withTimeout(
|
||||
window.api.aiChat(repairMessages, {
|
||||
sessionId: context.sessionId,
|
||||
providerId: selectedModel.providerId,
|
||||
modelId: selectedModel.model,
|
||||
timeoutMs: reportTimeoutSeconds * 1000
|
||||
@@ -792,7 +795,12 @@ export function useGroupReportGeneration({
|
||||
imageInsightsInjectedIntoPrompt:
|
||||
input.imageInsightSummary.succeeded > 0 && input.prompt.includes('AI 图片识别摘要:')
|
||||
})
|
||||
const context: PreparedReportContext = { input, startedAt: startGenerateTime, logs }
|
||||
const context: PreparedReportContext = {
|
||||
sessionId: crypto.randomUUID(),
|
||||
input,
|
||||
startedAt: startGenerateTime,
|
||||
logs
|
||||
}
|
||||
preparedContextRef.current = context
|
||||
if (input.imageInsightSummary.failed > 0) {
|
||||
setPreparationProgress({
|
||||
|
||||
@@ -117,6 +117,8 @@ export interface LegacyAIConfig {
|
||||
}
|
||||
|
||||
export interface AIChatRequestOptions {
|
||||
/** Stable ID shared by requests and retries belonging to one conversation or task. */
|
||||
sessionId?: string
|
||||
providerId?: string
|
||||
modelId?: string
|
||||
timeoutMs?: number
|
||||
|
||||
Reference in New Issue
Block a user