refactor(agentos): drop the host function wrappers, names, and descriptions - #2006
Conversation
|
🚅 Environment agentos-pr-2006 in rivet-frontend has no services deployed. |
…ptions
Host functions are now a record of collections. The keys name everything and a
function needs only `inputSchema` and `execute`.
hostFunctions: {
store: {
listOrders: { inputSchema, execute },
},
}
Removed from the public API: the `hostFunction()` and `hostFunctions()`
wrappers, `HostFunctions.name`, `HostFunctions.description`, the
`functions:` nesting key, `HostFunction.description`,
`MAX_HOST_FUNCTION_DESCRIPTION_LENGTH`, `validateHostFunctions`, and
`HostFunctionDefinition.commandAliases`.
The description now comes from the input schema's `.describe()`, so it is one
optional field instead of two required ones. The sidecar keeps the length cap
and no longer requires a description at all.
`NodeRuntime` now takes the same shape. The host function module moves down
into runtime-core so both layers share one implementation, which is a breaking
change for guest code: a function is reached as `agentos-<collection>
<function>` rather than as a top-level command named after the function.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
c06de1d to
150b793
Compare
| // bundle loading from the projected package dirs. | ||
| const localMounts = await resolveCompatLocalMounts(options?.mounts); | ||
| if (options?.hostFunctions && options.hostFunctions.length > 0) { | ||
| validateHostFunctions(options.hostFunctions); | ||
| } | ||
| // Keys become command names, so resolve and check them before anything | ||
| // else in `create()` allocates a sidecar or a sandbox. | ||
| const resolvedHostFunctions = options?.hostFunctions | ||
| ? resolveHostFunctions(options.hostFunctions) | ||
| : []; | ||
|
|
There was a problem hiding this comment.
🔴 High · Sandbox host functions are discarded before VM registration
resolveHostFunctions runs before resolveSandboxOptions, but the latter is what adds the automatic sandbox collection. hostFunctions is then fixed to the earlier result, so AgentOs.create({ sandbox: ... }) mounts the sandbox filesystem but never registers agentos-sandbox or any process callbacks. Resolve the expanded options.hostFunctions after sandbox expansion (while validating caller-provided functions before starting the provider if needed).
| const runCommandResponse = (await hostFunctions.hostFunctions[ | ||
| "run-command" | ||
| ].execute({ |
There was a problem hiding this comment.
🟠 Medium · Sandbox integration test still calls the removed wrapper shape
createSandboxHostFunctions() now returns the collection directly (runCommand, createProcess, and so on), so hostFunctions.hostFunctions is undefined. This test throws before exercising the sandbox, and the same stale access remains for create/list/kill below. Update these calls to the new camelCase members so the migrated integration test can run.
| hostFunction, | ||
| MAX_HOST_FUNCTION_DESCRIPTION_LENGTH, | ||
| hostFunctions, |
There was a problem hiding this comment.
🟠 Medium · Removed exports leave a default test file unloadable
The non-nightly packages/core/tests/host-function-command-exec.test.ts still imports both hostFunction and hostFunctions from this entry point and constructs its fixture with them. Removing these exports without migrating that test makes Vitest fail while loading the default core suite, before any tests execute. Convert the fixture to the new keyed object API in this PR.
| export function evaluate< | ||
| T = JsonValue, | ||
| HOST_FUNCTIONS extends HostFunctionSchemas = HostFunctionSchemas, |
There was a problem hiding this comment.
🔵 Low · Explicit evaluation result types disable host-function input inference
TypeScript does not infer omitted type parameters after any explicit type argument; it uses their defaults. Therefore the common evaluate<MyResult>(..., { hostFunctions: ... }) form fixes HOST_FUNCTIONS to HostFunctionSchemas, and every inline execute(input) falls back to any, defeating the new schema-derived typing. Add a type-level regression test for this call form and reshape the API so the result annotation does not prevent host-function inference.
Host functions are now a plain record of collections. The keys name everything, and a function needs only a schema and a handler:
Removed from the public API
hostFunction()andhostFunctions()wrappers.HostFunctions.nameandHostFunctions.description(the collection key names it).functions:nesting key (functions are the collection's own keys).HostFunction.description(comes from the schema's.describe()).MAX_HOST_FUNCTION_DESCRIPTION_LENGTHandvalidateHostFunctions.HostFunctionsas an interface, replaced byHostFunctionCollection/HostFunctionCollections.HostFunctionDefinitionand itscommandAliases, which only made sense inNodeRuntime's old one-command-per-function model.Behavior
store.listOrdersisagentos-store list-orderson the CLI andstore.listOrders(input)in guest JavaScript. A key that cannot become a command name, or two keys that collide once converted, throw before the VM is created.executestill gets its input typed from its owninputSchema, with no wrapper to hang the inference on. The options types carry a schema type parameter thatAgentOs.create(),agentOS(),NodeRuntime.create()and thesecure-execentry points infer from the literal. A collection built outside the call that takes it has nothing to infer from, so its input falls back toanyrather than forcing every handler to annotate.HostFunctionlosesname/description,HostFunctionsbecomesHostFunctionCollections(aBTreeMap), and the description is read from the JSON Schema.Breaking change for
NodeRuntimeguest codeNodeRuntimeused to take a flat map and register each function as its own single-callback collection, so the guest invoked it as a top-level command named after the function (add --json ...). It now takes the same two-level collections asAgentOs.create(), and the guest reaches a function asagentos-<collection> <function>. The host function module moves frompackages/coredown intopackages/runtime-coreso both layers share one implementation rather than two parallel ones.agentos list-bindingsis intentionally retained as an alias forlist-host-functions.Docs, examples, and both docs bundles are updated to the inline form.
🤖 Generated with Claude Code