Skip to content

Commit 7b3ea07

Browse files
eg-renovate-userdd-eg-user
authored andcommitted
add pricing estimate for tripo3d
1 parent 340d39f commit 7b3ea07

File tree

4 files changed

+419
-1
lines changed

4 files changed

+419
-1
lines changed

src/providers/tripo3d/README.md

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
# Tripo3D Provider - Credit Tracking
2+
3+
The Tripo3D provider now includes credit tracking functionality to help users understand and monitor their API usage costs.
4+
5+
## Credit Tracking Features
6+
7+
### `getTask` Response - Credits Used
8+
When checking a completed task status, the response now includes a `credits_used` field:
9+
10+
```json
11+
{
12+
"code": 0,
13+
"data": {
14+
"task_id": "abc123",
15+
"type": "text_to_3d",
16+
"status": "success",
17+
"progress": 100,
18+
"input": {
19+
"type": "text_to_3d",
20+
"prompt": "A cute robot",
21+
"texture_quality": "high",
22+
"pbr": true
23+
},
24+
"output": {
25+
"model": "https://...",
26+
"pbr_model": "https://..."
27+
},
28+
"credits_used": 17,
29+
"create_time": 1692825600
30+
},
31+
"provider": "tripo3d"
32+
}
33+
```
34+
35+
## Credit Calculation
36+
37+
Credits are calculated based on:
38+
39+
1. **Base Task Cost** - Varies by task type:
40+
- `text_to_3d`, `image_to_3d`, `multiview_to_3d`: 10 credits
41+
- `animate`: 15 credits
42+
- `refine_model`, `retexture`, `stylize`: 5 credits
43+
- `convert`: 2 credits
44+
- Others: 5 credits (default)
45+
46+
2. **Quality Modifiers**:
47+
- `texture_quality: "standard"`: +0 credits
48+
- `texture_quality: "high"`: +5 credits
49+
- `texture_quality: "ultra"`: +10 credits
50+
51+
3. **Feature Modifiers**:
52+
- `pbr: true`: +2 credits
53+
- `quad: true`: +3 credits
54+
- `with_animation: true`: +5 credits
55+
- `bake_animation: true`: +2 credits
56+
- `pack_uv: true`: +1 credit
57+
- `bake: true`: +2 credits
58+
59+
## Example Calculations
60+
61+
### Basic Text-to-3D
62+
```javascript
63+
// Request
64+
{
65+
"type": "text_to_3d",
66+
"prompt": "A simple cube"
67+
}
68+
// Credits: 10 (base)
69+
```
70+
71+
### High-Quality Text-to-3D with PBR
72+
```javascript
73+
// Request
74+
{
75+
"type": "text_to_3d",
76+
"prompt": "A detailed robot",
77+
"texture_quality": "high",
78+
"pbr": true
79+
}
80+
// Credits: 10 (base) + 5 (high quality) + 2 (PBR) = 17
81+
```
82+
83+
### Animation Task with Multiple Features
84+
```javascript
85+
// Request
86+
{
87+
"type": "animate",
88+
"with_animation": true,
89+
"bake_animation": true
90+
}
91+
// Credits: 15 (base) + 5 (animation) + 2 (bake) = 22
92+
```
93+
94+
## Important Notes
95+
96+
1. **Estimates Only**: These are estimated credits based on embedded pricing logic. Actual credits may vary if Tripo3D changes their pricing.
97+
98+
2. **Completed Tasks Only**: `credits_used` field only appears for tasks with `status: "success"`.
99+
100+
3. **Async Limitation**: Credits are consumed when tasks complete, not when created. This is due to Tripo3D's async task architecture.
101+
102+
4. **Pricing Updates**: The pricing table in `src/providers/tripo3d/pricing.ts` should be updated when Tripo3D changes their pricing structure.
103+
104+
## Testing
105+
106+
Run the pricing calculation tests:
107+
```bash
108+
npx jest src/providers/tripo3d/pricing.test.ts
109+
```

src/providers/tripo3d/getTask.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {
44
generateErrorResponse,
55
generateInvalidProviderResponseError,
66
} from '../utils';
7+
import { calculateEstimatedCredits } from './pricing';
78

