mirror of
https://github.com/deepseek-ai/deepseek-harness.git
synced 2026-09-14 04:01:35 +00:00
95 lines
4.1 KiB
TypeScript
95 lines
4.1 KiB
TypeScript
/** Model-facing discovery of LLM routes available to child Agents. */
|
|
|
|
import type { Context } from '@deepseek-ai/cordis'
|
|
import type LlmRuntime from '@deepseek-ai/dsh-llm'
|
|
import type { LlmProviderInfo } from '@deepseek-ai/dsh-llm'
|
|
import { defineTool } from '@deepseek-ai/dsh-tools'
|
|
|
|
interface ListSubagentModelsRequest {
|
|
readonly provider?: string
|
|
readonly model?: string
|
|
}
|
|
|
|
/** Resolve one registered provider with a model-correctable diagnostic. */
|
|
function registeredProvider(llm: LlmRuntime, providerId: string): LlmProviderInfo {
|
|
const providers = llm.listProviders()
|
|
const provider = providers.find(candidate => candidate.id === providerId)
|
|
if (provider !== undefined) return provider
|
|
const available = providers.map(candidate => candidate.id).join(', ') || '(none)'
|
|
throw new Error(`LLM provider "${providerId}" is not registered; available providers: ${available}`)
|
|
}
|
|
|
|
/** Render one advertised or resolved model. */
|
|
function modelLine(provider: string, model: { id: string; name: string; description?: string }): string {
|
|
return `${provider}/${model.id} — ${model.name}${model.description === undefined ? '' : `: ${model.description}`}`
|
|
}
|
|
|
|
/** Read the requested provider, advertised models, or exact-model efforts. */
|
|
async function listSubagentModels(
|
|
ctx: Context,
|
|
request: ListSubagentModelsRequest,
|
|
signal: AbortSignal,
|
|
): Promise<string> {
|
|
const llm = ctx.get('llm')
|
|
if (llm === undefined) {
|
|
throw new Error('cannot discover child LLM routes because the `llm` service is unavailable')
|
|
}
|
|
if (request.model !== undefined && request.provider === undefined) {
|
|
throw new Error('`model` requires `provider`')
|
|
}
|
|
if (request.provider === undefined) {
|
|
const providers = llm.listProviders()
|
|
return providers.length === 0
|
|
? '(no LLM providers)'
|
|
: providers.map(provider => `${provider.id} — ${provider.name}`).join('\n')
|
|
}
|
|
if (request.provider.length === 0) throw new Error('`provider` must be non-empty')
|
|
const provider = registeredProvider(llm, request.provider)
|
|
if (request.model === undefined) {
|
|
const models = await llm.listModels(provider.id)
|
|
return models.length === 0
|
|
? `(no advertised models for ${provider.id})`
|
|
: models.map(model => modelLine(provider.id, model)).join('\n')
|
|
}
|
|
if (request.model.length === 0) throw new Error('`model` must be non-empty')
|
|
const model = await llm.resolveModelInfo(provider.id, request.model, signal)
|
|
const efforts = model.reasoning?.efforts.map(effort => (
|
|
`${effort.id}${model.reasoning?.defaultEffort === effort.id ? ' (default)' : ''} — ${effort.name}`
|
|
+ (effort.description === undefined ? '' : `: ${effort.description}`)
|
|
)).join('\n') || '(no advertised reasoning efforts)'
|
|
return `${modelLine(provider.id, model)}\nReasoning efforts:\n${efforts}`
|
|
}
|
|
|
|
/**
|
|
* Register `list_subagent_models` for one owning delegation-tool instance.
|
|
* @param ctx - Context whose tool registry owns the fixed discovery definition.
|
|
*/
|
|
export function registerListSubagentModels(ctx: Context): void {
|
|
ctx.tools.register(defineTool({
|
|
name: 'list_subagent_models',
|
|
description:
|
|
'Discover LLM routes for subagents without changing the current Agent. Call with no arguments to list '
|
|
+ 'registered providers, with `provider` to list its advertised models, or with `provider` and `model` '
|
|
+ 'to inspect that exact model and its reasoning efforts. Catalog membership is advisory: an adapter may '
|
|
+ 'accept an unlisted model id. Use the returned ids with a delegation tool\'s `provider`, `model`, and '
|
|
+ '`reasoning_effort` fields.',
|
|
parameters: {
|
|
provider: {
|
|
type: 'string',
|
|
description: 'Registered LLM provider id. Omit to list providers.',
|
|
},
|
|
model: {
|
|
type: 'string',
|
|
description: 'Exact model id to inspect. Requires provider; omit to list that provider\'s advertised models.',
|
|
},
|
|
},
|
|
output: {
|
|
schema: { type: 'string' },
|
|
render: (_args, result) => [{ type: 'text', text: result }],
|
|
},
|
|
execute(args, exec) {
|
|
return listSubagentModels(ctx, args, exec.signal)
|
|
},
|
|
}))
|
|
}
|