Skip to main content
Recipe endpoints help you understand model lineage, visualize dependencies between bakes, and recreate complex model hierarchies. This guide shows how to use recipe functionality with the SDK.
SDK Support:
  • TypeScript SDK: getDependencyGraph() and getRecreationPlan() are available via client.recipes. getTree() is available via client.repo.getTree().
  • Python SDK: get_dependency_graph() and get_recreation_plan() are available via client.recipes. get_tree() is available via client.repo.get_tree().

Understanding Model Lineage

When bakes depend on other bakes (using checkpoints), they form a lineage tree. Recipe endpoints help you:
  • Visualize dependencies: See how bakes, targets, and prompts connect
  • Recreate models: Get step-by-step plans to rebuild complex model hierarchies
  • Track evolution: View the complete model lineage tree for a repository

Get Dependency Graph

The dependency graph shows all resources needed to recreate a specific bake, including parent bakes and all transitive dependencies.
import Bread from '@aibread/sdk';

const client = new Bread({
  apiKey: process.env.BREAD_API_KEY,
});

// Get dependency graph for a bake
const graph = await client.recipes.getDependencyGraph('my_bake', {
  repo_name: 'my_repo',
});

console.log(`Base model: ${graph.base_model}`);
console.log(`\nBakes:`);
for (const [name, config] of Object.entries(graph.bakes)) {
  console.log(`  ${name}:`, config);
}

console.log(`\nTargets:`);
for (const [name, config] of Object.entries(graph.targets)) {
  console.log(`  ${name}:`, config);
}

console.log(`\nPrompts:`);
for (const [name, path] of Object.entries(graph.prompts)) {
  console.log(`  ${name}: ${path}`);
}

console.log(`\nDependency edges:`);
for (const edge of graph.edges) {
  const [sourceType, sourceName, targetType, targetName] = edge;
  console.log(`  ${sourceType}:${sourceName} -> ${targetType}:${targetName}`);
}
Use Cases:
  • Understanding what resources a bake depends on
  • Debugging missing dependencies
  • Documenting model architecture
  • Planning migrations or recreations

Get Recreation Plan

The recreation plan provides a step-by-step, topologically sorted list of actions needed to recreate a bake and all its dependencies.
import Bread from '@aibread/sdk';

const client = new Bread({
  apiKey: process.env.BREAD_API_KEY,
});

// Get recreation plan
const plan = await client.recipes.getRecreationPlan('my_bake', {
  repo_name: 'my_repo',
});

console.log(`Base model: ${plan.base_model}`);
console.log(`Total steps: ${plan.total_steps}`);
console.log(`\nResources needed:`);
console.log(`  Prompts: ${plan.resources.prompts.join(', ')}`);
console.log(`  Targets: ${plan.resources.targets.join(', ')}`);
console.log(`  Bakes: ${plan.resources.bakes.join(', ')}`);

console.log(`\nExecution plan:`);
for (const step of plan.steps) {
  console.log(`\nStep ${step.step}: ${step.action}`);
  console.log(`  Resource: ${step.resource_type}:${step.resource_name}`);
  if (step.dependencies.length > 0) {
    console.log(`  Depends on: ${step.dependencies.join(', ')}`);
  }
  console.log(`  Config:`, JSON.stringify(step.config, null, 2));
}
Use Cases:
  • Recreating a bake in a new repository
  • Understanding execution order for complex workflows
  • Automating model recreation
  • Documentation and training

Get Repository Tree

The repository tree shows the complete model lineage for all bakes in a repository, including parent-child relationships and status.
import Bread from '@aibread/sdk';

const client = new Bread({
  apiKey: process.env.BREAD_API_KEY,
});

// Get repository tree
const tree = await client.repo.getTree('my_repo');

// Visualize lineage
// tree.bakes is a dictionary keyed by bake name
// tree.edges contains parent-child relationships: [source_type, source_name, target_type, target_name]
function printBake(bakeName: string, bake: any, indent = 0) {
  const prefix = '  '.repeat(indent);
  const statusIcon = bake.status === 'complete' ? '✓' : bake.status === 'running' ? '⟳' : '○';
  console.log(`${prefix}${statusIcon} ${bakeName} (${bake.status})`);
  
  if (bake.model_name && bake.model_name.length > 0) {
    console.log(`${prefix}  Models: ${bake.model_name.join(', ')}`);
  }
  
  // Find children using edges
  const children = tree.edges
    .filter((edge: string[]) => edge[0] === 'bake' && edge[2] === 'bake' && edge[3] === bakeName)
    .map((edge: string[]) => edge[1]);
  
  if (children.length > 0) {
    console.log(`${prefix}  Children:`);
    for (const childName of children) {
      if (tree.bakes[childName]) {
        printBake(childName, tree.bakes[childName], indent + 2);
      }
    }
  }
}

// Find root bakes (no incoming edges)
const allBakes = new Set(Object.keys(tree.bakes));
const childBakes = new Set(
  tree.edges
    .filter((edge: string[]) => edge[0] === 'bake' && edge[2] === 'bake')
    .map((edge: string[]) => edge[1])
);
const rootBakes = Array.from(allBakes).filter(name => !childBakes.has(name));

console.log(`Base model: ${tree.base_model}`);
console.log('Model Lineage Tree:\n');
for (const bakeName of rootBakes) {
  printBake(bakeName, tree.bakes[bakeName]);
}
Use Cases:
  • Visualizing complete model evolution
  • Finding all child models derived from a base bake
  • Tracking model status across the repository
  • Understanding model relationships without specifying a starting point

Example: Recreating a Model

Here’s a complete example of using the recreation plan to recreate a bake:
import Bread from '@aibread/sdk';

const client = new Bread({
  apiKey: process.env.BREAD_API_KEY,
});

async function recreateBake(sourceRepo: string, targetRepo: string, bakeName: string) {
  // Get recreation plan
  const plan = await client.recipes.getRecreationPlan(bakeName, {
    repo_name: sourceRepo,
  });

  // Ensure target repo exists
  await client.repo.create({
    repo_name: targetRepo,
    base_model: plan.base_model,
  });

  // Execute steps in order
  for (const step of plan.steps) {
    console.log(`Executing step ${step.step}: ${step.action} ${step.resource_type}:${step.resource_name}`);
    
    switch (step.resource_type) {
      case 'prompt':
        await client.prompts.create(targetRepo, {
          prompt_name: step.resource_name,
          messages: step.config.messages as any,
        });
        break;
        
      case 'target':
        await client.targets.create(targetRepo, {
          target_name: step.resource_name,
          template: 'default',
          overrides: step.config as any,
        });
        break;
        
      case 'bake':
        await client.bakes.create(targetRepo, {
          bake_name: step.resource_name,
          template: 'default',
          overrides: step.config as any,
        });
        break;
    }
  }

  console.log(`\nRecreation complete! Bake '${bakeName}' is ready in repo '${targetRepo}'`);
}

// Usage
recreateBake('source_repo', 'target_repo', 'my_bake');