Assembly
An assembly is the one toolkit a model is given for a turn, made of the tools of every source a
workspace has. toolkit names each tool by its source and its own name, leaves out the tools a
decision blocks, and marks the tools a decision asks about before they run. The model calls a
tool by that name, and the call reaches the source that owns the tool by the name that source
knows it by.
Which of a tool’s decisions is the right one is the host’s to say, from what it has stored. A source’s hints are its own claims, so no decision is made from them here.
Since v0.1.0
Constructors
Section titled “Constructors”toolkit
Section titled “toolkit”Builds the toolkit of members. The tools of a member that decide blocks are left out, and the
names of the others must be distinct, or the assembly fails with the names that are not.
A model knows a tool by its source’s name and its own, as github__create_issue, and a tool
that decide asks to approve needs approval before it runs. Building contacts none of the
sources.
Example (The toolkit of a turn, from a workspace’s sources and its policy)
import { Assembly, type ToolSource } from "@amends-dev/toolkit"import { Effect } from "effect"
declare const github: ToolSource.ToolSourcedeclare const linear: ToolSource.ToolSource// What the host stored of each source: a decision for a tool, and the one for the others.declare const policy: ReadonlyMap< string, { readonly tools: ReadonlyMap<string, Assembly.Decision>; readonly others: Assembly.Decision }>
const program = Effect.gen(function* () { // The definitions come from the host's catalog, filled from `discover` when it refreshed. const members = yield* Effect.forEach([github, linear], (source) => Effect.map(source.discover, (definitions) => ({ source, definitions })) ) const toolkit = yield* Assembly.toolkit(members, (source, definition) => { const stored = policy.get(source) return stored?.tools.get(definition.name) ?? stored?.others ?? "block" }) // The model knows the tools as `github__create_issue`, and a call reaches its source. return toolkit})Signature
declare const toolkit: ( members: ReadonlyArray<Member>, decide: (source: string, definition: ToolDefinition.ToolDefinition) => Decision, options?: Options | undefined) => Effect.Effect< WithHandler<{ readonly [x: string]: Tool< string, { readonly parameters: Schema.Unknown readonly success: Schema.Codec<Schema.Json, Schema.Json, never, never> readonly failure: Schema.Struct<{ readonly code: Schema.String readonly message: Schema.String readonly retryable: Schema.Boolean }> readonly failureMode: "return" }, never > }>, NameClash, never>Since v0.1.0
Errors
Section titled “Errors”NameClash (class)
Section titled “NameClash (class)”More than one tool has the same name, so the model could not tell which one it calls. toolkit
fails with it, holding every clash.
Signature
declare class NameClashSince v0.1.0
Models
Section titled “Models”Member (interface)
Section titled “Member (interface)”A source, with the definitions of the tools of it that the workspace has, from which toolkit
builds the model’s tools without asking the source.
Signature
export interface Member { readonly source: ToolSource.ToolSource
/** The definitions of the source's tools that the host holds in its catalog. */ readonly definitions: ReadonlyArray<ToolDefinition.ToolDefinition>}Since v0.1.0
Options
Section titled “Options”Options (interface)
Section titled “Options (interface)”What toolkit takes besides its members and the decision for each tool.
Signature
export interface Options { /** * The longest name a tool may have, for an agent that adds to the names it is given and so takes * fewer than the model APIs' 64 characters, such as an agent's `maxToolNameLength`. At least 16. */ readonly maxNameLength?: number}Since v0.1.0
Schemas
Section titled “Schemas”Tools the model would know by one name, as NameClash reports them.
Signature
declare const Clash: Schema.Struct<{ readonly name: Schema.String readonly tools: Schema.$Array<Schema.Struct<{ readonly source: Schema.String; readonly tool: Schema.String }>>}>Since v0.1.0
Clash (interface)
Section titled “Clash (interface)”Signature
export interface Clash extends Schema.Schema.Type<typeof Clash> {}Since v0.1.0
Decision
Section titled “Decision”What the model may do with a tool: call it, call it once the person has approved the call, or not be given it. A schema, so that a host can store its policy.
Signature
declare const Decision: Schema.Literals<readonly ["allow", "approve", "block"]>Since v0.1.0
Decision (type alias)
Section titled “Decision (type alias)”Signature
type Decision = typeof Decision.TypeSince v0.1.0