feat(mcp): append server instructions to context (#32490)
Co-authored-by: Aiden Cline <aidenpcline@gmail.com>
This commit is contained in:
@@ -1356,13 +1356,19 @@ export const layer = Layer.effect(
|
||||
|
||||
yield* plugin.trigger("experimental.chat.messages.transform", {}, { messages: msgs })
|
||||
|
||||
const [skills, env, instructions, modelMsgs] = yield* Effect.all([
|
||||
const [skills, env, instructions, mcpInstructions, modelMsgs] = yield* Effect.all([
|
||||
sys.skills(agent),
|
||||
sys.environment(model),
|
||||
instruction.system().pipe(Effect.orDie),
|
||||
sys.mcp(agent, session.permission),
|
||||
MessageV2.toModelMessagesEffect(msgs, model),
|
||||
])
|
||||
const system = [...env, ...instructions, ...(skills ? [skills] : [])]
|
||||
const system = [
|
||||
...env,
|
||||
...instructions,
|
||||
...(mcpInstructions ? [mcpInstructions] : []),
|
||||
...(skills ? [skills] : []),
|
||||
]
|
||||
const format = lastUser.format ?? { type: "text" as const }
|
||||
if (format.type === "json_schema") system.push(STRUCTURED_OUTPUT_SYSTEM_PROMPT)
|
||||
const result = yield* handle.process({
|
||||
|
||||
@@ -20,6 +20,8 @@ import { AbsolutePath } from "@opencode-ai/core/schema"
|
||||
import { Location } from "@opencode-ai/core/location"
|
||||
import { LocationServiceMap } from "@opencode-ai/core/location-layer"
|
||||
import { Reference } from "@opencode-ai/core/reference"
|
||||
import { MCP } from "@/mcp"
|
||||
import { PermissionV1 } from "@opencode-ai/core/v1/permission"
|
||||
|
||||
export function provider(model: Provider.Model) {
|
||||
if (model.api.id.includes("gpt-4") || model.api.id.includes("o1") || model.api.id.includes("o3"))
|
||||
@@ -40,6 +42,7 @@ export function provider(model: Provider.Model) {
|
||||
export interface Interface {
|
||||
readonly environment: (model: Provider.Model) => Effect.Effect<string[]>
|
||||
readonly skills: (agent: Agent.Info) => Effect.Effect<string | undefined>
|
||||
readonly mcp: (agent: Agent.Info, permission?: PermissionV1.Ruleset) => Effect.Effect<string | undefined>
|
||||
}
|
||||
|
||||
export class Service extends Context.Service<Service, Interface>()("@opencode/SystemPrompt") {}
|
||||
@@ -48,6 +51,7 @@ export const layer = Layer.effect(
|
||||
Service,
|
||||
Effect.gen(function* () {
|
||||
const skill = yield* Skill.Service
|
||||
const mcp = yield* MCP.Service
|
||||
const locations = yield* LocationServiceMap
|
||||
|
||||
return Service.of({
|
||||
@@ -102,14 +106,36 @@ export const layer = Layer.effect(
|
||||
Skill.fmt(list, { verbose: true }),
|
||||
].join("\n")
|
||||
}),
|
||||
|
||||
mcp: Effect.fn("SystemPrompt.mcp")(function* (agent: Agent.Info, permission?: PermissionV1.Ruleset) {
|
||||
const ruleset = Permission.merge(agent.permission, permission ?? [])
|
||||
const instructions = (yield* mcp.instructions()).filter(
|
||||
(item) => item.tools.length === 0 || Permission.disabled(item.tools, ruleset).size < item.tools.length,
|
||||
)
|
||||
if (instructions.length === 0) return
|
||||
|
||||
return [
|
||||
"<mcp_instructions>",
|
||||
...instructions.flatMap((item) => [
|
||||
` <server name="${item.name}">`,
|
||||
...item.instructions.split("\n").map((line) => ` ${line}`),
|
||||
" </server>",
|
||||
]),
|
||||
"</mcp_instructions>",
|
||||
].join("\n")
|
||||
}),
|
||||
})
|
||||
}),
|
||||
)
|
||||
|
||||
export const defaultLayer = layer.pipe(Layer.provide(Skill.defaultLayer), Layer.provide(LocationServiceMap.layer))
|
||||
export const defaultLayer = layer.pipe(
|
||||
Layer.provide(Skill.defaultLayer),
|
||||
Layer.provide(MCP.defaultLayer),
|
||||
Layer.provide(LocationServiceMap.layer),
|
||||
)
|
||||
|
||||
const locationServiceMapNode = LayerNode.make(LocationServiceMap.layer, [])
|
||||
|
||||
export const node = LayerNode.make(layer, [Skill.node, locationServiceMapNode])
|
||||
export const node = LayerNode.make(layer, [Skill.node, MCP.node, locationServiceMapNode])
|
||||
|
||||
export * as SystemPrompt from "./system"
|
||||
|
||||
Reference in New Issue
Block a user