@agenticprimitives/service-agent
v0.0.0-alpha.4
Published
Generic service-agent capability framework (spec 283): define -> assert -> entitle -> delegate -> primitive-plan -> execute -> receipt. Provider-neutral; all authority evaluators + primitives are injected. Domain catalogs (e.g. @agenticprimitives/treasury
Maintainers
Readme
@agenticprimitives/service-agent
Status: experimental (spec 283 PR1).
A generic framework for building service agents — agents that expose a catalog of capabilities
(skills) and execute them under layered authority. It is provider-neutral and Ring-0 pure: it depends only
on @agenticprimitives/types and imports no wallet, exchange, RPC, MCP, delegation, or policy code. The
concrete providers and authority evaluators are injected by the host.
Domain catalogs — e.g. @agenticprimitives/treasury — are separate packages that supply skill definitions
- a provider-neutral plan; this package runs the lifecycle.
The lifecycle
define → assert → entitle / delegate → primitive-plan → execute → receipt- define — a
SkillDefinitionstates a skill's meaning: id, version,effect(read|sign|spend|trade|admin), defaultexposure, the logical capabilities itrequires, optional I/O schemas, and acompile()that emits a primitive plan. A definition does NOT claim the host can run it. - assert —
assertSkillsresolves each definition'srequiresagainst thePrimitiveRegistry. A skill asserts only when every non-optional requirement binds to an installedPrimitivewhose constraints cover the requirement (monotonic). The result is anAssertionReport(asserted/unavailable/rejected). The optionalpublishAssertionhook is the seam for public disclosure (spec 282: vault claim →atl:skills→ discovery + A2A card). - entitle / delegate / guard — the plan's
.authorize('entitlement', …),.authorize('delegation', …)and.guard(…)steps call the injected evaluators (mapping totool-policy/entitlements,delegation, andtool-policyat the host). Every gate must ALLOW; the first denial throws the typed error and nothing further runs (fail-closed). - primitive-plan / execute —
runPlanresolvesref()s, calls registered primitives for.steps (plus built-inledger.reserve/ledger.finalize), and collects.output. - receipt —
invokereturns a normalizedExecutionReceipt(authority decisions + primitive bindings- outputs); the host sinks/signs it via
audit.
- outputs); the host sinks/signs it via
Example
import { ServiceAgent, defineSkill, createPrimitiveRegistry, primitivePlan, ref } from '@agenticprimitives/service-agent';
const balance = defineSkill<{ accountId: string }, { balance: string }>({
id: 'treasury.account.balance', version: '1.0.0', name: 'Read balance',
effect: 'read', defaultExposure: 'authenticated',
requires: [{ capability: 'account.balance' }],
compile: ({ input }) =>
primitivePlan('plan.balance')
.step('bal', 'account.balance', { accountId: input.accountId })
.output({ balance: ref('bal', 'balance') }),
});
const registry = createPrimitiveRegistry();
registry.register(myAccountProvider); // advertises { id: 'account.balance', version, constraints }
const agent = new ServiceAgent({ descriptor: { id: '0x…', name: 'Treasury', version: '1.0.0' }, primitives: registry });
agent.define(balance);
await agent.assert();
const receipt = await agent.invoke({ skillId: 'treasury.account.balance', input: { accountId: 'acct-1' } });For a spend skill, add .authorize('entitlement', …), .authorize('delegation', …), .guard(…), and the
ledger reserve/finalize steps; wire entitlements / delegations / policies / ledger into
ServiceAgentOptions. See test/conformance.test.ts for the full lifecycle with fakes.
What lives elsewhere
- Providers (EVM transfer, swap venue, RPC, KMS signer) — EXTERNAL (ADR-0037); they register as
Primitives. Demos ship fakes. - Authority logic —
delegation,tool-policy,entitlements; injected as evaluators. - The treasury catalog —
@agenticprimitives/treasury. Public disclosure — the app, viapublishAssertion(spec 282).
