How Prompt Connections Create Workflows in prompts.chat

Prompt connections in prompts.chat form directed workflow graphs by storing edges in a PostgreSQL database via Prisma, traversing connected prompts using BFS in a cached API endpoint, and rendering the results as interactive D3.js visualizations.

Prompt workflows allow users to chain individual prompts into multi-step automation sequences. In the f/prompts.chat repository, these workflows are built using a graph data model where nodes represent prompts and edges represent directional prompt connections. The implementation spans the database schema, REST API endpoints, and React frontend components that handle visualization and user interaction.

Database Schema for Prompt Connections

At the foundation of every workflow lies the PromptConnection model defined in prisma/schema.prisma around line 80. This table stores directed edges linking two prompts together.

model PromptConnection {
  id        String @id @default(cuid())
  sourceId  String
  targetId  String
  label     String
  order     Int    @default(0)
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt

  source Prompt @relation("ConnectionSource", fields: [sourceId], references: [id], onDelete: Cascade)
  target Prompt @relation("ConnectionTarget", fields: [targetId], references: [id], onDelete: Cascade)

  @@unique([sourceId, targetId])
  @@index([sourceId])
  @@index([targetId])
}

Each row represents a directed edge from sourceId to targetId. The schema enforces referential integrity with onDelete: Cascade and prevents duplicate relationships through the @@unique([sourceId, targetId]) constraint. The label field stores human-readable edge descriptions, while order controls the visual positioning of multiple outgoing connections.

API Architecture for Workflow Management

The system exposes two primary API surfaces: individual connection management and complete graph traversal.

Managing Direct Connections

The src/app/api/prompts/[id]/connections/route.ts file implements CRUD operations for prompt connections.

GET requests return two arrays—outgoing and incoming—filtered to exclude AI-suggested connections (where label: { not: "related" }). The endpoint also filters out private prompts unless the requester is the author.

POST requests create new workflow edges. The handler validates that the authenticated user owns both the source and target prompts, prevents self-connections, and ensures uniqueness. Upon successful creation, it calls revalidateTag("prompt-flow") to invalidate cached graph data.

DELETE requests remove specific connections after confirming ownership via the src/app/api/prompts/[id]/connections/[connectionId] route.

Traversing Complete Workflow Graphs

The src/app/api/prompts/[id]/flow/route.ts endpoint computes the transitive closure of a prompt's workflow using breadth-first search (BFS). The implementation uses unstable_cache tagged with "prompt-flow" for performance.

The algorithm:

  1. Collects all reachable prompt IDs via BFS while tracking visited nodes to prevent infinite loops
  2. Performs a single batch query (db.prompt.findMany) to fetch all node data
  3. Filters out private prompts where isPrivate && authorId !== userId
  4. Returns a minimal graph structure with nodes and edges arrays

Frontend Implementation

Data Fetching with PromptConnections

The PromptConnections component in src/components/prompts/prompt-connections.tsx orchestrates data fetching by parallelizing requests to both endpoints:

const [connRes, flowRes] = await Promise.all([
  fetch(`/api/prompts/${promptId}/connections`),
  fetch(`/api/prompts/${promptId}/flow`),
]);

This approach retrieves both the direct connection list (for editing) and the complete workflow graph (for visualization) simultaneously.

Interactive Visualization with FlowGraph

Inside the same file, the FlowGraph subcomponent consumes the graph data to render an interactive SVG. The D3-based implementation performs topological sorting to assign vertical levels, ensuring a left-to-right, top-to-bottom flow layout. It generates virtual input/output nodes for prompts requiring media uploads and draws curved edges with arrowheads and labels.

Creating Connections via AddConnectionDialog

The AddConnectionDialog component in src/components/prompts/add-connection-dialog.tsx provides the search interface for finding target prompts. When users submit the form, the component constructs the appropriate directional edge:

const sourceId = connectionType === "previous" 
  ? selectedPrompt.id 
  : promptId;
const targetId = connectionType === "previous" 
  ? promptId 
  : selectedPrompt.id;

await fetch(`/api/prompts/${sourceId}/connections`, {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ targetId, label: label.trim() }),
});

Implementing Workflow Connections

To programmatically create a workflow link between two prompts, send an authenticated POST request:

// Creating a "next" connection
await fetch(`/api/prompts/${sourcePromptId}/connections`, {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    targetId: targetPromptId,
    label: "Generate image",
  }),
});

After creation, the revalidateTag("prompt-flow") call ensures the next request to the flow endpoint rebuilds the graph including the new edge.

Privacy and Visibility Controls

The workflow system respects prompt privacy settings by filtering private prompts from graph results when the requester is not the author. This filtering occurs in the database queries within the flow endpoint and in the connection list endpoint, ensuring private prompts never appear in other users' workflow visualizations.

Summary

  • PromptConnection model: Stores directed edges with sourceId, targetId, labels, and ordering in PostgreSQL via Prisma at prisma/schema.prisma
  • API endpoints: Separate handlers for individual connections ([id]/connections) and complete graph traversal ([id]/flow) using BFS with unstable_cache
  • Caching strategy: revalidateTag("prompt-flow") invalidates cached graphs immediately after connection mutations
  • Frontend components: PromptConnections fetches data, FlowGraph renders D3 visualizations with topological sorting, and AddConnectionDialog handles the creation UI
  • Security model: Ownership validation on all mutations and visibility filtering on all reads protect private prompt workflows

Frequently Asked Questions

What database structure enables prompt connections in prompts.chat?

Prompt connections rely on the PromptConnection model in prisma/schema.prisma, which defines a directed edge with sourceId and targetId foreign keys referencing the Prompt table. The model includes fields for label (edge description), order (UI positioning), and unique constraints preventing duplicate relationships between the same prompts.

How does the flow API handle circular references in workflows?

The flow endpoint in src/app/api/prompts/[id]/flow/route.ts implements a breadth-first search algorithm that tracks visited prompt IDs in a Set data structure. This ensures each prompt is processed only once, preventing infinite recursion in circular workflow configurations while still capturing all unique nodes and edges.

Can users create connections between prompts they don't own?

No. The POST handler in src/app/api/prompts/[id]/connections/route.ts validates that the authenticated user owns both the source and target prompts by checking authorId against the session user ID. The API returns an authorization error if ownership validation fails, ensuring users can only connect prompts within their own workflow pipelines.

What triggers updates to the cached workflow visualization?

The system uses Next.js unstable_cache tagged with "prompt-flow". When mutations occur—such as creating or deleting connections via POST or DELETE requests—the handlers call revalidateTag("prompt-flow"), which invalidates the cached graph data. Subsequent requests to the flow endpoint regenerate the workflow graph from the database.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →