Adding an Agent to an Effect Golem Component
SkillAI & modelsLets your agent define Effect-based agent types with durable state in Golem projects.
Use Adding an Agent to an Effect Golem Component in Claude, ChatGPT or Ahel Desktop
Free. Sign in, add Adding an Agent to an Effect Golem Component and connect your AI. About a minute.
Also: Claude Code · Cursor · Codex
Then ask your AI: use the Adding an Agent to an Effect Golem Component 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
Adding an Effect-based agent to a Golem component. Use when creating or defining an agent type, adding agent methods, schemas, durable state, or Effect implementations in an @golemcloud/effect-golem project.
What this skill tells your AI
The instructions your AI receives, as published by golemcloud/golem in golem-skills/skills/effect/golem-add-agent-effect/SKILL.md and read by Ahel’s review.
Effect Golem agents declare their public contract with Effect Schema and implement every method
as an Effect. A top-level defineAgent(...).implement({ init, methods }) call registers the agent when its
module is imported.
Steps
- Add
src/<agent-name>.tswith the schemas, definition, and implementation. - Declare constructor identity and method contracts with
defineAgentandmethod. - Implement
initas an Effect and derive all handlers from its shared state withmethods. - For snapshot-enabled
Refstate, declareSnapshot.define(...)and usesnapshot: Snapshot.ref<Saved>(). - Add
import "./<agent-name>.js"tosrc/main.tsso the implementation registers. - Run
golem buildto type-check and build the component.
Durable Agent Example
import { Effect, Ref, Schema } from "effect";
import { defineAgent, method, Snapshot } from "@golemcloud/effect-golem";
const Item = Schema.Struct({
id: Schema.String,
name: Schema.String,
});
const RepositoryState = Schema.Struct({
items: Schema.Record(Schema.String, Item),
});
export const ItemRepositoryAgent = defineAgent({
name: "ItemRepositoryAgent",
mode: "durable",
id: {
repositoryName: Schema.String,
},
snapshotting: Snapshot.define({
schema: RepositoryState,
policy: Snapshot.policy.everyN(10),
}),
methods: {
createItem: method({
input: { item: Item },
success: Item,
}),
getItem: method({
input: { id: Schema.String },
success: Item,
}),
updateItem: method({
input: { item: Item },
success: Item,
}),
deleteItem: method({
input: { id: Schema.String },
success: Schema.Boolean,
}),
listItems: method({
input: {},
success: Schema.Array(Item),
}),
},
}).implement({
init: () => Ref.make({ items: {} as Record<string, typeof Item.Type> }),
methods: (state) => ({
createItem: ({ item }) =>
Ref.update(state, ({ items }) => ({
items: { ...items, [item.id]: item },
})).pipe(Effect.as(item)),
getItem: ({ id }) =>
Ref.get(state).pipe(
Effect.map(({ items }) => items[id]),
Effect.flatMap((item) =>
item === undefined
? Effect.die(new Error(`item not found: ${id}`))
: Effect.succeed(item),
),
),
updateItem: ({ item }) =>
Ref.update(state, ({ items }) => ({
items: { ...items, [item.id]: item },
})).pipe(Effect.as(item)),
deleteItem: ({ id }) =>
Ref.modify(state, ({ items }) => {
if (!(id in items)) return [false, { items }] as const;
const { [id]: _, ...remainingItems } = items;
return [true, { items: remainingItems }] as const;
}),
listItems: () =>
Ref.get(state).pipe(Effect.map(({ items }) => Object.values(items))),
}),
snapshot: Snapshot.ref<{ items: Record<string, typeof Item.Type> }>(),
});
Register the implementation from the component entry point:
// src/main.ts
import "./item-repository-agent.js";
Local imports use the emitted .js suffix because generated Effect projects use ESM and
NodeNext module resolution.
Method Contracts and Errors
input is a record of named method parameters. A method with one record parameter declares the
record schema as that parameter's value:
createItem: method({
input: { item: Item },
success: Item,
});
Expected domain failures belong in the Effect error channel and need a matching error schema:
const ItemNotFound = Schema.Struct({
_tag: Schema.Literal("ItemNotFound"),
id: Schema.String,
});
getItem: method({
input: { id: Schema.String },
success: Item,
error: ItemNotFound,
});
// In the implementation:
Effect.fail({ _tag: "ItemNotFound" as const, id });
Use defects such as Effect.dieMessage(...) only for unexpected failures that should fail and
retry the invocation. Do not use defects to represent normal business outcomes.
Key Constraints
- Import Effect APIs from
effectand Golem APIs from@golemcloud/effect-golem. - Use Effect Schema values for every agent id field, method parameter, success, and typed error.
- Constructor parameters define durable agent identity.
- Handlers return
Effectvalues; do not implement them as plainasyncfunctions. - Use
Snapshot.ref<Saved>()when a snapshottedRefcontains the saved schema value. - Keep snapshot values schema-serializable; do not put JavaScript
Map, functions, or services in snapshot state. - Agents are created on first invocation and process invocations sequentially.
- Import every implementation module from
src/main.tsfor side-effect registration. - Do not edit files under
golem-temp/.
Signals
- GitHub stars
- 2k
- Forks
- 210
- Last commit
- Oct 2026
Advanced
- Item type
- skill
- Key
golem-add-agent-effect- Source
- github.com/golemcloud/golem
Related picks
Skill · mattpocock
The pick for TypeScripttypescript-pro
Skill · jeffallan
The pick for TypeScriptnodejs-backend-patterns
Skill · wshobson
The pick for Noderun-node-tests
Skill · hiroro-work
The pick for Nodeskill-creator
Skill · anthropics
More in AI & modelstriage
Skill · mattpocock
More in AI & models