wauldo 0.12.0 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -919,6 +919,125 @@ declare class AgentsClient {
919
919
  streamTask(taskId: string): AsyncGenerator<StateTransition>;
920
920
  }
921
921
 
922
+ /**
923
+ * Workflows API client — Wauldo Workflow Runtime (Step Functions style).
924
+ *
925
+ * State-machine workflows authored as `Task` / `Choice` / `Wait` / `Pass` /
926
+ * `Fail` / `Succeed` states. Runs are async: `startRun` returns an
927
+ * `execution_id`, then poll `getRun` (or use `waitForRun`) until a terminal
928
+ * status.
929
+ *
930
+ * @example
931
+ * ```ts
932
+ * import { WorkflowsClient } from "wauldo/workflows";
933
+ * const wf = new WorkflowsClient({ baseUrl: "https://api.wauldo.com", apiKey: "..." });
934
+ * const created = await wf.create({
935
+ * name: "triage",
936
+ * startAt: "Compute",
937
+ * states: {
938
+ * Compute: { type: "Task", resource: "tool:calculator", next: "Done" },
939
+ * Done: { type: "Succeed" },
940
+ * },
941
+ * });
942
+ * const run = await wf.startRun(created.id, { operation: "add", a: 21, b: 21 });
943
+ * const final = await wf.waitForRun(created.id, run.execution_id);
944
+ * console.log(final.status, final.output);
945
+ * ```
946
+ */
947
+ interface WorkflowsClientConfig {
948
+ baseUrl: string;
949
+ apiKey?: string;
950
+ /** Tenant identifier forwarded via x-rapidapi-user header. */
951
+ tenant?: string;
952
+ /** Per-request timeout in ms. Default 120_000. */
953
+ timeoutMs?: number;
954
+ }
955
+ /** A workflow definition. */
956
+ interface Workflow {
957
+ id: string;
958
+ tenant_id: string;
959
+ name: string;
960
+ description?: string;
961
+ start_at: string;
962
+ states: Record<string, unknown>;
963
+ version: string;
964
+ created_at: number;
965
+ updated_at: number;
966
+ }
967
+ interface CreateWorkflowInput {
968
+ name: string;
969
+ startAt: string;
970
+ states: Record<string, unknown>;
971
+ description?: string;
972
+ }
973
+ interface WorkflowListResponse {
974
+ workflows: Workflow[];
975
+ }
976
+ /** 202 response from `POST /v1/workflows/:id/runs`. */
977
+ interface StartRunResponse {
978
+ execution_id: string;
979
+ workflow_id: string;
980
+ status: string;
981
+ }
982
+ /**
983
+ * A workflow execution record. `status` is one of `running`, `succeeded`,
984
+ * `failed`, `timed_out`. `output` is populated on success; `error` on
985
+ * terminal failure.
986
+ */
987
+ interface WorkflowExecution {
988
+ id: string;
989
+ workflow_id: string;
990
+ tenant_id: string;
991
+ status: string;
992
+ current_state?: string | null;
993
+ input: unknown;
994
+ output?: unknown;
995
+ started_at: number;
996
+ ended_at?: number | null;
997
+ error?: string | null;
998
+ }
999
+ declare const TERMINAL_WORKFLOW_STATUSES: readonly ["succeeded", "failed", "timed_out"];
1000
+ declare function isWorkflowRunTerminal(status: string): boolean;
1001
+ declare class WorkflowsClient {
1002
+ private readonly config;
1003
+ constructor(config: WorkflowsClientConfig);
1004
+ private headers;
1005
+ private request;
1006
+ /**
1007
+ * `POST /v1/workflows` — create a workflow definition.
1008
+ *
1009
+ * The server validates cycles, transition targets, choice operators,
1010
+ * and the per-tenant cap (100) before returning 201.
1011
+ */
1012
+ create(input: CreateWorkflowInput): Promise<Workflow>;
1013
+ /** `GET /v1/workflows` — list workflows for the calling tenant. */
1014
+ list(): Promise<WorkflowListResponse>;
1015
+ /** `GET /v1/workflows/:id` */
1016
+ get(workflowId: string): Promise<Workflow>;
1017
+ /** `DELETE /v1/workflows/:id` */
1018
+ delete(workflowId: string): Promise<void>;
1019
+ /**
1020
+ * `POST /v1/workflows/:id/runs` — start an async execution.
1021
+ *
1022
+ * Returns 202 with an `execution_id` immediately. Poll {@link getRun}
1023
+ * or use {@link waitForRun} to await completion.
1024
+ */
1025
+ startRun(workflowId: string, input?: unknown): Promise<StartRunResponse>;
1026
+ /** `GET /v1/workflows/:id/runs/:execution_id` — fetch one execution. */
1027
+ getRun(workflowId: string, executionId: string): Promise<WorkflowExecution>;
1028
+ /**
1029
+ * Poll {@link getRun} until the run reaches a terminal status.
1030
+ *
1031
+ * Rejects with an error if the run hasn't terminated within
1032
+ * `timeoutMs`. The server enforces its own 60s wall-clock cap per run,
1033
+ * so a timeout larger than ~75_000 is just slack for polling overhead.
1034
+ */
1035
+ waitForRun(workflowId: string, executionId: string, opts?: {
1036
+ timeoutMs?: number;
1037
+ pollIntervalMs?: number;
1038
+ }): Promise<WorkflowExecution>;
1039
+ }
1040
+
922
1041
  /**
923
1042
  * History API client — Wauldo Funnel #1 audit log.
924
1043
  *
@@ -1027,4 +1146,4 @@ declare class HistoryClient {
1027
1146
  deleteTask(taskId: string): Promise<number>;
1028
1147
  }
1029
1148
 
1030
- export { type A2aResponse, AgentClient, type AgentListResponse, type AgentRevision, type AgentRunResponse, AgentsClient, type AgentsClientConfig, type CallToolResponse, type ChatChoice, type ChatClientLike, type ChatMessage, type ChatRequest, type ChatResponse, type ChatUsage, type Chunk, type ChunkResult, type ClientOptions, type Concept, type ConceptResult, ConnectionError, Conversation, type CreateAgentInput, type CreateRevisionInput, type CreateRevisionResponse, type DeployedAgent, type DetailLevel, type EmbeddingData, type EmbeddingResponse, type EmbeddingUsage, type GraphNode, type GuardClaim, type GuardMode, type GuardResponse, HistoryClient, type HistoryClientConfig, type ExportOptions as HistoryExportOptions, type ListOptions as HistoryListOptions, type HistoryListResponse, HttpClient, type HttpClientConfig, HttpError, type KnowledgeGraphResult, type ListRevisionsResponse, type LogLevel, MockHttpClient, type ModelInfo, type ModelList, type OrchestratorResponse, type PlanOptions, type PlanResult, type PlanStep, type RagAuditInfo, type RagQueryResponse, type RagSource, type RagUploadResponse, type ReasoningOptions, type ReasoningResult, type RequestOptions, type RetrievalResult, ServerError, type SourceType, type StateTransition, type Task, type TaskClaim, type TaskHistoryEntry, type TaskStatus, type TaskVerification, TimeoutError, type ToolContent, type ToolDefinition, ToolNotFoundError, type UpdateAgentPatch, ValidationError, type Verdict, WauldoError, chatContent, guardIsBlocked, guardIsSafe, isTerminalStatus, supportScore };
1149
+ export { type A2aResponse, AgentClient, type AgentListResponse, type AgentRevision, type AgentRunResponse, AgentsClient, type AgentsClientConfig, type CallToolResponse, type ChatChoice, type ChatClientLike, type ChatMessage, type ChatRequest, type ChatResponse, type ChatUsage, type Chunk, type ChunkResult, type ClientOptions, type Concept, type ConceptResult, ConnectionError, Conversation, type CreateAgentInput, type CreateRevisionInput, type CreateRevisionResponse, type CreateWorkflowInput, type DeployedAgent, type DetailLevel, type EmbeddingData, type EmbeddingResponse, type EmbeddingUsage, type GraphNode, type GuardClaim, type GuardMode, type GuardResponse, HistoryClient, type HistoryClientConfig, type ExportOptions as HistoryExportOptions, type ListOptions as HistoryListOptions, type HistoryListResponse, HttpClient, type HttpClientConfig, HttpError, type KnowledgeGraphResult, type ListRevisionsResponse, type LogLevel, MockHttpClient, type ModelInfo, type ModelList, type OrchestratorResponse, type PlanOptions, type PlanResult, type PlanStep, type RagAuditInfo, type RagQueryResponse, type RagSource, type RagUploadResponse, type ReasoningOptions, type ReasoningResult, type RequestOptions, type RetrievalResult, ServerError, type SourceType, type StartRunResponse, type StateTransition, TERMINAL_WORKFLOW_STATUSES, type Task, type TaskClaim, type TaskHistoryEntry, type TaskStatus, type TaskVerification, TimeoutError, type ToolContent, type ToolDefinition, ToolNotFoundError, type UpdateAgentPatch, ValidationError, type Verdict, WauldoError, type Workflow, type WorkflowExecution, type WorkflowListResponse, WorkflowsClient, type WorkflowsClientConfig, chatContent, guardIsBlocked, guardIsSafe, isTerminalStatus, isWorkflowRunTerminal, supportScore };
package/dist/index.d.ts CHANGED
@@ -919,6 +919,125 @@ declare class AgentsClient {
919
919
  streamTask(taskId: string): AsyncGenerator<StateTransition>;
920
920
  }
921
921
 
922
+ /**
923
+ * Workflows API client — Wauldo Workflow Runtime (Step Functions style).
924
+ *
925
+ * State-machine workflows authored as `Task` / `Choice` / `Wait` / `Pass` /
926
+ * `Fail` / `Succeed` states. Runs are async: `startRun` returns an
927
+ * `execution_id`, then poll `getRun` (or use `waitForRun`) until a terminal
928
+ * status.
929
+ *
930
+ * @example
931
+ * ```ts
932
+ * import { WorkflowsClient } from "wauldo/workflows";
933
+ * const wf = new WorkflowsClient({ baseUrl: "https://api.wauldo.com", apiKey: "..." });
934
+ * const created = await wf.create({
935
+ * name: "triage",
936
+ * startAt: "Compute",
937
+ * states: {
938
+ * Compute: { type: "Task", resource: "tool:calculator", next: "Done" },
939
+ * Done: { type: "Succeed" },
940
+ * },
941
+ * });
942
+ * const run = await wf.startRun(created.id, { operation: "add", a: 21, b: 21 });
943
+ * const final = await wf.waitForRun(created.id, run.execution_id);
944
+ * console.log(final.status, final.output);
945
+ * ```
946
+ */
947
+ interface WorkflowsClientConfig {
948
+ baseUrl: string;
949
+ apiKey?: string;
950
+ /** Tenant identifier forwarded via x-rapidapi-user header. */
951
+ tenant?: string;
952
+ /** Per-request timeout in ms. Default 120_000. */
953
+ timeoutMs?: number;
954
+ }
955
+ /** A workflow definition. */
956
+ interface Workflow {
957
+ id: string;
958
+ tenant_id: string;
959
+ name: string;
960
+ description?: string;
961
+ start_at: string;
962
+ states: Record<string, unknown>;
963
+ version: string;
964
+ created_at: number;
965
+ updated_at: number;
966
+ }
967
+ interface CreateWorkflowInput {
968
+ name: string;
969
+ startAt: string;
970
+ states: Record<string, unknown>;
971
+ description?: string;
972
+ }
973
+ interface WorkflowListResponse {
974
+ workflows: Workflow[];
975
+ }
976
+ /** 202 response from `POST /v1/workflows/:id/runs`. */
977
+ interface StartRunResponse {
978
+ execution_id: string;
979
+ workflow_id: string;
980
+ status: string;
981
+ }
982
+ /**
983
+ * A workflow execution record. `status` is one of `running`, `succeeded`,
984
+ * `failed`, `timed_out`. `output` is populated on success; `error` on
985
+ * terminal failure.
986
+ */
987
+ interface WorkflowExecution {
988
+ id: string;
989
+ workflow_id: string;
990
+ tenant_id: string;
991
+ status: string;
992
+ current_state?: string | null;
993
+ input: unknown;
994
+ output?: unknown;
995
+ started_at: number;
996
+ ended_at?: number | null;
997
+ error?: string | null;
998
+ }
999
+ declare const TERMINAL_WORKFLOW_STATUSES: readonly ["succeeded", "failed", "timed_out"];
1000
+ declare function isWorkflowRunTerminal(status: string): boolean;
1001
+ declare class WorkflowsClient {
1002
+ private readonly config;
1003
+ constructor(config: WorkflowsClientConfig);
1004
+ private headers;
1005
+ private request;
1006
+ /**
1007
+ * `POST /v1/workflows` — create a workflow definition.
1008
+ *
1009
+ * The server validates cycles, transition targets, choice operators,
1010
+ * and the per-tenant cap (100) before returning 201.
1011
+ */
1012
+ create(input: CreateWorkflowInput): Promise<Workflow>;
1013
+ /** `GET /v1/workflows` — list workflows for the calling tenant. */
1014
+ list(): Promise<WorkflowListResponse>;
1015
+ /** `GET /v1/workflows/:id` */
1016
+ get(workflowId: string): Promise<Workflow>;
1017
+ /** `DELETE /v1/workflows/:id` */
1018
+ delete(workflowId: string): Promise<void>;
1019
+ /**
1020
+ * `POST /v1/workflows/:id/runs` — start an async execution.
1021
+ *
1022
+ * Returns 202 with an `execution_id` immediately. Poll {@link getRun}
1023
+ * or use {@link waitForRun} to await completion.
1024
+ */
1025
+ startRun(workflowId: string, input?: unknown): Promise<StartRunResponse>;
1026
+ /** `GET /v1/workflows/:id/runs/:execution_id` — fetch one execution. */
1027
+ getRun(workflowId: string, executionId: string): Promise<WorkflowExecution>;
1028
+ /**
1029
+ * Poll {@link getRun} until the run reaches a terminal status.
1030
+ *
1031
+ * Rejects with an error if the run hasn't terminated within
1032
+ * `timeoutMs`. The server enforces its own 60s wall-clock cap per run,
1033
+ * so a timeout larger than ~75_000 is just slack for polling overhead.
1034
+ */
1035
+ waitForRun(workflowId: string, executionId: string, opts?: {
1036
+ timeoutMs?: number;
1037
+ pollIntervalMs?: number;
1038
+ }): Promise<WorkflowExecution>;
1039
+ }
1040
+
922
1041
  /**
923
1042
  * History API client — Wauldo Funnel #1 audit log.
924
1043
  *
@@ -1027,4 +1146,4 @@ declare class HistoryClient {
1027
1146
  deleteTask(taskId: string): Promise<number>;
1028
1147
  }
1029
1148
 
1030
- export { type A2aResponse, AgentClient, type AgentListResponse, type AgentRevision, type AgentRunResponse, AgentsClient, type AgentsClientConfig, type CallToolResponse, type ChatChoice, type ChatClientLike, type ChatMessage, type ChatRequest, type ChatResponse, type ChatUsage, type Chunk, type ChunkResult, type ClientOptions, type Concept, type ConceptResult, ConnectionError, Conversation, type CreateAgentInput, type CreateRevisionInput, type CreateRevisionResponse, type DeployedAgent, type DetailLevel, type EmbeddingData, type EmbeddingResponse, type EmbeddingUsage, type GraphNode, type GuardClaim, type GuardMode, type GuardResponse, HistoryClient, type HistoryClientConfig, type ExportOptions as HistoryExportOptions, type ListOptions as HistoryListOptions, type HistoryListResponse, HttpClient, type HttpClientConfig, HttpError, type KnowledgeGraphResult, type ListRevisionsResponse, type LogLevel, MockHttpClient, type ModelInfo, type ModelList, type OrchestratorResponse, type PlanOptions, type PlanResult, type PlanStep, type RagAuditInfo, type RagQueryResponse, type RagSource, type RagUploadResponse, type ReasoningOptions, type ReasoningResult, type RequestOptions, type RetrievalResult, ServerError, type SourceType, type StateTransition, type Task, type TaskClaim, type TaskHistoryEntry, type TaskStatus, type TaskVerification, TimeoutError, type ToolContent, type ToolDefinition, ToolNotFoundError, type UpdateAgentPatch, ValidationError, type Verdict, WauldoError, chatContent, guardIsBlocked, guardIsSafe, isTerminalStatus, supportScore };
1149
+ export { type A2aResponse, AgentClient, type AgentListResponse, type AgentRevision, type AgentRunResponse, AgentsClient, type AgentsClientConfig, type CallToolResponse, type ChatChoice, type ChatClientLike, type ChatMessage, type ChatRequest, type ChatResponse, type ChatUsage, type Chunk, type ChunkResult, type ClientOptions, type Concept, type ConceptResult, ConnectionError, Conversation, type CreateAgentInput, type CreateRevisionInput, type CreateRevisionResponse, type CreateWorkflowInput, type DeployedAgent, type DetailLevel, type EmbeddingData, type EmbeddingResponse, type EmbeddingUsage, type GraphNode, type GuardClaim, type GuardMode, type GuardResponse, HistoryClient, type HistoryClientConfig, type ExportOptions as HistoryExportOptions, type ListOptions as HistoryListOptions, type HistoryListResponse, HttpClient, type HttpClientConfig, HttpError, type KnowledgeGraphResult, type ListRevisionsResponse, type LogLevel, MockHttpClient, type ModelInfo, type ModelList, type OrchestratorResponse, type PlanOptions, type PlanResult, type PlanStep, type RagAuditInfo, type RagQueryResponse, type RagSource, type RagUploadResponse, type ReasoningOptions, type ReasoningResult, type RequestOptions, type RetrievalResult, ServerError, type SourceType, type StartRunResponse, type StateTransition, TERMINAL_WORKFLOW_STATUSES, type Task, type TaskClaim, type TaskHistoryEntry, type TaskStatus, type TaskVerification, TimeoutError, type ToolContent, type ToolDefinition, ToolNotFoundError, type UpdateAgentPatch, ValidationError, type Verdict, WauldoError, type Workflow, type WorkflowExecution, type WorkflowListResponse, WorkflowsClient, type WorkflowsClientConfig, chatContent, guardIsBlocked, guardIsSafe, isTerminalStatus, isWorkflowRunTerminal, supportScore };
package/dist/index.js CHANGED
@@ -29,14 +29,17 @@ __export(index_exports, {
29
29
  HttpError: () => HttpError,
30
30
  MockHttpClient: () => MockHttpClient,
31
31
  ServerError: () => ServerError,
32
+ TERMINAL_WORKFLOW_STATUSES: () => TERMINAL_WORKFLOW_STATUSES,
32
33
  TimeoutError: () => TimeoutError,
33
34
  ToolNotFoundError: () => ToolNotFoundError,
34
35
  ValidationError: () => ValidationError,
35
36
  WauldoError: () => WauldoError,
37
+ WorkflowsClient: () => WorkflowsClient,
36
38
  chatContent: () => chatContent,
37
39
  guardIsBlocked: () => guardIsBlocked,
38
40
  guardIsSafe: () => guardIsSafe,
39
41
  isTerminalStatus: () => isTerminalStatus,
42
+ isWorkflowRunTerminal: () => isWorkflowRunTerminal,
40
43
  supportScore: () => supportScore
41
44
  });
42
45
  module.exports = __toCommonJS(index_exports);
@@ -1599,6 +1602,133 @@ var AgentsClient = class {
1599
1602
  }
1600
1603
  };
1601
1604
 
1605
+ // src/workflows.ts
1606
+ var TERMINAL_WORKFLOW_STATUSES = [
1607
+ "succeeded",
1608
+ "failed",
1609
+ "timed_out"
1610
+ ];
1611
+ function isWorkflowRunTerminal(status) {
1612
+ return TERMINAL_WORKFLOW_STATUSES.includes(status);
1613
+ }
1614
+ var WorkflowsClient = class {
1615
+ constructor(config) {
1616
+ this.config = config;
1617
+ if (!config.baseUrl) throw new Error("baseUrl is required");
1618
+ }
1619
+ headers() {
1620
+ const h = { "Content-Type": "application/json" };
1621
+ if (this.config.apiKey) h["Authorization"] = `Bearer ${this.config.apiKey}`;
1622
+ if (this.config.tenant) h["x-rapidapi-user"] = this.config.tenant;
1623
+ return h;
1624
+ }
1625
+ async request(method, path, body) {
1626
+ const url = this.config.baseUrl.replace(/\/$/, "") + path;
1627
+ const controller = new AbortController();
1628
+ const timeout = setTimeout(
1629
+ () => controller.abort(),
1630
+ this.config.timeoutMs ?? 12e4
1631
+ );
1632
+ try {
1633
+ const init = {
1634
+ method,
1635
+ headers: this.headers(),
1636
+ signal: controller.signal
1637
+ };
1638
+ if (body !== void 0) init.body = JSON.stringify(body);
1639
+ const resp = await fetch(url, init);
1640
+ if (resp.status === 204) return null;
1641
+ const bytes = await _boundedRead(resp, MAX_RESPONSE_SIZE);
1642
+ const text = new TextDecoder().decode(bytes);
1643
+ if (!resp.ok) {
1644
+ throw new HttpError(resp.status, resp.statusText, text);
1645
+ }
1646
+ return text ? JSON.parse(text) : null;
1647
+ } finally {
1648
+ clearTimeout(timeout);
1649
+ }
1650
+ }
1651
+ // ── CRUD ──────────────────────────────────────────────────────────
1652
+ /**
1653
+ * `POST /v1/workflows` — create a workflow definition.
1654
+ *
1655
+ * The server validates cycles, transition targets, choice operators,
1656
+ * and the per-tenant cap (100) before returning 201.
1657
+ */
1658
+ async create(input) {
1659
+ const body = {
1660
+ name: input.name,
1661
+ start_at: input.startAt,
1662
+ states: input.states
1663
+ };
1664
+ if (input.description !== void 0) body.description = input.description;
1665
+ const env = await this.request("POST", "/v1/workflows", body);
1666
+ return env.workflow;
1667
+ }
1668
+ /** `GET /v1/workflows` — list workflows for the calling tenant. */
1669
+ async list() {
1670
+ return await this.request("GET", "/v1/workflows");
1671
+ }
1672
+ /** `GET /v1/workflows/:id` */
1673
+ async get(workflowId) {
1674
+ const env = await this.request(
1675
+ "GET",
1676
+ `/v1/workflows/${workflowId}`
1677
+ );
1678
+ return env.workflow;
1679
+ }
1680
+ /** `DELETE /v1/workflows/:id` */
1681
+ async delete(workflowId) {
1682
+ await this.request("DELETE", `/v1/workflows/${workflowId}`);
1683
+ }
1684
+ // ── Runs ──────────────────────────────────────────────────────────
1685
+ /**
1686
+ * `POST /v1/workflows/:id/runs` — start an async execution.
1687
+ *
1688
+ * Returns 202 with an `execution_id` immediately. Poll {@link getRun}
1689
+ * or use {@link waitForRun} to await completion.
1690
+ */
1691
+ async startRun(workflowId, input) {
1692
+ const body = {};
1693
+ if (input !== void 0) body.input = input;
1694
+ return await this.request(
1695
+ "POST",
1696
+ `/v1/workflows/${workflowId}/runs`,
1697
+ body
1698
+ );
1699
+ }
1700
+ /** `GET /v1/workflows/:id/runs/:execution_id` — fetch one execution. */
1701
+ async getRun(workflowId, executionId) {
1702
+ const env = await this.request(
1703
+ "GET",
1704
+ `/v1/workflows/${workflowId}/runs/${executionId}`
1705
+ );
1706
+ return env.execution;
1707
+ }
1708
+ /**
1709
+ * Poll {@link getRun} until the run reaches a terminal status.
1710
+ *
1711
+ * Rejects with an error if the run hasn't terminated within
1712
+ * `timeoutMs`. The server enforces its own 60s wall-clock cap per run,
1713
+ * so a timeout larger than ~75_000 is just slack for polling overhead.
1714
+ */
1715
+ async waitForRun(workflowId, executionId, opts = {}) {
1716
+ const timeoutMs = opts.timeoutMs ?? 9e4;
1717
+ const pollIntervalMs = opts.pollIntervalMs ?? 1e3;
1718
+ const deadline = Date.now() + timeoutMs;
1719
+ while (true) {
1720
+ const execution = await this.getRun(workflowId, executionId);
1721
+ if (isWorkflowRunTerminal(execution.status)) return execution;
1722
+ if (Date.now() >= deadline) {
1723
+ throw new Error(
1724
+ `workflow run ${executionId} did not terminate within ${timeoutMs}ms (last status: ${execution.status})`
1725
+ );
1726
+ }
1727
+ await new Promise((r) => setTimeout(r, pollIntervalMs));
1728
+ }
1729
+ }
1730
+ };
1731
+
1602
1732
  // src/history.ts
