feat(plugin): flat tool draft with namespace
Effect draft.add accepts flat tool objects matching Promise ergonomics. Migrate the tool grouping concept fully to namespace: rename MCP's group helper/registration to namespace and thread namespace through the flat Effect and Promise draft declarations.
This commit is contained in:
parent
64ca9b8d77
commit
6714f74433
13 changed files with 157 additions and 88 deletions
|
|
@ -46,24 +46,11 @@ export const registerToolPlugin = <R>(plugin: {
|
|||
const context = host({
|
||||
tool: {
|
||||
transform: (callback) =>
|
||||
Effect.gen(function* () {
|
||||
const registrations: Array<{
|
||||
readonly name: string
|
||||
readonly tool: Tool.AnyTool
|
||||
readonly options?: Tool.RegisterOptions
|
||||
}> = []
|
||||
callback({
|
||||
add: (name, tool, options) => {
|
||||
registrations.push({ name, tool, ...(options ? { options } : {}) })
|
||||
},
|
||||
})
|
||||
yield* Effect.forEach(
|
||||
registrations,
|
||||
(registration) => tools.register({ [registration.name]: registration.tool }, registration.options),
|
||||
{ discard: true },
|
||||
).pipe(Effect.orDie)
|
||||
return { dispose: Effect.void }
|
||||
}),
|
||||
Effect.forEach(
|
||||
Tool.fromDraft(callback),
|
||||
({ name, tool, options }) => tools.register({ [name]: tool }, options),
|
||||
{ discard: true },
|
||||
).pipe(Effect.orDie, Effect.as({ dispose: Effect.void })),
|
||||
hook: () => Effect.die("registerToolPlugin does not support tool hooks"),
|
||||
},
|
||||
})
|
||||
|
|
|
|||
|
|
@ -274,7 +274,7 @@ describe("PluginV2", () => {
|
|||
}),
|
||||
)
|
||||
|
||||
it.effect("groups tool names and routes codemode registrations through execute", () =>
|
||||
it.effect("namespaces tool names and routes codemode registrations through execute", () =>
|
||||
Effect.gen(function* () {
|
||||
const plugins = yield* PluginV2.Service
|
||||
const registry = yield* ToolRegistry.Service
|
||||
|
|
@ -286,13 +286,13 @@ describe("PluginV2", () => {
|
|||
execute: () => Effect.succeed({ ok: true }),
|
||||
})
|
||||
const plugin = EffectPlugin.define({
|
||||
id: "grouped-tools",
|
||||
id: "namespaced-tools",
|
||||
effect: (ctx) =>
|
||||
ctx.tool
|
||||
.transform((draft) => {
|
||||
draft.add("plain", tool("Plain"), { codemode: false })
|
||||
draft.add("look/up", tool("Lookup"), { group: "context 7", codemode: false })
|
||||
draft.add("search", tool("Search"), { group: "context 7" })
|
||||
draft.add("look/up", tool("Lookup"), { namespace: "context 7", codemode: false })
|
||||
draft.add("search", tool("Search"), { namespace: "context 7" })
|
||||
})
|
||||
.pipe(Effect.orDie),
|
||||
})
|
||||
|
|
@ -307,6 +307,41 @@ describe("PluginV2", () => {
|
|||
}),
|
||||
)
|
||||
|
||||
it.effect("accepts flat Effect draft declarations with namespace", () =>
|
||||
Effect.gen(function* () {
|
||||
const plugins = yield* PluginV2.Service
|
||||
const registry = yield* ToolRegistry.Service
|
||||
const plugin = EffectPlugin.define({
|
||||
id: "flat-tools",
|
||||
effect: (ctx) =>
|
||||
ctx.tool
|
||||
.transform((draft) => {
|
||||
draft.add({
|
||||
name: "send",
|
||||
namespace: "slack",
|
||||
description: "Send a Slack message",
|
||||
input: Schema.Struct({ text: Schema.String }),
|
||||
output: Schema.Struct({ sent: Schema.Boolean }),
|
||||
execute: () => Effect.succeed({ sent: true }),
|
||||
})
|
||||
draft.add({
|
||||
name: "edit",
|
||||
codemode: false,
|
||||
description: "Edit a file",
|
||||
input: Schema.Struct({}),
|
||||
output: Schema.Struct({ ok: Schema.Boolean }),
|
||||
execute: () => Effect.succeed({ ok: true }),
|
||||
})
|
||||
})
|
||||
.pipe(Effect.orDie),
|
||||
})
|
||||
|
||||
yield* plugins.activate([versioned(plugin)])
|
||||
|
||||
expect((yield* registry.materialize()).definitions.map((tool) => tool.name)).toEqual(["edit", "execute"])
|
||||
}),
|
||||
)
|
||||
|
||||
it.effect("fires before/after tool hooks with mutable events around settlement", () =>
|
||||
Effect.gen(function* () {
|
||||
const plugins = yield* PluginV2.Service
|
||||
|
|
|
|||
|
|
@ -135,7 +135,7 @@ describe("fromPromise", () => {
|
|||
await ctx.tool.transform((tools) => {
|
||||
tools.add({
|
||||
name: "hello",
|
||||
options: { codemode: false },
|
||||
codemode: false,
|
||||
description: "Hello",
|
||||
input: Schema.Struct({ name: Schema.String }),
|
||||
output: Schema.String,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue