Ask → session → artifact
Full Ask journey: start with a pinned workflow, wait for execution, download
session-report.md.
Ask journeys use the API token only (no webhook token).
| Step | What the SDK does |
|---|---|
| 1. Start | POST /guild/api/v1/guild/ask/start |
| 2. Poll | Wait until execution settles |
| 3. Artifact | Poll session artifacts, then download to a local path |
Minimal — one SDK call
from stackgen import StackgenClient, StackgenConfig
client = StackgenClient(
StackgenConfig(
base_url="https://app.stackgen.com",
api_token="stackgen_…",
workspace_id="<workspace-uuid>",
)
)
result = client.aiden.run_ask_and_download_artifact(
"Run triage for checkout CPU alert",
entity_refs=[{"name": "incident-triage", "type": "workflow"}],
)
print(result.trace_id, result.session_id, result.output_path)import { StackgenClient, StackgenConfig } from "stackgen-sdk";
const client = new StackgenClient(
new StackgenConfig({
baseUrl: "https://app.stackgen.com",
apiToken: "stackgen_…",
workspaceId: "<workspace-uuid>",
}),
);
const result = await client.aiden.runAskAndDownloadArtifact({
message: "Run triage for checkout CPU alert",
entityRefs: [{ name: "incident-triage", type: "workflow" }],
});
console.log(result.traceId, result.sessionId, result.outputPath);result, err := client.Aiden.RunAskAndDownloadArtifact(ctx,
"Run triage for checkout CPU alert",
aiden.StartAskOptions{
EntityRefs: []aiden.EntityRef{{Name: "incident-triage", Type: "workflow"}},
},
"session-report.md",
"session-report.md",
)
if err != nil { return err }
fmt.Println(result.TraceID, result.SessionID, result.OutputPath)
return nilRunnable CLI
- Python:
examples/ask/ask-download-report.py - TypeScript:
examples/ask/ask-download-report.ts - Go:
examples/go/ask/ask-download-report.go
#!/usr/bin/env python3
"""Ask → wait → download session artifact (CI-friendly, no webhook token)."""
from __future__ import annotations
import argparse
import os
import sys
from stackgen import StackgenClient, StackgenConfig
def main() -> int:
parser = argparse.ArgumentParser(
description="Start Ask, poll execution, download a session artifact.",
)
parser.add_argument("--base-url", default=os.environ.get("STACKGEN_URL", ""), help="Mothership URL (no /guild suffix)")
parser.add_argument("--api-token", default=os.environ.get("STACKGEN_TOKEN", ""), help="API token (stackgen_…)")
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", ""),
help="Workspace UUID (sent as orgId)",
)
parser.add_argument("--message", required=True, help="Natural-language task for Ask")
parser.add_argument(
"--workflow-name",
required=True,
help="Workflow skill name to pin via entity_refs",
)
parser.add_argument("--timeout-seconds", type=int, default=1800)
parser.add_argument(
"--artifact-name",
default="session-report.md",
help="Session artifact filename to download",
)
parser.add_argument(
"--output-path",
default="session-report.md",
help="Local path to write the artifact",
)
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,
artifact_name=args.artifact_name,
output_path=args.output_path,
timeout_seconds=args.timeout_seconds,
)
)
result = client.aiden.run_ask_and_download_artifact(
args.message,
entity_refs=[{"name": args.workflow_name, "type": "workflow"}],
artifact_name=args.artifact_name,
output_path=args.output_path,
)
print(
f"trace_id={result.trace_id} session_id={result.session_id} "
f"output={result.output_path}",
file=sys.stderr,
)
return 0
if __name__ == "__main__":
raise SystemExit(main())/**
* Ask → wait → download session artifact (CI-friendly, no webhook token).
*
* Docs: https://appcd-dev.github.io/stackgen-sdk/code-samples/ask-artifact/
*
* Usage:
* npx tsx ask-download-report.ts \
* --base-url https://app.stackgen.com \
* --api-token stackgen_… \
* --workspace-id <workspace-uuid> \
* --message 'Run triage for checkout CPU alert' \
* --workflow-name incident-triage
*/
import { parseArgs } from "node:util";
import { StackgenClient, StackgenConfig } 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-name": { type: "string" },
"artifact-name": { type: "string", default: "session-report.md" },
"output-path": { type: "string", default: "session-report.md" },
"timeout-seconds": { type: "string", default: "1800" },
},
});
if (!values.message || !values["workflow-name"] || !values["base-url"] || !values["api-token"] || !(values["org-id"] || values["workspace-id"])) {
throw new Error("require --message, --workflow-name, 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"]),
artifactName: values["artifact-name"],
outputPath: values["output-path"],
timeoutSeconds: Number(values["timeout-seconds"]),
}),
);
const result = await client.aiden.runAskAndDownloadArtifact(values.message, {
entityRefs: [{ name: values["workflow-name"], type: "workflow" }],
artifactName: values["artifact-name"],
outputPath: values["output-path"],
});
console.error(
`traceId=${result.traceId} sessionId=${result.sessionId} output=${result.outputPath}`,
);
}
main().catch((err) => {
console.error(err instanceof Error ? err.message : err);
process.exit(1);
});// Ask start, wait, and download a session artifact.
//
// Documented at https://appcd-dev.github.io/stackgen-sdk/code-samples/ask-artifact/
//
// go run ./examples/go/ask/ask-download-report.go \
// --message 'Run triage for checkout CPU alert' \
// --workflow-name incident-triage
package main
import (
"context"
"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 (no /guild suffix)")
apiToken := flag.String("api-token", envOr("STACKGEN_TOKEN"), "API token (stackgen_…)")
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", "", "Natural-language task for Ask")
workflowName := flag.String("workflow-name", "", "Workflow name to pin via entity_refs")
timeoutSeconds := flag.Int("timeout-seconds", 1800, "Overall timeout")
artifactName := flag.String("artifact-name", "session-report.md", "Session artifact filename")
outputPath := flag.String("output-path", "session-report.md", "Local path to write the artifact")
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(*workflowName) == "" {
fmt.Fprintln(os.Stderr, "--message and --workflow-name are required")
os.Exit(2)
}
client, err := stackgen.NewClient(stackgen.Config{
BaseURL: *baseURL,
APIToken: *apiToken,
WorkspaceID: *orgID,
ArtifactName: *artifactName,
OutputPath: *outputPath,
TimeoutSeconds: *timeoutSeconds,
})
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
result, err := client.Aiden.RunAskAndDownloadArtifact(context.Background(), *message, aiden.StartAskOptions{
EntityRefs: []aiden.EntityRef{{Name: *workflowName, Type: "workflow"}},
}, *artifactName, *outputPath)
if err != nil {
fmt.Fprintln(os.Stderr, "error:", err)
os.Exit(1)
}
fmt.Fprintf(os.Stderr, "trace_id=%s session_id=%s output=%s\n", result.TraceID, result.SessionID, result.OutputPath)
}Related: Ask → execution
— poll only, no download.
Ask → session artifacts
— startAsk + subscribe wait + list/download every file (changelog and operator notes).