89
export const Tripo3DGetTaskConfig: ProviderConfig = {
910
task_id: {
@@ -44,6 +45,8 @@ export interface Tripo3DTask {
4445
create_time: number;
4546
running_left_time?: number;
4647
queuing_num?: number;
48+
// Added by Portkey for pricing/usage tracking
49+
credits_used?: number;
4750
}
4851

4952
export interface Tripo3DGetTaskResponse {
@@ -70,9 +73,19 @@ export const Tripo3DGetTaskResponseTransform: (
7073
}
7174

7275
if (response.data) {
76+
const taskData = { ...response.data };
77+
78+
// Add credits_used for completed tasks
79+
if (taskData.status === 'success' && taskData.type && taskData.input) {
80+
taskData.credits_used = calculateEstimatedCredits(
81+
taskData.type,
82+
taskData.input
83+
);
84+
}
85+
7386
return {
7487
code: response.code,
75-
data: response.data,
88+
data: taskData,
7689
provider: TRIPO3D,
7790
};
7891
}
Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
import {
2+
calculateEstimatedCredits,
3+
getTaskTypePricing,
4+
TRIPO3D_PRICING,
5+
} from './pricing';
6+
7+
describe('Tripo3D Pricing', () => {
8+
describe('calculateEstimatedCredits', () => {
9+
it('should return base cost for known task types', () => {
10+
expect(calculateEstimatedCredits('text_to_3d')).toBe(10);
11+
expect(calculateEstimatedCredits('image_to_3d')).toBe(10);
12+
expect(calculateEstimatedCredits('refine_model')).toBe(5);
13+
expect(calculateEstimatedCredits('animate')).toBe(15);
14+
expect(calculateEstimatedCredits('convert')).toBe(2);
15+
});
16+
17+
it('should return default cost for unknown task types', () => {
18+
expect(calculateEstimatedCredits('unknown_task_type')).toBe(5);
19+
expect(calculateEstimatedCredits('')).toBe(5);
20+
});
21+
22+
it('should add texture quality modifiers', () => {
23+
expect(
24+
calculateEstimatedCredits('text_to_3d', { texture_quality: 'standard' })
25+
).toBe(10);
26+
expect(
27+
calculateEstimatedCredits('text_to_3d', { texture_quality: 'high' })
28+
).toBe(15);
29+
expect(
30+
calculateEstimatedCredits('text_to_3d', { texture_quality: 'ultra' })
31+
).toBe(20);
32+
});
33+
34+
it('should add PBR feature modifier', () => {
35+
expect(calculateEstimatedCredits('text_to_3d', { pbr: true })).toBe(12);
36+
expect(calculateEstimatedCredits('text_to_3d', { pbr: false })).toBe(10);
37+
});
38+
39+
it('should add quad topology modifier', () => {
40+
expect(calculateEstimatedCredits('text_to_3d', { quad: true })).toBe(13);
41+
expect(calculateEstimatedCredits('text_to_3d', { quad: false })).toBe(10);
42+
});
43+
44+
it('should add animation modifiers', () => {
45+
expect(
46+
calculateEstimatedCredits('text_to_3d', { with_animation: true })
47+
).toBe(15);
48+
expect(
49+
calculateEstimatedCredits('text_to_3d', { bake_animation: true })
50+
).toBe(12);
51+
});
52+
53+
it('should add texture processing modifiers', () => {
54+
expect(calculateEstimatedCredits('text_to_3d', { pack_uv: true })).toBe(
55+
11
56+
);
57+
expect(calculateEstimatedCredits('text_to_3d', { bake: true })).toBe(12);
58+
});
59+
60+
it('should combine multiple modifiers', () => {
61+
const params = {
62+
texture_quality: 'high',
63+
pbr: true,
64+
quad: true,
65+
with_animation: true,
66+
pack_uv: true,
67+
bake: true,
68+
};
69+
// base (10) + high quality (5) + pbr (2) + quad (3) + animation (5) + pack_uv (1) + bake (2) = 28
70+
expect(calculateEstimatedCredits('text_to_3d', params)).toBe(28);
71+
});
72+
73+
it('should return minimum of 1 credit', () => {
74+
// Even if we had a task with 0 base cost, it should return at least 1
75+
const zeroBaseCost = { ...TRIPO3D_PRICING };
76+
zeroBaseCost.baseCosts.test_task = 0;
77+
78+
// Our current minimum is handled in the function
79+
expect(calculateEstimatedCredits('test_task')).toBe(5); // Returns default
80+
});
81+
82+
it('should handle empty parameters object', () => {
83+
expect(calculateEstimatedCredits('text_to_3d', {})).toBe(10);
84+
});
85+
86+
it('should ignore unknown parameters', () => {
87+
const params = {
88+
unknown_param: true,
89+
another_unknown: 'value',
90+
texture_quality: 'high',
91+
};
92+
expect(calculateEstimatedCredits('text_to_3d', params)).toBe(15); // base + high quality only
93+
});
94+
});
95+
96+
describe('getTaskTypePricing', () => {
97+
it('should return pricing info for known task types', () => {
98+
const pricing = getTaskTypePricing('text_to_3d');
99+
expect(pricing).toEqual({
100+
taskType: 'text_to_3d',
101+
baseCost: 10,
102+
availableModifiers: expect.arrayContaining([
103+
'pbr',
104+
'quad',
105+
'with_animation',
106+
]),
107+
textureQualityOptions: expect.arrayContaining([
108+
'standard',
109+
'high',
110+
'ultra',
111+
]),
112+
});
113+
});
114+
115+
it('should return default pricing for unknown task types', () => {
116+
const pricing = getTaskTypePricing('unknown_task');
117+
expect(pricing).toEqual({
118+
taskType: 'unknown_task',
119+
baseCost: 5,
120+
availableModifiers: expect.arrayContaining([
121+
'pbr',
122+
'quad',
123+
'with_animation',
124+
]),
125+
textureQualityOptions: expect.arrayContaining([
126+
'standard',
127+
'high',
128+
'ultra',
129+
]),
130+
});
131+
});
132+
});
133+
134+
describe('TRIPO3D_PRICING configuration', () => {
135+
it('should have all required pricing sections', () => {
136+
expect(TRIPO3D_PRICING).toHaveProperty('baseCosts');
137+
expect(TRIPO3D_PRICING).toHaveProperty('modifiers');
138+
expect(TRIPO3D_PRICING.modifiers).toHaveProperty('texture_quality');
139+
expect(TRIPO3D_PRICING.modifiers).toHaveProperty('features');
140+
});
141+
142+
it('should have default task type', () => {
143+
expect(TRIPO3D_PRICING.baseCosts).toHaveProperty('default');
144+
expect(typeof TRIPO3D_PRICING.baseCosts.default).toBe('number');
145+
});
146+
147+
it('should have standard texture quality as baseline', () => {
148+
expect(TRIPO3D_PRICING.modifiers.texture_quality).toHaveProperty(
149+
'standard'
150+
);
151+
expect(TRIPO3D_PRICING.modifiers.texture_quality.standard).toBe(0);
152+
});
153+
});
154+
});

0 commit comments

Comments
 (0)