mit einem Klick
create-decision-pack-programmatically
// How to create a dlab decision-pack directory using generate_dpack() from Python code
// How to create a dlab decision-pack directory using generate_dpack() from Python code
| name | Create decision-pack Programmatically |
| description | How to create a dlab decision-pack directory using generate_dpack() from Python code |
Reference: dlab/create_dpack.py
A decision-pack is a directory that defines everything needed to run an agent in a Docker container:
my-dpack/
config.yaml # Name, model, hooks
.env.example # Required API keys
.gitignore # Excludes .env
docker/
Dockerfile # Container setup
requirements.txt # Dependencies (or environment.yml / pixi.toml)
modal_app/ # (optional) Modal serverless compute
opencode/
opencode.json # Permissions and default agent
agents/
orchestrator.md # Main agent system prompt
example-worker.md # (optional) Subagent
tools/ # (optional) Custom TypeScript tools
skills/ # (optional) Knowledge files
parallel_agents/ # (optional) Parallel agent configs
from pathlib import Path
from dlab.create_dpack import generate_dpack
dpack_path = generate_dpack(
output_dir=Path("."),
config={
# Required
"name": "my-dpack",
# Optional (shown with defaults)
"description": "dlab decision-pack: my-dpack",
"docker_image_name": "dlab-my-dpack",
"default_model": "opencode/big-pickle",
"requires_data": True,
"requires_prompt": True,
"cli_name": "", # Override command name for install (default: name)
"package_manager": "pip", # pip | conda | uv | pixi
"base_image": "python:3.11-slim",
"agent_name": "orchestrator",
"agent_description": "Main orchestrator for my-dpack",
# Skeletons — which directories to scaffold
"skeletons": {
"skills": True, # opencode/skills/ with example
"tools": True, # opencode/tools/ with example-tool.ts
"subagents": True, # opencode/agents/example-worker.md
"parallel_agents": True, # opencode/parallel_agents/ + parallel tool
},
# Permissions — written to opencode.json
"permissions": {
"bash": "allow",
"edit": "allow",
"webfetch": "allow",
"websearch": "allow",
"external_directory": "allow",
"task": "allow",
"skill": "allow",
"codesearch": "allow",
"lsp": "deny",
"todoread": "allow",
"todowrite": "allow",
},
# Optional features
"python_lib": False,
"python_lib_name": "", # e.g. "my_dpack_lib"
"modal_integration": False,
"selected_skills": [], # List of {"org_slug": "...", "skill_name": "..."}
# Overwrite existing directory
"overwrite_existing": False,
},
on_progress=print, # Optional callback for progress messages
)
Generated with these keys:
name, description, docker_image_name, default_model, requires_data, requires_prompthooks section: active pre-run: deploy_modal.sh when modal enabled, commented template otherwise| Manager | Base Image | Env File | Notes |
|---|---|---|---|
pip | python:3.11-slim | requirements.txt | Simplest |
conda | continuumio/miniconda3:latest | environment.yml | Scientific Python |
uv | python:3.11-slim | requirements.txt | Fast pip replacement |
pixi | debian:bookworm-slim | pixi.toml | Modern conda-forge |
When modal_integration=True, modal is automatically added to the env file.
The tools section in orchestrator.md depends on skeleton selections:
| Skeletons | Tools Block |
|---|---|
parallel_agents=True (with or without subagents) | parallel-agents: true only |
subagents=True only | read: true, edit: true, bash: true, task: true |
| Neither | read: true (placeholder) |
Defined in CONFIGURABLE_PERMISSIONS (list of tuples). First 6 are high-impact:
webfetch, websearch, bash, edit, external_directory, task
Remaining are internal: skill, codesearch, lsp (default deny), todoread, todowrite
Hardcoded (always set): read, glob, grep, list = allow; question = deny
Custom tools in opencode/tools/ MUST use execute, not run:
import { tool } from "@opencode-ai/plugin"
export default tool({
description: "What this tool does",
args: {
input: tool.schema.string().describe("Input description"),
},
async execute(args) { // MUST be "execute", NOT "run"
// Use Bun shell for CLI commands (Python, bash, etc.)
const result = await Bun.$`python -c "print('hello')"`.nothrow()
const stdout = result.stdout.toString()
const stderr = result.stderr.toString()
if (result.exitCode !== 0) {
return `ERROR (exit code ${result.exitCode}):\n${stderr}`
}
return stdout.trim()
},
})
CRITICAL rules for custom tools:
execute, not run — OpenCode calls def.execute(args, ctx) internally. Using run causes def.execute is not a function at runtime.Bun.$\...`for CLI commands** — tools run inside OpenCode's Bun runtime. Use.nothrow()` to handle non-zero exit codes gracefully.result.exitCode — return errors as strings so the agent can diagnose issues.When modal_integration=True, generates:
docker/modal_app/__init__.py + example.py with hash-based cache bustingdeploy_modal.sh pre-run hook (respects DLAB_RUN_MODAL_TOOL_LOCALLY env var — skips deploy when set to 1)opencode/tools/run-on-modal.ts (if tools skeleton enabled) — uses modal.Function.from_name("{name}-compute", "run_compute")modal added to env fileMODAL_TOKEN_ID + MODAL_TOKEN_SECRET in .env.exampleThe generated deploy_modal.sh hook checks DLAB_RUN_MODAL_TOOL_LOCALLY (default: 1 = local). Set to 0 in the .env file to enable Modal cloud execution. The hook also checks for Modal tokens and skips deployment if they're missing. decision-packs can rename this variable to something domain-specific (e.g., the MMM dpack uses DLAB_FIT_MODEL_LOCALLY).
Note: All environment variables starting with DLAB_ are automatically forwarded from the host to the Docker container by the dlab CLI. decision-packs can define their own DLAB_* variables for configuration without any framework changes.
Auto-generated from the selected model's provider. Uses get_provider_env_vars(model_id) which checks:
KNOWN_PROVIDER_ENVS dict (anthropic, openai, opencode, google, deepseek, etc.)Pass selected_skills as a list of dicts with org_slug and skill_name. These are downloaded via the Decision Hub API and extracted into opencode/skills/.
tempfile.TemporaryDirectory)from dlab.create_dpack import (
validate_dpack_name, # Returns error string or None
filter_models, # Case-insensitive substring filter
get_model_list, # KNOWN_MODELS + cached API models
get_provider_env_vars, # Env vars needed for a model's provider
fetch_models_from_api, # Fetch from models.dev (network call)
ask_skills, # Natural-language skill search via Decision Hub
)
Complete reference for decision-lab (dlab). Use when the user asks about creating decision-packs, designing data science agents, running sessions, analyzing results, or anything related to dlab CLI, agent architecture, parallel subagents, or decision-pack configuration. Covers the full workflow from scaffolding to analysis.
Design agent system prompts, parallel architectures, and methodological guardrails for data science decision-packs. Use when creating orchestrator, subagent, or parallel agent systems for analytical workflows. Covers anti-fabrication rules, epistemic humility, when to stop, conflict detection, uncertainty reporting, retry protocols, prompt design principles, and the decision-lab runtime mechanics.
Guide a human through creating a dlab decision-pack by asking questions and then calling generate_dpack(). Use this skill whenever the user wants to create, set up, or scaffold a new decision-pack, agent environment, or Docker-sandboxed config for dlab — even if they don't use the word "decision-pack" explicitly. Trigger on phrases like "set up a new agent", "create an environment for X", "I want to run opencode for Y", "scaffold a project", or "make a new config".
Visual language and UX patterns for Textual TUI applications in dlab