// ~/.openclaw/extensions/podium/index.ts
import { Type } from '@sinclair/typebox';
import { createPodiumClient } from '@podium-sdk/node-sdk';
export default function (api: any) {
const client = createPodiumClient({
apiKey: process.env.PODIUM_API_KEY!,
});
api.registerTool({
name: 'podium_search',
description: 'Search the Podium product catalog',
parameters: Type.Object({
categories: Type.Optional(Type.String({ description: 'Comma-separated categories' })),
limit: Type.Optional(Type.Number({ description: 'Max results (1-50)', default: 10 })),
}),
async execute(_id: string, params: { categories?: string; limit?: number }) {
const feed = await client.agentic.listProductsFeed({
categories: params.categories,
limit: params.limit ?? 10,
});
return {
content: [{ type: 'text', text: JSON.stringify(feed.products, null, 2) }],
};
},
});
api.registerTool({
name: 'podium_get_product',
description: 'Get full details for a specific product',
parameters: Type.Object({
productId: Type.String({ description: 'Product ID' }),
}),
async execute(_id: string, params: { productId: string }) {
const product = await client.product.get({ id: params.productId });
return {
content: [{ type: 'text', text: JSON.stringify(product, null, 2) }],
};
},
});
api.registerTool({
name: 'podium_profile',
description: 'Get a user\'s companion/taste profile',
parameters: Type.Object({
userId: Type.String({ description: 'Podium user ID' }),
}),
async execute(_id: string, params: { userId: string }) {
const profile = await client.companion.listProfile({ userId: params.userId });
return {
content: [{ type: 'text', text: JSON.stringify(profile, null, 2) }],
};
},
});
api.registerTool({
name: 'podium_recommendations',
description: 'Get personalized product recommendations for a user',
parameters: Type.Object({
userId: Type.String({ description: 'Podium user ID' }),
count: Type.Optional(Type.Number({ default: 5 })),
category: Type.Optional(Type.String()),
}),
async execute(_id: string, params: { userId: string; count?: number; category?: string }) {
const recs = await client.companion.listRecommendations({
userId: params.userId,
count: params.count ?? 5,
category: params.category,
});
return {
content: [{ type: 'text', text: JSON.stringify(recs, null, 2) }],
};
},
});
api.registerTool({
name: 'podium_points',
description: 'Check a user\'s points balance',
parameters: Type.Object({
userId: Type.String({ description: 'Podium user ID' }),
}),
async execute(_id: string, params: { userId: string }) {
const points = await client.user.listPoints({ id: params.userId });
return {
content: [{
type: 'text',
text: `Balance: ${points.balance} | Earned: ${points.totalEarned} | Spent: ${points.totalSpent}`,
}],
};
},
});
api.registerTool({
name: 'podium_checkout',
description: 'Create a checkout session for a product purchase',
parameters: Type.Object({
productId: Type.String(),
quantity: Type.Optional(Type.Number({ default: 1 })),
}),
async execute(_id: string, params: { productId: string; quantity?: number }) {
const session = await client.agentic.createCheckoutSessions({
requestBody: {
items: [{ id: params.productId, quantity: params.quantity ?? 1 }],
},
});
return {
content: [{
type: 'text',
text: JSON.stringify({ sessionId: session.id, total: session.total, status: session.status }, null, 2),
}],
};
},
});
api.registerTool({
name: 'podium_tasks',
description: 'List available task bounties',
parameters: Type.Object({}),
async execute() {
const tasks = await client.tasks.listTasks();
return {
content: [{ type: 'text', text: JSON.stringify(tasks, null, 2) }],
};
},
});
}