DSH HUB
HomePlugin StorePlugin PacksCommunityRankingsResourcesPublish Guide
Plugin source
Back to catalog

JJTovo /

JJTovo/dsh-hunyuan-3d

Verified

Tencent Cloud Hunyuan 3D (ai3d / HunyuanTo3D) modeling tools for dsh: text-to-3D and image-to-3D job submission, result polling, and on-disk asset download so other tools can consume a real file path.

★ 0 Stars0 Forks0 IssuesN/A Community rating0 Confirmed installs
View on GitHub
READMESource: main@93850a4b

dsh-hunyuan-3d

CI

Tencent Cloud Hunyuan 3D (混元生3D, the ai3d OpenAPI) as dsh agent tools: text-to-3D and image-to-3D job submission, result polling, and on-disk asset download so later turns and other tools (Blender, format converters) can consume a real file path.

Tools

Tool Purpose
hunyuan_3d_model Submit a modeling job and, by default, wait for it and download the assets.
hunyuan_3d_query Re-check a job started with wait: false, or recover a result later.

Both return the same canonical result: job_id, mode, status (WAIT/RUN/FAIL/DONE), message, optional error_code / error_message / credits_consumed / credit_details, and files[] with the downloaded path, bytes, type, source_url and preview_image_url.

Result URLs expire 24 hours after generation, so a job that finished long ago must be re-run rather than re-downloaded.

Two API doors

Tencent publishes the same 3D service behind two front doors, and the plugin supports both — pick one in the settings card:

OpenAI-compatible (default) Native cloud API
Base URL https://api.ai3d.cloud.tencent.com https://ai3d.tencentcloudapi.com
Submit POST /v1/ai3d/submit POST / + X-TC-Action: SubmitHunyuanTo3DProJob
Query POST /v1/ai3d/query POST / + X-TC-Action: QueryHunyuanTo3DProJob
Auth Authorization: <api key> (console "API KEY" page) TC3-HMAC-SHA256 (SecretId/SecretKey/Region)
Credentials one key, HUNYUAN3D_API_KEY TENCENTCLOUD_SECRET_ID + TENCENTCLOUD_SECRET_KEY (+ optional token)
Modes pro only — the compatibility layer publishes no rapid endpoint pro and rapid

The API key is sent as the bare Authorization value, which is what the documentation's cURL example uses. A gateway that refuses that shape is retried once with Bearer , so OpenAI-style clients work unchanged.

The base URL may be pasted as the origin, …/v1, …/v1/ai3d, or the full …/v1/ai3d/submit: the API path is stripped rather than duplicated, because a doubled path is a routing failure the service answers with an unhelpful 4xx.

Failures report the service's own response body and status, so a rejected call is diagnosable from the settings card without a separate request log.

Both doors share the request/response vocabulary (Prompt, ImageUrl, MultiViewImages, FaceCount, Status, ResultFile3Ds, …), so tool arguments and results are identical whichever you choose. Responses are read tolerantly: a bare body and a Response-wrapped one both parse, and key casing is ignored.

In-app configuration

The plugin registers a settings card under Settings → Plugins → Configurable ("腾讯云混元生3D"). It edits the plugin's hunyuan-3d settings namespace and, for the credentials, writes through the host credential store.

Card control Where it lands
API Key (compatible) or SecretId / SecretKey / STS Token (native) dsh credential store (.credentials.yaml), write-only
provider, baseUrl, region, endpoint settings.yaml under hunyuan-3d
resultDir, pollIntervalMs, defaultWaitMs, httpTimeoutMs settings.yaml under hunyuan-3d

Two rules the card follows, matching dsh's shipped configuration cards:

  • A credential value never travels host → browser. The card learns only whether a reference is configured and whether it is writable; typing a value posts it one-way. An untouched field never clears a stored key.
  • Settings take effect immediately. The tools read the resolved section on every call, so a saved change applies to the next call without a restart.

The card talks to the host through a loopback-fenced bridge:

Route Purpose
GET/POST /api/dsh-hunyuan-3d/settings read the resolved section + credential status; save a patch
POST /api/dsh-hunyuan-3d/credentials { role, action: set | unset, value? }
POST /api/dsh-hunyuan-3d/test authenticate against the live endpoint without billing (compatible: POST /v1/ai3d/query on a job id that cannot exist; native: QueryHunyuanTo3DProJob on the same)

