tripo-cli 0.3.2 → 0.4.0
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/README.md +1 -1
- package/dist/ai/experts.js +2 -2
- package/dist/commands/completion.js +2 -1
- package/dist/commands/make.js +1 -1
- package/dist/commands/mcp.js +1 -1
- package/dist/commands/process-groups.js +19 -1
- package/dist/core/requests.js +8 -1
- package/dist/knowledge/chains.js +25 -3
- package/dist/knowledge/models.js +16 -3
- package/dist/knowledge/params.js +84 -8
- package/package.json +1 -1
- package/skill/SKILL.md +2 -2
- package/skill/commands/generate.md +80 -11
- package/skill/commands/make.md +1 -1
- package/skill/commands/process.md +68 -10
- package/skill/common-errors.md +21 -2
package/README.md
CHANGED
|
@@ -20,7 +20,7 @@ Works with both Tripo regions from the same install — international (`openapi.
|
|
|
20
20
|
## Why this CLI
|
|
21
21
|
|
|
22
22
|
- **One magic command.** `tripo make <anything>` detects what you gave it — prompt text, an image, 2–4 view images, a model file, a URL, a task id, or `@last` — picks the right endpoint, model, and parameters, then waits and downloads the artifacts. No file_token, no polling loops.
|
|
23
|
-
- **A 3D domain brain, not a thin API wrapper.** Model choice is a fixed rule (low-poly intent or face budget ≤ 20000 → `tripo-p1`, everything else → `tripo-v3.1`),
|
|
23
|
+
- **A 3D domain brain, not a thin API wrapper.** Model choice is a fixed rule (low-poly intent or face budget ≤ 20000 → `tripo-p1`, everything else → `tripo-v3.1`; opt into the P-series preview with `--model tripo-p2` for quad low-poly), P-series illegal parameters are stripped locally, quad + GLB is rejected before it costs you credits, and 7 scenario presets (`--for game-mobile|game-pc|film|print|ar-web|anim|toy`) encode sane parameters + processing chains + delivery formats.
|
|
24
24
|
- **Agent-native.** Non-TTY runs are automatically headless (`--json --yes --no-open`), stdout carries exactly one JSON line per command, progress goes to stderr, exit codes are stable, and NDJSON pipes compose: `tripo make cat.png | tripo model texture | tripo anim rig`. An LLM-facing skill package ships inside the npm package (`tripo docs --llm`).
|
|
25
25
|
|
|
26
26
|
## Commands
|
package/dist/ai/experts.js
CHANGED
|
@@ -7,12 +7,12 @@
|
|
|
7
7
|
* result is re-validated locally before anything is spent.
|
|
8
8
|
*/
|
|
9
9
|
import { getLocale, t, tList } from '../i18n.js';
|
|
10
|
-
import { parseThenExpression, validateChain
|
|
10
|
+
import { availableSteps, parseThenExpression, validateChain } from '../knowledge/chains.js';
|
|
11
11
|
import { chooseModel, detectLowPolyIntent, RIG_MODEL_V25 } from '../knowledge/models.js';
|
|
12
12
|
import { getScenario, SCENARIOS } from '../knowledge/scenarios.js';
|
|
13
13
|
import { chatJson } from './llm.js';
|
|
14
14
|
const SCENARIO_TABLE = SCENARIOS.map((s) => `- ${s.id}: ${s.description.en} | model=${s.model} | chain=${s.chain.map((c) => c.step).join('→') || 'none'} | deliver=${s.deliverables.join('/')}`).join('\n');
|
|
15
|
-
const STEP_TABLE =
|
|
15
|
+
const STEP_TABLE = availableSteps().map((s) => s.name).join(', ');
|
|
16
16
|
const PRODUCER_SYSTEM = `You are the producer/router of the Tripo 3D generation CLI.
|
|
17
17
|
Classify the user's request into exactly one scenario and extract a clean English 3D generation prompt.
|
|
18
18
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/** `tripo completion <shell>` — static shell completion scripts. */
|
|
2
2
|
import { UsageError } from '../core/errors.js';
|
|
3
|
+
import { isMeshEditEnabled } from '../knowledge/chains.js';
|
|
3
4
|
const COMMANDS = [
|
|
4
5
|
'login', 'logout', 'whoami', 'use', 'balance', 'usage', 'topup',
|
|
5
6
|
'make', 'view', 'redo', 'ai',
|
|
@@ -10,7 +11,7 @@ const SUBS = {
|
|
|
10
11
|
generate: ['text-to-model', 'image-to-model', 'multiview-to-model', 'text-to-image', 'image-to-image', 'image-to-multiview', 'edit-multiview', 'image-to-splat'],
|
|
11
12
|
model: ['refine', 'texture', 'stylize', 'convert', 'import'],
|
|
12
13
|
anim: ['check', 'rig', 'retarget'],
|
|
13
|
-
mesh: ['segment', 'complete', 'decimate', 'smartsegment'],
|
|
14
|
+
mesh: ['segment', 'complete', 'decimate', ...(isMeshEditEnabled() ? ['edit'] : []), 'smartsegment'],
|
|
14
15
|
task: ['get', 'list', 'watch'],
|
|
15
16
|
files: ['upload'],
|
|
16
17
|
batch: ['run'],
|
package/dist/commands/make.js
CHANGED
|
@@ -18,7 +18,7 @@ export function registerMakeCommand(program) {
|
|
|
18
18
|
.argument('<input...>', 'prompt text, image file(s), model file, URL, task id, or @last')
|
|
19
19
|
.option('--for <scenario>', `scenario preset: ${scenarioIds().join('|')}`)
|
|
20
20
|
.option('--then <steps>', 'processing chain, e.g. "texture,rig,convert:fbx"')
|
|
21
|
-
.option('--model <model>', 'force model version (tripo-v3.1 / tripo-p1 / ...)')
|
|
21
|
+
.option('--model <model>', 'force model version (tripo-v3.1 / tripo-p1 / tripo-p2 / ...)')
|
|
22
22
|
.option('-n, --candidates <n>', 'generate N candidates in parallel', (v) => Number(v), 1)
|
|
23
23
|
.option('--seed <n>', 'model_seed for reproducible geometry', (v) => Number(v));
|
|
24
24
|
withTaskOptions(cmd);
|
package/dist/commands/mcp.js
CHANGED
|
@@ -26,7 +26,7 @@ const TOOLS = [
|
|
|
26
26
|
input: { type: 'string', description: 'prompt text, image file path, image URL, or task id' },
|
|
27
27
|
scenario: { type: 'string', enum: scenarioIds(), description: 'production scenario preset' },
|
|
28
28
|
then: { type: 'string', description: 'processing chain, e.g. "texture,rig,convert:fbx"' },
|
|
29
|
-
model: { type: 'string', description: 'force model: tripo-v3.1 or tripo-
|
|
29
|
+
model: { type: 'string', description: 'force model: tripo-v3.1, tripo-p1 or tripo-p2 (P-series preview with quad)' },
|
|
30
30
|
output_dir: { type: 'string', description: 'directory for artifacts' },
|
|
31
31
|
},
|
|
32
32
|
required: ['input'],
|
|
@@ -9,7 +9,7 @@ import { log, warn } from '../core/output.js';
|
|
|
9
9
|
import { buildStepRequest } from '../core/requests.js';
|
|
10
10
|
import { resolveInputValue, runTask } from '../core/task-service.js';
|
|
11
11
|
import { t } from '../i18n.js';
|
|
12
|
-
import { getStep } from '../knowledge/chains.js';
|
|
12
|
+
import { getStep, isMeshEditEnabled } from '../knowledge/chains.js';
|
|
13
13
|
import { readPipedTask } from '../pipeline/stdin.js';
|
|
14
14
|
import { newClient, printTaskResult, withTaskOptions } from './shared.js';
|
|
15
15
|
async function resolveStepInput(client, raw) {
|
|
@@ -84,6 +84,8 @@ function collectStepArgs(step, flags) {
|
|
|
84
84
|
return pick(['completion_mode']);
|
|
85
85
|
case 'smartsegment':
|
|
86
86
|
return pick(['seg_type', 'granularity', 'hint']);
|
|
87
|
+
case 'edit':
|
|
88
|
+
return pick(['bbox', 'face_limit', 'ref_image', 'model']);
|
|
87
89
|
default:
|
|
88
90
|
return {};
|
|
89
91
|
}
|
|
@@ -157,6 +159,22 @@ export function registerProcessCommands(program) {
|
|
|
157
159
|
.option('--face-limit <n>', 'target faces 500–20000 tri / 500–10000 quad', (v) => Number(v))
|
|
158
160
|
.option('--quad', 'quad output')
|
|
159
161
|
.option('--no-bake', 'skip baking textures onto the low-poly')).action(makeStepAction('decimate'));
|
|
162
|
+
// Hidden until /v3/mesh/edit is live server-side (see isMeshEditEnabled).
|
|
163
|
+
if (isMeshEditEnabled()) {
|
|
164
|
+
withTaskOptions(mesh
|
|
165
|
+
.command('edit [input]')
|
|
166
|
+
.description('local retry/refine inside a bounding box (P2 pipeline, model P2-20260801)')
|
|
167
|
+
.option('--bbox <x1,y1,z1,x2,y2,z2>', 'required 2×3 axis-aligned bbox in model space')
|
|
168
|
+
.option('--face-limit <n>', 'output face limit (≥100)', (v) => Number(v))
|
|
169
|
+
.option('--ref-image <file-or-url>', 'reference image for semantic guidance')
|
|
170
|
+
.option('--model <v>', 'P2-20260801 (only supported value)')).action(async (input, flags) => {
|
|
171
|
+
// --ref-image may be a local file: upload it to a file_token first.
|
|
172
|
+
if (typeof flags.refImage === 'string') {
|
|
173
|
+
flags.refImage = (await resolveInputValue(newClient(), flags.refImage)).value;
|
|
174
|
+
}
|
|
175
|
+
await makeStepAction('edit')(input, flags);
|
|
176
|
+
});
|
|
177
|
+
}
|
|
160
178
|
withTaskOptions(mesh
|
|
161
179
|
.command('smartsegment [input]')
|
|
162
180
|
.description('smart segmentation (image or model pipeline)')
|
package/dist/core/requests.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* `parameters`), so new API options work without a CLI release.
|
|
6
6
|
*/
|
|
7
7
|
import { getStep } from '../knowledge/chains.js';
|
|
8
|
-
import { validateConvertParams, validateDecimateParams, validateGenerationParams, validateRetargetParams, } from '../knowledge/params.js';
|
|
8
|
+
import { validateConvertParams, validateDecimateParams, validateGenerationParams, validateMeshEditParams, validateRetargetParams, } from '../knowledge/params.js';
|
|
9
9
|
import { CAPABILITY_DEFAULTS, SEGMENT_MODELS, TEXTURE_MODELS, normalizeModel, normalizeRigModel, } from '../knowledge/models.js';
|
|
10
10
|
import { UsageError } from './errors.js';
|
|
11
11
|
function ensure(result) {
|
|
@@ -135,6 +135,13 @@ export function buildStepRequest(stepName, input, args) {
|
|
|
135
135
|
warnings.push(...v.warnings);
|
|
136
136
|
break;
|
|
137
137
|
}
|
|
138
|
+
case 'edit': {
|
|
139
|
+
const v = validateMeshEditParams(params);
|
|
140
|
+
ensure(v);
|
|
141
|
+
params = v.params;
|
|
142
|
+
warnings.push(...v.warnings);
|
|
143
|
+
break;
|
|
144
|
+
}
|
|
138
145
|
case 'rig': {
|
|
139
146
|
// Marketing names (rig-v1.0/rig-v2.0) are rejected by the server; normalize to wire versions.
|
|
140
147
|
params.model = params.model === undefined
|
package/dist/knowledge/chains.js
CHANGED
|
@@ -16,6 +16,7 @@ export const MODEL_PRODUCING_TYPES = new Set([
|
|
|
16
16
|
'highpoly_to_lowpoly',
|
|
17
17
|
'mesh_segmentation',
|
|
18
18
|
'mesh_completion',
|
|
19
|
+
'mesh_edit',
|
|
19
20
|
'animate_rig',
|
|
20
21
|
'animate_retarget',
|
|
21
22
|
]);
|
|
@@ -31,6 +32,8 @@ export const STEPS = [
|
|
|
31
32
|
{ name: 'segment', endpoint: '/v3/mesh/segment', produces: 'mesh_segmentation', accepts: 'any-model', acceptsFile: true },
|
|
32
33
|
{ name: 'complete', endpoint: '/v3/mesh/complete', produces: 'mesh_completion', accepts: ['mesh_segmentation'], acceptsFile: false },
|
|
33
34
|
{ name: 'decimate', endpoint: '/v3/mesh/decimate', produces: 'highpoly_to_lowpoly', accepts: 'any-model', acceptsFile: true, aliases: ['lowpoly'] },
|
|
35
|
+
// mesh/edit: local retry/refine inside a bbox, P2 pipeline (model fixed to P2-20260801).
|
|
36
|
+
{ name: 'edit', endpoint: '/v3/mesh/edit', produces: 'mesh_edit', accepts: 'any-model', acceptsFile: true },
|
|
34
37
|
// smartsegment's `input` is file_token/URL only (the server does not resolve
|
|
35
38
|
// task ids here), so it cannot chain after a task. Type is refined to
|
|
36
39
|
// smartsegment_image|smartsegment_model at request-build time per seg_type.
|
|
@@ -42,8 +45,25 @@ for (const s of STEPS) {
|
|
|
42
45
|
for (const a of s.aliases ?? [])
|
|
43
46
|
stepIndex.set(a, s);
|
|
44
47
|
}
|
|
48
|
+
/**
|
|
49
|
+
* `/v3/mesh/edit` is documented but not yet deployed (cn returns 4001). The
|
|
50
|
+
* step stays hidden until the backend ships; set TRIPO_EXPERIMENTAL_MESH_EDIT=1
|
|
51
|
+
* to opt in early. Flip this default once the endpoint is live.
|
|
52
|
+
*/
|
|
53
|
+
export function isMeshEditEnabled() {
|
|
54
|
+
return process.env.TRIPO_EXPERIMENTAL_MESH_EDIT === '1';
|
|
55
|
+
}
|
|
56
|
+
const EXPERIMENTAL_STEPS = new Set(['edit']);
|
|
57
|
+
function isStepAvailable(def) {
|
|
58
|
+
return !EXPERIMENTAL_STEPS.has(def.name) || isMeshEditEnabled();
|
|
59
|
+
}
|
|
60
|
+
/** Steps usable right now (experimental ones only when opted in). */
|
|
61
|
+
export function availableSteps() {
|
|
62
|
+
return STEPS.filter(isStepAvailable);
|
|
63
|
+
}
|
|
45
64
|
export function getStep(name) {
|
|
46
|
-
|
|
65
|
+
const def = stepIndex.get(name);
|
|
66
|
+
return def && isStepAvailable(def) ? def : undefined;
|
|
47
67
|
}
|
|
48
68
|
/**
|
|
49
69
|
* Parse a --then expression: "texture,rig,convert:fbx" or
|
|
@@ -68,7 +88,7 @@ export function parseThenExpression(expr) {
|
|
|
68
88
|
applyArg(prev.args, part);
|
|
69
89
|
continue;
|
|
70
90
|
}
|
|
71
|
-
throw new ChainError(`unknown step "${stepName}" (valid: ${
|
|
91
|
+
throw new ChainError(`unknown step "${stepName}" (valid: ${availableSteps().map((s) => s.name).join(', ')})`);
|
|
72
92
|
}
|
|
73
93
|
const args = {};
|
|
74
94
|
const argStr = rest.join(':').trim();
|
|
@@ -100,11 +120,13 @@ function applyPrimaryArg(step, args, value) {
|
|
|
100
120
|
rig: 'rig_type',
|
|
101
121
|
segment: 'model',
|
|
102
122
|
smartsegment: 'granularity',
|
|
123
|
+
// bbox as "x1/y1/z1/x2/y2/z2" (slashes: commas already separate --then tokens)
|
|
124
|
+
edit: 'bbox',
|
|
103
125
|
};
|
|
104
126
|
const key = primary[step];
|
|
105
127
|
if (!key)
|
|
106
128
|
throw new ChainError(`step "${step}" does not take a bare argument ("${value}")`);
|
|
107
|
-
args[key] = coerce(value);
|
|
129
|
+
args[key] = key === 'bbox' ? value : coerce(value);
|
|
108
130
|
}
|
|
109
131
|
function coerce(raw) {
|
|
110
132
|
if (raw === 'true')
|
package/dist/knowledge/models.js
CHANGED
|
@@ -7,12 +7,14 @@
|
|
|
7
7
|
*/
|
|
8
8
|
/**
|
|
9
9
|
* Wire values are what the server actually accepts (backend whitelist:
|
|
10
|
-
* v3.1-20260211, v3.0-20250812, v2.5-20250123, P1-20260311).
|
|
11
|
-
* `tripo-*` names from marketing docs are CLI-side aliases only —
|
|
12
|
-
* them raw returns 400 "invalid model".
|
|
10
|
+
* v3.1-20260211, v3.0-20250812, v2.5-20250123, P1-20260311, P2-20260801).
|
|
11
|
+
* The friendly `tripo-*` names from marketing docs are CLI-side aliases only —
|
|
12
|
+
* sending them raw returns 400 "invalid model".
|
|
13
13
|
*/
|
|
14
14
|
export const MODEL_V31 = 'v3.1-20260211';
|
|
15
15
|
export const MODEL_P1 = 'P1-20260311';
|
|
16
|
+
/** P-series upgrade (Preview): adds quad output; explicit --model only, never auto-selected. */
|
|
17
|
+
export const MODEL_P2 = 'P2-20260801';
|
|
16
18
|
/** User-facing aliases normalized to the wire values above. */
|
|
17
19
|
export const MODEL_ALIASES = {
|
|
18
20
|
'v3.1': MODEL_V31,
|
|
@@ -22,6 +24,10 @@ export const MODEL_ALIASES = {
|
|
|
22
24
|
P1: MODEL_P1,
|
|
23
25
|
'P1-20260311': MODEL_P1,
|
|
24
26
|
'tripo-p1': MODEL_P1,
|
|
27
|
+
p2: MODEL_P2,
|
|
28
|
+
P2: MODEL_P2,
|
|
29
|
+
'P2-20260801': MODEL_P2,
|
|
30
|
+
'tripo-p2': MODEL_P2,
|
|
25
31
|
// Older whitelisted versions, alias → wire.
|
|
26
32
|
'v3.0': 'v3.0-20250812',
|
|
27
33
|
'tripo-v3.0': 'v3.0-20250812',
|
|
@@ -39,6 +45,10 @@ export const P1_FORBIDDEN_PARAMS = [
|
|
|
39
45
|
'generate_parts',
|
|
40
46
|
'geometry_quality',
|
|
41
47
|
];
|
|
48
|
+
/** P2 face_limit windows (official docs): 48–50000 triangles, 48–25000 with quad=true. */
|
|
49
|
+
export const P2_FACE_LIMIT = { min: 48, triMax: 50000, quadMax: 25000 };
|
|
50
|
+
/** Parameters the server rejects for P2 (quad is allowed, unlike P1). */
|
|
51
|
+
export const P2_FORBIDDEN_PARAMS = ['smart_low_poly', 'generate_parts', 'geometry_quality'];
|
|
42
52
|
/** Rig wire versions (backend whitelist; marketing names rig-v1.0/rig-v2.0 are rejected). */
|
|
43
53
|
export const RIG_MODEL_V1 = 'v1.0-20240301';
|
|
44
54
|
export const RIG_MODEL_V25 = 'v2.5-20260210';
|
|
@@ -138,6 +148,9 @@ export function normalizeModel(input) {
|
|
|
138
148
|
export function isP1(model) {
|
|
139
149
|
return normalizeModel(model) === MODEL_P1;
|
|
140
150
|
}
|
|
151
|
+
export function isP2(model) {
|
|
152
|
+
return normalizeModel(model) === MODEL_P2;
|
|
153
|
+
}
|
|
141
154
|
/** The one rule. Returns the model plus a human-readable reason. */
|
|
142
155
|
export function chooseModel(intent) {
|
|
143
156
|
if (intent.explicit) {
|
package/dist/knowledge/params.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* Every rule here prevents a guaranteed 400 or a silently wasted credit.
|
|
6
6
|
* Rules marked [hard] mirror server enforcement; [soft] are CLI smart defaults.
|
|
7
7
|
*/
|
|
8
|
-
import { CONVERT_FORMATS, EXPORT_ORIENTATIONS, FBX_PRESETS, P1_FACE_LIMIT, P1_FORBIDDEN_PARAMS, TEXTURE_FORMATS, TEXTURE_QUALITIES, isP1, } from './models.js';
|
|
8
|
+
import { CONVERT_FORMATS, EXPORT_ORIENTATIONS, FBX_PRESETS, MODEL_P2, P1_FACE_LIMIT, P1_FORBIDDEN_PARAMS, P2_FACE_LIMIT, P2_FORBIDDEN_PARAMS, TEXTURE_FORMATS, TEXTURE_QUALITIES, isP1, isP2, normalizeModel, } from './models.js';
|
|
9
9
|
const PROMPT_MAX = 1024;
|
|
10
10
|
const NEGATIVE_PROMPT_MAX = 255;
|
|
11
11
|
/** Validate + auto-fix parameters for 3D generation (text/image/multiview-to-model). */
|
|
@@ -19,6 +19,26 @@ export function validateGenerationParams(model, input) {
|
|
|
19
19
|
if (typeof params.negative_prompt === 'string' && params.negative_prompt.length > NEGATIVE_PROMPT_MAX) {
|
|
20
20
|
errors.push(`negative_prompt exceeds ${NEGATIVE_PROMPT_MAX} characters`);
|
|
21
21
|
}
|
|
22
|
+
// [hard] P-series unsupported params are stripped first, so an unsupported
|
|
23
|
+
// generate_parts cannot cascade into disabling texture/pbr/quad below.
|
|
24
|
+
if (isP1(model)) {
|
|
25
|
+
for (const key of P1_FORBIDDEN_PARAMS) {
|
|
26
|
+
if (params[key] !== undefined) {
|
|
27
|
+
delete params[key];
|
|
28
|
+
warnings.push(key === 'quad'
|
|
29
|
+
? 'P1 does not support quad (removed); need a quad low-poly? use --model tripo-p2'
|
|
30
|
+
: `P1 does not support ${key} (removed)`);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
else if (isP2(model)) {
|
|
35
|
+
for (const key of P2_FORBIDDEN_PARAMS) {
|
|
36
|
+
if (params[key] !== undefined) {
|
|
37
|
+
delete params[key];
|
|
38
|
+
warnings.push(`P2 does not support ${key} (removed)`);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
22
42
|
// [hard] pbr=true forces texture=true (PBR is a superset of texturing).
|
|
23
43
|
if (params.pbr === true && params.texture === false) {
|
|
24
44
|
params.texture = true;
|
|
@@ -33,14 +53,8 @@ export function validateGenerationParams(model, input) {
|
|
|
33
53
|
}
|
|
34
54
|
}
|
|
35
55
|
}
|
|
36
|
-
// [hard] P1
|
|
56
|
+
// [hard] P1 face_limit range.
|
|
37
57
|
if (isP1(model)) {
|
|
38
|
-
for (const key of P1_FORBIDDEN_PARAMS) {
|
|
39
|
-
if (params[key] !== undefined) {
|
|
40
|
-
delete params[key];
|
|
41
|
-
warnings.push(`P1 does not support ${key} (removed)`);
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
58
|
const face = params.face_limit;
|
|
45
59
|
if (typeof face === 'number') {
|
|
46
60
|
if (face < P1_FACE_LIMIT.min || face > P1_FACE_LIMIT.max) {
|
|
@@ -49,6 +63,18 @@ export function validateGenerationParams(model, input) {
|
|
|
49
63
|
}
|
|
50
64
|
}
|
|
51
65
|
}
|
|
66
|
+
else if (isP2(model)) {
|
|
67
|
+
// [hard] P2 face_limit range: quad halves the budget.
|
|
68
|
+
const face = params.face_limit;
|
|
69
|
+
if (typeof face === 'number') {
|
|
70
|
+
const quad = params.quad === true;
|
|
71
|
+
const max = quad ? P2_FACE_LIMIT.quadMax : P2_FACE_LIMIT.triMax;
|
|
72
|
+
if (face < P2_FACE_LIMIT.min || face > max) {
|
|
73
|
+
errors.push(`P2 face_limit must be within ${P2_FACE_LIMIT.min}–${max}${quad ? ' with quad=true' : ''} (got ${face}); ` +
|
|
74
|
+
`use tripo-v3.1 for higher budgets`);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
52
78
|
else {
|
|
53
79
|
// [hard] smart_low_poly face_limit windows: 500–20000 tri / 500–10000 quad.
|
|
54
80
|
if (params.smart_low_poly === true && typeof params.face_limit === 'number') {
|
|
@@ -201,3 +227,53 @@ export function validateRetargetParams(input) {
|
|
|
201
227
|
}
|
|
202
228
|
return { params, warnings, errors };
|
|
203
229
|
}
|
|
230
|
+
const MESH_EDIT_FACE_MIN = 100;
|
|
231
|
+
/**
|
|
232
|
+
* Normalize a bbox given as [[x,y,z],[x,y,z]], a flat 6-number array, or a
|
|
233
|
+
* string "x1/y1/z1/x2/y2/z2" (also comma-separated) into the 2×3 wire shape.
|
|
234
|
+
* Returns undefined when the input is not 6 finite numbers.
|
|
235
|
+
*/
|
|
236
|
+
function normalizeBbox(raw) {
|
|
237
|
+
let flat;
|
|
238
|
+
if (typeof raw === 'string') {
|
|
239
|
+
flat = raw.split(/[/,;\s]+/).filter(Boolean).map(Number);
|
|
240
|
+
}
|
|
241
|
+
else if (Array.isArray(raw)) {
|
|
242
|
+
flat = raw.flat();
|
|
243
|
+
}
|
|
244
|
+
else {
|
|
245
|
+
return undefined;
|
|
246
|
+
}
|
|
247
|
+
if (flat.length !== 6 || !flat.every((n) => typeof n === 'number' && Number.isFinite(n)))
|
|
248
|
+
return undefined;
|
|
249
|
+
const nums = flat;
|
|
250
|
+
return [nums.slice(0, 3), nums.slice(3, 6)];
|
|
251
|
+
}
|
|
252
|
+
/** Validate parameters for mesh/edit (P2 pipeline): model fixed to P2, bbox required (2×3), face_limit ≥ 100. */
|
|
253
|
+
export function validateMeshEditParams(input) {
|
|
254
|
+
const params = { ...input };
|
|
255
|
+
const warnings = [];
|
|
256
|
+
const errors = [];
|
|
257
|
+
const model = params.model === undefined ? MODEL_P2 : normalizeModel(String(params.model));
|
|
258
|
+
if (model !== MODEL_P2) {
|
|
259
|
+
errors.push(`mesh edit only supports model ${MODEL_P2} (got "${String(params.model)}")`);
|
|
260
|
+
}
|
|
261
|
+
params.model = model;
|
|
262
|
+
if (params.bbox === undefined) {
|
|
263
|
+
errors.push('mesh edit requires bbox (x1/y1/z1/x2/y2/z2 or [[x1,y1,z1],[x2,y2,z2]])');
|
|
264
|
+
}
|
|
265
|
+
else {
|
|
266
|
+
const bbox = normalizeBbox(params.bbox);
|
|
267
|
+
if (!bbox)
|
|
268
|
+
errors.push('bbox must be 6 finite numbers: x1/y1/z1/x2/y2/z2');
|
|
269
|
+
else
|
|
270
|
+
params.bbox = bbox;
|
|
271
|
+
}
|
|
272
|
+
if (params.face_limit !== undefined) {
|
|
273
|
+
const face = params.face_limit;
|
|
274
|
+
if (typeof face !== 'number' || face < MESH_EDIT_FACE_MIN) {
|
|
275
|
+
errors.push(`mesh edit face_limit must be an integer ≥ ${MESH_EDIT_FACE_MIN} (got ${String(face)})`);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
return { params, warnings, errors };
|
|
279
|
+
}
|
package/package.json
CHANGED
package/skill/SKILL.md
CHANGED
|
@@ -35,8 +35,8 @@ Regions (ov = international, cn = China mainland) share one CLI: `tripo login --
|
|
|
35
35
|
3. **Artifacts are local files.** The result JSON has `output_dir`, `model_file`, `preview`. Look at `preview.png` to judge quality; re-roll with `tripo redo` if needed.
|
|
36
36
|
4. **Exit codes are stable** — branch on them:
|
|
37
37
|
- 0 success · 2 usage/params · 3 auth · 4 insufficient credits (tell the human to run `tripo topup`) · 5 content policy · 6 task failed (credits auto-refunded) · 7 network · 8 not found · 9 rate limit (retry with backoff)
|
|
38
|
-
5. **Never invent parameters.** Unknown `--param key=value` pairs pass through to the API; stick to documented ones (
|
|
39
|
-
6. **Don't pick legacy model versions.** The CLI auto-selects `tripo-v3.1` (high fidelity) or `tripo-p1` (low-poly, face budget ≤ 20000). Only override `--model` when the human asks.
|
|
38
|
+
5. **Never invent parameters.** Unknown `--param key=value` pairs pass through to the API; stick to documented ones. The full parameter/model/preset reference from the official API docs is bundled: `tripo docs --topic commands/generate` (3D + image generation) and `tripo docs --topic commands/process` (texture/convert/rig/retarget/mesh) — read those instead of browsing the website.
|
|
39
|
+
6. **Don't pick legacy model versions.** The CLI auto-selects `tripo-v3.1` (high fidelity) or `tripo-p1` (low-poly, face budget ≤ 20000). Only override `--model` when the human asks (e.g. `--model tripo-p2` for the P-series preview with quad support, or `tripo-v3.0` / `tripo-v2.5` for reproducing old projects).
|
|
40
40
|
|
|
41
41
|
## The one command you usually need
|
|
42
42
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# tripo generate — deterministic endpoint access
|
|
2
2
|
|
|
3
3
|
Use `tripo make` unless you need exact endpoint control. All subcommands accept the shared task options (`--json --yes -o --no-wait --no-download --timeout --name -p key=value`).
|
|
4
|
+
Everything below is the full parameter reference from the official API docs — you should not need to consult the website.
|
|
4
5
|
|
|
5
6
|
## 3D
|
|
6
7
|
|
|
@@ -10,14 +11,59 @@ tripo generate image-to-model photo.png [-p texture_alignment=original_image] [-
|
|
|
10
11
|
tripo generate multiview-to-model front.png back.png [left.png right.png]
|
|
11
12
|
```
|
|
12
13
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
-
|
|
18
|
-
-
|
|
19
|
-
- `
|
|
20
|
-
-
|
|
14
|
+
### 3D models (`--model`)
|
|
15
|
+
|
|
16
|
+
| alias | wire value sent | positioning | notes |
|
|
17
|
+
| --- | --- | --- | --- |
|
|
18
|
+
| `tripo-v3.1` (default) | `v3.1-20260211` | latest high-precision; AAA / 3D printing | full feature set |
|
|
19
|
+
| `tripo-p1` | `P1-20260311` | best low-poly; games / UGC / mobile | face_limit 48–20000 (CLI enforces ≥50); **no** `quad` `smart_low_poly` `generate_parts` `geometry_quality`; ~2s mesh; extra `export_uv` |
|
|
20
|
+
| `tripo-p2` | `P2-20260801` | P1 upgrade (P series, Preview) | adds `quad` (forces FBX); face_limit 48–50000 tri / 48–25000 quad (validated locally); still **no** `smart_low_poly` `generate_parts` `geometry_quality` (stripped with a warning); credits 100 (no texture) / 110 / 120 / 130 for standard / detailed / extreme. Explicit `--model` only — the CLI never auto-selects it |
|
|
21
|
+
| `tripo-v3.0` / `tripo-v2.5` | `v3.0-20250812` / `v2.5-20250123` | legacy | only when the human asks |
|
|
22
|
+
|
|
23
|
+
`tripo-turbo` / `tripo-v2.0` appear in some docs but are **not** on the v3 server whitelist (400).
|
|
24
|
+
|
|
25
|
+
### Parameters (text / image / multiview-to-model)
|
|
26
|
+
|
|
27
|
+
| param | default | applies to | notes |
|
|
28
|
+
| --- | --- | --- | --- |
|
|
29
|
+
| `prompt` | — | text | ≤1024 chars |
|
|
30
|
+
| `negative_prompt` | — | text | ≤255 chars |
|
|
31
|
+
| `input` | — | image | `file_` token, `http(s)://` URL or `task_` id (e.g. a text-to-image task) — the CLI uploads local files for you |
|
|
32
|
+
| `inputs` | — | multiview | see "multiview inputs" below |
|
|
33
|
+
| `model_seed` / `image_seed` / `texture_seed` | random | all | geometry / text-to-image stage / texture seeds — the key to reproducibility (`task.json` records them) |
|
|
34
|
+
| `face_limit` | adaptive | all | max polycount; P1 48–20000, P2 48–50000 |
|
|
35
|
+
| `texture` | `true` | all | set `false` for bare geometry (print / re-texture later) — saves credits |
|
|
36
|
+
| `pbr` | `true` | all | PBR maps; **forces `texture=true`** |
|
|
37
|
+
| `texture_quality` | `standard` | all | `standard` / `detailed` / `extreme` (price tiers) |
|
|
38
|
+
| `geometry_quality` | `standard` | v3.x | `detailed` = Ultra mode (extra HD credit) |
|
|
39
|
+
| `auto_size` | `false` | all | scale to real-world metres |
|
|
40
|
+
| `quad` | `false` | v3.x, P2 | quad mesh; **forces FBX output** (quads cannot live in GLB) |
|
|
41
|
+
| `smart_low_poly` | `false` | v3.x | hand-crafted-style low-poly; face_limit 500–20000 tri / 500–10000 quad |
|
|
42
|
+
| `generate_parts` | `false` | v3.x | editable segmented parts — see rules below |
|
|
43
|
+
| `compress` | — | v3.x | `geometry` = meshopt compression |
|
|
44
|
+
| `export_orientation` | `+x` | all | forward axis `+x` / `-x` / `+y` / `-y` — see warning below |
|
|
45
|
+
| `export_uv` | `true` | P series only | `false` = faster, smaller file (no UV unwrap) |
|
|
46
|
+
| `enable_image_autofix` | `false` | image | auto-repair low-quality inputs |
|
|
47
|
+
| `texture_alignment` | `original_image` | image, multiview | `original_image` (match the picture) / `geometry` (match the mesh) |
|
|
48
|
+
| `orientation` | `default` | image, multiview | `align_image` = align the model to the input viewpoint |
|
|
49
|
+
|
|
50
|
+
Only valid when `model >= tripo-v3.0`: `texture_quality` `geometry_quality` `auto_size` `quad` `smart_low_poly` `generate_parts` `compress`.
|
|
51
|
+
|
|
52
|
+
**`generate_parts` rules (server-enforced):**
|
|
53
|
+
- `texture=true` or `pbr=true` (including simply omitting `texture`, which defaults to true) → request rejected with `1004`. The CLI flips both to `false` for you and warns; re-texture afterwards with `tripo model texture`.
|
|
54
|
+
- `quad=true` → quad is ignored; parts come back as triangle meshes.
|
|
55
|
+
- `smart_low_poly=true` → smart_low_poly wins and **no parts are produced**.
|
|
56
|
+
|
|
57
|
+
**`export_orientation` warning:** it applies to this generation only. Downstream tasks (texture, rig, retarget, convert, …) do **not** inherit it — they read the model in default orientation and produce a wrongly-oriented result while still reporting `success`. If you will post-process, leave it unset and set `export_orientation` on the final `convert` step instead.
|
|
58
|
+
|
|
59
|
+
### Multiview inputs
|
|
60
|
+
|
|
61
|
+
The API accepts three `inputs` shapes (never mix them):
|
|
62
|
+
- **view-key (recommended)**: `[{"front":…},{"back":…}]` with keys `front/left/back/right`; `front` required, ≥2 views, order irrelevant.
|
|
63
|
+
- **legacy positional**: exactly 4 strings `[front, left, back, right]`, `""` skips a slot.
|
|
64
|
+
- **task_id**: `[{"task_id":"<image-to-multiview or edit-multiview task>"}]` to reuse a 4-view sheet (source task must be `success`).
|
|
65
|
+
|
|
66
|
+
The CLI builds view-key payloads from your files: filename hints (`front|back|left|right`, or 正面/背面/左/右) win; otherwise positional order front, left, back, right. A front view is mandatory.
|
|
21
67
|
|
|
22
68
|
## Images (2D pipeline before 3D)
|
|
23
69
|
|
|
@@ -29,6 +75,29 @@ tripo generate edit-multiview <multiview-task-id> -p 'prompts=[{"view":"front","
|
|
|
29
75
|
tripo generate image-to-splat photo.png # gaussian splat
|
|
30
76
|
```
|
|
31
77
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
78
|
+
### Image models (`--model`)
|
|
79
|
+
|
|
80
|
+
| model | provider | notes |
|
|
81
|
+
| --- | --- | --- |
|
|
82
|
+
| `seedream_v4` | ByteDance | text-to-image default (balanced); **not accepted by image-to-image** |
|
|
83
|
+
| `seedream_v5` | ByteDance | image-to-image default; higher quality |
|
|
84
|
+
| `gemini-2.5-flash` / `gemini-3-pro` / `gemini-3.1-flash` | Google | fast / high quality / latest fast. Backend aliases `banana` / `banana_pro` / `banana2` are also accepted |
|
|
85
|
+
| `chat_image_1` / `chat_image_1.5` / `chat_image_2` | OpenAI | GPT image; 1.5 = higher quality, 2 = latest |
|
|
86
|
+
|
|
87
|
+
### Image parameters
|
|
88
|
+
|
|
89
|
+
| param | default | endpoint | notes |
|
|
90
|
+
| --- | --- | --- | --- |
|
|
91
|
+
| `prompt` | — | t2i (required), i2i | ≤1024 chars; i2i: required unless `template` is set |
|
|
92
|
+
| `input` | — | i2i, i2mv, edit-mv, splat | `file_` token / URL (i2i also accepts a `task_` id) |
|
|
93
|
+
| `inputs` | — | i2i | multiple reference images: seedream ≤4, gemini ≤10 (gpt ≤16); reference them in the prompt as `[image 1]`, `[image 2]`… |
|
|
94
|
+
| `template` | — | t2i, i2i | `asset_extraction` `character_completion` `t_pose` `head_extraction` `3d_enhance` `variants` `print_clay` `figure` |
|
|
95
|
+
| `t_pose` | `false` | t2i, i2i | boolean shortcut: convert the subject to a T-pose |
|
|
96
|
+
| `sketch_to_render` | `false` | t2i, i2i | turn a sketch into a rendered image |
|
|
97
|
+
| `model_seed` | random | splat | same seed + same image = repeatable `.splat` |
|
|
98
|
+
|
|
99
|
+
- `template=t_pose` (or `t_pose=true`) is the golden pre-step for the animation pipeline; `3d_enhance` cleans a photo before image-to-model; `print_clay` previews a single-colour print look.
|
|
100
|
+
- Sizes are billed in 1K / 2K / 4K tiers; `aspect_ratio` is only honoured by the gemini family.
|
|
101
|
+
- `image-to-multiview` output: `front_view_url` `left_view_url` `back_view_url` `right_view_url` — feed them (or the task id, see above) to `multiview-to-model`.
|
|
102
|
+
- `edit-multiview` takes a successful `image-to-multiview` task; `prompts` is 1–4 `{view, prompt}` objects.
|
|
103
|
+
- `image-to-splat` returns a `.splat` file in `output.model_url` (not a mesh — no texture / rig / convert downstream). Fixed **30 credits**, ~4 minutes. Input PNG / JPEG / WebP ≤20 MB, ≥256×256 px, subject clear and centred. Use image-to-model when you need an editable mesh.
|
package/skill/commands/make.md
CHANGED
|
@@ -20,7 +20,7 @@ tripo make <input...> [options]
|
|
|
20
20
|
|
|
21
21
|
- `--for <scenario>` — `game-mobile` `game-pc` `film` `print` `ar-web` `anim` `toy`. Sets model+params+chain+format from the domain knowledge base.
|
|
22
22
|
- `--then <steps>` — processing chain, comma-separated. Steps: `refine texture stylize convert import rig-check rig retarget segment complete decimate smartsegment`. Args: `step:key=value,...`; bare value maps to the step's primary arg (`convert:fbx` → format, `stylize:lego` → style, `decimate:5000` → face_limit, `retarget:preset:walk` → animation). Overrides the scenario chain.
|
|
23
|
-
- `--model <m>` — force `tripo-v3.1` (high fidelity, default)
|
|
23
|
+
- `--model <m>` — force `tripo-v3.1` (high fidelity, default), `tripo-p1` (low-poly; face_limit 50–20000; quad/parts/geometry_quality unsupported and stripped) or `tripo-p2` (P-series preview; adds quad, face_limit 48–50000 tri / 48–25000 quad; never auto-selected). The CLI normalizes these aliases to the wire versions (`v3.1-20260211` / `P1-20260311` / `P2-20260801`) the server actually accepts.
|
|
24
24
|
- `-n, --candidates <n>` — up to 4 parallel candidates with different seeds (interactive pick when chaining).
|
|
25
25
|
- `--seed <n>` — fixed model_seed for reproducible geometry.
|
|
26
26
|
- `-p, --param key=value` — extra API parameter, repeatable. Common: `texture=false pbr=false` (bare geometry, cheaper), `texture_quality=detailed`, `face_limit=15000`, `quad=true` (forces FBX), `auto_size=true`, `negative_prompt=...`.
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
All subcommands take input as: explicit argument (task id / @last / @name / file / URL) > piped stdin JSON > `@last`.
|
|
4
4
|
Shared options: `--json --yes -o --no-wait --no-download --timeout --name -p key=value`.
|
|
5
|
+
Any API parameter without a first-class flag can be passed with `-p key=value` (JSON values allowed: `-p 'part_names=["head","body"]'`).
|
|
5
6
|
|
|
6
7
|
## tripo model
|
|
7
8
|
|
|
@@ -17,7 +18,37 @@ tripo model convert [input] --format GLTF|USDZ|FBX|OBJ|STL|3MF \
|
|
|
17
18
|
tripo model import <file-or-url> # GLB/GLTF/FBX/OBJ/STL ≤150MB
|
|
18
19
|
```
|
|
19
20
|
|
|
20
|
-
|
|
21
|
+
| step | input accepted | params |
|
|
22
|
+
| --- | --- | --- |
|
|
23
|
+
| `refine` | successful `text_to_model` task only | `model` (default `tripo-v3.1`) |
|
|
24
|
+
| `texture` | task / file / URL (file/URL is imported implicitly) | `model` `v3.0-20250812` (default) / `v2.5-20250123`; `texture_quality` standard/detailed/extreme; `pbr` (default true); `texture_seed`; `texture_alignment` original_image/geometry |
|
|
25
|
+
| `stylize` | task / file (no URL) | `style` lego/voxel/voronoi/minecraft; `block_size` 32–128 (minecraft only, default 80) |
|
|
26
|
+
| `convert` | task / file | see table below; `format` required |
|
|
27
|
+
| `import` | file / URL | GLB / GLTF / FBX / OBJ / STL ≤150 MB. `.gltf` references external files, so it only works as a URL — upload `.glb` |
|
|
28
|
+
|
|
29
|
+
### convert parameters (full)
|
|
30
|
+
|
|
31
|
+
| group | param | default | notes |
|
|
32
|
+
| --- | --- | --- | --- |
|
|
33
|
+
| basic | `format` | — | `GLTF` `USDZ` `FBX` `OBJ` `STL` `3MF` (3MF = single colour) |
|
|
34
|
+
| mesh | `quad` | false | quad remesh; **cannot export GLTF** — use FBX/OBJ/USDZ |
|
|
35
|
+
| mesh | `force_symmetry` | false | only with `quad=true` |
|
|
36
|
+
| mesh | `face_limit` | keep original | target polycount |
|
|
37
|
+
| mesh | `flatten_bottom` / `flatten_bottom_threshold` | false / 0.01 | flat base for printing |
|
|
38
|
+
| texture | `texture_size` | 4096 | diffuse size in px |
|
|
39
|
+
| texture | `texture_format` | JPEG | `BMP` `DPX` `HDR` `JPEG` `OPEN_EXR` `PNG` `TARGA` `TIFF` `WEBP` |
|
|
40
|
+
| texture | `bake` | true | bake advanced materials into base textures |
|
|
41
|
+
| texture | `pack_uv` | false | pack all UVs into one layout |
|
|
42
|
+
| texture | `export_vertex_colors` | false | **OBJ / GLTF only** |
|
|
43
|
+
| export | `pivot_to_center_bottom` | false | pivot at bottom centre |
|
|
44
|
+
| export | `scale_factor` | 1 | uniform scale |
|
|
45
|
+
| export | `with_animation` | true | keep skeleton + animation data |
|
|
46
|
+
| export | `animate_in_place` | false | strip root motion |
|
|
47
|
+
| export | `part_names` | — | export only these parts (names from a segment task) |
|
|
48
|
+
| export | `export_orientation` | `+x` | forward axis `+x` / `-x` / `+y` / `-y` — set orientation **here**, as the last step (generation-time `export_orientation` is not inherited by other steps) |
|
|
49
|
+
| export | `fbx_preset` | blender | `blender` / `3dsmax` / `mixamo` (FBX only) |
|
|
50
|
+
|
|
51
|
+
Billing: any non-default convert option bills as "complex convert" (pricier than a plain format swap).
|
|
21
52
|
|
|
22
53
|
## tripo anim
|
|
23
54
|
|
|
@@ -29,12 +60,32 @@ tripo anim retarget [input] --animation preset:walk [preset:run ...] \
|
|
|
29
60
|
[--out-format glb|fbx] [--animate-in-place]
|
|
30
61
|
```
|
|
31
62
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
- v1.0
|
|
36
|
-
|
|
37
|
-
|
|
63
|
+
| step | input accepted | params |
|
|
64
|
+
| --- | --- | --- |
|
|
65
|
+
| `check` (rig-check) | task / file / URL — **GLB only**, ≤150 MB | none. Output: `riggable` (bool) + recommended `rig_type` (one of the 7 below). Run it first: not riggable → stop before spending rig credits |
|
|
66
|
+
| `rig` | task / file | `model`: `rig-v2.0` (wire `v2.5-20260210`, **CLI default**, presets for all body types) / `rig-v1.0` (wire `v1.0-20240301`, server default, biped-only presets); `rig_type` biped/quadruped/hexapod/octopod/avian/serpentine/aquatic (default biped — use rig-check's value); `spec` tripo/mixamo; `out_format` glb/fbx |
|
|
67
|
+
| `retarget` | **rig task id only** | `animation` (one) or `animations` (list, ≤5, billed per animation); `out_format` glb/fbx; `bake_animation` (default true, glb only); `export_with_geometry` (default true); `animate_in_place` (default false) |
|
|
68
|
+
|
|
69
|
+
- Marketing names `rig-v1.0` / `rig-v2.0` are normalized to the wire versions automatically (sending them raw is a 400).
|
|
70
|
+
- Mixamo / Unity Humanoid → `--spec mixamo` (+ `--fbx-preset mixamo` at convert time).
|
|
71
|
+
- Game code drives movement → `--animate-in-place`.
|
|
72
|
+
- The preset set depends on **which rig model the upstream rig task used**.
|
|
73
|
+
|
|
74
|
+
### Presets for rig v2.0 / v2.5 (all rig types)
|
|
75
|
+
|
|
76
|
+
`preset:idle` `preset:walk` `preset:run` `preset:dive` `preset:climb` `preset:jump` `preset:slash` `preset:shoot` `preset:hurt` `preset:fall` `preset:turn`
|
|
77
|
+
Body-specific: `preset:quadruped:walk` `preset:hexapod:walk` `preset:octopod:walk` `preset:serpentine:march` `preset:aquatic:march`
|
|
78
|
+
|
|
79
|
+
### Presets for rig v1.0 (biped only, 90+)
|
|
80
|
+
|
|
81
|
+
All prefixed `preset:biped:`
|
|
82
|
+
- basic: `idle` `walk` `run` `run_upstairs` `turn` `jump` `jump_down` `jump_rope_01` `jump_rope_02` `fall` `climb` `dive` `swim` `surf` `flip` `sit` `standing_relax` `look_around` `wait` `swagger`
|
|
83
|
+
- dance: `dance_01` … `dance_06` `freaky`
|
|
84
|
+
- performance: `sing_01` … `sing_04` `cheer`
|
|
85
|
+
- emotion: `clap` `bow` `greet_01` … `greet_04` `wave_goodbye_01` `wave_goodbye_02` `agree` `heart_pose` `hug` `fold_arms` `laugh_01` `laugh_02` `cry` `sob` `afraid` `frightened` `scared_01` `scared_02` `angry_01` … `angry_03` `depressed` `frustrated_01` `frustrated_02` `complain_01` `complain_02` `victory_celebration` `defeat_02` `defeat_03`
|
|
86
|
+
- daily: `scratch` `make_a_call_01` `make_a_call_02` `play_mobile_game` `play_video_game` `dig` `chop` `shovel` `lift_heavy`
|
|
87
|
+
- sports: `warm_up` `press-up` `cross_body_crunch` `basketball_shot` `crossover_dribble` `dribble` `pitch_baseball` `golf` `volleyball` `football_catch` `football_save` `football_pass`
|
|
88
|
+
- combat: `box_01` … `box_03` `front_kick_01` `front_kick_02` `slash` `shoot` `fire` `cast_a_spell` `hurt` `hit_to_body_01` `hit_to_body_02` `hit_to_head` `hit_to_side` `hit_to_stomach` `flee_01` `flee_02`
|
|
38
89
|
|
|
39
90
|
## tripo mesh
|
|
40
91
|
|
|
@@ -45,6 +96,13 @@ tripo mesh decimate [input] --face-limit 5000 [--quad] [--no-bake] # 500
|
|
|
45
96
|
tripo mesh smartsegment <file-or-url> [--seg-type image|model] [--granularity coarse|medium|fine] [--hint "..."]
|
|
46
97
|
```
|
|
47
98
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
99
|
+
| step | input accepted | params |
|
|
100
|
+
| --- | --- | --- |
|
|
101
|
+
| `segment` | task / file / URL | `model` `v1.0-20250506` (default, geometry-based) / `v2.0-20260430` (Beta, semantic labels + geometry). **v2 only**: `segmentation_granularity` simple/balanced/detailed (default balanced), `split_by_connectivity` (default true), `ref_image` file_token/URL — when `ref_image` is set the other two are ignored; setting `ref_image` on v1 → `1004` |
|
|
102
|
+
| `complete` | **segment task only** | `completion_mode` `ai_completion` (AI diffusion, default) / `quick_cap` (fast hole-fill, no AI); `part_names` (default: all parts); `model` `v1.0-20250506` (only version) |
|
|
103
|
+
| `decimate` | task / file | `face_limit` (docs quote 1000–20000; CLI accepts 500–20000 tri / 500–10000 quad); `quad`; `bake` (default true — bake textures onto the low-poly, right for LODs); `part_names`. `-p model=v1.0`: up to 2,000,000 tri / 150,000 quad but `face_limit` becomes required and `bake`/`part_names` are unsupported |
|
|
104
|
+
| `smartsegment` | **file / URL only (no task ids)** | `seg_type` `image` (photo → auto-model → segment, **85 credits**) / `model` (existing **GLB only** → segment, **55 credits**; CLI default); `granularity` coarse/medium/fine (default medium); `hint` free text describing the parts; `transform` 4×4 column-major matrix required for `model` — the CLI auto-fills identity |
|
|
105
|
+
|
|
106
|
+
- `segment` vs `smartsegment`: segment only splits an existing model; smartsegment is the end-to-end pipeline (asset → auto modelling → segmentation).
|
|
107
|
+
- smartsegment output: `prompt` (comma-separated part labels), `mask_url` (PNG semantic mask), `seg_model_url` (segmented GLB), `seg_task_id` (inner segmentation task), `model_task_id` (inner image_to_model / import task). Task types: `smartsegment_image` / `smartsegment_model`.
|
|
108
|
+
- `mesh complete` only accepts segmentation tasks; segmented / completed parts can then be exported selectively via `convert -p 'part_names=[...]'`.
|
package/skill/common-errors.md
CHANGED
|
@@ -4,8 +4,9 @@
|
|
|
4
4
|
| --- | --- | --- | --- |
|
|
5
5
|
| 3 | 1002 | authentication failed (invalid/missing API key) | set `TRIPO_API_KEY` or run `tripo login`; check the key wasn't revoked |
|
|
6
6
|
| 3 | 1005 | forbidden (no permission for this resource) | check account permissions |
|
|
7
|
-
| 2 | 1003/1004 | malformed request / invalid parameter | check spelling against `tripo docs --topic commands/<cmd>`; the CLI already strips illegal P1 params |
|
|
8
|
-
| 9 | 1007
|
|
7
|
+
| 2 | 1003/1004 | malformed request / invalid parameter | check spelling against `tripo docs --topic commands/<cmd>`; the CLI already strips illegal P1 params. Classic 1004s: `generate_parts=true` with texture/pbr on, `ref_image` on segment v1, `quad=true` on P1, non-GLB input to smartsegment `model` / rig-check |
|
|
8
|
+
| 9 | 1007 | per-API-key rate limit | wait and retry with backoff; honour `Retry-After` / `X-RateLimit-Reset` headers |
|
|
9
|
+
| 9 | 2000 | per-account concurrency pool full (see table below) | wait for a task in that category to finish, or lower `--concurrency` in batch; other categories are unaffected |
|
|
9
10
|
| 8 | 2001 | task not found | task ids are account-scoped — same key that created it? right region (ov/cn)? |
|
|
10
11
|
| 2 | 2003 | empty input file / unreachable URL | verify the file isn't empty and the URL is publicly accessible |
|
|
11
12
|
| 2 | 2004 | unsupported file type | images: PNG/JPEG/WebP/BMP/TIFF ≤20MB; models: GLB/FBX/OBJ/STL ≤150MB (.gltf not uploadable — use .glb or a URL) |
|
|
@@ -22,6 +23,19 @@
|
|
|
22
23
|
| 6 | — | task failed server-side | frozen credits auto-refund; `tripo redo` often succeeds with a new seed |
|
|
23
24
|
| 7 | — | network/5xx | auto-retried 3×; check `tripo doctor`; region mismatch (ov/cn) is a common cause |
|
|
24
25
|
|
|
26
|
+
## Concurrency pools (default per account; error 2000 when full)
|
|
27
|
+
|
|
28
|
+
| category | task types | default concurrency |
|
|
29
|
+
| --- | --- | --- |
|
|
30
|
+
| 3D generation — H series | text/image/multiview-to-model on `tripo-v3.x` / `v2.5` | 10 |
|
|
31
|
+
| 3D generation — P series | text/image/multiview-to-model on `tripo-p1` / P2 | 5 |
|
|
32
|
+
| image generation | text-to-image, image-to-image, image-to-multiview, edit-multiview | **1** |
|
|
33
|
+
| animation | rig-check, rig, retarget | 10 |
|
|
34
|
+
| model processing | texture, convert, refine | 5 |
|
|
35
|
+
| mesh operations | segment, complete, decimate | 10 |
|
|
36
|
+
|
|
37
|
+
Pools are independent: a full H-series pool does not block P-series or image tasks. Image generation is serial by default — do not fan out text-to-image jobs. Higher limits are granted on request via support.
|
|
38
|
+
|
|
25
39
|
## Frequent local validations (caught before spending credits)
|
|
26
40
|
|
|
27
41
|
- `refine` only accepts a successful `text_to_model` task
|
|
@@ -36,3 +50,8 @@
|
|
|
36
50
|
- `model_url` in task output points to a file that may be named `pbr_model` etc. — normal, just download it (the CLI does).
|
|
37
51
|
- Output URLs expire in ~5 minutes — never cache them; re-run `tripo task get <id> --download`.
|
|
38
52
|
- `frozen` balance = holds for running tasks; it settles or refunds automatically.
|
|
53
|
+
- `credits_consumed` / `balance` / `frozen` are decimals (e.g. `48.00`) — parse as float, never as int.
|
|
54
|
+
- Task status can also be `banned` (content policy — change the input) or `expired` (output files gone — regenerate); the CLI treats both as terminal failures.
|
|
55
|
+
- A downstream step after a generation that used `export_orientation` succeeds but comes out **wrongly oriented** — no error is raised. Set the orientation on the final `convert` step instead.
|
|
56
|
+
- `generate_parts` with `smart_low_poly=true` silently produces no parts (smart_low_poly wins); with `quad=true` the parts are triangles.
|
|
57
|
+
- `image-to-splat` yields a `.splat`, not a mesh — texture / rig / convert steps cannot follow it.
|