Defining Golem Components
Creating a project
Golem’s command line interface provides a set of predefined, Golem-specific templates to choose from as a starting point.
TypeScript
To get started from scratch, first create a new application using the TypeScript template:
golem new --template ts --yes my-app
cd my-appAn application can consist of multiple components. Add a new component by choosing from one of the available templates. To see the list of available templates, run:
golem templatesThen create a new component using the chosen template:
TypeScript
golem new . --template ts --component-name my:component --yesTypeScript agents, tools, and middleware
TypeScript components use one default guest world for agents, tools, snapshots, and tool middleware. Select the ts component template regardless of which of these categories the component exports:
components:
my:middleware:
dir: middleware
templates: tsStandalone middleware components remain supported. Import their authoring APIs from the middleware entry point; unused agent and tool discovery returns empty lists:
import {
toolDefinition,
universalToolMiddleware,
} from '@golemcloud/golem-ts-sdk/middleware';The default guest imports golem:tool/host; ambient calls remain subject to runtime permission
checks. Invocation-scoped underlying access still advances the pinned middleware chain.
Defining agents
Defining Golem agents is done using the Golem SDK, which is included in all the templates provided by golem.
TypeScript
An agent is declared with defineAgent(...) and given its behaviour with .implement(...):
import { z } from 'zod';
import { defineAgent, method } from '@golemcloud/golem-ts-sdk';
export const MyAgent = defineAgent({
name: 'MyAgent',
id: { /* constructor parameters — see below */ },
methods: {
// ...
},
});
export const MyAgentImpl = MyAgent.implement({
init: () => ({ /* initial state */ }),
methods: {
// ...
},
});An agent component must define at least one agent, but can also define multiple ones.
Agent constructors
Every agent must define a constructor with an arbitrary number of parameters. These parameters form the agent identifier. Every possible parameter value combination identifies a particular agent instance.
For example, an agent working on a particular user’s particular request could be defined as:
TypeScript
import { z } from 'zod';
import { defineAgent } from '@golemcloud/golem-ts-sdk';
export const RequestHandler = defineAgent({
name: 'RequestHandler',
id: { userId: z.string(), requestId: z.string() },
methods: {
// ...
},
});The Effect agent shown here is identified by RequestHandler("user-123", "request-456"); agent identifiers preserve the declared agent name.
Agent methods
Every method an agent declares is an agent method, which can be called by other remote agents, externally through Golem’s invocation API, and can also be mapped to HTTP APIs.
Agent methods can (and should) be also annotated with the metadata such as prompt and description
promptshould provide information for an external AI to understand what needs to be passed to the method as parametersdescriptionshould be a human-readable description of what the method does
This metadata is stored in the Golem component and can be used when exposing the agents through MCP, for example.
The following example shows the use of how to attach these metadata to simple agent methods in different languages
TypeScript
import { z } from 'zod';
import { defineAgent, method } from '@golemcloud/golem-ts-sdk';
const TaskDetails = z.object({ description: z.string(), priority: z.number() });
const RequestHandlerStatus = z.object({
status: z.enum(['success', 'failure']),
summary: z.string(),
});
export const RequestHandler = defineAgent({
name: 'RequestHandler',
id: { userId: z.string(), requestId: z.string() },
methods: {
addDetails: method({
input: { details: TaskDetails },
returns: RequestHandlerStatus,
description:
"Adds some more details to the request handler about the task being performed. The result is an update of the current status.",
promptHint: "Enter new details about the task",
}),
},
});Agent methods can be both sync or async. Effect TypeScript handlers always return an Effect, whether the work represented by that Effect is synchronous or asynchronous.
Supported data types
The SDK supports a large variety of data types in agent constructors and agent methods, both in parameter and return type position. Validation timing is SDK-specific; Effect TypeScript validates whether its schemas have an unambiguous Golem representation during registration and discovery.
TypeScript
In TypeScript, declare constructor parameters, method inputs, and return values using supported runtime schemas, such as Zod schemas. Use z.object(...) for records and z.enum(...) for string alternatives; TypeScript types are inferred from these schemas.
Library support
TypeScript
See the JS APIs page for a detailed overview of all the supported Web Platform and Node.js APIs. Most 3rd party libraries can be installed using npm and used in the agent code, as long as they only rely on the supported APIs and do not require native addons.
Agent mode - durable or ephemeral
By default every agent is durable. To define an ephemeral agent, override the agent mode in the agent definition:
TypeScript
export const EphemeralAgent = defineAgent({
name: 'EphemeralAgent',
mode: 'ephemeral',
id: { name: z.string() },
methods: {
// ...
},
});Agent configuration
It is often required to pass configuration values to agents when they are started.
Golem supports two ways of doing this:
- Defining key-value pairs available as environment variables.
- Defining dedicated typed configuration values.
Environment variables
TypeScript
Environment variables are accessible through the node:process module:
import { env } from "node:process";Environment variables can be specified when an agent is explicitly created, but there are some environment variables that are always set by Golem:
GOLEM_AGENT_ID- the ID of the agentGOLEM_AGENT_TYPE- the agent type (first part of the agent ID)GOLEM_COMPONENT_ID- the ID of the agent’s componentGOLEM_COMPONENT_REVISION- the revision of the component used for this agent
In addition to these, when using Agent to Agent communication, agents created by remote calls inherit the environment variables of the caller.
This feature makes environment variables a good fit for passing configuration such as hostnames, ports, or access tokens to trees of agents.
Default environment variables
It is possible to define default environment values and config key-value pairs for a component using the app manifest. These values are automatically set for each agent created from the component, but can be overridden when creating the agent.
To set component level environment variables, use the env section of the golem.yaml:
components:
my:component:
env:
MY_ENV_VAR: "some value"
ANOTHER_ENV_VAR: "another value"Per-agent configuration
Configuration resolves from the component template and component first. Agent templates are then applied, followed by agent properties, environment presets, and finally custom presets. Each level can define env (environment variables) and files (initial filesystem), with later, more specific levels overriding earlier ones according to their merge modes.
Agent-level configuration in golem.yaml
agents:
InboxAgent:
env:
OPENAI_API_KEY: "{{ OPENAI_API_KEY }}"
MODEL: gpt-4.1-mini
files:
- sourcePath: ./prompts/inbox-system.md
targetPath: /prompts/system.md
permissions: read-only
config:
defaultQueue: general
summarizeReplies: true
EscalationAgent:
env:
JIRA_BASE_URL: https://acme.atlassian.net
files:
- sourcePath: ./prompts/escalation-system.md
targetPath: /prompts/system.md
permissions: read-onlyMerge modes
By default, child-level environment variables are upserted (added or updated) into parent values. This can be changed with envMergeMode:
| Mode | Behavior |
|---|---|
upsert | (default) Add new keys, overwrite existing ones |
replace | Discard all parent env vars, use only this level’s values |
remove | Remove the listed keys from the parent map |
Similarly, filesMergeMode controls how initial files are merged: append (default), prepend, or replace.
Presets
Both components and agents support presets that can override configuration per deployment target:
environments:
local:
default: true
server: local
componentPresets: local
prod:
server: cloud
componentPresets: cloud