Ask → wait for execution
Start Ask with a pinned workflow, then poll until execution.status settles.
No artifact download — use this when you only need trace/session ids or execution outcome.
Ask journeys use the API token only (no webhook token). Pin a workflow with
entity_refs in CI so routing is deterministic.
| Step | What the SDK does |
|---|---|
| 1. Start | POST /guild/api/v1/guild/ask/start with message and optional entity_refs |
| 2. Poll | GET /guild/api/v1/executions/{traceId} until status is terminal and trace_settled |
Minimal — start and poll
from stackgen import StackgenClient, StackgenConfig
client = StackgenClient(
StackgenConfig(
base_url="https://app.stackgen.com",
api_token="stackgen_…",
workspace_id="<workspace-uuid>",
)
)
start = client.aiden.start_ask(
"Run triage for checkout CPU alert",
entity_refs=[{"name": "incident-triage", "type": "workflow"}],
)
trace = client.aiden.wait_for_execution(start["trace_id"])
print(trace["session_id"], trace["execution"]["status"])import { StackgenClient, StackgenConfig } from "stackgen-sdk";
const client = new StackgenClient(
new StackgenConfig({
baseUrl: "https://app.stackgen.com",
apiToken: "stackgen_…",
workspaceId: "<workspace-uuid>",
}),
);
const start = await client.aiden.startAsk("Run triage for checkout CPU alert", {
entityRefs: [{ name: "incident-triage", type: "workflow" }],
});
const trace = await client.aiden.waitForExecution(String(start.trace_id));
const execution = trace.execution as Record<string, unknown>;
console.log(trace.session_id, execution.status);start, err := client.Aiden.StartAsk(ctx, "Run triage for checkout CPU alert", aiden.StartAskOptions{
EntityRefs: []aiden.EntityRef{{Name: "incident-triage", Type: "workflow"}},
})
if err != nil { return err }
trace, err := client.Aiden.WaitForExecution(ctx, start.TraceID)
if err != nil { return err }
execution, _ := trace["execution"].(map[string]any)
fmt.Println(trace["session_id"], execution["status"])
return nilRunnable CLI
- Python:
examples/ask/ask-wait-session.py - TypeScript:
examples/ask/ask-wait-session.ts - Go:
examples/go/ask/ask-wait-session.go
#!/usr/bin/env python3
"""Ask start → wait for execution (no artifact download).
Documented at https://appcd-dev.github.io/stackgen-sdk/code-samples/ask-execution/
Usage:
python ask-wait-session.py \\
--base-url https://app.stackgen.com \\
--api-token stackgen_… \\
--workspace-id <workspace-uuid> \\
--message 'Run triage for checkout CPU alert' \\
--workflow incident-triage
"""
from __future__ import annotations
import argparse
import json
import os
import sys
from stackgen import StackgenClient, StackgenConfig
from stackgen.errors import StackgenError
def main() -> int:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--base-url", default=os.environ.get("STACKGEN_URL", ""))
parser.add_argument("--api-token", default=os.environ.get("STACKGEN_TOKEN", ""))
parser.add_argument(
"--workspace-id",
"--org-id",
default=os.environ.get("STACKGEN_WORKSPACE_ID") or os.environ.get("STACKGEN_PROJECT") or os.environ.get("STACKGEN_PROJECT_ID", ""),
)
parser.add_argument("--message", required=True)
parser.add_argument(
"--workflow",
required=True,
help="Workflow name for entity_refs pin",
)
parser.add_argument("--timeout-seconds", type=int, default=1800)
parser.add_argument("--poll-interval-seconds", type=int, default=5)
args = parser.parse_args()
if not args.base_url or not args.api_token or not args.workspace_id:
parser.error("set --base-url/--api-token/--workspace-id or STACKGEN_URL/STACKGEN_TOKEN/STACKGEN_WORKSPACE_ID")
client = StackgenClient(
StackgenConfig(
base_url=args.base_url,
api_token=args.api_token,
workspace_id=args.workspace_id,
timeout_seconds=args.timeout_seconds,
poll_interval_seconds=args.poll_interval_seconds,
)
)
start = client.aiden.start_ask(
args.message,
entity_refs=[{"name": args.workflow, "type": "workflow"}],
)
trace_id = start.get("trace_id")
session_id = start.get("session_id")
print("start:", json.dumps(start, indent=2))
trace = client.aiden.wait_for_execution(str(trace_id))
execution = trace.get("execution") or {}
session_id = session_id or trace.get("session_id")
print(
f"settled status={execution.get('status')} "
f"trace_settled={execution.get('trace_settled')} "
f"session_id={session_id}",
file=sys.stderr,
)
return 0
if __name__ == "__main__":
try:
raise SystemExit(main())
except StackgenError as exc:
print(f"error: {exc}", file=sys.stderr)
raise SystemExit(1)/**
* Ask start → wait for execution (no artifact download).
*
* Docs: https://appcd-dev.github.io/stackgen-sdk/code-samples/ask-execution/
*
* Usage:
* npx tsx ask-wait-session.ts \
* --base-url https://app.stackgen.com \
* --api-token stackgen_… \
* --workspace-id <workspace-uuid> \
* --message 'Run triage for checkout CPU alert' \
* --workflow incident-triage
*/
import { parseArgs } from "node:util";
import { StackgenClient, StackgenConfig, StackgenError } from "stackgen-sdk";
async function main(): Promise<void> {
const { values } = parseArgs({
options: {
"base-url": { type: "string", default: process.env.STACKGEN_URL || "" },
"api-token": { type: "string", default: process.env.STACKGEN_TOKEN || "" },
"org-id": { type: "string" },
"workspace-id": {
type: "string",
default: process.env.STACKGEN_WORKSPACE_ID || process.env.STACKGEN_PROJECT || process.env.STACKGEN_PROJECT_ID || "",
},
message: { type: "string" },
workflow: { type: "string" },
"timeout-seconds": { type: "string", default: "1800" },
"poll-interval-seconds": { type: "string", default: "5" },
},
});
if (!values["base-url"] || !values["api-token"] || !(values["org-id"] || values["workspace-id"]) || !values.message || !values.workflow) {
throw new Error("require --message, --workflow, and STACKGEN_URL/STACKGEN_TOKEN/STACKGEN_WORKSPACE_ID or matching flags");
}
const client = new StackgenClient(
new StackgenConfig({
baseUrl: values["base-url"],
apiToken: values["api-token"],
workspaceId: (values["org-id"] || values["workspace-id"]),
timeoutSeconds: Number(values["timeout-seconds"]),
pollIntervalSeconds: Number(values["poll-interval-seconds"]),
}),
);
const start = await client.aiden.startAsk(values.message, {
entityRefs: [{ name: values.workflow, type: "workflow" }],
});
console.log("start:", JSON.stringify(start, null, 2));
const traceId = String(start.trace_id ?? "");
let sessionId = String(start.session_id ?? "");
const trace = await client.aiden.waitForExecution(traceId);
const execution = (trace.execution ?? {}) as Record<string, unknown>;
if (!sessionId) {
sessionId = String(trace.session_id ?? "");
}
console.error(
`settled status=${execution.status} trace_settled=${execution.trace_settled} sessionId=${sessionId}`,
);
}
main().catch((err) => {
console.error(err instanceof StackgenError ? err.message : err);
process.exit(1);
});// Ask start, then poll until the execution settles.
//
// Documented at https://appcd-dev.github.io/stackgen-sdk/code-samples/ask-execution/
//
// go run ./examples/go/ask/ask-wait-session.go \
// --message 'Run triage for checkout CPU alert' \
// --workflow incident-triage
package main
import (
"context"
"encoding/json"
"flag"
"fmt"
"os"
"strings"
stackgen "github.com/appcd-dev/stackgen-sdk/clients/go"
"github.com/appcd-dev/stackgen-sdk/clients/go/aiden"
)
func envOr(keys ...string) string {
for _, key := range keys {
if v := strings.TrimSpace(os.Getenv(key)); v != "" {
return v
}
}
return ""
}
func main() {
baseURL := flag.String("base-url", envOr("STACKGEN_URL"), "Mothership URL")
apiToken := flag.String("api-token", envOr("STACKGEN_TOKEN"), "API token")
orgID := flag.String("workspace-id", envOr("STACKGEN_WORKSPACE_ID", "STACKGEN_PROJECT", "STACKGEN_PROJECT_ID"), "Workspace UUID (sent as orgId)")
flag.StringVar(orgID, "org-id", *orgID, "Deprecated: use -workspace-id")
message := flag.String("message", "", "Ask message")
workflow := flag.String("workflow", "", "Workflow name for entity_refs")
timeoutSeconds := flag.Int("timeout-seconds", 1800, "Overall timeout")
pollInterval := flag.Int("poll-interval-seconds", 5, "Poll interval")
flag.Parse()
if *baseURL == "" || *apiToken == "" || *orgID == "" {
fmt.Fprintln(os.Stderr, "set --base-url/--api-token/--workspace-id or STACKGEN_URL/STACKGEN_TOKEN/STACKGEN_WORKSPACE_ID")
os.Exit(2)
}
if strings.TrimSpace(*message) == "" || strings.TrimSpace(*workflow) == "" {
fmt.Fprintln(os.Stderr, "--message and --workflow are required")
os.Exit(2)
}
client, err := stackgen.NewClient(stackgen.Config{
BaseURL: *baseURL,
APIToken: *apiToken,
WorkspaceID: *orgID,
TimeoutSeconds: *timeoutSeconds,
PollIntervalSeconds: *pollInterval,
})
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
ctx := context.Background()
started, err := client.Aiden.StartAsk(ctx, *message, aiden.StartAskOptions{
EntityRefs: []aiden.EntityRef{{Name: *workflow, Type: "workflow"}},
})
if err != nil {
fmt.Fprintln(os.Stderr, "error:", err)
os.Exit(1)
}
raw, _ := json.MarshalIndent(started.Raw, "", " ")
fmt.Println("start:", string(raw))
trace, err := client.Aiden.WaitForExecution(ctx, started.TraceID)
if err != nil {
fmt.Fprintln(os.Stderr, "error:", err)
os.Exit(1)
}
execution, _ := trace["execution"].(map[string]any)
sessionID := started.SessionID
if sessionID == "" {
if v, ok := trace["session_id"].(string); ok {
sessionID = v
}
}
fmt.Fprintf(os.Stderr, "settled status=%v trace_settled=%v session_id=%s\n", execution["status"], execution["trace_settled"], sessionID)
}Related: Ask → artifact — same start flow plus artifact download.