Ctrl K
ComunidadGuías…

docs/SELF_EXTENSION.md

Rama master · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
# Self-extension: forging and self-improvement

An agent can add to itself in three ways, two on the runtime and one in `agency()`, each behind its own switch: it can forge a tool, it can adjust its own personality, skills, workflows and parameters, and a hierarchical agency's manager can spawn a specialist.

## Forging a tool

With `emergent: true` on the runtime config, the tool orchestrator registers the `forge_tool` meta-tool ([`ToolOrchestrator`](https://github.com/framerslab/agentos/blob/master/src/core/tools/ToolOrchestrator.ts), [`ForgeToolMetaTool`](https://github.com/framerslab/agentos/blob/master/src/cognition/emergent/ForgeToolMetaTool.ts)). A request names the tool, its input and output JSON Schemas, test cases and an implementation. The name is an ASCII letter, then ASCII letters, digits, underscores and hyphens, at most 200 characters, since it also names the tool's folder when the tool is exported as a skill. `forge_tool` refuses any other name before the engine runs, with `details: { code: 'INVALID_TOOL_NAME', problem }`; the error of a missing or empty name reads `name is required and must be a string`, its `problem` `type` or `empty`. The implementation: `compose` chains existing tools through [`ComposableToolBuilder`](https://github.com/framerslab/agentos/blob/master/src/cognition/emergent/ComposableToolBuilder.ts); `sandbox` runs agent-written JavaScript through [`SandboxedToolForge`](https://github.com/framerslab/agentos/blob/master/src/cognition/emergent/SandboxedToolForge.ts) on its executor, an in-process `node:vm` context by default or a QuickJS WebAssembly instance per call with [`QuickJSExecutor`](https://github.com/framerslab/agentos/blob/master/src/cognition/emergent/executor/QuickJSExecutor.ts), and is rejected until `emergentConfig.allowSandboxTools` is true. The [`EmergentCapabilityEngine`](https://github.com/framerslab/agentos/blob/master/src/cognition/emergent/EmergentCapabilityEngine.ts) builds the candidate, runs its tests, submits it to the [`EmergentJudge`](https://github.com/framerslab/agentos/blob/master/src/cognition/emergent/EmergentJudge.ts) (one model call scoring safety, correctness, determinism and boundedness; approval needs safety and correctness to pass; with no judge model call configured every request is rejected) and registers an approved tool at the session tier of the [`EmergentToolRegistry`](https://github.com/framerslab/agentos/blob/master/src/cognition/emergent/EmergentToolRegistry.ts).

Session-tier tools live in memory for the session (mirrored to SQLite when a storage adapter exists). After five uses (`totalUses`, whether or not they succeeded) with a judge confidence of at least 0.8, a two-reviewer promotion panel can move a tool to the agent tier, persisted in the `agentos_emergent_tools` table (a use on a turn the learning layer refuses a self-change counts and checks no promotion); the shared tier needs an explicit `promote()` call, which records an approver only when the caller passes `approvedBy`. Forge, promotion and removal decisions go to the `agentos_emergent_audit_log` table when a storage adapter is configured. Raw sandbox source is not stored unless `persistSandboxSource` is set.

The sandbox bans `eval`, `Function`, `require`, `import`, `process` and `child_process` at validation time, and every file-mutating call but the two a ceiling can grant, and enforces a wall clock of `sandboxTimeoutMs` (5000 ms by default; a request's own `timeoutMs` takes precedence). Without a ceiling (`emergentConfig.capabilities` unset) it exposes `fetch`, `fs.readFile` and `crypto` when a request's allowlist names them, reads files under the process working directory, and lets `fetch` reach any host. With a ceiling, each capability is scoped to the hosts, roots and bounds the host writes, and the host can also grant `fs.write` (`fs.writeFile`), `fs.delete` (`fs.unlink`) and the state-changing `fetch` methods, on `QuickJSExecutor` only; a forge's test cases then run as dry runs that write, delete and send nothing (see [Effects](architecture/EMERGENT_CAPABILITIES.md#effects-writes-deletes-and-state-changing-requests)).

## Self-improvement tools

With `emergentConfig.selfImprovement.enabled`, four more tools are registered: `adapt_personality` (HEXACO deltas clamped to the 0 to 1 range and a per-session budget, recorded in the [`PersonalityMutationStore`](https://github.com/framerslab/agentos/blob/master/src/cognition/emergent/PersonalityMutationStore.ts) when a storage adapter exists), `manage_skills`, `create_workflow` and `self_evaluate` (scores a response with a model call, adjusts `temperature`, `verbosity` or a trait within `selfEval.adjustableParams`, and reports on the session). Stored mutations are not reloaded into a later GMI; a trait change lasts for the instance that made it.

On a host with a learning layer (the `learning` option, or a layer passed in `gmiManagerConfig.learningLayer`; [Learning](./GMI.md#learning)), every tool call carries the turn's learner and mode, and the actions that change the agent refuse before they act: `forge_tool`, `create_workflow`'s `create`, `manage_skills`' `enable` and `disable`, `self_evaluate`'s `adjust` and `adapt_personality` return a failed result whose `details` are `{ status: 'rejected', reason }`, with `frozen` in mode `frozen`, `off` in mode `off` and `no_learner` on a turn with no learner. `self_evaluate`'s `evaluate` on such a turn scores the response and keeps it in the session's report, stores no memory trace, applies no adjustment and names the reason in `selfChangeRefused`; `list`, `search`, `report` and `create_workflow`'s `run` answer as they do without a layer. On every host, with a layer or without one, `adapt_personality` refuses `honesty` and `emotionality` (`operator_only`); with a layer it also refuses a step above 0.02 and a fourth accepted call in one session, and keeps the calls and the per-trait budget per learner (the turn's organization, persona and user). `AGENTOS_LEARNING_FREEZE=1` makes all five refuse with `frozen`, with a layer or without one. With the tool orchestrator's approval gate on, a call the tool refuses this way is answered before the gate, and no one is asked to approve it.

## Spawning a specialist

In an agency running the hierarchical strategy with `emergent.enabled`, the manager gets a `spawn_specialist` tool: [`EmergentAgentForge`](https://github.com/framerslab/agentos/blob/master/src/cognition/emergent/EmergentAgentForge.ts) turns the manager's spec into an agent config, [`EmergentAgentJudge`](https://github.com/framerslab/agentos/blob/master/src/cognition/emergent/EmergentAgentJudge.ts) reviews it when `emergent.judge` is `true` (otherwise no review runs), and the new agent joins the roster as a `delegate_to_<role>` tool for the manager's next turn ([`hierarchical.ts`](https://github.com/framerslab/agentos/blob/master/src/api/runtime/strategies/hierarchical.ts)). At most five specialists per run by default (`emergent.planner.maxSpecialists`); spawned specialists are reset between `send()` calls.

## Launching a team

A GMI with `agencies.launch` can launch a temporary team from a turn with the `launch_agency` tool, on `gmi()` and on the full runtime ([Teams a GMI launches](./AGENCIES.md#teams-a-gmi-launches)). It changes nothing of the agent itself: the team runs one goal under the launch's depth, seat, spend and time bounds, returns one result and closes. A seat never gets the five self-modification tools or the memory tools, and a launched team's manager has no `spawn_specialist`.

## What is not there

No weights are updated anywhere. A `self_evaluate` adjustment of `temperature` or `verbosity` (its `adjust` action, or an `evaluate` with `autoAdjust` applying the judge's suggestion) is held by the runtime's session manager (`SelfImprovementSessionManager.setRuntimeParam()`) and merged into the later `processRequest()` turns of the same session, where a value the request sets itself wins: a numeric temperature as a completion option, and the verbosity as a user preference that the prompt engine turns into a length instruction when it names a level the engine knows (`concise`, `balanced` or `detailed`, or a synonym such as `brief`, `normal` or `thorough`); any other verbosity value adds no instruction. The values live in that `AgentOS` instance's session manager, in memory: nothing removes them and nothing stores them. No loop rewrites the agent's own code or prompts persistently. [Emergent Capabilities](./architecture/EMERGENT_CAPABILITIES.md) is the full guide.