mirror of
https://github.com/deepseek-ai/deepseek-harness
synced 2026-08-15 21:04:50 +00:00
Merge remote-tracking branch 'origin/master' into worktree-guifork
This commit is contained in:
@@ -7,7 +7,11 @@ import { randomUUID } from 'node:crypto'
|
||||
import { mkdir, stat } from 'node:fs/promises'
|
||||
import { join } from 'node:path'
|
||||
import type { Context } from 'cordis'
|
||||
import type { Agent, AgentMessage, AgentMessageId, AgentStatus } from '@deepseek-ai/dsh-agent'
|
||||
import { installAgentLlmTarget } from '@deepseek-ai/dsh-agent'
|
||||
import type {
|
||||
Agent, AgentLlmTarget, AgentLlmTargetRef, AgentMessage, AgentMessageId, AgentStatus,
|
||||
} from '@deepseek-ai/dsh-agent'
|
||||
import { ReasoningEffortId } from '@deepseek-ai/dsh-llm'
|
||||
import { errorChain } from '@deepseek-ai/dsh-llm'
|
||||
import type { ContentBlock, MessageSource } from '@deepseek-ai/dsh-llm'
|
||||
import type { JsonValue, Session, SessionEvent, SessionHeader, SessionId } from '@deepseek-ai/dsh-session'
|
||||
@@ -20,8 +24,9 @@ import {
|
||||
// Type-only: brings the `ctx.tools` Context merge into this program (viewFor reads presenters).
|
||||
import type {} from '@deepseek-ai/dsh-tools'
|
||||
import type {
|
||||
ApiProxy, HistoryEntry, HostFrame, MuxFrame, QuestionResponsePayload, SessionProjectionsBlock,
|
||||
SessionSummary, ToolEventView, WorkspaceId, WorkspaceView,
|
||||
ApiProxy, HistoryEntry, HostFrame, ModelCatalogFailure, ModelProviderGroup, ModelReasoning,
|
||||
MuxFrame, QuestionResponsePayload, SessionProjectionsBlock, SessionSummary, ToolEventView,
|
||||
WorkspaceId, WorkspaceView,
|
||||
} from './api/index.ts'
|
||||
// Type-only: resolves `ctx.get('sessionProjections')` to the projection registry.
|
||||
import type {} from '@deepseek-ai/dsh-session-projection'
|
||||
@@ -351,6 +356,8 @@ function changedWorkspaceView(workspaceId: string, value: unknown): WorkspaceVie
|
||||
*/
|
||||
export function createApiProxy(ctx: Context, defaults: ApiProxyDefaults): ApiProxy {
|
||||
const agentOptions = { provider: defaults.provider, model: defaults.model }
|
||||
type WebLlmTargetRef = AgentLlmTargetRef & { current: AgentLlmTarget }
|
||||
const targets = new WeakMap<Agent, WebLlmTargetRef>()
|
||||
/** Implicit resume of cold sessions, deduplicating concurrent calls (follows the jsonrpc sessionCreations precedent). */
|
||||
const resumes = new Map<SessionId, Promise<Agent>>()
|
||||
/** Client-chosen identity creation/resume, deduplicated across concurrent retries. */
|
||||
@@ -360,6 +367,40 @@ export function createApiProxy(ctx: Context, defaults: ApiProxyDefaults): ApiPro
|
||||
const pendingQuestions = new Map<RpcId, PendingQuestion>()
|
||||
const muxQueues = new Set<FrameQueue<RpcRequest<MuxFrame>>>()
|
||||
|
||||
/**
|
||||
* Install or return the session-local target that prompt assembly snapshots.
|
||||
* Seed order: latest logged request/header, else the host default routing.
|
||||
* There is no create-time per-session override tier on this wire — if one
|
||||
* returns (a create-options contribution), it must fold in between the two.
|
||||
*/
|
||||
function targetFor(agent: Agent): WebLlmTargetRef {
|
||||
const installed = targets.get(agent)
|
||||
if (installed !== undefined) return installed
|
||||
const logged = agent.session.requestHeader()?.config
|
||||
const target: WebLlmTargetRef = {
|
||||
current: logged === undefined
|
||||
? { provider: defaults.provider, model: defaults.model }
|
||||
: {
|
||||
provider: logged.provider,
|
||||
model: logged.model,
|
||||
...logged.reasoningEffort === undefined
|
||||
? {}
|
||||
: { reasoningEffort: logged.reasoningEffort },
|
||||
},
|
||||
assembled: undefined,
|
||||
}
|
||||
installAgentLlmTarget(agent.ctx, target)
|
||||
targets.set(agent, target)
|
||||
return target
|
||||
}
|
||||
|
||||
/** Pre-publication setup used by both fresh and resumed Web agents. */
|
||||
function installTarget(agentCtx: Context): void {
|
||||
const agent = agentCtx.agent
|
||||
if (agent === undefined) throw new Error('api-proxy: agent setup has no scoped agent')
|
||||
targetFor(agent)
|
||||
}
|
||||
|
||||
/** Send one transient frame to every connected mux consumer. */
|
||||
function broadcast(payload: MuxFrame): void {
|
||||
const envelope = frame(payload)
|
||||
@@ -493,7 +534,11 @@ export function createApiProxy(ctx: Context, defaults: ApiProxyDefaults): ApiPro
|
||||
resume = (async () => {
|
||||
try {
|
||||
await assertServable(sessionId)
|
||||
const handle = await ctx.agents.resume({ resumeSessionId: sessionId, agentOptions })
|
||||
const handle = await ctx.agents.resume({
|
||||
resumeSessionId: sessionId,
|
||||
agentOptions,
|
||||
setup: installTarget,
|
||||
})
|
||||
return handle.agent
|
||||
} finally {
|
||||
resumes.delete(sessionId)
|
||||
@@ -528,7 +573,11 @@ export function createApiProxy(ctx: Context, defaults: ApiProxyDefaults): ApiPro
|
||||
if (stored.cwd !== cwd) {
|
||||
throw new SessionCwdConflict(sessionId, cwd, stored.cwd)
|
||||
}
|
||||
return (await ctx.agents.resume({ resumeSessionId: sessionId, agentOptions })).agent
|
||||
return (await ctx.agents.resume({
|
||||
resumeSessionId: sessionId,
|
||||
agentOptions,
|
||||
setup: installTarget,
|
||||
})).agent
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -536,7 +585,12 @@ export function createApiProxy(ctx: Context, defaults: ApiProxyDefaults): ApiPro
|
||||
} catch (error: unknown) {
|
||||
throw new Error(`failed to ensure project directory "${cwd}": ${String(error)}`, { cause: error })
|
||||
}
|
||||
return (await ctx.agents.create({ sessionId, agentOptions, meta: { cwd } })).agent
|
||||
return (await ctx.agents.create({
|
||||
sessionId,
|
||||
agentOptions,
|
||||
meta: { cwd },
|
||||
setup: installTarget,
|
||||
})).agent
|
||||
})().catch((error: unknown) => {
|
||||
// Another Host entry path may have published the same identity while
|
||||
// this operation crossed an asynchronous persistence/filesystem step.
|
||||
@@ -677,6 +731,107 @@ export function createApiProxy(ctx: Context, defaults: ApiProxyDefaults): ApiPro
|
||||
})
|
||||
},
|
||||
|
||||
async models(request) {
|
||||
const { sessionId } = request.payload
|
||||
const found = await agentFor(sessionId)
|
||||
if ('error' in found) return err(request, found.error)
|
||||
const current = targetFor(found.agent).current
|
||||
const catalog = await Promise.all(ctx.llm.listProviders().map(async (provider) => {
|
||||
try {
|
||||
const advertised = await ctx.llm.listModels(provider.id)
|
||||
const models = [...advertised]
|
||||
if (
|
||||
provider.id === current.provider
|
||||
&& !models.some(model => model.id === current.model)
|
||||
) {
|
||||
models.push({
|
||||
provider: provider.id,
|
||||
id: current.model,
|
||||
name: current.model,
|
||||
})
|
||||
}
|
||||
const entries = await Promise.all(models.map(async (model) => {
|
||||
const resolved = await ctx.llm.resolveModelInfo(provider.id, model.id)
|
||||
const reasoning: ModelReasoning | undefined = resolved.reasoning === undefined
|
||||
? undefined
|
||||
: {
|
||||
efforts: resolved.reasoning.efforts.map(effort => ({
|
||||
id: effort.id,
|
||||
name: effort.name,
|
||||
...effort.description === undefined
|
||||
? {}
|
||||
: { description: effort.description },
|
||||
})),
|
||||
...resolved.reasoning.defaultEffort === undefined
|
||||
? {}
|
||||
: { defaultEffort: resolved.reasoning.defaultEffort },
|
||||
}
|
||||
return {
|
||||
id: model.id,
|
||||
name: model.name,
|
||||
...model.description === undefined ? {} : { description: model.description },
|
||||
...provider.id === current.provider
|
||||
&& model.id === current.model
|
||||
&& !advertised.some(candidate => candidate.id === current.model)
|
||||
? { unlisted: true as const }
|
||||
: {},
|
||||
...reasoning === undefined ? {} : { reasoning },
|
||||
}
|
||||
}))
|
||||
const group: ModelProviderGroup = {
|
||||
id: provider.id,
|
||||
name: provider.name,
|
||||
models: entries,
|
||||
}
|
||||
return { kind: 'group' as const, group }
|
||||
} catch (error: unknown) {
|
||||
const failure: ModelCatalogFailure = {
|
||||
id: provider.id,
|
||||
name: provider.name,
|
||||
message: error instanceof Error ? error.message : String(error),
|
||||
}
|
||||
return { kind: 'failure' as const, failure }
|
||||
}
|
||||
}))
|
||||
const groups = catalog.flatMap(item => item.kind === 'group' ? [item.group] : [])
|
||||
const failures = catalog.flatMap(item => item.kind === 'failure' ? [item.failure] : [])
|
||||
return ok(request, {
|
||||
current: { ...current },
|
||||
groups: groups.filter(group => group.models.length > 0),
|
||||
failures,
|
||||
})
|
||||
},
|
||||
|
||||
async selectModel(request) {
|
||||
const { sessionId, provider, model, reasoningEffort } = request.payload
|
||||
const found = await agentFor(sessionId)
|
||||
if ('error' in found) return err(request, found.error)
|
||||
try {
|
||||
const resolved = await ctx.llm.resolveCallConfig({
|
||||
provider,
|
||||
model,
|
||||
...reasoningEffort === undefined
|
||||
? {}
|
||||
: { reasoningEffort: ReasoningEffortId(reasoningEffort) },
|
||||
})
|
||||
const selected: AgentLlmTarget = {
|
||||
provider: resolved.provider,
|
||||
model: resolved.model,
|
||||
...resolved.reasoningEffort === undefined
|
||||
? {}
|
||||
: { reasoningEffort: resolved.reasoningEffort },
|
||||
}
|
||||
targetFor(found.agent).current = selected
|
||||
return ok(request, { selected: { ...selected } })
|
||||
} catch (error: unknown) {
|
||||
return err(request, {
|
||||
code: 'model-unavailable',
|
||||
message: error instanceof Error ? error.message : String(error),
|
||||
details: { provider, model },
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
async prompt(request) {
|
||||
const { sessionId, mode, content } = request.payload
|
||||
const found = await agentFor(sessionId)
|
||||
|
||||
@@ -25,7 +25,10 @@ export interface ApiProxy {
|
||||
}
|
||||
|
||||
// ---- Domain interfaces and payload entities ----
|
||||
export type { HistoryEntry, SessionProjectionsBlock, SessionsApi, SessionSummary } from './sessions.ts'
|
||||
export type {
|
||||
HistoryEntry, ModelCatalogFailure, ModelCatalogModel, ModelProviderGroup, ModelReasoning,
|
||||
ModelReasoningEffort, ModelTarget, SessionModels, SessionProjectionsBlock, SessionsApi, SessionSummary,
|
||||
} from './sessions.ts'
|
||||
export type { HostApi } from './host.ts'
|
||||
export type { WorkspaceApi, WorkspaceId, WorkspaceView } from './workspace.ts'
|
||||
export type { CommandsApi, CommandDescriptor } from './commands.ts'
|
||||
|
||||
@@ -20,6 +20,8 @@ export interface RpcMethodMap {
|
||||
'session.list': SessionsApi['list']
|
||||
'session.create': SessionsApi['create']
|
||||
'session.history': SessionsApi['history']
|
||||
'session.models': SessionsApi['models']
|
||||
'session.selectModel': SessionsApi['selectModel']
|
||||
'session.prompt': SessionsApi['prompt']
|
||||
'session.cancel': SessionsApi['cancel']
|
||||
'host.describe': HostApi['describe']
|
||||
|
||||
@@ -35,6 +35,7 @@ export const rpcErrorSchema: z.ZodType<RpcError> = z.discriminatedUnion('code',
|
||||
z.object({ code: z.literal('bad-request'), message: z.string(), details: z.object({ issues: z.array(z.custom<ZodIssue>()) }) }),
|
||||
z.object({ code: z.literal('cancelled'), message: z.string(), details: z.object({}) }),
|
||||
z.object({ code: z.literal('session-not-found'), message: z.string(), details: z.object({ sessionId: z.string() }) }),
|
||||
z.object({ code: z.literal('model-unavailable'), message: z.string(), details: z.object({ provider: z.string(), model: z.string() }) }),
|
||||
z.object({ code: z.literal('session-conflict'), message: z.string(), details: z.object({ sessionId: z.string(), requestedCwd: z.string(), existingCwd: z.string().optional() }) }),
|
||||
z.object({ code: z.literal('workspace-attach-failed'), message: z.string(), details: z.object({ sessionId: z.string(), workspaceId: z.string() }) }),
|
||||
z.object({ code: z.literal('workspace-not-found'), message: z.string(), details: z.object({ workspaceId: z.string() }) }),
|
||||
|
||||
@@ -32,6 +32,7 @@ export interface RpcErrorDetailsMap {
|
||||
'bad-request': { issues: ZodIssue[] }
|
||||
'cancelled': {}
|
||||
'session-not-found': { sessionId: SessionId }
|
||||
'model-unavailable': { provider: string; model: string }
|
||||
'session-conflict': { sessionId: SessionId; requestedCwd: string; existingCwd?: string }
|
||||
'workspace-attach-failed': { sessionId: SessionId; workspaceId: string }
|
||||
'workspace-not-found': { workspaceId: string }
|
||||
|
||||
@@ -9,7 +9,10 @@ import { z } from 'zod'
|
||||
import type { SessionEvent, SessionId } from '@deepseek-ai/dsh-session/types'
|
||||
import type { RequestPayload, ResponseValue } from './rpc-map.ts'
|
||||
import type { Wire } from './rpc.schema.ts'
|
||||
import type { HistoryEntry, SessionProjectionsBlock, SessionSummary } from './sessions.ts'
|
||||
import type {
|
||||
HistoryEntry, ModelCatalogFailure, ModelCatalogModel, ModelProviderGroup, ModelReasoning,
|
||||
ModelReasoningEffort, ModelTarget, SessionProjectionsBlock, SessionSummary,
|
||||
} from './sessions.ts'
|
||||
import type { ToolEventView } from './events.ts'
|
||||
import type { WorkspaceId } from './workspace.ts'
|
||||
|
||||
@@ -76,6 +79,49 @@ export const sessionHistoryRequestSchema = z.object({
|
||||
maxMessages: z.number().int().positive().optional(),
|
||||
}) satisfies z.ZodType<Wire<RequestPayload<'session.history'>>>
|
||||
|
||||
/** Complete provider/model target. */
|
||||
export const modelTargetSchema = z.object({
|
||||
provider: z.string().min(1),
|
||||
model: z.string().min(1),
|
||||
reasoningEffort: z.string().min(1).optional(),
|
||||
}) satisfies z.ZodType<Wire<ModelTarget>>
|
||||
|
||||
/** One adapter-owned reasoning effort. */
|
||||
export const modelReasoningEffortSchema = z.object({
|
||||
id: z.string().min(1),
|
||||
name: z.string().min(1),
|
||||
description: z.string().optional(),
|
||||
}) satisfies z.ZodType<Wire<ModelReasoningEffort>>
|
||||
|
||||
/** Exact-model reasoning metadata. */
|
||||
export const modelReasoningSchema = z.object({
|
||||
efforts: z.array(modelReasoningEffortSchema).min(1),
|
||||
defaultEffort: z.string().min(1).optional(),
|
||||
}) satisfies z.ZodType<Wire<ModelReasoning>>
|
||||
|
||||
/** One advisory model entry inside a provider group. */
|
||||
export const modelCatalogModelSchema = z.object({
|
||||
id: z.string().min(1),
|
||||
name: z.string().min(1),
|
||||
description: z.string().optional(),
|
||||
unlisted: z.literal(true).optional(),
|
||||
reasoning: modelReasoningSchema.optional(),
|
||||
}) satisfies z.ZodType<Wire<ModelCatalogModel>>
|
||||
|
||||
/** One successfully loaded provider group. */
|
||||
export const modelProviderGroupSchema = z.object({
|
||||
id: z.string().min(1),
|
||||
name: z.string().min(1),
|
||||
models: z.array(modelCatalogModelSchema),
|
||||
}) satisfies z.ZodType<Wire<ModelProviderGroup>>
|
||||
|
||||
/** One provider-local catalog failure. */
|
||||
export const modelCatalogFailureSchema = z.object({
|
||||
id: z.string().min(1),
|
||||
name: z.string().min(1),
|
||||
message: z.string(),
|
||||
}) satisfies z.ZodType<Wire<ModelCatalogFailure>>
|
||||
|
||||
/**
|
||||
* ToolEventView passthrough: lock only the `for` discriminant and the presence
|
||||
* of a card-tagged `view` object. The view interior is a host-computed product
|
||||
@@ -111,6 +157,31 @@ export const sessionHistoryValueSchema = z.object({
|
||||
projections: sessionProjectionsBlockSchema.optional(),
|
||||
}) satisfies z.ZodType<Wire<ResponseValue<'session.history'>>>
|
||||
|
||||
/** session.models request payload. */
|
||||
export const sessionModelsRequestSchema = z.object({
|
||||
sessionId: sessionIdSchema,
|
||||
}) satisfies z.ZodType<Wire<RequestPayload<'session.models'>>>
|
||||
|
||||
/** session.models response value. */
|
||||
export const sessionModelsValueSchema = z.object({
|
||||
current: modelTargetSchema,
|
||||
groups: z.array(modelProviderGroupSchema),
|
||||
failures: z.array(modelCatalogFailureSchema),
|
||||
}) satisfies z.ZodType<Wire<ResponseValue<'session.models'>>>
|
||||
|
||||
/** session.selectModel request payload. */
|
||||
export const sessionSelectModelRequestSchema = z.object({
|
||||
sessionId: sessionIdSchema,
|
||||
provider: z.string().min(1),
|
||||
model: z.string().min(1),
|
||||
reasoningEffort: z.string().min(1).optional(),
|
||||
}) satisfies z.ZodType<Wire<RequestPayload<'session.selectModel'>>>
|
||||
|
||||
/** session.selectModel response value. */
|
||||
export const sessionSelectModelValueSchema = z.object({
|
||||
selected: modelTargetSchema,
|
||||
}) satisfies z.ZodType<Wire<ResponseValue<'session.selectModel'>>>
|
||||
|
||||
/** ContentBlock passthrough: core is merge-extensible — the type discriminant envelope is strict, the rest stays wide. */
|
||||
export const contentBlockSchema = z.looseObject({ type: z.string() })
|
||||
|
||||
|
||||
@@ -52,6 +52,78 @@ export interface SessionProjectionsBlock {
|
||||
values: Partial<SessionProjectionMap>
|
||||
}
|
||||
|
||||
/** Complete model target selected for one session. */
|
||||
export interface ModelTarget {
|
||||
/** Registered provider route. */
|
||||
provider: string
|
||||
/** Provider-owned model id. */
|
||||
model: string
|
||||
/** Adapter-owned reasoning effort; absence preserves adapter/provider default behavior. */
|
||||
reasoningEffort?: string
|
||||
}
|
||||
|
||||
/** One adapter-owned reasoning effort displayed for an exact model route. */
|
||||
export interface ModelReasoningEffort {
|
||||
/** Opaque value submitted back to the owning adapter. */
|
||||
id: string
|
||||
/** Adapter-supplied display name. */
|
||||
name: string
|
||||
/** Optional adapter-supplied description. */
|
||||
description?: string
|
||||
}
|
||||
|
||||
/** Selectable reasoning metadata for one exact model route. */
|
||||
export interface ModelReasoning {
|
||||
/** Efforts in adapter-preferred display order. */
|
||||
efforts: ModelReasoningEffort[]
|
||||
/** Adapter-configured default; absence preserves the provider default. */
|
||||
defaultEffort?: string
|
||||
}
|
||||
|
||||
/** One model displayed inside its provider group. */
|
||||
export interface ModelCatalogModel {
|
||||
/** Provider-owned model id. */
|
||||
id: string
|
||||
/** Provider-supplied display name. */
|
||||
name: string
|
||||
/** Optional provider-supplied description. */
|
||||
description?: string
|
||||
/** The current model was inserted because the advisory catalog omitted it. */
|
||||
unlisted?: true
|
||||
/** Exact-route reasoning metadata when the adapter exposes it. */
|
||||
reasoning?: ModelReasoning
|
||||
}
|
||||
|
||||
/** One provider and the models it advertised successfully. */
|
||||
export interface ModelProviderGroup {
|
||||
/** Provider route id used for requests. */
|
||||
id: string
|
||||
/** Provider display name. */
|
||||
name: string
|
||||
/** Models in provider-preferred order. */
|
||||
models: ModelCatalogModel[]
|
||||
}
|
||||
|
||||
/** A provider whose asynchronous catalog lookup failed. */
|
||||
export interface ModelCatalogFailure {
|
||||
/** Provider route id. */
|
||||
id: string
|
||||
/** Provider display name. */
|
||||
name: string
|
||||
/** Lookup failure diagnostic. */
|
||||
message: string
|
||||
}
|
||||
|
||||
/** Detached model-directory snapshot for one session. */
|
||||
export interface SessionModels {
|
||||
/** Target selected for the session's next assembled step. */
|
||||
current: ModelTarget
|
||||
/** Successfully loaded provider groups. */
|
||||
groups: ModelProviderGroup[]
|
||||
/** Provider-local failures; successful groups remain usable. */
|
||||
failures: ModelCatalogFailure[]
|
||||
}
|
||||
|
||||
/** Session list entry (v1 builds no index: list does readdir+stat). */
|
||||
export interface SessionSummary {
|
||||
sessionId: SessionId
|
||||
@@ -106,6 +178,22 @@ export interface SessionsApi {
|
||||
history(request: RpcRequest<{ sessionId: SessionId; beforeSeq?: number; maxMessages?: number }>):
|
||||
Promise<RpcResponse<{ events: HistoryEntry[]; hasMore: boolean; projections?: SessionProjectionsBlock }>>
|
||||
|
||||
/** Reads a fresh advisory model directory for this session. Provider lookups run independently. */
|
||||
models(request: RpcRequest<{ sessionId: SessionId }>): Promise<RpcResponse<SessionModels>>
|
||||
|
||||
/**
|
||||
* Selects the complete target for this session. Exact model metadata
|
||||
* validates an optional reasoning effort, while catalog membership remains
|
||||
* advisory.
|
||||
*/
|
||||
selectModel(request: RpcRequest<{
|
||||
sessionId: SessionId
|
||||
provider: string
|
||||
model: string
|
||||
reasoningEffort?: string
|
||||
}>):
|
||||
Promise<RpcResponse<{ selected: ModelTarget }>>
|
||||
|
||||
/** Sends a message. content is core's ContentBlock[] verbatim; mode maps 1:1 — queue→send, steer→steer. */
|
||||
prompt(request: RpcRequest<{ sessionId: SessionId; mode: 'queue' | 'steer'; content: ContentBlock[] }>):
|
||||
Promise<RpcResponse<{ accepted: true }>>
|
||||
|
||||
@@ -19,7 +19,9 @@ import {
|
||||
sessionCreateValueSchema,
|
||||
sessionHistoryValueSchema,
|
||||
sessionListValueSchema,
|
||||
sessionModelsValueSchema,
|
||||
sessionPromptValueSchema,
|
||||
sessionSelectModelValueSchema,
|
||||
} from '../api/sessions.schema.ts'
|
||||
import {
|
||||
workspaceCreateValueSchema,
|
||||
@@ -51,6 +53,8 @@ export interface IApiClient {
|
||||
list(payload: RequestPayload<'session.list'>, signal?: AbortSignal): Promise<RpcResponse<ResponseValue<'session.list'>>>
|
||||
create(payload: RequestPayload<'session.create'>, signal?: AbortSignal): Promise<RpcResponse<ResponseValue<'session.create'>>>
|
||||
history(payload: RequestPayload<'session.history'>, signal?: AbortSignal): Promise<RpcResponse<ResponseValue<'session.history'>>>
|
||||
models(payload: RequestPayload<'session.models'>, signal?: AbortSignal): Promise<RpcResponse<ResponseValue<'session.models'>>>
|
||||
selectModel(payload: RequestPayload<'session.selectModel'>, signal?: AbortSignal): Promise<RpcResponse<ResponseValue<'session.selectModel'>>>
|
||||
prompt(payload: RequestPayload<'session.prompt'>, signal?: AbortSignal): Promise<RpcResponse<ResponseValue<'session.prompt'>>>
|
||||
cancel(payload: RequestPayload<'session.cancel'>, signal?: AbortSignal): Promise<RpcResponse<ResponseValue<'session.cancel'>>>
|
||||
}
|
||||
@@ -88,6 +92,8 @@ const UNARY_VALUE_SCHEMAS: { [K in keyof RpcMethodMap]: z.ZodType<Wire<ResponseV
|
||||
'session.list': sessionListValueSchema,
|
||||
'session.create': sessionCreateValueSchema,
|
||||
'session.history': sessionHistoryValueSchema,
|
||||
'session.models': sessionModelsValueSchema,
|
||||
'session.selectModel': sessionSelectModelValueSchema,
|
||||
'session.prompt': sessionPromptValueSchema,
|
||||
'session.cancel': sessionCancelValueSchema,
|
||||
'host.describe': hostDescribeValueSchema,
|
||||
@@ -288,6 +294,8 @@ export abstract class AbstractApiClient implements IApiClient {
|
||||
list: (payload, signal) => this.callUnary('session.list', payload, signal),
|
||||
create: (payload, signal) => this.callUnary('session.create', payload, signal),
|
||||
history: (payload, signal) => this.callUnary('session.history', payload, signal),
|
||||
models: (payload, signal) => this.callUnary('session.models', payload, signal),
|
||||
selectModel: (payload, signal) => this.callUnary('session.selectModel', payload, signal),
|
||||
prompt: (payload, signal) => this.callUnary('session.prompt', payload, signal),
|
||||
cancel: (payload, signal) => this.callUnary('session.cancel', payload, signal),
|
||||
}
|
||||
|
||||
@@ -19,7 +19,9 @@ import {
|
||||
sessionCreateRequestSchema,
|
||||
sessionHistoryRequestSchema,
|
||||
sessionListRequestSchema,
|
||||
sessionModelsRequestSchema,
|
||||
sessionPromptRequestSchema,
|
||||
sessionSelectModelRequestSchema,
|
||||
} from '../api/sessions.schema.ts'
|
||||
import { hostDescribeRequestSchema, hostPickDirectoryRequestSchema } from '../api/host.schema.ts'
|
||||
import {
|
||||
@@ -52,6 +54,8 @@ const UNARY_ROUTES: UnaryRoutes = {
|
||||
'session.list': { schema: sessionListRequestSchema, invoke: (api, r) => api.sessions.list(r) },
|
||||
'session.create': { schema: sessionCreateRequestSchema, invoke: (api, r) => api.sessions.create(r) },
|
||||
'session.history': { schema: sessionHistoryRequestSchema, invoke: (api, r) => api.sessions.history(r) },
|
||||
'session.models': { schema: sessionModelsRequestSchema, invoke: (api, r) => api.sessions.models(r) },
|
||||
'session.selectModel': { schema: sessionSelectModelRequestSchema, invoke: (api, r) => api.sessions.selectModel(r) },
|
||||
'session.prompt': { schema: sessionPromptRequestSchema, invoke: (api, r) => api.sessions.prompt(r) },
|
||||
'session.cancel': { schema: sessionCancelRequestSchema, invoke: (api, r) => api.sessions.cancel(r) },
|
||||
'host.describe': { schema: hostDescribeRequestSchema, invoke: (api, r) => api.host.describe(r) },
|
||||
|
||||
@@ -45,7 +45,7 @@ export interface Config {
|
||||
* project directory and the fallback parent for name-created Workspaces.
|
||||
*/
|
||||
export class ApiProxyService extends Service implements ApiProxy {
|
||||
static inject = ['agents', 'sessions', 'tools', 'userInteraction', 'workspace']
|
||||
static inject = ['agents', 'llm', 'sessions', 'tools', 'userInteraction', 'workspace']
|
||||
|
||||
static Config: z<Config> = z.object({
|
||||
provider: z.string().required(),
|
||||
|
||||
Reference in New Issue
Block a user