feat(web): project plan mode through host API
This commit is contained in:
@@ -7,7 +7,7 @@
|
||||
|
||||
export type {
|
||||
ApiProxy, SessionsApi, SessionSummary, HostApi, EventsApi, MuxFrame, HostFrame,
|
||||
ApprovalResponsePayload, QuestionResponsePayload, HistoryEntry, ToolEventView,
|
||||
ApprovalResponsePayload, QuestionResponsePayload, HistoryEntry, PlanModeState, ToolEventView,
|
||||
} from '@deepseek-ai/dsh-host-apiproxy/api'
|
||||
export type { ToolCallView, ToolResultView } from '@deepseek-ai/dsh-tools/presentation'
|
||||
export type {
|
||||
|
||||
@@ -522,6 +522,8 @@ export function createFixtureApi(): ApiProxy {
|
||||
}
|
||||
return ok(request, { accepted: true as const })
|
||||
},
|
||||
planMode: request => ok(request, null),
|
||||
setPlanMode: request => ok(request, null),
|
||||
},
|
||||
host: {
|
||||
describe: request => ok(request, { version: '0.0.0-fixture', cwd: '/tmp/fixture', attachedSessions: 1 }),
|
||||
@@ -633,6 +635,8 @@ export class FixtureApiClient extends AbstractApiClient {
|
||||
case 'session.history': return this.api.sessions.history(request)
|
||||
case 'session.prompt': return this.api.sessions.prompt(request)
|
||||
case 'session.cancel': return this.api.sessions.cancel(request)
|
||||
case 'session.planMode': return this.api.sessions.planMode(request)
|
||||
case 'session.setPlanMode': return this.api.sessions.setPlanMode(request)
|
||||
case 'host.describe': return this.api.host.describe(request)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ import { WebApiClient } from './web-api-client.ts'
|
||||
// ---- Contract re-exports (browser-safe apiproxy channels + core types) ----
|
||||
export type {
|
||||
ApiProxy, SessionsApi, SessionSummary, HostApi, EventsApi, MuxFrame, HostFrame,
|
||||
ApprovalResponsePayload, QuestionResponsePayload, HistoryEntry, ToolEventView,
|
||||
ApprovalResponsePayload, QuestionResponsePayload, HistoryEntry, PlanModeState, ToolEventView,
|
||||
ToolCallView, ToolResultView,
|
||||
RpcRequest, RpcResponse, RpcResult, RpcError, RpcErrorCode,
|
||||
ClientRequest, ServerResponse, ServerRequest, ClientResponse, RpcMessage, RpcReceipt,
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// data source on a real clock; behavior tests need per-case responses and
|
||||
// deferred-controlled timing). Streams are hand pumps: pushMux/pushHost.
|
||||
import type {
|
||||
HostFrame, IApiClient, MuxFrame, RpcRequest, RpcResponse, SessionId,
|
||||
HostFrame, IApiClient, MuxFrame, PlanModeState, RpcRequest, RpcResponse, SessionId,
|
||||
} from '../src/client/api.ts'
|
||||
import { RpcId } from '../src/client/api.ts'
|
||||
|
||||
@@ -49,6 +49,10 @@ export class FakeApiClient implements IApiClient {
|
||||
|
||||
onPrompt: (payload: unknown) => Promise<RpcResponse<{ accepted: true }>> = () => Promise.resolve(ok({ accepted: true as const }))
|
||||
onCancel: (payload: unknown) => Promise<RpcResponse<{ accepted: true }>> = () => Promise.resolve(ok({ accepted: true as const }))
|
||||
onPlanMode: (payload: unknown) => Promise<RpcResponse<PlanModeState | null>> =
|
||||
() => Promise.resolve(ok(null))
|
||||
onSetPlanMode: (payload: unknown) => Promise<RpcResponse<PlanModeState | null>> =
|
||||
() => Promise.resolve(ok(null))
|
||||
onDescribe: (payload: unknown) => Promise<RpcResponse<{ version: string; cwd: string; attachedSessions: number }>> =
|
||||
() => Promise.resolve(ok({ version: '0-fake', cwd: '/f', attachedSessions: 0 }))
|
||||
|
||||
@@ -65,6 +69,8 @@ export class FakeApiClient implements IApiClient {
|
||||
this.record('session.history', payload, this.onHistory(payload)),
|
||||
prompt: (payload: unknown) => this.record('session.prompt', payload, this.onPrompt(payload)),
|
||||
cancel: (payload: unknown) => this.record('session.cancel', payload, this.onCancel(payload)),
|
||||
planMode: (payload: unknown) => this.record('session.planMode', payload, this.onPlanMode(payload)),
|
||||
setPlanMode: (payload: unknown) => this.record('session.setPlanMode', payload, this.onSetPlanMode(payload)),
|
||||
}
|
||||
|
||||
readonly host: IApiClient['host'] = {
|
||||
|
||||
@@ -48,6 +48,16 @@ describe('createFixtureApi', () => {
|
||||
expect(response.result.value.items[1]?.parentSessionId).toBe('fx-alpha') // lineage material
|
||||
})
|
||||
|
||||
it('reports plan mode as an unavailable optional fixture capability', async () => {
|
||||
const client = new FixtureApiClient()
|
||||
expect((await client.sessions.planMode({ sessionId: sid('fx-alpha') })).result).toEqual({
|
||||
ok: true, value: null,
|
||||
})
|
||||
expect((await client.sessions.setPlanMode({ sessionId: sid('fx-alpha'), active: true })).result).toEqual({
|
||||
ok: true, value: null,
|
||||
})
|
||||
})
|
||||
|
||||
it('pages history backwards on message-boundary cuts with seq-contiguous stitching', async () => {
|
||||
const api = createFixtureApi()
|
||||
const tail = await api.sessions.history(req({ sessionId: sid('fx-alpha'), maxMessages: 10 }))
|
||||
|
||||
Reference in New Issue
Block a user