This is Part 2 of the Upsun Task Containers series. In Part 1 we used a lightweight cron to trigger a task container for a heavy database job. Now we keep the exact same trigger pattern — but the task launches an AI agent instead of a shell command.In Part 1, the task ran a deterministic command: reindex, import, export. That is the natural first step. But a task container is also the ideal home for something less deterministic and more interesting: a background AI agent that reads your project’s logs, reasons about them, and reports back. In this episode we build a small but real agent. On a schedule, a cron triggers a task container that runs OpenCode over your cron and application logs. The agent summarizes what happened, flags anomalies (slow crons, repeated errors, suspicious patterns), and writes a Markdown report — visible in the task logs and saved to a temporary file. No issues created, no pull requests opened yet: just a clean, automated reading of your logs. That groundwork unlocks the autonomous Auto-RCA agent we build in Part 3.
Task containers are currently in prerelease. To enable them on your project,
open this prepopulated support ticket
and add your project ID before submitting.
Prerequisites
Before starting, make sure you have:- Completed Part 1, or are comfortable with the cron-triggers-a-task pattern
- An Upsun account with task containers enabled
- The Upsun CLI installed
- An API key for at least one LLM provider (for example Anthropic, OpenAI, or Google Gemini)
- Familiarity with How to Host OpenCode on Upsun and, optionally, How to slash OpenCode Token costs by 90% on Upsun
The architecture
The flow is identical to Part 1 — a cron mints a token and triggers the task — except the task now runs a Node.js entry point that drives OpenCode: The agent stays deliberately simple. It does not need the Upsun API token, GitHub access, or write permissions on your repository — it only reads logs and produces text. We add those capabilities, step by step, in the next episodes.Step 1 - Define the agent task
The task runs anodejs image and pulls in the opencode-ai package as a dependency so the opencode binary is
available at runtime. The container profile is bumped because
LLM agents are memory-hungry.
.upsun/config.yaml
dependencies.nodejs.opencode-aiinstalls the OpenCode CLI into the task image at build time, soopencode runworks without a separate install step.hooks.buildadds the official Upsun OpenCode skills. They are optional for pure log reading, but they make the agent Upsun-aware and set the stage for Part 3.container_profile: "HIGH_MEMORY"gives the agent enough memory to run a model session comfortably.relationships.applets the agent reach the application over HTTP if you later want it to pull logs from an endpoint instead of the filesystem.
Step 2 - Provide the LLM API key
OpenCode needs a provider key to talk to a model. Set it as a sensitive environment-level variable so it is injected into the task container at run time but never committed:Terminal
Step 3 - Write the agent
The agent is a small Node.js script. It collects the relevant log files, builds a focused prompt, runs OpenCode non-interactively, and writes the resulting report both to the task logs (so it shows up in the activity feed) and to a temporary file.agent/analyze.js
Step 4 - Trigger the agent from a cron
This is unchanged from Part 1: a tiny cron mints a short-lived token from the container-local broker and POSTs to the task run endpoint. Reuse the same trigger script, pointed at the new task name:bin/trigger-loganalyzer.sh
.upsun/config.yaml
Step 5 - Deploy and read the report
Commit and push:Terminal
Terminal
Terminal
=== Log-analysis report === markers, and the path of the saved /tmp
copy is printed at the end.