Run a Stateful Agent on Agent Substrate
Run local agents that suspend, resume, and diagnose a Kubernetes app.
Introduction
30 Second Summary
Most AI agents sit idle between requests, but their infrastructure keeps consuming resources. Running more agents usually means paying for more capacity that spends most of its time waiting.
In this project, you will run Agent Substrate with kagent on a local Kubernetes cluster. A troubleshooting agent diagnoses a broken app before releasing its worker between messages.
What You'll Build
Picture a sleeping troubleshooting chat remembering its earlier diagnosis after every original worker has been replaced.
By the end of this project, you'll have:
- A live operations view that shows how a WorkerPool shares ready workers across agent chats.
- A read-only diagnosis that identifies the misspelled image behind a broken web Deployment.
- A stateful scale-to-zero proof where the same Actor returns from a snapshot on replacement capacity with its earlier conversation intact.
- Secret Mission: Add four more agents to compare five chats against the smaller number of busy workers in the live savings table.
Are there any prerequisites?
- A Google account for Google AI Studio.
- A macOS, Linux, or Windows computer with WSL 2. It needs at least 4 CPUs, 6 GB of memory available to Docker, and about 10 GB of free disk space.
- No previous Kubernetes experience.
Before We Start
The hot-desk model gives you a clear way to picture how Agent Substrate keeps chat sessions available without reserving a worker for every idle conversation. This checkpoint captures your understanding before any hands-on work begins.
Launch Your Local Agent Platform
A hot-desk platform keeps reusable worker capacity ready for Actors to claim when needed. A missing tool or undersized Docker allocation can leave the host without enough container capacity, stopping the local WorkerPool before it starts.
The starter repository installs Agent Substrate with kagent on a local Kubernetes cluster. It also protects your model credential inside a local file.
In this step, get ready to:
- Prepare Docker for the setup script's host checks.
- Clone the starter repository and protect your Gemini API key.
- Launch the local cluster and inspect its ready worker capacity.
Prepare and verify your host
The installer needs at least 4 Docker CPUs and 6 GB of Docker memory. It downloads about 5.5 GB of files, so keep about 10 GB of disk space free.
The setup path differs by operating system. Choose your platform below to prepare Docker and the terminal that runs the project, but keep Docker's default resource settings unless the preflight reports a problem.
macOS
Docker Desktop supplies the container host for your local cluster. The setup script checks its available CPU and memory before creating anything.
- Follow the Docker Desktop installation guide for macOS if Docker Desktop is missing.
- Press Cmd+Space to open Spotlight.
- Type Docker Desktop in Spotlight.
- Press Enter to start Docker Desktop.
- Wait until Docker Desktop reports that it is running.
Understand the checkpoint limitation
Agent Substrate uses a gVisor sandbox checkpoint path when it saves an Actor. Docker Desktop often fails this path on macOS even when the installation succeeds.
Suspend or resume can fail later because of this limitation. Docker Engine on Linux provides the most reliable local lifecycle path.
- Continue the project in Terminal with a Bash-compatible shell.
- Confirm that Google Chrome is installed for the kagent interface.
Missing a host requirement?
Install any missing requirement before continuing. The setup script checks Docker access, CPU, and memory before creating the cluster.
Use help me prepare my macOS host if one of the checks is unclear.
Windows
Every project command runs inside Ubuntu on WSL 2. PowerShell is only used when WSL needs to be installed.
Check whether Ubuntu opens successfully from Windows search.
✔️ Ubuntu opens in WSL 2
Your WSL environment is available. Keep the Ubuntu terminal ready for every project command.
ⓧ WSL is not installed
- Press the Windows key to open search.
- Type PowerShell into search.
- Select the administrator option for PowerShell.
- Install WSL by running this command:
wsl --install
What does this command do?
The command installs WSL with a supported Linux distribution. Windows can request a restart before Ubuntu is ready.
- Restart Windows if the installer requests it.
- Complete Ubuntu's initial username setup after the restart.
- Open the Ubuntu terminal from Windows search.
- Follow the Docker Desktop installation guide for Windows if Docker Desktop is missing.
- Press the Windows key to open search.
- Type Docker Desktop into search.
- Press Enter to start Docker Desktop.
- Wait until Docker Desktop reports that it is running.
Understand the checkpoint limitation
Docker Desktop often fails the gVisor checkpoint path on Windows. The installation can succeed while suspend or resume later fails.
Docker Engine on Linux provides the most reliable local lifecycle path. Keep this limitation in mind if an Actor becomes stuck later.
- Continue every project command inside the Ubuntu terminal.
- Confirm that Google Chrome or Microsoft Edge is installed for the kagent interface.
Ubuntu cannot access Docker?
Confirm that Docker Desktop is running. Confirm that its Ubuntu integration is enabled.
Use help me connect Ubuntu to Docker Desktop if Docker remains unavailable inside Ubuntu.
Linux
Docker Engine supplies the container host directly on Linux. This is the most reliable path for the suspend and resume proof.
- Open the Docker Engine installation guide.
- Press Cmd to open Search.
- Type Docker Desktop in Spotlight.
- Press Enter to start Docker Desktop.
- Wait until Docker Desktop reports that it is running.
Docker access denied?
The Docker service can be running while your current user lacks access. Follow Docker's post-install instructions for your distribution before continuing.
Use help me fix Docker access on Linux if the permission check still fails.
Clone the repository and protect your key
The starter repository contains the scripts that build the platform in the correct order. Git copies those scripts to your computer as one folder.
Why use the repository installer?
A manual installation requires separate downloads plus certificate configuration and component ordering. The repository keeps this project focused on the Agent Substrate lifecycle.
You still inspect the resulting Kubernetes resources through the status script and kubectl.
- Move to your Desktop.
- Clone the repository and create its local credential file by running these commands:
cd ~/Desktop
git clone https://github.com/Nik-1019/agent-substrate-kagent-nextwork.git agent-substrate-kagent-nextwork
cd agent-substrate-kagent-nextwork
cp .env.example .env
What do these commands create?
- The first command downloads the starter repository into agent-substrate-kagent-nextwork.
- The second command moves the terminal into that folder.
- The final command creates .env from .env.example.
The completed command returns you to the terminal inside agent-substrate-kagent-nextwork. The repository now contains its setup scripts plus the manifests folder.
Repository clone failed?
Check the terminal for a Git or network failure. Rerun the clone after restoring your connection.
Use help me troubleshoot the repository clone if the folder is still unavailable.
A Gemini API key is a live credential. Creating it exposes the value briefly, so keep it away from screenshots and shared notes.
- Open Google AI Studio from the documentation.
- Sign in with your Google account.
- Create a Gemini API key.
- Copy the new key without displaying it anywhere else.
- Return to the terminal inside agent-substrate-kagent-nextwork.
- Open the credential file with nano by running:
nano .env
Why edit this file?
The installer reads your credential from .env. The repository excludes this local file from Git.
Only the value after GEMINI_API_KEY= needs to change. The key stays hidden from the setup output.
- Find the line beginning with GEMINI_API_KEY=.
- Paste the key directly after the equals sign.
- Press Ctrl+O to write the file.
- Press Enter to confirm the filename.
- Press Ctrl+X to close nano.
You return to the terminal without another save prompt. Your credential is now stored in the local .env file.
Keep your credential private
Never commit, share, screenshot, or paste the key into a chat. Treat it like a password.
Google states that free-tier Gemini content may be used to improve its products. Use synthetic cluster prompts throughout this project.
Install and inspect the platform
The setup script checks the host before creating anything. It then downloads the pinned tools and builds the cluster in dependency order.
The first run can take 5 to 10 minutes while Docker downloads images. Quiet stretches during this run are expected.
- Create the cluster and install the platform by running:
./setup.sh
What does the installer do?
- It downloads pinned tools into ./bin.
- It creates a local kind cluster named kagent with Kubernetes v1.37.0.
- It installs Agent Substrate v0.6.0-alpha3 with kagent v1.0.0-alpha16.
- It creates the WorkerPool capacity and opens the UI tunnel at http://localhost:8080.
You should see "Your agent platform is ready!" When setup finishes, your local cluster has the platform components plus ready worker capacity.
Setup stopped early?
- Read the final terminal message to identify the failed host check.
- Open Docker Desktop's Settings only if setup reports fewer than 4 CPUs.
- Select Resources in Docker Desktop.
- Set CPUs to 4.
- Add LOW_MEMORY=1 to .env only when setup reports at least 4 GB but less than 6 GB of Docker memory.
The low-memory fallback uses one ready worker. The lifecycle still works with that smaller pool.
Use help me diagnose setup.sh if the cause remains unclear.
Before you inspect the result, which hot-desk resources do you expect to see before any chat exists?
- Inspect the platform and its WorkerPool by running these commands:
./status.sh
./bin/kubectl get workerpool -n kagent
How to read the result
- The WorkerPool named kagent-default is the managed group of ready desks.
- Each worker row represents one ready desk that can host an Actor.
- The router is the receptionist that receives future requests and directs them to the current worker.
- The Actors table reports that no Actors exist because no chat has started.
- The UI address is http://localhost:8080.
- Enter http://localhost:8080 in your browser address bar.
What is kagent?
kagent is an open-source, Kubernetes-native platform for running AI agents. It defines agent behavior and runtime as Kubernetes resources, then runs each conversation inside Agent Substrate.
The Substrate page shows WorkerPools, workers, ActorTemplates, and Actors. Empty ActorTemplate and Actor tables are expected here because you have not created an agent or started a conversation yet.
- Click Substrate in the left sidebar.
- Find kagent/kagent-default in the Worker Pools table.
- Confirm that Replicas shows 1 or more.
- Confirm that the Workers table lists at least one pod assigned to kagent-default.
- Confirm that the Actor Templates table has no entries yet.
- Your local agent platform is live. The reusable worker desks are ready for the first agent conversation.
✔️ Awesome, I've got everything!
Your cluster, UI tunnel, WorkerPool, workers, and router are ready. Your protected credential remains local.
ⓧ I'd like to double check the full setup
- Confirm that ./.env contains a saved GEMINI_API_KEY without displaying the value.
- Confirm that ./agent-substrate-kagent-nextwork contains setup.sh, status.sh, teardown.sh, manifests/, and downloaded tools under ./bin.
- Confirm that the local cluster named kagent runs Kubernetes v1.37.0.
- Confirm that Agent Substrate v0.6.0-alpha3 and kagent v1.0.0-alpha16 are installed.
- Confirm that kagent-default has one ready worker when LOW_MEMORY=1 is set.
- Confirm that kagent-default has the repository's normal small pool capacity when the fallback is unused.
- Confirm that the router is ready to route future chat requests.
- Confirm that no Actors exist yet and the UI loads at http://localhost:8080.
Your reusable worker desks are ready. Next, you will define the agent recipe that can use them.
Build Your Troubleshooting Agent
Your local Agent Substrate platform is running.
Its WorkerPool has ready workers. Those workers need an agent definition before they can host a conversation.
In this step, you will use kagent to create ops-buddy from a shared template and harness. You will confirm its golden snapshot is ready before a message creates the first Actor.
In this step, get ready to:
- Create ops-buddy in the kagent namespace.
- Configure its shared template plus harness.
- Confirm its golden snapshot is ready without creating a chat Actor.
Create the ops-buddy agent
The template is the agent's playbook. The harness connects that playbook to the workers that run it.
- Switch back to the browser tab showing the kagent UI at http://localhost:8080.
- Select Agents in the navigation.
- Click New Agent.
- Enter ops-buddy in the Name field.
- Select kagent in the Namespace field.
- Keep Reference selected.
The form now identifies ops-buddy as a Reference agent in the kagent namespace.
- Choose kubernetes-agent in the Shared template field.
- Choose substrate-harness in the Harness field.
- Click Create agent.
How the pieces fit together
The template gives the agent its model, instructions, and read-only Kubernetes tools. It acts as the job description for ops-buddy.
The harness connects that job description to the running platform. Here, substrate-harness sends the work to the kagent-default WorkerPool.
Wait for the golden snapshot
Creating the agent also prepares a golden snapshot. This saved starting point lets the first chat wake faster because the platform does not rebuild the agent from scratch.
- Locate the ops-buddy row in the Agents table.
- Use the refresh control above the table while the agent is preparing.
- Wait until the Status value reads Ready.
That preparation is complete. ops-buddy now has a ready starting state for its first conversation.
Agent not reaching Ready?
- Use the refresh control once more to request the latest status.
- Confirm that Docker Desktop or Docker Engine remains running.
- Check that kubernetes-agent was selected as the shared template.
- Check that substrate-harness was selected as the harness.
- Ask for help with an agent that remains unready.
Verify the template without starting a chat
A ready agent and an active chat are different things. The prepared agent waits as a template until the first message creates a chat Actor.
Before you run the check, do you think a ready agent already has a chat Actor?
- Switch back to the terminal from earlier.
- Verify the agent state by running this command:
./status.sh
What does the status report prove?
- The TEMPLATES table shows ops-buddy with a ready golden snapshot.
- The ACTORS table is empty because no chat has started.
- The kagent-default WorkerPool still has room for the first conversation.
- The router is ready to send the first message to an available worker.
You have reached the clean starting point. The agent is prepared, no chat exists yet, and worker capacity is waiting.
Agent missing from status?
- Make sure the terminal is inside the agent-substrate-kagent-nextwork folder.
- Confirm that Docker Desktop or Docker Engine is still running.
- Return to the Agents surface in the kagent UI.
- Wait until ops-buddy shows Ready before running the status check again.
- Ask for help finding the agent in the status report.
The Substrate page shows the same state as a diagram. It lets you see the ready template and confirm that no chat Actor is running.
- Switch back to the kagent UI in your browser.
- Select the Substrate page.
- Locate the ready Actor template associated with ops-buddy.
- Check the Actors area for active chat sessions.
You should see the ready Actor template for ops-buddy. The Actors area is empty because you have not sent a message.
Your troubleshooting agent is ready. Next, you will give it a broken Kubernetes app and watch the first chat bring an Actor to life.
Diagnose the Broken Deployment
Your agent needs a real problem before it can show what it knows. You will create a small, controlled failure inside the local Kubernetes cluster.
After ops-buddy diagnoses the failure, Agent Substrate saves the chat Actor in a snapshot. The WorkerPool then gets its worker back for another conversation.
In this step, get ready to:
- Deploy the web workload and inspect its pod state.
- Enable request polling and run a two-message diagnosis with ops-buddy.
- Confirm that the chat Actor suspends with saved state and free worker capacity.
Create the web Deployment
A Deployment tells Kubernetes which app image to keep running. You will create one named web with a specific image tag, then inspect what happens.
- Switch back to your Terminal
- Create the web Deployment by running this command:
./bin/kubectl create deployment web --image=nginx:1.27-alpne
What does this command do?
- The create deployment web portion adds a Deployment named web to your local cluster.
- The --image=nginx:1.27-alpne value tells Kubernetes which container image the Deployment should run.
The terminal confirms that the Deployment was created. Kubernetes now tries to start its pod.
Before you inspect the pod, do you think Kubernetes can start the requested image?
- Inspect the pod state by running this command:
./bin/kubectl get pods
Not seeing ImagePullBackOff?
The command reads the pods in your current namespace. You should see the web pod reach ImagePullBackOff because nginx:1.27-alpne contains the intended spelling error.
- Wait a few seconds for Kubernetes to try the image download.
- Run the pod inspection command again.
- Help me understand why the pod has not reached ImagePullBackOff.
- Leave the web Deployment unchanged.
Enable polling and ask ops-buddy
The Substrate page shows the chat moving through each stage. A worker is the temporary seat that runs the Actor while it answers.
- Return to the kagent UI in your browser.
- Select the Substrate page from the navigation.
- Click Request polling: disabled.
You will see the control change to Request polling: enabled. The page now refreshes the lifecycle state while the request runs.
Keep practice data synthetic
Google states that free-tier Gemini content may be used to improve its products. Use only the made-up cluster details from this project.
- Keep real company or customer data out of the practice chat.
- Keep your Gemini API key out of every prompt.
- Create a second browser tab.
- Return to the kagent Agents surface in the second tab.
- Select ops-buddy to open its chat.
- Paste this troubleshooting prompt into the chat input:
My app called web isn't working. Can you find out why?
Why this prompt works
Naming web gives ops-buddy a specific Deployment to inspect. Asking what is wrong keeps the read-only agent focused on diagnosis instead of making changes.
- Submit the message with the chat send control.
- Return to the Substrate tab while the request runs.
You will see the Actor claim a worker inside a gVisor sandbox while it answers. When the reply finishes, the Actor moves to SUSPENDED and the worker becomes free again.
- Return to the ops-buddy chat after the lifecycle settles.
The reply identifies nginx:1.27-alpne as the misspelled image tag. Leave the Deployment broken so the next step can prove that the same chat remembers this diagnosis.
- Return to the terminal from earlier.
- Inspect the saved diagnosis and freed worker capacity by running this command:
./status.sh
In ACTORS, ops-buddy should show SUSPENDED with a higher snapshot count. In WORKERS, the worker shows BUSY?: free, so the conversation keeps its diagnosis without reserving compute.
This is the scale-to-zero moment
The worker finished the task and returned to the pool. The conversation stayed ready inside the Actor snapshot.
🙋♀️ Actor not suspended?
Suspend saves the Actor's conversation in its snapshot before releasing the worker. The ACTORS table should show SUSPENDED with no assigned worker.
The WorkerPool should show free capacity. The router stays ready to wake this same Actor when another message arrives.
- Wait until the ops-buddy reply stops generating text.
- Run the status command again.
- Confirm request polling is enabled on the Substrate page.
- Help me troubleshoot an Actor that is not suspended.
- Return to the existing ops-buddy chat.
- Send this follow-up message:
What evidence supports your diagnosis, and what image tag should I use to fix it? Do not change anything.
- Submit the message with the chat send control.
- Return to the Substrate tab while the request runs.
- Return to the ops-buddy chat after the reply finishes.
The agent should connect ImagePullBackOff to the misspelled nginx:1.27-alpne tag. It should recommend nginx:1.27-alpine without changing the Deployment.
- Return to the terminal from earlier.
- Inspect the second saved turn and freed worker capacity by running this command:
./status.sh
The snapshot count should rise again after the second reply. The Actor should return to SUSPENDED with the worker free.
The web pod remains in ImagePullBackOff, ready for the continuity test. Its diagnosis now lives inside a suspended Actor.
Your diagnosis is stored while worker capacity is free. Next, you will replace the original workers and wake the same conversation on new capacity.
Replace Workers and Resume the Actor
ops-buddy found why the web Deployment was broken. Its Actor saved that diagnosis in a snapshot before going to sleep.
Now you will remove every worker that could have held the conversation. If ops-buddy remembers its diagnosis after replacements take over, you have direct proof that its memory lives in the Actor snapshot.
In this step, get ready to:
- Replace the original worker pods and confirm the pool recovers.
- Resume the same Actor and continue its diagnosis across two follow-up messages.
- Correct the image tag and verify the replacement pod is running.
Replace the WorkerPool pods
A WorkerPool keeps a group of workers ready for new requests. When one pod disappears, Kubernetes creates another until the pool is full again.
- Return to the terminal from earlier inside the agent-substrate-kagent-nextwork repository.
- List the current runtime state by running this command:
./status.sh
What does this status show?
- The workers section gives you the original pod names to compare later.
- The Actor should still show SUSPENDED because you have not sent another message.
- The capacity summary shows a ready worker is available for the next request.
- Record the current worker pod names here: the original worker pod names.
Before you replace the workers, do you expect the recovered pool to keep the original pod names?
- Delete every current worker pod by running this command:
./bin/kubectl delete pod -n kagent -l ate.dev/worker-pool=kagent-default
The deletion is real
- The terminal names each original worker pod as Kubernetes deletes it.
- Those names should match the original worker pod names.
- The suspended Actor keeps its snapshot while the WorkerPool rebuilds.
- Watch Kubernetes create replacement worker pods by running this command:
./bin/kubectl get pods -n kagent -l ate.dev/worker-pool=kagent-default --watch
You may briefly see the replacements pass through Pending or ContainerCreating before they reach Running. Their pod names should be different from the original worker pod names.
- Stop the live watch after every replacement reaches Running by pressing Ctrl+C.
- Check the recovered WorkerPool and suspended Actor by running this command:
./status.sh
The worker is disposable
You deleted every original worker pod. The Actor and its diagnosis remained intact while Kubernetes rebuilt the pool.
The WORKERPOOL line should report every replacement ready under new pod names. In WORKERS, ACTIVE with BUSY?: free confirms that replacement capacity is available.
WorkerPool did not recover?
- Confirm Docker Desktop or Docker Engine is still running.
- Check that Docker still has the memory capacity you verified during setup.
- Repeat the status check after the cluster has had time to create the replacement pods.
help me troubleshoot why my kagent-default WorkerPool has no ready replacement workers after deleting its pods.
Resume the same Actor
Resume wakes a sleeping Actor from its latest snapshot on any worker with room. The router sends the next message to that restored conversation.
Before you send the follow-up, do you expect the chat to remember its earlier diagnosis after every original worker was replaced?
- Switch back to the browser tab containing your existing ops-buddy chat.
- Send this exact follow-up message:
What did I ask you earlier, and what fix did you recommend?
Why does this message prove continuity?
The follow-up makes sense only if the chat remembers the first question and diagnosis. A correct answer proves the resumed Actor received its saved conversation.
The reply should identify your earlier question about the broken web app. It should recall that nginx:1.27-alpne needs to change to nginx:1.27-alpine.
- Return to the terminal from earlier after the reply finishes.
- Inspect the resumed Actor immediately by running this command:
./status.sh
What does the resumed state show?
- The LAST WAKE-UP value records when the Actor moved onto replacement capacity.
- The SUSPENDED state shows the finished chat released its worker again.
- The newest snapshot now contains the first diagnosis and the follow-up reply.
- Record the displayed wake-up value here: the displayed LAST WAKE-UP time.
- Compare the current worker pod names with the original worker pod names.
The same conversation answered from replacement capacity with its earlier diagnosis intact. That is stateful scale-to-zero: memory survives while workers come and go.
Actor did not remember?
- Return to the existing ops-buddy conversation if the reply lacks the earlier context.
- Wait for the follow-up reply to finish before checking the Actor state.
- Switch back to the Substrate page to confirm that the Actor returns to its suspended state.
help me troubleshoot why my resumed ops-buddy Actor did not remember its earlier diagnosis after worker replacement.
- Return to the existing ops-buddy chat.
- Send this second follow-up message:
Before I change anything, summarize the root cause, the corrected image tag, and the two checks I should make after the repair. Do not make any changes.
- Submit the message with the chat send control.
- Return to the Substrate tab while the request runs.
- Return to the terminal after the reply finishes.
The reply should name nginx:1.27-alpne as the root cause and nginx:1.27-alpine as the correction. It should suggest checking that the pod reaches Running and that the Deployment stores the corrected image.
- Inspect the second resumed turn by running this command:
./status.sh
You should see the Actor suspended again with another saved snapshot. This repeated cycle proves one conversation can resume across several turns after worker replacement.
Repair the web Deployment
The web Deployment still uses the misspelled image that caused ImagePullBackOff. Correcting the tag tells Kubernetes to replace the failed pod with a working one.
- Correct the image used by the nginx container by running this command:
./bin/kubectl set image deployment/web nginx=nginx:1.27-alpine
What does this correction change?
The Deployment now asks for nginx:1.27-alpine instead of the misspelled tag. Kubernetes creates a replacement pod from that valid image.
Before you check the workload, which pod state would prove that the corrected image was pulled successfully?
- Check the repaired workload by running this command:
./bin/kubectl get pods
What does this check prove?
A replacement pod in Running proves Kubernetes started the repaired workload. The default pod table does not show the container image, so you will verify that field separately below.
The replacement pod may take a short moment to start while Kubernetes downloads the image. A brief starting state is normal.
- Repeat the pod check until the replacement web pod shows Running.
The replacement web pod now reaches Running. This table confirms pod health, but it does not display the image tag.
- Confirm the image stored in the web Deployment by running this command:
./bin/kubectl get deployment web -o jsonpath='{.spec.template.spec.containers[0].image}{"\n"}'
You should see only nginx:1.27-alpine. This confirms the Deployment template now points to the corrected image.
What did you just prove?
- The image update changed the web Deployment template from nginx:1.27-alpne to nginx:1.27-alpine.
- Kubernetes used the corrected template to replace the failed pod. The Running state shows the replacement started successfully.
- The JSONPath check read the image directly from the Deployment template. Seeing nginx:1.27-alpine confirms the typo is gone.
- Together, these checks prove the saved configuration and running workload now agree.
🙋♀️ Pod still cannot pull the image?
- Compare the corrected image tag with nginx:1.27-alpine character for character.
- Confirm Docker Desktop or Docker Engine still has network access.
- Repeat the pod check after the Deployment finishes replacing the failed pod.
help me troubleshoot why the web pod is not reaching Running after correcting its image tag.
Secret mission
Five Agents, Fewer Workers
Create five separate chats, then watch them take turns using the same small WorkerPool. The savings table shows why five conversations do not need five busy workers.
Clean Up Your Resources
Clean Up Your Resources
This local Kubernetes cluster has no ongoing cloud infrastructure charge. Choose whether to keep the environment running, pause its local services, or delete its resources.
Cost warning
The main path uses local compute. The gemini-3.5-flash-lite model is free of charge on the documented Gemini Free Tier.
Docker Desktop is free for personal use and education. Commercial use by larger enterprises requires a paid subscription.
Google states that free-tier Gemini content may be used to improve its products.
- Keep future prompts synthetic and non-sensitive.
Resources you used:
- The local kind cluster named kagent. It contains Agent Substrate, kagent resources, and the WorkerPool shared by all five chats.
- The local agent-substrate-kagent-nextwork repository folder, including .env, manifests/, and downloaded tools in ./bin.
- The Gemini API key created in Google AI Studio.
Keep everything running
No action is needed. Choose this if you want to continue experimenting with the five agents or their shared worker capacity.
- Leave the local kind cluster named kagent running.
- Keep the agent-substrate-kagent-nextwork folder in its current location.
- Retain the Gemini API key only while you still need it.
Pause - I'll come back to this later
Shut down the local runtime to free its CPU and memory. Your repository remains available for your return.
macOS
- Stop Docker Desktop from its application menu.
Your local cluster becomes unavailable while Docker Desktop is stopped.
Windows
- Stop Docker Desktop from its application menu.
Your local cluster becomes unavailable inside Ubuntu while Docker Desktop is stopped.
Linux
- Stop Docker Engine with your distribution's service manager.
Your local cluster becomes unavailable while Docker Engine is stopped.
- Keep the agent-substrate-kagent-nextwork folder in its current location.
- Restart your Docker runtime when you return.
- Switch back to the Bash terminal in agent-substrate-kagent-nextwork.
- Restore the local platform by running the repository's setup script:
./setup.sh
What does this restore?
The setup script checks the existing environment before restoring any missing components. It also restores the tunnel for the kagent UI.
- Refresh http://localhost:8080 in your browser.
You'll see the kagent UI again when the local platform is ready.
Setup does not recover?
- Confirm that your Docker runtime is running.
- Confirm that your terminal is inside agent-substrate-kagent-nextwork.
Ask for help with the local restart.
Delete - I don't want to use this again
Deleting the environment removes the local cluster permanently. You can recreate it later by cloning the repository again.
- Switch back to the Bash terminal in agent-substrate-kagent-nextwork.
- Delete the local cluster and UI tunnel by running the repository's teardown script:
./teardown.sh
What does this script delete?
The script deletes the local kind cluster named kagent.
The script also closes the kagent UI tunnel.
Your repository stays on disk. Your remote Gemini API key stays active.
- Refresh http://localhost:8080 in your browser.
Your browser should no longer reach the kagent UI.
Cluster still reachable?
- Confirm that Docker is running.
- Retry the teardown script from the agent-substrate-kagent-nextwork folder.
Help me troubleshoot the teardown script.
The next action removes the credential from this project. The remote key remains active until you delete it in Google AI Studio.
- Remove the local credential file by running this command:
rm .env
What does this command remove?
This command removes .env from the local repository.
It does not revoke the Gemini API key stored by Google AI Studio.
- Confirm that .env is absent from the repository's file list.
Credential file still present?
- Confirm that your terminal is inside agent-substrate-kagent-nextwork.
- Retry the credential removal command.
Help me remove the credential file safely.
Deleting the remote key revokes that credential permanently. You can create a new key if you revisit the project.
- Return to the API key page in Google AI Studio.
- Delete the Gemini API key you created for this project.
- Confirm that the deleted key is no longer listed.
Removing the repository folder is the final irreversible local action. The project can be downloaded again later.
- Switch back to the Bash terminal in agent-substrate-kagent-nextwork.
- Remove the local repository folder by running these commands:
cd ..
rm -rf agent-substrate-kagent-nextwork
What do these commands remove?
The first command moves the terminal to the folder above the repository.
The second command permanently removes the entire agent-substrate-kagent-nextwork folder.
- Check the parent folder in your file browser.
You should no longer see the agent-substrate-kagent-nextwork folder.
Repository folder still present?
- Confirm that the terminal started inside the agent-substrate-kagent-nextwork folder.
- Repeat the removal only after confirming the folder name.
Help me remove the repository safely.
Nice Work!
Nice Work!
Mission complete! Your local Kubernetes cluster now runs stateful agents through Agent Substrate, with several chats sharing the same workers.
You learned how to:
- Launched the platform with kagent and checked that its WorkerPool had ready workers using ./status.sh.
- Built ops-buddy as a read-only troubleshooting agent. Used it to find and fix the bad image tag that kept the Deployment from starting.
- Proved stateful scale-to-zero when an Actor saved its conversation in a snapshot. Replacing the workers did not erase the chat, and LAST WAKE-UP confirmed it ran again on new capacity.
- Secret Mission: Created five independent chats and watched them share workers. The SAVINGS TABLE compared total chats with busy workers.
Ready to quiz yourself?