Skip to main content

create-decision-pack-programmatically

How to create a dlab decision-pack directory using generate_dpack() from Python code

Ir para a instalação

Informações da origem

Repositório
pymc-labs/decision-lab
Última atividade na origem
20 de julho de 2026 às 16:21
Idioma detectado do SKILL.md
inglês
Estrelas
190
Forks
14

Opções de instalação

Por padrão, está selecionado o prompt que primeiro revisa a origem. Você pode mudar para um comando direto ou baixar uma cópia local.

Revise os arquivos de origem

Leia o SKILL.md e os arquivos complementares exibidos pelo SkillsMP antes de decidir se vai instalar.

Exibindo SKILL.md

SKILL.md
Instruções da origem · Visualização somente leitura
name
Create decision-pack Programmatically
description
How to create a dlab decision-pack directory using generate_dpack() from Python code
# Creating a decision-pack Programmatically Reference: `dlab/create_dpack.py` ## What Is a decision-pack 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 my_dpack_lib/ # (optional) Custom Python library (python_lib=True) tests/ # (required with a custom lib) pytest suite for the lib 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 ``` If the pack bundles a custom Python library (`python_lib=True`), it must also ship a pytest suite in `<pack>/tests/` covering the library's deterministic logic (loaders, numeric routines, invariants). `generate_dpack()` does not scaffold this yet — create it after generation. Reference layout: `decision-packs/mmm/tests/` (conftest, fixtures, pytest.ini). ## generate_dpack() ```python 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 ) ``` ## Config Keys Detail ### config.yaml Generated with these keys: - `name`, `description`, `docker_image_name`, `default_model`, `requires_data`, `requires_prompt` - `hooks` section: active `pre-run: deploy_modal.sh` when modal enabled, commented template otherwise ### Package Managers | 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. ### Agent .md Frontmatter (tools section) 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) | ### Permissions 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 (TypeScript) Custom tools in `opencode/tools/` **MUST** use `execute`, not `run`: ```typescript 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:** - **MUST use `execute`**, not `run` — OpenCode calls `def.execute(args, ctx)` internally. Using `run` causes `def.execute is not a function` at runtime. - **Use `Bun.$\`...\`` for CLI commands** — tools run inside OpenCode's Bun runtime. Use `.nothrow()` to handle non-zero exit codes gracefully. - **Always check `result.exitCode`** — return errors as strings so the agent can diagnose issues. ### Modal Integration When `modal_integration=True`, generates: - `docker/modal_app/__init__.py` + `example.py` with hash-based cache busting - `deploy_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 file - `MODAL_TOKEN_ID` + `MODAL_TOKEN_SECRET` in `.env.example` The 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. ### .env.example Auto-generated from the selected model's provider. Uses `get_provider_env_vars(model_id)` which checks: 1. Cached provider env vars from models.dev API 2. Fallback `KNOWN_PROVIDER_ENVS` dict (anthropic, openai, opencode, google, deepseek, etc.) ### Skills from Decision Hub 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/`. ## Creation Process 1. Validates decision-pack name (alphanumeric, hyphens, underscores) 2. Creates everything in a temp directory (`tempfile.TemporaryDirectory`) 3. On success: atomically moves to final location (with overwrite support) 4. On failure: temp dir is auto-cleaned ## Helper Functions ```python 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 ) ```
Ver no GitHub