Guides / Wait for a result
Wait for a result
Sometimes you only need to know whether the work finished and what it found. This guide waits for a mandate to end, handles waits that outlast your process, and reads the result along with its evidence.
Wait for a terminal status
wait returns when the mandate reaches completed, failed, canceled, or
expired, including work that already finished before you called it.
import { Shadway, ShadwayTimeoutError } from "shadway";
const shadway = new Shadway();
const work = shadway.mandate(mandateId);
try {
const result = await work.wait({ timeout: "30m" });
console.log(result.status, "-", result.currentState.summary);
} catch (error) {
if (!(error instanceof ShadwayTimeoutError)) throw error;
console.log("Still working. Reconnect later with mandate ID:", work.id);
}client, err := shadway.New()
if err != nil {
log.Fatal(err)
}
work := client.Mandate(mandateID)
result, err := work.Wait(ctx, shadway.WaitOptions{Timeout: 30 * time.Minute})
if err != nil {
if shadway.IsTimeout(err) {
fmt.Println("Still working. Reconnect later with mandate ID:", work.ID())
return
}
log.Fatal(err)
}
fmt.Println(result.Status, "-", result.CurrentState.Summary)A timeout ends only your local wait. The mandate keeps running on the server, and waiting again later, from the same process or a different one, picks it up wherever it is. With no timeout set, the wait runs until the mandate ends or you cancel the call.
Reconnect across restarts
Real work runs for days. Your process doesn't have to. The pattern is to store the mandate ID when you create the work, and reconnect by ID whenever you need the answer:
// In the request that starts the work:
const mandate = await shadway.mandates.create({ agent: agentId, objective });
await store.save({ jobId, mandateId: mandate.id });
// In a worker, any time later. Creating a handle starts nothing:
const { mandateId } = await store.load(jobId);
const result = await shadway.mandate(mandateId).wait({ timeout: "5m" });// In the request that starts the work:
mandate, err := client.Mandates.Create(ctx, shadway.MandateCreateParams{
Agent: agentID, Objective: objective,
})
if err != nil {
log.Fatal(err)
}
store.Save(jobID, mandate.ID)
// In a worker, any time later. Creating a handle starts nothing:
mandateID := store.Load(jobID)
result, err := client.Mandate(mandateID).Wait(ctx, shadway.WaitOptions{
Timeout: 5 * time.Minute,
})
if err != nil {
log.Fatal(err) // Or check shadway.IsTimeout and try again later.
}
fmt.Println(result.Status)If your process does more than wait, prefer short timeouts in a retry loop over one long blocking call. Each attempt is cheap, and checking often has no effect on the mandate.
Read the outcome
completed means every success criterion checked out against verified facts.
For any other status, read what the work recorded to understand what happened.
const result = await work.wait({ timeout: "30m" });
if (result.status === "completed") {
for await (const fact of work.facts.list()) {
console.log("fact:", fact.key, "=", fact.value, `(${fact.status})`);
}
for await (const evidence of work.evidence.list()) {
console.log("evidence:", evidence.title, "-", evidence.excerpt);
}
} else {
console.log("Ended", result.status, "-", result.currentState.summary);
for await (const issue of work.issues.list()) {
console.log("open question:", issue.question, `(${issue.state})`);
}
}result, err := work.Wait(ctx, shadway.WaitOptions{Timeout: 30 * time.Minute})
if err != nil {
log.Fatal(err)
}
if result.Status == shadway.MandateStatusCompleted {
for fact, err := range work.Facts(ctx, nil) {
if err != nil {
log.Fatal(err)
}
fmt.Printf("fact: %s = %v (%s)\n", fact.Key, fact.Value, fact.Status)
}
for evidence, err := range work.Evidence(ctx, nil) {
if err != nil {
log.Fatal(err)
}
fmt.Println("evidence:", evidence.Title, "-", evidence.Excerpt)
}
} else {
fmt.Println("Ended", result.Status, "-", result.CurrentState.Summary)
for issue, err := range work.Issues(ctx, nil) {
if err != nil {
log.Fatal(err)
}
fmt.Printf("open question: %s (%s)\n", issue.Question, issue.State)
}
}Facts and evidence are how you trust a completion, and issues are how you diagnose anything else. For how the statuses on facts decide what "completed" means, see Verification.
Wait for an approval instead
If you're waiting for a decision point rather than the end of the work, use
waitForApproval. It returns the pending approval, or nothing if the mandate
ends without asking. The full pattern is in
Handle an approval.