refactor(core): simplify tool admission flow (#36180)
This commit is contained in:
parent
3785eddfa0
commit
b452368b3b
16 changed files with 110 additions and 266 deletions
|
|
@ -35,7 +35,7 @@ Registrations are scoped:
|
|||
|
||||
- The latest active same-placement registration wins.
|
||||
- Closing any registration removes only that registration and reveals the next active one.
|
||||
- An invocation captures the effective tool once settlement starts.
|
||||
- Each model request captures the effective tools it advertises; later registration changes affect later requests.
|
||||
|
||||
`ToolRegistry.Service` is Location-scoped. Do not make the registry process-global or construct a separate application-tool service for each Location.
|
||||
|
||||
|
|
|
|||
|
|
@ -36,19 +36,19 @@ type CollectedFiles = {
|
|||
readonly files: Array<typeof ExecuteFile.Type>
|
||||
}
|
||||
|
||||
export interface Registration {
|
||||
interface Registration {
|
||||
readonly tool: AnyTool
|
||||
readonly name: string
|
||||
readonly group?: string
|
||||
}
|
||||
|
||||
export const create = (options: { readonly registrations: ReadonlyMap<string, Registration> }) => {
|
||||
export const create = (registrations: ReadonlyMap<string, Registration>) => {
|
||||
const runtime = (
|
||||
invoke: (name: string, registration: Registration, input: unknown) => Effect.Effect<unknown, unknown>,
|
||||
hooks?: CodeMode.ToolCallHooks,
|
||||
) => {
|
||||
const tools: Record<string, Tool.Definition<never> | Record<string, Tool.Definition<never>>> = {}
|
||||
for (const [name, registration] of options.registrations) {
|
||||
for (const [name, registration] of registrations) {
|
||||
const child = definition(name, registration.tool)
|
||||
const value = Tool.make({
|
||||
description: child.description,
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ export type ExecuteInput = {
|
|||
}
|
||||
|
||||
export interface Interface {
|
||||
readonly materialize: (input: MaterializeInput) => Effect.Effect<Materialization>
|
||||
readonly materialize: (permissions?: PermissionV2.Ruleset) => Effect.Effect<Materialization>
|
||||
/** Internal registration capability exposed publicly only through Tools.Service. */
|
||||
readonly register: (
|
||||
tools: Readonly<Record<string, AnyTool>>,
|
||||
|
|
@ -33,11 +33,6 @@ export interface Interface {
|
|||
) => Effect.Effect<void, RegistrationError, Scope.Scope>
|
||||
}
|
||||
|
||||
export interface MaterializeInput {
|
||||
readonly model: { readonly id: string; readonly provider: string }
|
||||
readonly permissions?: PermissionV2.Ruleset
|
||||
}
|
||||
|
||||
export interface Materialization {
|
||||
readonly definitions: ReadonlyArray<ToolDefinition>
|
||||
readonly settle: (input: ExecuteInput) => Effect.Effect<Settlement, ToolOutputStore.Error>
|
||||
|
|
@ -171,27 +166,20 @@ const registryLayer = Layer.effect(
|
|||
}),
|
||||
)
|
||||
}),
|
||||
materialize: Effect.fn("ToolRegistry.materialize")(function* (input) {
|
||||
const registrations = new Map<string, Registration>()
|
||||
materialize: Effect.fn("ToolRegistry.materialize")(function* (permissions) {
|
||||
const direct = new Map<string, Registration>()
|
||||
const deferred = new Map<string, Registration>()
|
||||
const rules = permissions ?? []
|
||||
for (const [name, entries] of local) {
|
||||
const registration = entries.at(-1)?.registration
|
||||
if (registration) registrations.set(name, registration)
|
||||
if (!registration) continue
|
||||
if (registration.deferred && !Flag.CODEMODE_ENABLED) continue
|
||||
if (whollyDisabled(permission(registration.tool, name), rules)) continue
|
||||
if (registration.deferred) deferred.set(name, registration)
|
||||
else direct.set(name, registration)
|
||||
}
|
||||
for (const [name, registration] of registrations) {
|
||||
if (
|
||||
(registration.deferred && !Flag.CODEMODE_ENABLED) ||
|
||||
whollyDisabled(permission(registration.tool, name), input.permissions ?? [])
|
||||
)
|
||||
registrations.delete(name)
|
||||
}
|
||||
const direct = new Map(Array.from(registrations).filter(([, registration]) => !registration.deferred))
|
||||
const deferred = new Map(Array.from(registrations).filter(([, registration]) => registration.deferred))
|
||||
const execute =
|
||||
deferred.size > 0 && !whollyDisabled("execute", input.permissions ?? [])
|
||||
? ExecuteTool.create({
|
||||
registrations: deferred,
|
||||
})
|
||||
: undefined
|
||||
deferred.size > 0 && !whollyDisabled("execute", rules) ? ExecuteTool.create(deferred) : undefined
|
||||
return {
|
||||
definitions: [
|
||||
...Array.from(direct, ([name, registration]) => definition(name, registration.tool)),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue