Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
23ec5d4
Durable AI first phase
Duncanma Aug 17, 2026
e85ef30
Make the integration grid & guide grid persist their filters in the URL
Duncanma Aug 17, 2026
15ec29e
Refactor AI Cookbook components and enhance integration with new Cook…
Duncanma Aug 17, 2026
8cc47d7
Update vercel.json to correct AI Cookbook destination paths for routi…
Duncanma Aug 17, 2026
1a5425a
Enhance CookbookPreview component to display remaining recipes count
Duncanma Aug 17, 2026
22bfd6d
Merge branch 'main' into ai-landing-page
Duncanma Aug 17, 2026
6124c6a
add option to hide sdk options that have no matching content
Duncanma Aug 18, 2026
a282ef2
Enhance AI documentation with new GridCardList component and featured…
Duncanma Aug 18, 2026
4cc0807
Update AI documentation to clarify community project showcase descrip…
Duncanma Aug 18, 2026
24a007e
Update AI documentation to rename section from "Use cases" to "Common…
Duncanma Aug 18, 2026
b58016d
Got rid of use cases, made that content part of the top intro
Duncanma Aug 18, 2026
19dad47
Refine AI documentation and terminology
Duncanma Aug 18, 2026
d55b432
Merge branch 'main' into ai-landing-page
Duncanma Aug 18, 2026
1dda3aa
Fix to old redirects with the new path.
Duncanma Aug 18, 2026
72b8027
Update Model training intro to include links to long-running activity…
Duncanma Aug 18, 2026
94a9761
Merge branch 'main' into ai-landing-page
Duncanma Aug 20, 2026
7b470b5
Update Temporal headings to specify 'AI Cookbook' as an exact phrase …
Duncanma Aug 20, 2026
38c8cd2
Merge branch 'main' into ai-landing-page
Duncanma Aug 20, 2026
d4782ea
Just add .md redirects
Duncanma Aug 20, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -55,5 +55,6 @@ test-results/*
# screenshots
screenshots
# Ignore cookbook recipes since they are synced from the remote repo
ai-cookbook
# (anchored to the root — fixtures/ai-cookbook/ is a real, tracked test fixture)
/ai-cookbook
scripts/mermaid-compare/*
1 change: 1 addition & 0 deletions bin/check-redirects-for-moved-pages.js
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ function loadRedirects() {
const config = JSON.parse(fs.readFileSync(VERCEL_JSON, 'utf8'));
return (config.redirects || []).map((r) => ({
source: r.source,
destination: r.destination,
regex: vercelPatternToRegex(r.source),
}));
}
Expand Down
30 changes: 30 additions & 0 deletions bin/check-redirects-for-moved-pages.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -165,4 +165,34 @@ describe('findMatchingRedirect', () => {
);
assert.strictEqual(match, undefined);
});

it('redirects the old AI Cookbook markdown landing page', () => {
const redirects = loadRedirects();
const match = findMatchingRedirect('/ai-cookbook.md', redirects);
assert.ok(match, 'expected /ai-cookbook.md to have a redirect');
assert.strictEqual(match.source, '/ai-cookbook.md');
assert.strictEqual(match.destination, '/ai/cookbook.md');
});

it('redirects renamed AI Cookbook recipe markdown URLs to the new slug', () => {
const redirects = loadRedirects();
const match = findMatchingRedirect(
'/ai-cookbook/basic-python.md',
redirects,
);
assert.ok(match, 'expected /ai-cookbook/basic-python.md to have a redirect');
assert.strictEqual(match.source, '/ai-cookbook/basic-python.md');
assert.strictEqual(
match.destination,
'/ai/cookbook/hello-world-openai-responses-python.md',
);
});

it('redirects the even older /cookbook.md landing page', () => {
const redirects = loadRedirects();
const match = findMatchingRedirect('/cookbook.md', redirects);
assert.ok(match, 'expected /cookbook.md to have a redirect');
assert.strictEqual(match.source, '/cookbook.md');
assert.strictEqual(match.destination, '/ai/cookbook.md');
});
});
8 changes: 4 additions & 4 deletions bin/generate-og-gallery.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ const OUT_FILE = path.join(BUILD_DIR, '__og-gallery.html');
// docusaurus.config.js — every docs plugin instance it renders cards for.
const DOC_TARGETS = [
{ dir: DOCS_DIR, routeBasePath: '/' },
{ dir: AI_COOKBOOK_DIR, routeBasePath: 'ai-cookbook', footerText: 'AI COOKBOOK' },
{ dir: AI_COOKBOOK_DIR, routeBasePath: 'ai/cookbook', footerText: 'AI COOKBOOK' },
];

// Section grouping/labeling is purely a gallery-review concern now — the
Expand Down Expand Up @@ -108,13 +108,13 @@ async function main() {
}
}

// /ai-cookbook (src/pages/ai-cookbook.tsx) is a plain page, not an MDX doc,
// /ai/cookbook (src/pages/ai/cookbook.tsx) is a plain page, not an MDX doc,
// so it's invisible to the DOC_TARGETS walk above — added manually so the
// gallery still shows every card the site actually ships.
const cookbookHomeHtmlPath = path.join(BUILD_DIR, 'ai-cookbook', 'index.html');
const cookbookHomeHtmlPath = path.join(BUILD_DIR, 'ai', 'cookbook', 'index.html');
if (fs.existsSync(cookbookHomeHtmlPath)) {
cards.push({
urlPath: '/ai-cookbook',
urlPath: '/ai/cookbook',
section: 'AI Cookbook',
title: 'AI Cookbook (landing page)',
isOverride: true,
Expand Down
17 changes: 13 additions & 4 deletions bin/sync-ai-cookbook.js
Original file line number Diff line number Diff line change
Expand Up @@ -442,9 +442,17 @@ function rewriteLinks(body, readmePath, slugLookup, assetMap) {
});
}

function rewriteCookbookLinkPrefix(body) {
// Recipe READMEs in the external ai-cookbook repo sometimes hardcode absolute
// links to other recipes using this site's current route (e.g.
// /ai-cookbook/some-recipe). Rewrite that prefix so those links keep
// resolving after the /ai/cookbook move, independent of any slug rename.
return body.split('/ai-cookbook/').join('/ai/cookbook/');
}

function applyCookbookSlugAliases(body) {
// Resolve aliased/renamed cookbook slugs in links to their current slugs.
// Handles both relative (./slug.mdx) and absolute (/ai-cookbook/slug) formats.
// Handles both relative (./slug.mdx) and absolute (/ai/cookbook/slug) formats.
if (SLUG_ALIASES.size === 0) {
return body;
}
Expand All @@ -457,8 +465,8 @@ function applyCookbookSlugAliases(body) {
return `${prefix}${newSlug}${ext || ''}${suffix || ''}`;
});

// Match absolute links: /ai-cookbook/old-slug (with optional query/hash)
const absolutePattern = new RegExp(`(/ai-cookbook/)${oldSlug}([?#][^)\\s"']*)?(?=[)\\s"'])`, 'g');
// Match absolute links: /ai/cookbook/old-slug (with optional query/hash)
const absolutePattern = new RegExp(`(/ai/cookbook/)${oldSlug}([?#][^)\\s"']*)?(?=[)\\s"'])`, 'g');
result = result.replace(absolutePattern, (match, prefix, suffix) => {
return `${prefix}${newSlug}${suffix || ''}`;
});
Expand Down Expand Up @@ -582,7 +590,8 @@ async function transformReadme(readmePath, slugLookup) {
const markdownImages = convertHtmlImagesToMarkdown(rewrittenBody);
const docusaurusAdmonitions = convertGitHubAdmonitions(markdownImages);
const mdxCompatibleBody = fixUnclosedHtmlTags(docusaurusAdmonitions);
const aliasResolvedBody = applyCookbookSlugAliases(mdxCompatibleBody);
const prefixRewrittenBody = rewriteCookbookLinkPrefix(mdxCompatibleBody);
const aliasResolvedBody = applyCookbookSlugAliases(prefixRewrittenBody);
const finalContent = `${frontMatterBlock}\n\n${aliasResolvedBody.length > 0 ? `${aliasResolvedBody}\n` : ''}`;

return {
Expand Down
6 changes: 3 additions & 3 deletions bin/validate-og-images.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ const AI_COOKBOOK_DIR = path.join(process.cwd(), 'ai-cookbook');
// this validator checks the same pages the plugin generates cards for.
const DOC_TARGETS = [
{ dir: DOCS_DIR, routeBasePath: '/' },
{ dir: AI_COOKBOOK_DIR, routeBasePath: 'ai-cookbook', footerText: 'AI COOKBOOK' },
{ dir: AI_COOKBOOK_DIR, routeBasePath: 'ai/cookbook', footerText: 'AI COOKBOOK' },
];

function walkHtmlFiles(dir) {
Expand Down Expand Up @@ -140,12 +140,12 @@ async function main() {
}
}

// /ai-cookbook (src/pages/ai-cookbook.tsx) is a plain page, not an MDX doc,
// /ai/cookbook (src/pages/ai/cookbook.tsx) is a plain page, not an MDX doc,
// so it never went through the DOC_TARGETS loop above — but it does declare
// its own og:image (see plugins/cookbook-index's postBuild), so it's
// checked here as a manual override rather than folded into "other pages
// must match the site default" below.
const cookbookHomeHtmlPath = path.join(BUILD_DIR, 'ai-cookbook', 'index.html');
const cookbookHomeHtmlPath = path.join(BUILD_DIR, 'ai', 'cookbook', 'index.html');
if (fs.existsSync(cookbookHomeHtmlPath)) {
docHtmlPaths.add(cookbookHomeHtmlPath);
docPagesChecked++;
Expand Down
122 changes: 122 additions & 0 deletions docs/ai/index.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
---
id: index
title: Durable AI
sidebar_label: Overview
description: Build durable AI agents and systems on Temporal, with runnable cookbook recipes, SDK integrations, and design patterns for agent workloads.
slug: /ai
---

import PatternCards from '@site/src/components/PatternCards';
import IntegrationsGrid from '@site/src/components/IntegrationsGrid';
import { CookbookPreview, GridCardList } from '@site/src/components';

Temporal gives AI applications and agents Durable Execution: a Workflow resumes automatically after a crash, a
network timeout, or a multi-day wait for a human to approve a step. Temporal shows up in four recurring types of AI
system:

**Agents.** Long-running, stateful agent loops that call LLMs and tools, wait on humans, and pick up exactly where
they left off after a failure. Start with the [AI Cookbook](/ai/cookbook) and the
[Approval](/design-patterns/approval) and [Entity Workflow](/design-patterns/entity-workflow) patterns.

**Processing pipelines.** Multi-step data and document pipelines, such as extraction, embedding, or batch inference,
that need to fan out, retry failed steps in isolation, and resume without reprocessing completed work. See the
[batch processing patterns](/design-patterns#batch-processing-patterns).

**Internal agent platforms.** Teams building a shared runtime for many agents reuse Temporal's Worker and Task Queue
primitives instead of building their own scheduler. See the
[worker configuration patterns](/design-patterns#worker-configuration-patterns) for routing and isolating agent
workloads.

**Model training.** Long-running training and fine-tuning jobs coordinated across GPU resources, with checkpointing
and recovery handled by Temporal's Event History instead of custom orchestration code. Start with the [long-running activity](/design-patterns/long-running-activity) and [parallel-execution](/design-patterns/parallel-execution) patterns.

> Looking to use an AI coding assistant to write Temporal code instead? See [Develop with AI](/with-ai).

## AI Cookbook
Comment thread
Duncanma marked this conversation as resolved.

Runnable, step-by-step recipes for building AI systems and agents with Temporal: tool calling, MCP, structured
output, human-in-the-loop, and more.

<CookbookPreview limit={4} />

## Agent framework integrations

Temporal integrations for the SDKs and frameworks teams use to build agents. This view is pre-filtered to agent
frameworks — browse [every integration](/integrations) for the full catalog.

<IntegrationsGrid defaultTags={["Agent framework"]} hideTagFilter hideEmptyOptions />

## Featured from the Code Exchange
Comment thread
Duncanma marked this conversation as resolved.

A hand-picked look at samples built with Temporal and AI. Browse the full
[Code Exchange](https://temporal.io/code-exchange) for more.

<GridCardList className="code-exchange-featured"
items={[
{
href: "https://temporal.io/code-exchange/ai-enhanced-e-commerce-application",
title: "AI enhanced e-commerce application",
description: "A sample e-commerce gift shop with hybrid full-text and vector search plus an AI-powered chat shopping assistant, built with Stripe and Temporal Workflows.",
tags: ["Hybrid search"],
sdk: "Dotnet",
},
{
href: "https://temporal.io/code-exchange/ai-question-planetarium",
title: "Temporal AI Question Planetarium",
description: "Runs a Hugging Face model inside Temporal Activities and Workers, streaming updates to the browser over WebSockets in real time.",
tags: ["Demo"],
sdk: "Python",
},
{
href: "https://temporal.io/code-exchange/document-processing-w-ai",
title: "Document Processing w/ AI",
description: "A mortgage underwriting demo that uses Gemini OCR and policy-grounded AI analysis in deterministic Workflows, with human-in-the-loop review and full traceability.",
tags: ["Gemini", "Mortgage"],
sdk: "Python",
},
{
href: "https://temporal.io/code-exchange/rust-confessional",
title: "Rust Confessional: a durable AI agent demo",
description: "A live demo where an AI agent judges audience programming confessions, its progress surviving a Worker crash mid-task.",
tags: ["Demo"],
sdk: "Rust",
},
]} />

## Design patterns for AI agents

<PatternCards items={[
{
href: "/design-patterns/approval",
icon: "approval-icon.svg",
title: "Approval",
description: "Human-in-the-loop Workflows that block until external approval decisions are made. Uses Signals to capture approval data with metadata.",
},
{
href: "/design-patterns/saga-pattern",
icon: "saga-icon.svg",
title: "Saga Pattern",
description: "Manages distributed transactions with compensating actions. Each step has a compensation that undoes its effects if subsequent steps fail.",
},
{
href: "/design-patterns/long-running-activity",
icon: "long-running-activity-icon.svg",
title: "Long-Running Activity",
description: "Long-running Activities report progress via heartbeats and enable resumption after failures with cancellation support.",
},
{
href: "/design-patterns/entity-workflow",
icon: "entity-workflow-icon.svg",
title: "Entity Workflow",
description: "Models long-lived business entities as individual Workflows that persist for the entity's entire lifetime, handling all state transitions through Signals and Updates.",
},
{
href: "/design-patterns/local-activities",
icon: "local-activities-icon.svg",
title: "Local Activities",
description: "Run Activity functions in-process inside the Workflow Task, eliminating all server scheduling round-trips. Best for short, idempotent Activities on a latency-sensitive path.",
},
]} />

Browse the full [Design Patterns catalog](/design-patterns) for more, or jump straight into the
[AI Cookbook](/ai/cookbook) for runnable code.
16 changes: 8 additions & 8 deletions docusaurus.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -113,9 +113,9 @@ module.exports = async function createConfigAsync() {
right: 'left',
},
{
label: 'AI Cookbook',
to: '/ai-cookbook',
activeBasePath: 'ai-cookbook',
label: 'Durable AI',
to: '/ai',
activeBasePath: 'ai',
position: 'left',
},
// hide this for now, making this a soft-launch
Expand Down Expand Up @@ -375,7 +375,7 @@ module.exports = async function createConfigAsync() {
{
id: 'ai-cookbook',
path: 'ai-cookbook',
routeBasePath: 'ai-cookbook', // published at /ai-cookbook/* ✅
routeBasePath: 'ai/cookbook', // published at /ai/cookbook/* ✅
sidebarPath: false, // no left nav for these pages ✅
// optional polish:
showLastUpdateAuthor: true,
Expand All @@ -395,15 +395,15 @@ module.exports = async function createConfigAsync() {
require.resolve('./plugins/cookbook-index'),
{
docsDir: 'ai-cookbook', // change if your folder differs
routeBasePath: 'ai-cookbook', // change if you use a different base
routeBasePath: 'ai/cookbook', // change if you use a different base
},
],
[
require.resolve('./plugins/markdown-pages'),
{
targets: [
{ docsDir: 'docs', routeBasePath: '/' },
{ docsDir: 'ai-cookbook', routeBasePath: 'ai-cookbook' },
{ docsDir: 'ai-cookbook', routeBasePath: 'ai/cookbook' },
],
llmsTxt: {
siteUrl: 'https://docs.temporal.io',
Expand Down Expand Up @@ -447,7 +447,7 @@ module.exports = async function createConfigAsync() {
{ path: 'best-practices', title: 'Best Practices', description: 'Recommended patterns for Temporal' },
{ path: 'design-patterns', title: 'Design Patterns', description: 'Reusable Workflow and Activity patterns for common orchestration problems.' },
{ path: 'guides', title: 'Guides', description: 'End-to-end walkthroughs that solve a specific problem with Temporal.' },
{ path: 'ai-cookbook', title: 'AI Cookbook', description: 'Runnable examples for building AI and agent applications with Temporal.' },
{ path: 'ai/cookbook', title: 'AI Cookbook', description: 'Runnable examples for building AI and agent applications with Temporal.' },
{ path: 'demos', title: 'Interactive Demos', description: 'Browser-based interactive demos. These pages are visual tools rather than prose documentation.' },
],
},
Expand All @@ -458,7 +458,7 @@ module.exports = async function createConfigAsync() {
{
targets: [
{ docsDir: 'docs', routeBasePath: '/' },
{ docsDir: 'ai-cookbook', routeBasePath: 'ai-cookbook', footerText: 'AI COOKBOOK' },
{ docsDir: 'ai-cookbook', routeBasePath: 'ai/cookbook', footerText: 'AI COOKBOOK' },
],
},
],
Expand Down
7 changes: 7 additions & 0 deletions fixtures/ai-cookbook/high-priority.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
title: High priority recipe
description: This one should sort first.
priority: 900
---

Fixture content.
7 changes: 7 additions & 0 deletions fixtures/ai-cookbook/index.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
id: cookbook
title: AI Cookbook
description: Should be excluded from readCookbookRecipes as the index page.
---

Fixture content.
6 changes: 6 additions & 0 deletions fixtures/ai-cookbook/no-priority-a.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
title: A recipe
description: Also no priority.
---

Fixture content.
6 changes: 6 additions & 0 deletions fixtures/ai-cookbook/no-priority-b.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
title: B recipe
description: No priority set.
---

Fixture content.
8 changes: 5 additions & 3 deletions plugins/cookbook-index/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ console.log('[cookbook-index] init with docsDir:', options.docsDir);
setGlobalData({ items: content.items });
},

// The /ai-cookbook landing page (src/pages/ai-cookbook.tsx) is a plain
// The /ai/cookbook landing page (src/pages/ai/cookbook.tsx) is a plain
// React page, not an MDX doc, so it's invisible to plugins/markdown-pages
// (which only walks docsDir trees). It links to a markdown alternate
// (<link rel="alternate" type="text/markdown">) same as every recipe
Expand All @@ -127,8 +127,10 @@ console.log('[cookbook-index] init with docsDir:', options.docsDir);
'',
];

fs.writeFileSync(path.join(outDir, 'ai-cookbook.md'), lines.join('\n'));
console.log(`[cookbook-index] Generated ai-cookbook.md index (${sorted.length} recipe(s))`);
const aiCookbookMdDir = path.join(outDir, 'ai');
fs.mkdirSync(aiCookbookMdDir, { recursive: true });
fs.writeFileSync(path.join(aiCookbookMdDir, 'cookbook.md'), lines.join('\n'));
console.log(`[cookbook-index] Generated ai/cookbook.md index (${sorted.length} recipe(s))`);

// Same reasoning as the .md file above: this page is invisible to
// plugins/og-image's docsDir walk, so nothing else renders it a card.
Expand Down
Loading