Product Tools

Access product catalog data with built-in tools.

Overview

Product tools provide access to your catalog data from within agent code. All tools handle Firestore queries, caching, and error handling automatically.

getProduct

Retrieve a single product by ID:

typescript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
import { getProduct } from '@hyperfold/actions-sdk';
// Get a product by ID
const product = await getProduct('prod_aero_x2');
// Returns:
{
product_id: 'prod_aero_x2',
name: 'AeroRun X2 Marathon Shoe',
description: 'Professional marathon shoe with Gore-Tex...',
pricing: {
list_price: 180.00,
currency: 'USD',
cost: 72.00,
min_margin: 0.15,
negotiable: true,
},
inventory: {
quantity: 847,
status: 'in_stock',
warehouse: 'us-west-1',
},
semantics: {
category: 'apparel/footwear/running',
usage_context: ['marathon', 'trail', 'wet_conditions'],
visual_tags: ['blue', 'reflective', 'mesh_upper'],
vibe_tags: ['professional', 'performance'],
},
attributes: {
brand: 'AeroRun',
weight_g: 280,
waterproof: true,
},
media: {
images: [
{ url: 'https://...', alt: 'Side view' },
],
},
}
// Get with specific fields only
const basic = await getProduct('prod_aero_x2', {
fields: ['name', 'pricing', 'inventory'],
});

searchProducts

Perform semantic search across your catalog:

typescript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
import { searchProducts } from '@hyperfold/actions-sdk';
// Semantic search
const results = await searchProducts('waterproof running shoes for marathon', {
limit: 10,
minConfidence: 0.7,
});
// Returns:
{
results: [
{
product_id: 'prod_aero_x2',
name: 'AeroRun X2 Waterproof',
confidence: 0.94,
price: 180.00,
in_stock: true,
},
// ... more results
],
total_count: 23,
facets: {
category: { 'running': 15, 'trail': 8 },
price_range: { '100-150': 8, '150-200': 12, '200+': 3 },
},
}
// Search with filters
const filtered = await searchProducts('running shoes', {
limit: 20,
filters: {
price_max: 150,
in_stock: true,
category: 'footwear/running',
},
sort: 'price_asc',
});
// Search with attribute filters
const specific = await searchProducts('shoes', {
attributes: {
waterproof: true,
size: '10',
color: 'blue',
},
});

checkInventory

Check real-time inventory levels:

typescript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
import { checkInventory } from '@hyperfold/actions-sdk';
// Check inventory for a product
const inventory = await checkInventory('prod_aero_x2');
// Returns:
{
product_id: 'prod_aero_x2',
total_quantity: 847,
status: 'in_stock', // 'in_stock' | 'low_stock' | 'out_of_stock'
by_warehouse: [
{ warehouse: 'us-west-1', quantity: 523 },
{ warehouse: 'us-east-1', quantity: 324 },
],
by_variant: [
{ sku: 'AERO-X2-BLU-9', quantity: 120 },
{ sku: 'AERO-X2-BLU-10', quantity: 89 },
{ sku: 'AERO-X2-BLK-10', quantity: 156 },
],
reorder_point: 100,
days_of_stock: 45, // Estimated days until stockout
}
// Check specific variant
const variantInventory = await checkInventory('prod_aero_x2', {
variant: 'AERO-X2-BLU-10',
});
// Check inventory at specific warehouse
const warehouseInventory = await checkInventory('prod_aero_x2', {
warehouse: 'us-west-1',
});
// Bulk inventory check
const bulkInventory = await checkInventory([
'prod_aero_x2',
'prod_storm_gt',
'prod_trail_king',
]);
Inventory data is fetched from Cloud Spanner for real-time accuracy. Results are cached for 30 seconds to reduce database load.

getVariants

Get product variants with options:

typescript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
import { getVariants } from '@hyperfold/actions-sdk';
// Get all variants for a product
const variants = await getVariants('prod_aero_x2');
// Returns:
{
product_id: 'prod_aero_x2',
variant_count: 12,
options: {
size: ['8', '9', '10', '11', '12'],
color: ['blue', 'black', 'white'],
},
variants: [
{
sku: 'AERO-X2-BLU-9',
size: '9',
color: 'blue',
quantity: 120,
price_adjustment: 0, // Same as base price
},
{
sku: 'AERO-X2-BLU-10',
size: '10',
color: 'blue',
quantity: 89,
price_adjustment: 0,
},
{
sku: 'AERO-X2-BLK-10',
size: '10',
color: 'black',
quantity: 156,
price_adjustment: 0,
},
// ... more variants
],
}
// Find specific variant by options
const variant = await getVariants('prod_aero_x2', {
size: '10',
color: 'blue',
});
// Check variant availability
const available = await getVariants('prod_aero_x2', {
inStockOnly: true,
});

Usage in Agent

Complete example using product tools in an agent:

typescript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
import {
HyperfoldAgent,
OnACPEvent,
getProduct,
searchProducts,
checkInventory,
} from '@hyperfold/actions-sdk';
@HyperfoldAgent({ name: 'catalog-agent', type: 'negotiator' })
export class CatalogAgent {
@OnACPEvent('search')
async handleSearch(query: string, filters: SearchFilters) {
// Use searchProducts for semantic discovery
const results = await searchProducts(query, {
limit: filters.limit || 10,
filters: {
price_max: filters.price_max,
in_stock: true,
},
});
return {
results: results.results,
total_count: results.total_count,
semantic_confidence: results.results[0]?.confidence || 0,
};
}
@OnACPEvent('quote')
async handleQuote(productId: string, offer: number) {
// Get full product details
const product = await getProduct(productId);
if (!product) {
return { status: 'error', error: 'product_not_found' };
}
// Check inventory before quoting
const inventory = await checkInventory(productId);
if (inventory.status === 'out_of_stock') {
return {
status: 'unavailable',
message: 'Product is currently out of stock',
alternatives: await this.findAlternatives(productId),
};
}
// Calculate price based on inventory status
const urgencyMultiplier = inventory.status === 'low_stock' ? 1.05 : 1.0;
const floorPrice = product.pricing.cost * (1 + product.pricing.min_margin);
// ... rest of quote logic
}
}
See Pricing Tools for dynamic price calculation.