feat: customize model provider requests
Model connections can now save bounded JSON request headers and top-level body fields. Direct requests and Continue support both; local OpenCode and DeepSeek Harness use only native header support, while the managed remote OpenCode gateway applies both. Runtime, protocol, and authentication fields keep precedence. Custom values are ordinary connection settings, not credential storage. This migrates Runtime settings from v20 to v21 and updates the DeepSeek control and managed Runtime ACP capabilities. Release note: 模型连接详情新增自定义请求头和请求体;直连与 Continue 支持两者,本地 OpenCode 和 DeepSeek Harness 仅应用原生支持的请求头,受管远程 OpenCode 支持两者,界面会明确提示生效范围。
This commit is contained in:
@@ -11,6 +11,12 @@ const profile: ResolvedModelProfile = {
|
||||
authentication: 'api-key',
|
||||
supportsImageInput: true,
|
||||
maximumOutputTokens: 8_192,
|
||||
requestHeaders: {
|
||||
'x-tenant-id': 'remote-tenant'
|
||||
},
|
||||
requestBody: {
|
||||
temperature: 0.2
|
||||
},
|
||||
apiKey: 'prompt-scoped-secret'
|
||||
}
|
||||
|
||||
@@ -29,6 +35,12 @@ describe('managed Agent prompt model setup', () => {
|
||||
protocol: 'openai-responses',
|
||||
authentication: 'api-key',
|
||||
apiKey: 'prompt-scoped-secret',
|
||||
requestHeaders: {
|
||||
'x-tenant-id': 'remote-tenant'
|
||||
},
|
||||
requestBody: {
|
||||
temperature: 0.2
|
||||
},
|
||||
capabilities: { imageInput: true },
|
||||
limits: {
|
||||
maximumOutputTokens: 8_192,
|
||||
|
||||
@@ -55,6 +55,14 @@ export function createManagedModelBridge(options: {
|
||||
...(selected.apiKey === undefined
|
||||
? {}
|
||||
: { apiKey: selected.apiKey }),
|
||||
...(selected.requestHeaders &&
|
||||
Object.keys(selected.requestHeaders).length > 0
|
||||
? { requestHeaders: selected.requestHeaders }
|
||||
: {}),
|
||||
...(selected.requestBody &&
|
||||
Object.keys(selected.requestBody).length > 0
|
||||
? { requestBody: selected.requestBody }
|
||||
: {}),
|
||||
capabilities: {
|
||||
imageInput: selected.supportsImageInput === true
|
||||
},
|
||||
|
||||
@@ -297,7 +297,7 @@ describe('createManagedRemoteAcpRuntime', () => {
|
||||
fixture.options.agentServices.connectionManager.acquire
|
||||
).toHaveBeenCalledWith('host-1', expect.objectContaining({
|
||||
requiredCapabilities: [
|
||||
{ name: 'runtime/acp', exactVersion: 4, critical: true }
|
||||
{ name: 'runtime/acp', exactVersion: 5, critical: true }
|
||||
]
|
||||
}))
|
||||
|
||||
@@ -514,7 +514,7 @@ function capabilities() {
|
||||
return {
|
||||
generation: 7,
|
||||
capabilities: [
|
||||
{ name: 'runtime/acp', version: 4, critical: true }
|
||||
{ name: 'runtime/acp', version: 5, critical: true }
|
||||
],
|
||||
runtimes: [
|
||||
{
|
||||
|
||||
@@ -26,10 +26,14 @@ import type {
|
||||
RemoteRuntimeInstallationIdentity,
|
||||
RemoteRuntimeInstallationManager
|
||||
} from './remote-runtime-installation-manager'
|
||||
import {
|
||||
RUNTIME_ACP_CAPABILITY_NAME,
|
||||
RUNTIME_ACP_CAPABILITY_VERSION
|
||||
} from '../../shared/agent-protocol'
|
||||
|
||||
const RUNTIME_ACP_CAPABILITY = {
|
||||
name: 'runtime/acp',
|
||||
exactVersion: 4,
|
||||
name: RUNTIME_ACP_CAPABILITY_NAME,
|
||||
exactVersion: RUNTIME_ACP_CAPABILITY_VERSION,
|
||||
critical: true
|
||||
} as const
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ function advertisedCapabilities(): DaemonCapabilities {
|
||||
generation: 2,
|
||||
capabilities: [
|
||||
{ name: 'workspace/read', version: 1, critical: true },
|
||||
{ name: 'runtime/acp', version: 4, critical: true },
|
||||
{ name: 'runtime/acp', version: 5, critical: true },
|
||||
{
|
||||
name: 'runtime/model-bridge',
|
||||
version: 1,
|
||||
@@ -250,7 +250,7 @@ describe('ManagedRemoteProjectRuntimeValidator', () => {
|
||||
...advertisedCapabilities(),
|
||||
capabilities: [
|
||||
{ name: 'workspace/read', version: 1, critical: true },
|
||||
{ name: 'runtime/acp', version: 4, critical: true }
|
||||
{ name: 'runtime/acp', version: 5, critical: true }
|
||||
]
|
||||
}
|
||||
],
|
||||
@@ -260,7 +260,7 @@ describe('ManagedRemoteProjectRuntimeValidator', () => {
|
||||
...advertisedCapabilities(),
|
||||
capabilities: [
|
||||
{ name: 'workspace/read', version: 1, critical: true },
|
||||
{ name: 'runtime/acp', version: 4, critical: true },
|
||||
{ name: 'runtime/acp', version: 5, critical: true },
|
||||
{
|
||||
name: 'runtime/model-bridge',
|
||||
version: 3,
|
||||
@@ -276,7 +276,7 @@ describe('ManagedRemoteProjectRuntimeValidator', () => {
|
||||
capabilities: [
|
||||
{
|
||||
name: 'runtime/acp',
|
||||
version: 4,
|
||||
version: 5,
|
||||
critical: false
|
||||
}
|
||||
]
|
||||
|
||||
@@ -10,11 +10,12 @@ import type {
|
||||
RemoteRuntimeInstallationIdentity,
|
||||
RemoteRuntimeInstallationManager
|
||||
} from './remote-runtime-installation-manager'
|
||||
|
||||
const RUNTIME_ACP_CAPABILITY = 'runtime/acp'
|
||||
const RUNTIME_ACP_CAPABILITY_VERSION = 4
|
||||
const RUNTIME_MODEL_BRIDGE_CAPABILITY = 'runtime/model-bridge'
|
||||
const RUNTIME_MODEL_BRIDGE_CAPABILITY_VERSION = 1
|
||||
import {
|
||||
RUNTIME_ACP_CAPABILITY_NAME,
|
||||
RUNTIME_ACP_CAPABILITY_VERSION,
|
||||
RUNTIME_MODEL_BRIDGE_CAPABILITY_NAME,
|
||||
RUNTIME_MODEL_BRIDGE_CAPABILITY_VERSION
|
||||
} from '../../shared/agent-protocol'
|
||||
|
||||
export class ManagedRemoteProjectRuntimeValidator
|
||||
implements RemoteProjectRuntimeValidator
|
||||
@@ -178,11 +179,11 @@ function assertRuntimeCapability(
|
||||
installation: RemoteRuntimeInstallationIdentity
|
||||
): void {
|
||||
const acp = capabilities.capabilities.find(
|
||||
(capability) => capability.name === RUNTIME_ACP_CAPABILITY
|
||||
(capability) => capability.name === RUNTIME_ACP_CAPABILITY_NAME
|
||||
)
|
||||
const modelBridge = capabilities.capabilities.find(
|
||||
(capability) =>
|
||||
capability.name === RUNTIME_MODEL_BRIDGE_CAPABILITY
|
||||
capability.name === RUNTIME_MODEL_BRIDGE_CAPABILITY_NAME
|
||||
)
|
||||
const runtimes = capabilities.runtimes.filter(
|
||||
(runtime) => runtime.runtimeId === 'opencode'
|
||||
|
||||
@@ -320,7 +320,7 @@ function validCapabilities(): DaemonCapabilities {
|
||||
return {
|
||||
generation: 11,
|
||||
capabilities: [
|
||||
{ name: 'runtime/acp', version: 4, critical: true }
|
||||
{ name: 'runtime/acp', version: 5, critical: true }
|
||||
],
|
||||
runtimes: [
|
||||
{
|
||||
|
||||
@@ -16,7 +16,11 @@ import {
|
||||
acpReplayChannelResultSchema,
|
||||
acpReconcilePromptRequestSchema as promptReconciliationRequestSchema,
|
||||
acpReconcilePromptResultSchema as promptReconciliationResultSchema,
|
||||
acpResumeChannelResultSchema
|
||||
acpResumeChannelResultSchema,
|
||||
RUNTIME_ACP_CAPABILITY_NAME,
|
||||
RUNTIME_ACP_CAPABILITY_VERSION,
|
||||
RUNTIME_MODEL_BRIDGE_CAPABILITY_NAME,
|
||||
RUNTIME_MODEL_BRIDGE_CAPABILITY_VERSION
|
||||
} from '../../shared/agent-protocol'
|
||||
import { AgentFrameError } from '../../shared/agent-protocol/frame'
|
||||
import {
|
||||
@@ -75,10 +79,6 @@ import type {
|
||||
MainModelBridgePoison
|
||||
} from './main-model-bridge-dispatcher'
|
||||
|
||||
const RUNTIME_ACP_CAPABILITY = 'runtime/acp'
|
||||
const RUNTIME_ACP_CAPABILITY_VERSION = 4
|
||||
const RUNTIME_MODEL_BRIDGE_CAPABILITY = 'runtime/model-bridge'
|
||||
const RUNTIME_MODEL_BRIDGE_CAPABILITY_VERSION = 1
|
||||
const DEFAULT_CONTROL_TIMEOUT_MS = 15_000
|
||||
const DEFAULT_MAXIMUM_PENDING_CONTROL_REQUESTS = 32
|
||||
const UNBOUNDED_REMOTE_PROMPT_DEADLINE_MS = Date.parse(
|
||||
@@ -1817,13 +1817,14 @@ function assertRuntimeCapability(
|
||||
requireModelBridge: boolean
|
||||
): RuntimeProtocolConnection['capabilities']['runtimes'][number] {
|
||||
const capability = capabilities.capabilities.find(
|
||||
(entry) => entry.name === RUNTIME_ACP_CAPABILITY
|
||||
(entry) => entry.name === RUNTIME_ACP_CAPABILITY_NAME
|
||||
)
|
||||
const runtimes = capabilities.runtimes.filter(
|
||||
(entry) => entry.runtimeId === runtimeId
|
||||
)
|
||||
const modelBridgeCapability = capabilities.capabilities.find(
|
||||
(entry) => entry.name === RUNTIME_MODEL_BRIDGE_CAPABILITY
|
||||
(entry) =>
|
||||
entry.name === RUNTIME_MODEL_BRIDGE_CAPABILITY_NAME
|
||||
)
|
||||
if (
|
||||
!Number.isSafeInteger(capabilities.generation) ||
|
||||
|
||||
Reference in New Issue
Block a user