feat(host): 版本自适应宿主调用(0.1.7 sessionController / 0.1.0 apiProxy),在 DSH Desktop 内置 0.1.7-rc.2 上实测镜像与发消息全通
This commit is contained in:
+42
-29
@@ -148,7 +148,30 @@ export function apply(ctx) {
|
||||
writeEndpoint()
|
||||
ctx.effect(() => () => { try { fs.rmSync(endpointFile, { force: true }) } catch { } })
|
||||
|
||||
// ---------------------------------------------------------------- 会话镜像缓冲
|
||||
// ---------------------------------------------------------------- 版本自适应的宿主调用
|
||||
// dsh 0.1.x 早期:ctx.apiProxy.sessions.*(信封 { rpcId, payload })
|
||||
// dsh 0.1.7+ :ctx.sessionController.*(Typert Remote 的宿主面,扁平信封)
|
||||
// 两个都试,谁在就用谁;都没有就返回可读错误,绝不让插件抛出去。
|
||||
async function hostCall(method, payload) {
|
||||
const sc = ctx.get('sessionController')
|
||||
if (sc && typeof sc[method] === 'function') {
|
||||
const flat = { ...payload }
|
||||
delete flat.rpcId
|
||||
if (!flat.requestId) flat.requestId = randomUUID()
|
||||
// 0.1.7 的 Remote 签名是 (request, signal);signal 缺失时宿主内部会
|
||||
// "Cannot read properties of undefined (reading 'throwIfAborted')"
|
||||
const r = await sc[method](flat, new AbortController().signal)
|
||||
return { value: r?.value ?? r, via: 'sessionController.' + method }
|
||||
}
|
||||
const api = ctx.get('apiProxy')
|
||||
if (api?.sessions && typeof api.sessions[method] === 'function') {
|
||||
const r = await api.sessions[method]({ rpcId: randomUUID(), payload })
|
||||
return { value: r?.result?.value ?? r?.result ?? r, via: 'apiProxy.sessions.' + method }
|
||||
}
|
||||
throw new Error(`no host API for "${method}" (tried sessionController / apiProxy)`)
|
||||
}
|
||||
|
||||
|
||||
const MAX_ROWS = 120
|
||||
const rows = new Map() // sessionId -> row[]
|
||||
const counts = new Map() // sessionId -> 事件计数兜底(没有 sessionProjection 也能出数字)
|
||||
@@ -338,22 +361,16 @@ export function apply(ctx) {
|
||||
}
|
||||
const target = sessionId || lastSessionId
|
||||
try {
|
||||
const api = ctx.get('apiProxy')
|
||||
if (!api?.sessions?.prompt) throw new Error('apiProxy unavailable')
|
||||
if (!target) throw new Error('no session yet')
|
||||
const r = await api.sessions.prompt({
|
||||
rpcId: randomUUID(),
|
||||
payload: {
|
||||
sessionId: target,
|
||||
mode: 'queue',
|
||||
content: [{ type: 'text', text }],
|
||||
clientTimeZone: Intl.DateTimeFormat().resolvedOptions().timeZone,
|
||||
},
|
||||
const { value, via } = await hostCall('prompt', {
|
||||
sessionId: target,
|
||||
mode: 'queue',
|
||||
content: [{ type: 'text', text }],
|
||||
clientTimeZone: Intl.DateTimeFormat().resolvedOptions().timeZone,
|
||||
})
|
||||
const result = r?.result ?? r
|
||||
log(`chat -> session ${target}: ${JSON.stringify(result).slice(0, 160)}`)
|
||||
log(`chat -> session ${target} via ${via}: ${short(value, 160)}`)
|
||||
res.writeHead(200, { ...cors, 'Content-Type': 'application/json; charset=utf-8' })
|
||||
res.end(JSON.stringify({ ok: true, sessionId: target, result }))
|
||||
res.end(JSON.stringify({ ok: true, sessionId: target, result: value, via }))
|
||||
} catch (e) {
|
||||
const detail = e?.data || e?.message || e
|
||||
log('chat failed: ' + short(detail, 200))
|
||||
@@ -372,24 +389,20 @@ export function apply(ctx) {
|
||||
} catch { }
|
||||
const json = (obj) => { res.writeHead(200, { ...cors, 'Content-Type': 'application/json; charset=utf-8' }); res.end(JSON.stringify(obj)) }
|
||||
try {
|
||||
const api = ctx.get('apiProxy')
|
||||
if (!api?.sessions) throw new Error('apiProxy unavailable')
|
||||
if (body.action === 'create') {
|
||||
const r = await api.sessions.create({
|
||||
rpcId: randomUUID(),
|
||||
payload: {
|
||||
sessionId: body.sessionId ? String(body.sessionId) : randomUUID(),
|
||||
...(body.cwd ? { cwd: String(body.cwd) } : {}),
|
||||
...(body.workspaceId ? { workspaceId: body.workspaceId } : {}),
|
||||
},
|
||||
const { value, via } = await hostCall('create', {
|
||||
sessionId: body.sessionId ? String(body.sessionId) : randomUUID(),
|
||||
...(body.cwd ? { cwd: String(body.cwd) } : {}),
|
||||
...(body.workspaceId ? { workspaceId: body.workspaceId } : {}),
|
||||
...(body.agentPreset ? { agentPreset: String(body.agentPreset) } : {}),
|
||||
})
|
||||
const result = r?.result ?? r
|
||||
if (result?.sessionId) lastSessionId = result.sessionId
|
||||
log('session created: ' + short(result, 160))
|
||||
json({ ok: true, ...result })
|
||||
const sessionId = value?.sessionId || null
|
||||
if (sessionId) lastSessionId = sessionId
|
||||
log(`session created via ${via}: ` + short(value, 160))
|
||||
json({ ok: true, sessionId, via, result: value })
|
||||
} else if (body.action === 'cancel') {
|
||||
const r = await api.sessions.cancel({ rpcId: randomUUID(), payload: { sessionId: body.sessionId || lastSessionId } })
|
||||
json({ ok: true, result: r?.result ?? r })
|
||||
const { value, via } = await hostCall('cancel', { sessionId: body.sessionId || lastSessionId })
|
||||
json({ ok: true, via, result: value })
|
||||
} else {
|
||||
json({ ok: true, sessions: snapshot().sessions, current: lastSessionId })
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user