Calling a workflow
A conversation can’t pause for 30 minutes while a patient finishes a scan. A workflow can. So the agent starts the workflow and keeps talking.
The person says “I’ve had chest pain since this morning.” The agent decides they need a scan, starts health-scan with their patient id and phone number, and replies that the link is on the way.
The files
clinic/
index.ts agent
health-scan.ts workflow
tools.ts helpershealth-scan.ts is the workflow from the workflow Quick start. It stays in its own file, because a file runs its first workflow() or chatAgent(), not both.
The tool
The tool imports the workflow and starts a run with trigger:
import { defineTool, Type } from "@loops/sdk";
import { healthScanWorkflow } from "./health-scan";
export const startHealthScan = defineTool({
name: "start_health_scan",
description: "Send the patient a facial scan link",
parameters: Type.Object({
patientId: Type.String(),
phoneNumber: Type.String(),
}),
execute: async (input) => {
const { runId, scanUrl } = await healthScanWorkflow.trigger(input);
return { runId, scanUrl };
},
});input becomes the workflow’s event.body, the same as a POST. trigger returns { runId, workflowInstanceId, scanSessionId?, scanUrl? } once the run has started. It does not wait for the scan.
The workflow has to be in the same project. Triggering one in another project fails.
The agent
import { chatAgent, model } from "@loops/sdk";
import { startHealthScan } from "./tools";
export const healthChatAgent = chatAgent({
id: "health-chat",
execute: async ({ submit, messages }) =>
submit({
messages,
instructions:
"You are a health concierge. When someone describes a symptom, offer a face scan and send the link.",
tools: [startHealthScan],
model: model("gpt-4o-mini"),
}),
});The model calls start_health_scan when the conversation needs a scan. It gets back runId and scanUrl, and can hand the link to the person in its reply.
What happens next
- The agent replies in the thread: “Here is your scan link.”
- The workflow run creates the scan and pauses on
waitForScan. - The patient finishes, or 30 minutes pass. The workflow sends the notification.
- The thread is still there. When the person comes back, the agent sees the whole conversation.
The agent never waits on the workflow’s result. If it needs to know how the scan went, that comes from the next message or from what the workflow saved with ctx.USER, not from the tool call.
trigger starts a new run each time it is called. If the model calls the tool twice, there are two runs.