Skip to main content

create-decision-pack-programmatically

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

설치로 이동

소스 정보

저장소
pymc-labs/decision-lab
최근 소스 활동
2026년 7월 20일 16:21
감지된 SKILL.md 언어
영어
스타
190
포크
14

설치 방법

기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.

소스 파일 검토

설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.

SKILL.md 표시 중

SKILL.md
소스 지침 · 읽기 전용 미리보기
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 ) ```
GitHub에서 보기