1603
1733
  var HistoryClient = class {
1604
1734
  constructor(config) {
@@ -1718,13 +1848,16 @@ var HistoryClient = class {
1718
1848
  HttpError,
1719
1849
  MockHttpClient,
1720
1850
  ServerError,
1851
+ TERMINAL_WORKFLOW_STATUSES,
1721
1852
  TimeoutError,
1722
1853
  ToolNotFoundError,
1723
1854
  ValidationError,
1724
1855
  WauldoError,
1856
+ WorkflowsClient,
1725
1857
  chatContent,
1726
1858
  guardIsBlocked,
1727
1859
  guardIsSafe,
1728
1860
  isTerminalStatus,
1861
+ isWorkflowRunTerminal,
1729
1862
  supportScore
1730
1863
  });
package/dist/index.mjs CHANGED
@@ -1556,6 +1556,133 @@ var AgentsClient = class {
1556
1556
  }
1557
1557
  };
1558
1558
 
1559
+ // src/workflows.ts
1560
+ var TERMINAL_WORKFLOW_STATUSES = [
1561
+ "succeeded",
1562
+ "failed",
1563
+ "timed_out"
1564
+ ];
1565
+ function isWorkflowRunTerminal(status) {
1566
+ return TERMINAL_WORKFLOW_STATUSES.includes(status);
1567
+ }
1568
+ var WorkflowsClient = class {
1569
+ constructor(config) {
1570
+ this.config = config;
1571
+ if (!config.baseUrl) throw new Error("baseUrl is required");
1572
+ }
1573
+ headers() {
1574
+ const h = { "Content-Type": "application/json" };
1575
+ if (this.config.apiKey) h["Authorization"] = `Bearer ${this.config.apiKey}`;
1576
+ if (this.config.tenant) h["x-rapidapi-user"] = this.config.tenant;
1577
+ return h;
1578
+ }
1579
+ async request(method, path, body) {
1580
+ const url = this.config.baseUrl.replace(/\/$/, "") + path;
1581
+ const controller = new AbortController();
1582
+ const timeout = setTimeout(
1583
+ () => controller.abort(),
1584
+ this.config.timeoutMs ?? 12e4
1585
+ );
1586
+ try {
1587
+ const init = {
1588
+ method,
1589
+ headers: this.headers(),
1590
+ signal: controller.signal
1591
+ };
1592
+ if (body !== void 0) init.body = JSON.stringify(body);
1593
+ const resp = await fetch(url, init);
1594
+ if (resp.status === 204) return null;
1595
+ const bytes = await _boundedRead(resp, MAX_RESPONSE_SIZE);
1596
+ const text = new TextDecoder().decode(bytes);
1597
+ if (!resp.ok) {
1598
+ throw new HttpError(resp.status, resp.statusText, text);
1599
+ }
1600
+ return text ? JSON.parse(text) : null;
1601
+ } finally {
1602
+ clearTimeout(timeout);
1603
+ }
1604
+ }
1605
+ // ── CRUD ──────────────────────────────────────────────────────────
1606
+ /**
1607
+ * `POST /v1/workflows` — create a workflow definition.
1608
+ *
1609
+ * The server validates cycles, transition targets, choice operators,
1610
+ * and the per-tenant cap (100) before returning 201.
1611
+ */
1612
+ async create(input) {
1613
+ const body = {
1614
+ name: input.name,
1615
+ start_at: input.startAt,
1616
+ states: input.states
1617
+ };
1618
+ if (input.description !== void 0) body.description = input.description;
1619
+ const env = await this.request("POST", "/v1/workflows", body);
1620
+ return env.workflow;
1621
+ }
1622
+ /** `GET /v1/workflows` — list workflows for the calling tenant. */
1623
+ async list() {
1624
+ return await this.request("GET", "/v1/workflows");
1625
+ }
1626
+ /** `GET /v1/workflows/:id` */
1627
+ async get(workflowId) {
1628
+ const env = await this.request(
1629
+ "GET",
1630
+ `/v1/workflows/${workflowId}`
1631
+ );
1632
+ return env.workflow;
1633
+ }
1634
+ /** `DELETE /v1/workflows/:id` */
1635
+ async delete(workflowId) {
1636
+ await this.request("DELETE", `/v1/workflows/${workflowId}`);
1637
+ }
1638
+ // ── Runs ──────────────────────────────────────────────────────────
1639
+ /**
1640
+ * `POST /v1/workflows/:id/runs` — start an async execution.
1641
+ *
1642
+ * Returns 202 with an `execution_id` immediately. Poll {@link getRun}
1643
+ * or use {@link waitForRun} to await completion.
1644
+ */
1645
+ async startRun(workflowId, input) {
1646
+ const body = {};
1647
+ if (input !== void 0) body.input = input;
1648
+ return await this.request(
1649
+ "POST",
1650
+ `/v1/workflows/${workflowId}/runs`,
1651
+ body
1652
+ );
1653
+ }
1654
+ /** `GET /v1/workflows/:id/runs/:execution_id` — fetch one execution. */
1655
+ async getRun(workflowId, executionId) {
1656
+ const env = await this.request(
1657
+ "GET",
1658
+ `/v1/workflows/${workflowId}/runs/${executionId}`
1659
+ );
1660
+ return env.execution;
1661
+ }
1662
+ /**
1663
+ * Poll {@link getRun} until the run reaches a terminal status.
1664
+ *
1665
+ * Rejects with an error if the run hasn't terminated within
1666
+ * `timeoutMs`. The server enforces its own 60s wall-clock cap per run,
1667
+ * so a timeout larger than ~75_000 is just slack for polling overhead.
1668
+ */
1669
+ async waitForRun(workflowId, executionId, opts = {}) {
1670
+ const timeoutMs = opts.timeoutMs ?? 9e4;
1671
+ const pollIntervalMs = opts.pollIntervalMs ?? 1e3;
1672
+ const deadline = Date.now() + timeoutMs;
1673
+ while (true) {
1674
+ const execution = await this.getRun(workflowId, executionId);
1675
+ if (isWorkflowRunTerminal(execution.status)) return execution;
1676
+ if (Date.now() >= deadline) {
1677
+ throw new Error(
1678
+ `workflow run ${executionId} did not terminate within ${timeoutMs}ms (last status: ${execution.status})`
1679
+ );
1680
+ }
1681
+ await new Promise((r) => setTimeout(r, pollIntervalMs));
1682
+ }
1683
+ }
1684
+ };
1685
+
1559
1686
  // src/history.ts
1560
1687
  var HistoryClient = class {
1561
1688
  constructor(config) {
@@ -1674,13 +1801,16 @@ export {
1674
1801
  HttpError,
1675
1802
  MockHttpClient,
1676
1803
  ServerError,
1804
+ TERMINAL_WORKFLOW_STATUSES,
1677
1805
  TimeoutError,
1678
1806
  ToolNotFoundError,
1679
1807
  ValidationError,
1680
1808
  WauldoError,
1809
+ WorkflowsClient,
1681
1810
  chatContent,
1682
1811
  guardIsBlocked,
1683
1812
  guardIsSafe,
1684
1813
  isTerminalStatus,
1814
+ isWorkflowRunTerminal,
1685
1815
  supportScore
1686
1816
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wauldo",
3
- "version": "0.12.0",
3
+ "version": "0.13.0",
4
4
  "description": "Official TypeScript SDK for Wauldo — Verified AI answers from your documents",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",