Marking Agent Methods as Read-Only (TypeScript)
SkillAI & modelsMarks your agent's TypeScript methods as read-only so they cannot cause side effects and their results get cached.
Use Marking Agent Methods as Read-Only (TypeScript) in Claude, ChatGPT or Ahel Desktop
Free. Sign in, add Marking Agent Methods as Read-Only (TypeScript) and connect your AI. About a minute.
Also: Claude Code · Cursor · Codex
Then ask your AI: use the Marking Agent Methods as Read-Only (TypeScript) skill
Details
Instructions available. Your AI can read the instructions. Execution depends on the setup they require.
Account requirements not reviewed. Check the skill instructions before use; Ahel provides instructions and does not run this skill.
No other account needed.
Add Ahel to your AI once: Claude, ChatGPT, Cursor, Claude Code or Codex. Then ask it to use this.
About this skill
Marking TypeScript agent methods as read-only for a side-effect-free guarantee and result caching. Use when the user wants a cacheable query method, a method that must not write to the oplog, or HTTP GET endpoints that emit cache headers.
What this skill tells your AI
The instructions your AI receives, as published by golemcloud/golem in golem-skills/skills/ts/golem-mark-read-only-ts/SKILL.md and read by Ahel’s review.
Overview
A read-only agent method is one you promise is a pure read of the agent's already-loaded state: it must not mutate anything and its result must depend only on its inputs and the current state. Golem enforces the most important part of this contract — writes to persistent state, outgoing HTTP, and RPC calls trap at runtime with a ReadOnlyViolation agent error before they run — but it does not detect every source of impurity (in-memory mutation, clocks, randomness, env reads), so keeping the method pure is partly your responsibility (see What Works in a Read-Only Method).
Marking a method read-only also lets the host treat it as a side-effect-free query: it may bypass the invocation queue and agent loading, and read-only methods mapped to GET/HEAD participate in HTTP caching semantics.
Mark a method read-only by setting readOnly: true on the method(...) spec.
Usage
import { z } from 'zod';
import { defineAgent, method } from '@golemcloud/golem-ts-sdk';
export const CounterAgent = defineAgent({
name: 'CounterAgent',
id: { name: z.string() },
methods: {
// Non-read-only: writes shared state
increment: method({ input: {}, returns: z.number() }),
// Read-only: pure read over already-loaded state
getCount: method({ input: {}, returns: z.number(), readOnly: true }),
},
});
export const CounterAgentImpl = CounterAgent.implement({
init: () => ({ count: 0 }),
methods: {
increment() {
this.count += 1;
return this.count;
},
getCount() {
return this.count;
},
},
});
Cache policy.
readOnly: trueuses theuntil-writecache policy (the base-SDK default). For finer control, pass an object instead of the boolean:readOnly: { cache: 'no-cache' | 'until-write' | { ttlNanos: <bigint> }, usesPrincipal?: boolean }—no-cachenever caches,until-writecaches until a mutating (non-read-only) method runs,{ ttlNanos }caches for that time-to-live, andusesPrincipal: truekeys the cache per caller principal. Reach for a regular (non-read-only) method whenever you need a side effect.
What Works in a Read-Only Method
A read-only method must be a pure function of the agent's already-loaded state and the method inputs. The operations in the middle column go through Golem's durability layer and trap with a ReadOnlyViolation agent error before they run and before anything is persisted. The operations in the right column are not detected — they do not trap, but they still break the contract and must be avoided by you.
| Allowed | Not allowed — traps with ReadOnlyViolation | Not allowed — not checked, your responsibility |
|---|---|---|
Reading this state fields | Writing persistent state (storage, databases, …) | Mutating in-memory state |
| Computation over inputs | Outgoing HTTP (fetch) | Reading the clock / Date.now() |
| Returning derived values | RPC calls to other agents | Randomness (Math.random()) |
| Reading environment variables | ||
| Remote / blob reads |
Common Pitfalls
- Mutating state, reading a clock, randomness, or env in a read-only method is NOT detected. These do not trap — but they either mutate state that should be immutable here or make the result non-deterministic. The runtime cannot catch them; keeping the method pure is your responsibility. If you need any of them, use a regular (non-read-only) method instead.
- Writes to persistent state, outgoing HTTP (
fetch), and RPC do trap. Those go through the durability layer and raiseReadOnlyViolationbefore running. - A method that mutates
thisstate must not bereadOnly: true— assigning to a state field is a plain in-memory write, not a host call, so it does not trap; keeping the method mutation-free is your responsibility.
Key Points
readOnlyis per-method; an agent can mix read-only and regular methods freely.- Read-only methods are the natural fit for HTTP
GET/HEADendpoints (loadgolem-add-http-endpoint-ts). - A read-only method cannot call another agent via RPC; do read-only RPC fan-out from a regular method instead (see
golem-call-another-agent-ts).
Signals
- GitHub stars
- 2k
- Forks
- 210
- Last commit
- Oct 2026
Advanced
- Item type
- skill
- Key
golem-mark-read-only-ts- Source
- github.com/golemcloud/golem
Related picks
Skill · mattpocock
The pick for TypeScripttypescript-pro
Skill · jeffallan
The pick for TypeScriptskill-creator
Skill · anthropics
More in AI & modelstriage
Skill · mattpocock
More in AI & modelsalgorithmic-art
Skill · anthropics
More in AI & modelscode-review-and-quality
Skill · addyosmani
More in AI & models