@tianshu-ai/tianshu 0.43.2 → 0.43.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tianshu-ai/tianshu",
|
|
3
|
-
"version": "0.43.
|
|
3
|
+
"version": "0.43.3",
|
|
4
4
|
"description": "An open AI agent platform with a sidecar browser. Built in public.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"homepage": "https://github.com/tianshu-ai/tianshu",
|
|
@@ -32,6 +32,7 @@
|
|
|
32
32
|
"plugins/**/skills/**",
|
|
33
33
|
"plugins/**/agent-seeds/**",
|
|
34
34
|
"plugins/**/templates/**",
|
|
35
|
+
"plugins/**/sandbox-image/**",
|
|
35
36
|
"README.md",
|
|
36
37
|
"LICENSE"
|
|
37
38
|
],
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
# syntax=docker/dockerfile:1
|
|
2
|
+
#
|
|
3
|
+
# Tianshu OpenCode sandbox image.
|
|
4
|
+
#
|
|
5
|
+
# Extends the OpenShell community base (Ubuntu + Node 22 + uv/python +
|
|
6
|
+
# claude/gh/codex CLIs + the default sandbox policy) and PREINSTALLS,
|
|
7
|
+
# for the sandbox user, everything an OpenCode worker needs:
|
|
8
|
+
# - opencode-ai pinned to a version with the websearch tool +
|
|
9
|
+
# OPENCODE_ENABLE_PARALLEL flag (the base image ships an older
|
|
10
|
+
# opencode that lacks these), installed to a user-writable prefix
|
|
11
|
+
# so the sandbox user runs it without root/EACCES.
|
|
12
|
+
# - oh-my-openagent (omo) + its (large) dependency tree, warmed into
|
|
13
|
+
# opencode's plugin cache so a task run does NOT download ~500 MB
|
|
14
|
+
# of deps on every start.
|
|
15
|
+
#
|
|
16
|
+
# Why preinstall: the worker used to install these at task time, but
|
|
17
|
+
# omo pulls a huge dep tree over the deny-by-default egress (one host
|
|
18
|
+
# approved at a time), which is slow and repeats per isolated task.
|
|
19
|
+
# Baking it into the image = one build, instant startup, no per-task
|
|
20
|
+
# network install.
|
|
21
|
+
#
|
|
22
|
+
# Build (from this dir):
|
|
23
|
+
# docker build -t tianshu/opencode-sandbox:latest .
|
|
24
|
+
# Then point the openshell plugin at it:
|
|
25
|
+
# plugins.openshell.config.fromImage = "tianshu/opencode-sandbox:latest"
|
|
26
|
+
#
|
|
27
|
+
# The openshell runner passes this to `openshell sandbox create --from`.
|
|
28
|
+
|
|
29
|
+
ARG BASE_IMAGE=ghcr.io/nvidia/openshell-community/sandboxes/base:latest
|
|
30
|
+
FROM ${BASE_IMAGE}
|
|
31
|
+
|
|
32
|
+
# Versions pinned for reproducibility. Keep OPENCODE_VERSION in sync
|
|
33
|
+
# with OPENCODE_VERSION in plugins/workboard/src/worker/opencode-worker.ts.
|
|
34
|
+
ARG OPENCODE_VERSION=1.17.13
|
|
35
|
+
# Pin an EXACT omo version (never @latest). opencode re-resolves an
|
|
36
|
+
# unpinned plugin against npm on every startup, which stalls through
|
|
37
|
+
# the openshell egress proxy and hangs plugin-load; a pinned version
|
|
38
|
+
# warmed here matches what the worker requests (OMO_VERSION in
|
|
39
|
+
# opencode-worker.ts) so opencode uses the cached package and skips
|
|
40
|
+
# the npm resolve. Keep in sync with OMO_VERSION in the worker.
|
|
41
|
+
ARG OMO_PACKAGE=oh-my-openagent@4.15.1
|
|
42
|
+
|
|
43
|
+
USER root
|
|
44
|
+
# --- 0. System packages + dev tools --------------------------------
|
|
45
|
+
# P0: daily dev essentials
|
|
46
|
+
RUN apt-get update -qq && apt-get install -y --no-install-recommends \
|
|
47
|
+
jq tree wget zip unzip ripgrep fd-find fzf bat htop sqlite3 \
|
|
48
|
+
&& rm -rf /var/lib/apt/lists/*
|
|
49
|
+
|
|
50
|
+
# P1: audio/video + Remotion rendering
|
|
51
|
+
RUN apt-get update -qq && apt-get install -y --no-install-recommends \
|
|
52
|
+
ffmpeg sox \
|
|
53
|
+
chromium-browser \
|
|
54
|
+
libnss3 libatk1.0-0 libatk-bridge2.0-0 libcups2 libdrm2 \
|
|
55
|
+
libxkbcommon0 libxcomposite1 libxdamage1 libxrandr2 \
|
|
56
|
+
libgbm1 libasound2t64 libpangocairo-1.0-0 libgtk-3-0 \
|
|
57
|
+
fonts-noto-cjk fonts-noto-color-emoji fonts-liberation \
|
|
58
|
+
&& rm -rf /var/lib/apt/lists/*
|
|
59
|
+
|
|
60
|
+
# P1: document processing (PDF / OCR — no LibreOffice for now)
|
|
61
|
+
RUN apt-get update -qq && apt-get install -y --no-install-recommends \
|
|
62
|
+
pandoc wkhtmltopdf ghostscript poppler-utils \
|
|
63
|
+
tesseract-ocr tesseract-ocr-chi-sim tesseract-ocr-eng \
|
|
64
|
+
imagemagick libcairo2-dev libjpeg-dev libpango1.0-dev libgif-dev librsvg2-dev \
|
|
65
|
+
default-jre-headless \
|
|
66
|
+
&& rm -rf /var/lib/apt/lists/*
|
|
67
|
+
|
|
68
|
+
# Node global tools (P0 + P1)
|
|
69
|
+
RUN npm install -g \
|
|
70
|
+
tsx typescript \
|
|
71
|
+
eslint prettier \
|
|
72
|
+
@remotion/cli sharp puppeteer playwright \
|
|
73
|
+
pdf-lib exceljs docx pdfkit mammoth
|
|
74
|
+
|
|
75
|
+
# Playwright browsers (Chromium only, reuse system deps above)
|
|
76
|
+
RUN npx playwright install --with-deps chromium
|
|
77
|
+
|
|
78
|
+
# Python libraries (P0 + P1 + P2)
|
|
79
|
+
RUN pip install --no-cache-dir \
|
|
80
|
+
pyyaml python-dotenv jinja2 requests aiohttp beautifulsoup4 \
|
|
81
|
+
numpy scipy pandas polars matplotlib seaborn Pillow plotly \
|
|
82
|
+
pydub edge-tts gtts \
|
|
83
|
+
openpyxl xlsxwriter python-docx python-pptx \
|
|
84
|
+
pymupdf pdfplumber PyPDF2 reportlab weasyprint \
|
|
85
|
+
markdown camelot-py[cv] tabula-py \
|
|
86
|
+
httpie playwright
|
|
87
|
+
|
|
88
|
+
# yq (YAML processor) — binary install
|
|
89
|
+
RUN curl -sL "https://github.com/mikefarah/yq/releases/latest/download/yq_linux_$(dpkg --print-architecture)" \
|
|
90
|
+
-o /usr/local/bin/yq && chmod +x /usr/local/bin/yq
|
|
91
|
+
|
|
92
|
+
# --- 1. Upgrade opencode (root global) -----------------------------
|
|
93
|
+
# The base image preinstalls an older opencode at /usr/lib/node_modules.
|
|
94
|
+
# Overwrite it with our pinned version so `opencode` on PATH is the
|
|
95
|
+
# right one for every user (no per-task user-prefix install needed).
|
|
96
|
+
USER root
|
|
97
|
+
# strace: for debugging the opencode/omo plugin-load deadlock in the
|
|
98
|
+
# openshell gRPC-exec tunnel (lets us trace exactly which syscall the
|
|
99
|
+
# hung opencode.exe blocks on). Small, harmless to ship.
|
|
100
|
+
RUN apt-get update -qq && apt-get install -y -qq strace >/dev/null 2>&1 || true
|
|
101
|
+
RUN npm install -g opencode-ai@${OPENCODE_VERSION} \
|
|
102
|
+
&& opencode --version
|
|
103
|
+
|
|
104
|
+
# --- 2. Warm the omo plugin cache for the sandbox user -------------
|
|
105
|
+
# opencode auto-installs npm `plugin` entries via Bun into
|
|
106
|
+
# $XDG_CACHE_HOME/opencode/node_modules on first run. We pre-warm that
|
|
107
|
+
# cache as the `sandbox` user (HOME=/sandbox) by launching opencode
|
|
108
|
+
# once with an opencode.json that lists the plugin, so the heavy
|
|
109
|
+
# dependency download happens at build time, not per task.
|
|
110
|
+
#
|
|
111
|
+
# The warm run is offline-friendly: it only needs the npm/GitHub
|
|
112
|
+
# fetches for the plugin install; we give it a throwaway config with
|
|
113
|
+
# no provider so it installs the plugin then exits. A non-zero exit
|
|
114
|
+
# from the (provider-less) run is fine — we only care that the plugin
|
|
115
|
+
# + deps got cached.
|
|
116
|
+
USER sandbox
|
|
117
|
+
WORKDIR /sandbox
|
|
118
|
+
RUN mkdir -p /sandbox/.config/opencode /sandbox/.warmup/.opencode
|
|
119
|
+
# The warmup config lists the plugin AND ships an omo config that
|
|
120
|
+
# looks like a real task's, so the warm run triggers not just the
|
|
121
|
+
# plugin DEP install but also omo's one-time FIRST-INIT PROVISIONING
|
|
122
|
+
# (codegraph binary + ast-grep + ~/.omo state). That provisioning,
|
|
123
|
+
# if left to the first real task, stalls under the openshell gRPC
|
|
124
|
+
# exec tunnel (observed: omo hangs at first init in a fresh sandbox);
|
|
125
|
+
# doing it at build time bakes the provisioned ~/.omo + caches into
|
|
126
|
+
# the image so every runtime start is already "hot" and skips it.
|
|
127
|
+
RUN cat > /sandbox/.warmup/opencode.json <<'JSON'
|
|
128
|
+
{
|
|
129
|
+
"$schema": "https://opencode.ai/config.json",
|
|
130
|
+
"snapshot": false,
|
|
131
|
+
"autoupdate": false,
|
|
132
|
+
"plugin": ["oh-my-openagent@4.15.1"],
|
|
133
|
+
"permission": { "*": "allow" }
|
|
134
|
+
}
|
|
135
|
+
JSON
|
|
136
|
+
# NOTE: mirror the RUNTIME omo config here (esp. disabled_mcps:["lsp"])
|
|
137
|
+
# so the warm run does the SAME first-init as a real task — with the
|
|
138
|
+
# lsp-daemon MCP disabled. Otherwise the warm run leaves lsp-daemon
|
|
139
|
+
# state that differs from runtime and the first real task still pays
|
|
140
|
+
# (and hangs on) the cold first-init. Keep in sync with buildOmoConfig
|
|
141
|
+
# in plugins/workboard/src/worker/opencode-worker.ts.
|
|
142
|
+
RUN cat > /sandbox/.warmup/.opencode/oh-my-opencode.jsonc <<'JSON'
|
|
143
|
+
{
|
|
144
|
+
"agents": { "sisyphus": { "model": "warmup/none" } },
|
|
145
|
+
"model_fallback": false,
|
|
146
|
+
"runtime_fallback": false,
|
|
147
|
+
"telemetry": false,
|
|
148
|
+
"disabled_mcps": ["lsp"]
|
|
149
|
+
}
|
|
150
|
+
JSON
|
|
151
|
+
# Run opencode once with the omo config active. It installs the
|
|
152
|
+
# plugin deps AND kicks omo's first-init provisioning. No model is
|
|
153
|
+
# reachable, so it exits non-zero after provisioning — that's fine,
|
|
154
|
+
# we only want the cached deps + provisioned ~/.omo state.
|
|
155
|
+
RUN cd /sandbox/.warmup \
|
|
156
|
+
&& (OPENCODE_DISABLE_LSP_DOWNLOAD=1 OPENCODE_CONFIG=./opencode.json \
|
|
157
|
+
timeout 600 opencode run "noop" --format json < /dev/null \
|
|
158
|
+
> /sandbox/.warmup/warm.log 2>&1 || true) \
|
|
159
|
+
&& echo "opencode plugin cache warmed:" \
|
|
160
|
+
&& du -sh /sandbox/.cache/opencode 2>/dev/null || true \
|
|
161
|
+
&& echo "omo provisioned state:" \
|
|
162
|
+
&& du -sh /sandbox/.omo 2>/dev/null || true
|
|
163
|
+
|
|
164
|
+
# Drop the throwaway warmup workdir + config; KEEP the warmed caches
|
|
165
|
+
# (~/.cache/opencode) and omo's provisioned state (~/.omo). BUT also
|
|
166
|
+
# drop the codegraph LOCK dir the warm run left behind
|
|
167
|
+
# (~/.omo/codegraph/locks/codegraph-buildkitsandbox.lock, named after
|
|
168
|
+
# the build container): baking a stale lock into the image makes
|
|
169
|
+
# omo's codegraph init contend/wait on a lock from a process that no
|
|
170
|
+
# longer exists, which intermittently hangs the first task in a fresh
|
|
171
|
+
# sandbox. Keep the provisioned codegraph data, drop only the locks.
|
|
172
|
+
RUN rm -rf /sandbox/.warmup /sandbox/.config/opencode/opencode.json \
|
|
173
|
+
&& rm -rf /sandbox/.omo/codegraph/locks /sandbox/.omo/*/locks \
|
|
174
|
+
&& find /sandbox/.omo -name '*.lock' -exec rm -rf {} + 2>/dev/null || true
|
|
175
|
+
|
|
176
|
+
USER sandbox
|
|
177
|
+
ENTRYPOINT ["/bin/bash"]
|