Non-loopback callers (foreign host, non-loopback peer address, cross-site fetch metadata) get 403; any other method gets 405.

Credentials

The card is the normal path; environment variables still work and win when both are set. The plugin resolves, in order:

  1. the dsh credential store (ctx.credentials.resolve), then
  2. the process environment.
Setting Default reference
SecretId TENCENTCLOUD_SECRET_ID
SecretKey TENCENTCLOUD_SECRET_KEY
STS token (optional) TENCENTCLOUD_TOKEN

The contributing account needs 混元生3D activated for the region you call; missing activation or an unauthorized action surfaces as an API error code, not a silent failure.

Requests are signed in-process with TC3-HMAC-SHA256 (src/tc3.js), so no Tencent Cloud SDK is shipped or required.

Concurrency

The service grants a fixed number of simultaneous jobs — three, per the product documentation — and answers anything beyond it with RequestLimitExceeded. The plugin therefore gates submissions locally instead of spending a round trip to learn what it already knows.

  • Up to maxConcurrency jobs hold a service slot. Further calls queue.
  • A slot is held for as long as the job occupies the service, not merely while a call is in flight. wait: false returns at once, and the job keeps its slot until a later hunyuan_3d_query observes DONE or FAIL.
  • A call whose wait budget expires keeps its slot too, for the same reason; the status message says so and names the query that frees it.
  • A full queue is refused with the retryable concurrency-queue-full; a queued call that waits past queueTimeoutMs fails with concurrency-wait-timeout and reports that nothing was submitted.
Setting Default Meaning
maxConcurrency 3 Simultaneous jobs. Lower it to 1 to serialize.
queueLimit 32 Calls allowed to wait in line before new ones are refused.
queueTimeoutMs 600000 How long a queued call waits before giving up.

All three are editable in the settings card, which also shows live usage (占用 1/3,排队 2). The limits are read per call, so a change applies to the next submission without a restart.

Abandoned jobs. A job started with wait: false and never queried would hold its slot indefinitely, which is the correct reading of "the service is still working on it" but worth knowing: query a background job, or let queueTimeoutMs bound the waiters behind it.

Verification

npm test                            # 26 tests, no network, no credits

Part 1 pins the wire format: the hand-written schemas must satisfy dsh's own schema compiler and assertSupportedJsonSchema, and the registered definitions must survive dsh's register() guard.

Part 2 drives the real plugin against tests/mock-ai3d.mjs — a local double that implements the verified envelope contract and rejects badly signed requests — covering submit, poll, download, background mode, rapid mode, local image inlining, cancellation, job failure, missing credentials and invalid arguments.

The browser half is verified without a browser: tests/client.test.mjs runs the real built lib/client.js against a loader double, renders the card with real React, and asserts the field set, the write-only credential inputs, and that React stays external.

The dsh checkout supplying the schema compiler defaults to E:/deepseek_harness/packages/core/tools/lib/index.js; override with DSH_TOOLS_LIB or those assertions skip.

Acceptance check without dsh

node tests/mock-ai3d.mjs --port 1731 --delay-ms 400 &
TENCENTCLOUD_SECRET_ID=AKIDmock TENCENTCLOUD_SECRET_KEY=SECRETmock \
DSH_HUNYUAN3D_ENDPOINT=127.0.0.1:1731 DSH_HUNYUAN3D_SCHEME=http \
DSH_HUNYUAN3D_POLL_MS=150 DSH_HUNYUAN3D_RESULT_DIR=/tmp/hy3d-out \
  node bin/model.mjs --prompt "一只低多边形风格的宝箱" --format GLB

Exit code 0 means the call completed and the returned value satisfied the same schema the model is shown. --dry-run prints the arguments and schema without calling anything; --query --job <JobId> exercises the recovery path.

Against a real account, drop the DSH_HUNYUAN3D_* overrides and use real credentials — that spends credits.

Installing into a dsh profile

From this repository:

git clone git@github.com:JJTovo/dsh-hunyuan-3d.git
# or, without an SSH key: https://github.com/JJTovo/dsh-hunyuan-3d.git

cd "$DSH_HOME/profiles/web"
pnpm add "github:JJTovo/dsh-hunyuan-3d"

