An agent that starts a workflow

The agent owns the conversation and offloads the slow work. A tool starts an enrich-profile workflow and returns right away, so the user does not wait while the background job runs. Swap start for startAndWait when the agent needs the result before it replies.

The whole agent is a single deep-agents/onboarding/index.ts file. It builds on the agent examples and the workflow examples.

deep-agents/onboarding/index.ts
import { tool } from '@langchain/core/tools';
import { z } from 'zod';
import { defineDeepAgent } from '@stackbone/sdk/deep';
import { stackbone } from '@stackbone/sdk';

const enrichProfile = tool(
  async ({ userId }: { userId: string }) => {
    const handle = await stackbone.workflows.start('enrich-profile', { userId });
    // `queued` means the workflow is serial and an earlier run holds the lock,
    // so there is no run id yet. It starts on its own when the lock frees.
    return JSON.stringify({ status: handle.status, runId: handle.runId ?? null });
  },
  {
    name: 'enrich_profile',
    description: 'Start background enrichment for a user profile.',
    schema: z.object({ userId: z.string() }),
  },
);

export default defineDeepAgent({
  name: 'onboarding',
  model: 'openai/gpt-4o-mini',
  tools: [enrichProfile],
});

The agent's instruction lives in Studio, not in this file. You write and publish it there as a prompt in the catalogue keyed onboarding: help new users get set up, call enrich_profile with the user's id, and say the enrichment is running in the background. The name you pass is both the folder name under deep-agents/ and the default prompt key, so the two must match. See Prompts.

start resolves as soon as the runtime accepts the run, so the tool hands the model an acceptance status rather than the workflow's answer. See serial execution for the queued case.

If the agent needs the workflow's result before it replies, swap start for startAndWait. It suspends until the workflow finishes, then returns the output validated against the target's outputSchema:

const profile = await stackbone.workflows.startAndWait<{ tier: string }>('enrich-profile', {
  userId,
});
return JSON.stringify({ tier: profile.tier });

Both live on the stackbone.workflows namespace. There is no top-level startWorkflow import to reach for.

What's next

BUILT WITH ❤️ FROM CANADA AND SPAIN