Appearance
Session context
The agent loop runs against an AgentEnvironmentSpec (runtime/AgentEnvironmentSpec.ts:19-66). Every turn — internal oracle, Claude Code worker, Codex worker — assembles the same shape and hands it to its runtime adapter.
The full shape
ts
interface AgentEnvironmentSpec {
targetRef: TargetRef;
targetKey: string;
profile: {
key: string;
purpose?: string;
systemPrompt?: string;
outputContract?: string;
};
prompt: {
text: string;
requestId: string;
traceId?: string;
parentSpanId?: string;
};
session: {
sessionId: string;
profileKey: string;
targetKey: string;
priorMessages?: readonly unknown[];
};
runtime: {
kind: WorkerKind; // 'internal' | 'claude-code' | 'codex' | 'deterministic'
workerRef?: WorkerRef;
model?: string;
provider?: string;
cwd?: string;
repoRoot?: string;
worktreeId?: string;
containerId?: string;
sandbox?: string;
approvalPolicy?: string;
};
toolContext: ResolvedToolContext; // matrix tools + permissions + instructions
skills?: readonly { name; content; version? }[];
sinks: {
activityTo: readonly string[]; // mounts that receive activity frames
traceTo?: readonly string[];
};
principal?: { principalId?; delegationId? };
}Where the pieces come from
| Field | Resolved by |
|---|---|
targetRef, targetKey | the incoming $prompt payload |
profile | resolveAgencyProfile (profiles/AgencyProfileResolver.ts) — picks one of BUILT_IN_AGENCY_PROFILES based on appliesTo rules |
prompt | the incoming envelope (text + correlation IDs from transport metadata) |
session | from AgentsStore — session id and prior messages for resume |
runtime | from the WorkerRef if a situated worker, otherwise { kind: 'internal' } |
toolContext | resolveToolContext (tools/ToolContextResolver.ts) — merges contexts referenced by the profile and skills |
skills | resolveSkillContext (skills/SkillResolver.ts) — picks BUILT_IN_SKILLS whose appliesTo matches |
sinks.activityTo | the caller's mount (Director, Chat, etc.) plus any subscribers |
principal | from transport metadata — never from payload (RULE 5) |
What the model sees
OraclePromptBuilder assembles a system prompt out of:
- The profile's
systemPrompt(or a generated default frompurpose). - The skill bundle (each
ResolvedSkill.contentjoined in deterministic order). - The target snapshot (rendered as a structured tree).
- The tool list (rendered as JSON Schema for native tool calling).
- The prior conversation (for resume).
Four prompt formats are wired (AgentActorProps.promptFormat): legacy, edn, sexp, markdown. Today the default is legacy. The other three are A/B/C/D test surfaces in PromptEnvelopeBuilder.ts.
Cross-turn invariants
- Profile cannot change mid-session. If the user wants to switch profiles, that's a new session.
- Skills can change between turns (the cascade is recomputed against the current target/profile).
- Tools can change between turns (the resolver re-runs on every prompt).
- Snapshot is captured at session start and reused; if the target's structure changes, the model is shown a stale snapshot until the next
session.create.
See also
Source:
projects/matrix-3/packages/agents/src/runtime/AgentEnvironmentSpec.ts:19-66(the contract);projects/matrix-3/packages/agents/src/profiles/AgencyProfile.ts:48-109(six built-in profiles);projects/matrix-3/packages/agents/src/skills/SkillDescriptor.ts:48-94(three built-in skills).