A git dependency runs the package's prepare script, so lib/client.js is rebuilt from src/client/index.js at install time.

From a local checkout:

cd "$DSH_HOME/profiles/web"
pnpm add "file:/absolute/path/to/dsh-hunyuan-3d"

Then add the bundle (or the plugin row) to cordis.patch.yml:

- insert:
    - id: hunyuan-3d
      name: 'dsh-hunyuan-3d'
      config:
        region: ap-guangzhou

A file: dependency is copied at install time, so re-run pnpm add (or reinstall) after editing the plugin source. See cordis.patch.yml in this package for the same row written as a bundle patch.

Portability across machines

The plugin is vendored inside the profile and referenced by a relative path:

"dsh-hunyuan-3d": "file:./plugins/dsh-hunyuan-3d"

so pnpm-lock.yaml records directory: plugins/dsh-hunyuan-3d — a path that does not name a drive, a user, or an absolute location. Moving the harness home to another machine (or another drive on the same machine) keeps it valid.

Moving to a new machine

  1. Copy the whole harness home ($DSH_HOME, by default ~/.dsh) — it holds the profile, this plugin's source, settings.yaml and .credentials.yaml.

  2. In profiles/web, reinstall dependencies:

    cd "$DSH_HOME/profiles/web"
    pnpm install
    

    node_modules may be copied or rebuilt; either works. Deleting it first is the cleanest, because pnpm's store paths are machine-local.

  3. If you did not copy .credentials.yaml, re-enter the API key in Settings > Plugins > 腾讯云混元生3D.

No build step is required: lib/client.js (the browser half) is committed alongside the source, so the plugin runs as shipped. npm run build only regenerates it after editing src/client/.

What is machine-independent

Piece Portable?
src/, lib/, cordis.patch.yml yes — no absolute paths, no runtime dependencies
Profile dependency specifier yes — relative (file:./plugins/dsh-hunyuan-3d)
settings.yaml (provider, baseUrl) yes — non-secret, no paths
.credentials.yaml API key travels with $DSH_HOME; otherwise re-enter it
node_modules/ machine-local by nature; reinstall it
resultDir resolves from $DSH_HOME at runtime, never stored as an absolute path

Known machine-local exception

bin/validate-result.mjs and tests/hunyuan3d.test.mjs default their DSH_TOOLS_LIB to a developer checkout path (E:/deepseek_harness/packages/core/tools/lib/index.js). That is test-only: without it those two assertions skip and everything else still runs. Set DSH_TOOLS_LIB to point at your own checkout when you want the strict schema assertions.

When a restart is required

Editing src/ changes files on disk, but a running host keeps the module it already imported. dsh's patchReload: live re-reads patch files; it does not re-import a plugin's module. After changing plugin code:

cd "$DSH_HOME/profiles/web" && pnpm install   # re-materialize the vendored copy
# then restart dsh

Settings changes are different — the tools read the resolved section per call, so a saved setting applies to the next call with no restart.

Verifying a move

cd "$DSH_HOME/profiles/web/plugins/dsh-hunyuan-3d"
npm test                       # 27 tests, no network, no credits
dsh --profile web --no-open --port 0
# expect: zero "did not activate" warnings, and the settings card lists 腾讯云混元生3D

Boundaries

  • Billing. Every completed job consumes credits; a failed job reports error_code instead of retrying, so the caller decides.
  • No retry loops. Timeouts and network errors are marked retryable and reported; the plugin never re-submits on its own, because a retried submit can bill twice.
  • Concurrency. The service allows limited simultaneous jobs per account; RequestLimitExceeded surfaces as an API error.
  • Result expiry. Download happens within the same call that observes DONE, which keeps the plugin inside the 24-hour URL window.
  • Image inputs. prompt and an image are mutually exclusive unless generate_type: Sketch; pro mode additionally accepts multi_view_images.
  • Formats. result_format is a preference: the service may return OBJ plus GLB, or a data: URL, both handled on download.
—/ 5

No ratings yet

Verified DSH bundle

Commit 93850a4bf761

Community comments

No comments yet. Be the first to write one.

DSH HUB

A community index for DSH plugins. Not an official GitHub or DeepSeek AI product.

CommunityResourcesAPIAbout