@cadraos/sdk 0.3.14-p46.4 → 0.3.15

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.
Files changed (38) hide show
  1. package/README.md +104 -53
  2. package/dist/ai-functions/react/index.cjs +176 -0
  3. package/dist/ai-functions/react/index.cjs.map +1 -0
  4. package/dist/ai-functions/react/index.d.cts +129 -0
  5. package/dist/ai-functions/react/index.d.ts +129 -0
  6. package/dist/ai-functions/react/index.js +153 -0
  7. package/dist/ai-functions/react/index.js.map +1 -0
  8. package/dist/ai-functions/server/index.cjs +296 -0
  9. package/dist/ai-functions/server/index.cjs.map +1 -0
  10. package/dist/ai-functions/server/index.d.cts +334 -0
  11. package/dist/ai-functions/server/index.d.ts +334 -0
  12. package/dist/ai-functions/server/index.js +284 -0
  13. package/dist/ai-functions/server/index.js.map +1 -0
  14. package/dist/chat/index.cjs +303 -17
  15. package/dist/chat/index.cjs.map +1 -1
  16. package/dist/chat/index.d.cts +211 -0
  17. package/dist/chat/index.d.ts +211 -0
  18. package/dist/chat/index.js +303 -17
  19. package/dist/chat/index.js.map +1 -1
  20. package/dist/index.cjs +225 -3
  21. package/dist/index.cjs.map +1 -1
  22. package/dist/index.d.cts +279 -1
  23. package/dist/index.d.ts +279 -1
  24. package/dist/index.js +219 -4
  25. package/dist/index.js.map +1 -1
  26. package/dist/kanban/index.cjs +218 -3
  27. package/dist/kanban/index.cjs.map +1 -1
  28. package/dist/kanban/index.d.cts +211 -0
  29. package/dist/kanban/index.d.ts +211 -0
  30. package/dist/kanban/index.js +218 -3
  31. package/dist/kanban/index.js.map +1 -1
  32. package/dist/teams/index.cjs +218 -3
  33. package/dist/teams/index.cjs.map +1 -1
  34. package/dist/teams/index.d.cts +211 -0
  35. package/dist/teams/index.d.ts +211 -0
  36. package/dist/teams/index.js +218 -3
  37. package/dist/teams/index.js.map +1 -1
  38. package/package.json +21 -1
package/dist/index.d.ts CHANGED
@@ -62,6 +62,13 @@ interface RequestOptions {
62
62
  skipRetry?: boolean;
63
63
  /** Idempotency key */
64
64
  idempotencyKey?: string;
65
+ /**
66
+ * Per-request timeout in milliseconds. Overrides the client-wide
67
+ * `config.timeout` for this call only (p93 AIF-010: a paid AI-function run
68
+ * waits for the server's route ceiling while every other call keeps the
69
+ * 30 s default).
70
+ */
71
+ timeoutMs?: number;
65
72
  }
66
73
  /**
67
74
  * HTTP Client class
@@ -71,6 +78,8 @@ declare class HttpClient {
71
78
  private tokenRefreshAttempts;
72
79
  private readonly maxTokenRefreshAttempts;
73
80
  constructor(config: HttpClientConfig);
81
+ /** The client-wide request timeout (ms) this client was configured with. */
82
+ get timeoutMs(): number;
74
83
  /**
75
84
  * Get authorization header value
76
85
  */
@@ -93,6 +102,7 @@ declare class HttpClient {
93
102
  post<T>(path: string, body?: unknown, options?: {
94
103
  idempotencyKey?: string;
95
104
  skipRetry?: boolean;
105
+ timeoutMs?: number;
96
106
  }): Promise<T>;
97
107
  /**
98
108
  * PATCH request
@@ -1146,6 +1156,16 @@ interface ToolResultEvent {
1146
1156
  result: unknown;
1147
1157
  /** Duration in milliseconds */
1148
1158
  durationMs: number;
1159
+ /**
1160
+ * CAD-243: true when the tool call FAILED (the producer stamps
1161
+ * `isError: true` + `status: 'failed'` on a thrown tool call). Absent on
1162
+ * older producers — consumers then fall back to the result shape.
1163
+ */
1164
+ isError?: boolean;
1165
+ /** CAD-243: producer verdict, `'failed'` for a failed call. */
1166
+ status?: string;
1167
+ /** CAD-243: error text for a failed call. */
1168
+ error?: string;
1149
1169
  /** See {@link ToolCallEvent.forwardedFrom} */
1150
1170
  forwardedFrom?: string;
1151
1171
  /** See {@link ToolCallEvent.sourceExecutionId} (CAD-87 S1-001). */
@@ -1529,6 +1549,140 @@ interface StreamingConfig {
1529
1549
  sseRetryIntervalMs?: number;
1530
1550
  }
1531
1551
 
1552
+ /**
1553
+ * AI function types (p93 — specs §4 run contract, D27 discovery, §6.5 run reads).
1554
+ *
1555
+ * An AI function is a published prompt in the Cadra Prompts library that makes
1556
+ * ONE direct AI-provider call (never an agent). Callers reference it by its
1557
+ * `functionKey` (unique per org), by prompt uuid, or — for platform features —
1558
+ * by slot key.
1559
+ */
1560
+ /** Output kind of an AI function. */
1561
+ type AiFunctionOutputKind = 'text' | 'json' | 'image';
1562
+ /** Parameter (prompt variable) types — specs D10 + D26d. */
1563
+ type AiFunctionParameterType = 'string' | 'text' | 'number' | 'boolean' | 'enum' | 'image';
1564
+ /** A value passed for one parameter. `image` parameters take an artifact uuid (string). */
1565
+ type AiFunctionVariableValue = string | number | boolean;
1566
+ /** Parameters (variables) for one run, keyed by parameter name. */
1567
+ type AiFunctionVariables = Record<string, AiFunctionVariableValue>;
1568
+ /** How a run names its function (§4). */
1569
+ type AiFunctionRef = {
1570
+ slot: string;
1571
+ } | {
1572
+ functionKey: string;
1573
+ } | {
1574
+ promptUuid: string;
1575
+ };
1576
+ /** One declared parameter of a function's live (golden) version — D27a. */
1577
+ interface AiFunctionParameter {
1578
+ name: string;
1579
+ type: AiFunctionParameterType;
1580
+ required: boolean;
1581
+ defaultValue?: AiFunctionVariableValue;
1582
+ maxLength?: number;
1583
+ options?: string[];
1584
+ description?: string;
1585
+ }
1586
+ /**
1587
+ * The discovery "index" entry for one callable function — D27a. Built from the
1588
+ * golden version snapshot; never carries prompt or system text.
1589
+ */
1590
+ interface AiFunctionDescriptor {
1591
+ functionKey: string;
1592
+ title: string;
1593
+ description?: string | null;
1594
+ outputKind: AiFunctionOutputKind;
1595
+ /** The live (golden) version number. */
1596
+ liveVersion: number;
1597
+ parameters: AiFunctionParameter[];
1598
+ /** JSON schema of the output, for `json` functions. */
1599
+ outputSchema?: Record<string, unknown> | null;
1600
+ }
1601
+ /** Who paid for a run (D4). */
1602
+ type AiFunctionBilledTo = 'own_key' | 'credits' | 'platform_funded';
1603
+ /** Runtime params a slot may accept per run (D26d3). */
1604
+ interface AiFunctionRuntimeParams {
1605
+ aspect_ratio?: string;
1606
+ image_size?: string;
1607
+ }
1608
+ /** Options for the object form `run(ref, { variables, … })`. */
1609
+ interface AiFunctionRunOptions {
1610
+ /** Parameters for this run (sent as `variables`). */
1611
+ variables: AiFunctionVariables;
1612
+ /** Pin a published version number (D3d). Skips the client-side check. */
1613
+ version?: number;
1614
+ /** Idempotency key (uuid). Generated when omitted (D15). */
1615
+ idempotencyKey?: string;
1616
+ /** Slot runtime params (D26d3). */
1617
+ params?: AiFunctionRuntimeParams;
1618
+ /** `false` skips the client-side parameter check (D27c). Default true. */
1619
+ validate?: boolean;
1620
+ }
1621
+ /** Options for the shorthand `run('function_key', parameters, opts)`. */
1622
+ type AiFunctionRunShorthandOptions = Omit<AiFunctionRunOptions, 'variables'>;
1623
+ /** Image produced by an `image` function. Over HTTP only `url` (presigned, 1 h) is set. */
1624
+ interface AiFunctionImage {
1625
+ mimeType: string;
1626
+ url?: string;
1627
+ bytes?: Uint8Array;
1628
+ }
1629
+ /** Output of a run, by kind (§4). `TOutput` types `json`. */
1630
+ type AiFunctionOutput<TOutput = unknown> = {
1631
+ type: 'text';
1632
+ text: string;
1633
+ } | {
1634
+ type: 'json';
1635
+ json: TOutput;
1636
+ } | {
1637
+ type: 'image';
1638
+ images: AiFunctionImage[];
1639
+ };
1640
+ /** Token and billing usage of a run (§4). */
1641
+ interface AiFunctionUsage {
1642
+ promptTokens: number;
1643
+ completionTokens: number;
1644
+ imageCount: number;
1645
+ billedTo: AiFunctionBilledTo;
1646
+ }
1647
+ /** Result of a successful run (§4). */
1648
+ interface AiFunctionRunResult<TOutput = unknown> {
1649
+ /** = the run's execution uuid (usage-ledger executionUuid). */
1650
+ executionId: string;
1651
+ functionUuid: string;
1652
+ version: number;
1653
+ output: AiFunctionOutput<TOutput>;
1654
+ usage: AiFunctionUsage;
1655
+ latencyMs: number;
1656
+ }
1657
+ /** Run status as reported by run reads (D12; `abandoned` is computed on read). */
1658
+ type AiFunctionRunStatus = 'running' | 'succeeded' | 'failed_provider' | 'failed_timeout' | 'refused_billing' | 'failed_output' | 'failed_delivery' | 'abandoned';
1659
+ /** Safe projection of one of the caller org's own runs (§6.5). */
1660
+ interface AiFunctionRun {
1661
+ executionId: string;
1662
+ ref: {
1663
+ slot?: string;
1664
+ functionKey?: string;
1665
+ promptUuid?: string;
1666
+ };
1667
+ version: number | null;
1668
+ status: AiFunctionRunStatus;
1669
+ errorCode: string | null;
1670
+ promptTokens: number | null;
1671
+ completionTokens: number | null;
1672
+ imageCount: number | null;
1673
+ latencyMs: number | null;
1674
+ billedTo: AiFunctionBilledTo | null;
1675
+ createdAt: string;
1676
+ finishedAt: string | null;
1677
+ }
1678
+ /** Why a parameter failed the client-side check (D27c). */
1679
+ type AiFunctionParameterIssueCode = 'missing' | 'type' | 'option' | 'too_long' | 'unknown';
1680
+ /** One client-side parameter problem (D27c). */
1681
+ interface AiFunctionParameterIssue {
1682
+ name: string;
1683
+ code: AiFunctionParameterIssueCode;
1684
+ }
1685
+
1532
1686
  /**
1533
1687
  * Base Resource API
1534
1688
  *
@@ -1557,6 +1711,7 @@ declare abstract class BaseResourceAPI {
1557
1711
  protected httpPost<T>(path: string, body?: unknown, options?: {
1558
1712
  idempotencyKey?: string;
1559
1713
  skipRetry?: boolean;
1714
+ timeoutMs?: number;
1560
1715
  }): Promise<T>;
1561
1716
  /**
1562
1717
  * HTTP PATCH request helper
@@ -3254,6 +3409,81 @@ declare class RemoteRunnersAPI extends BaseResourceAPI {
3254
3409
  list(options?: RemoteRunnerListOptions): Promise<PaginatedResponse<RemoteRunner>>;
3255
3410
  }
3256
3411
 
3412
+ /**
3413
+ * AI Functions API (p93 AIF-010 — specs §9, D27).
3414
+ *
3415
+ * @example
3416
+ * ```typescript
3417
+ * // Discover what the org can call, and with which parameters
3418
+ * const functions = await client.aiFunctions.list();
3419
+ * const fn = await client.aiFunctions.get('summarise_ticket');
3420
+ *
3421
+ * // Call it — parameters are checked against the live version before sending
3422
+ * const result = await client.aiFunctions.run('summarise_ticket', { ticket_text: '…' });
3423
+ * if (result.output.type === 'text') console.log(result.output.text);
3424
+ * ```
3425
+ */
3426
+
3427
+ /**
3428
+ * How long the client waits for a paid run. It tracks cadra-web
3429
+ * `AI_FUNCTION_ROUTE_MAX_MS` (300 s, the Vercel `maxDuration` of the run
3430
+ * routes) plus 10 s, so the server always answers first — with the result or
3431
+ * with its own `failed_timeout` — and the client never abandons a run the
3432
+ * server is still finishing. A larger client-wide `timeout` wins.
3433
+ * (Was 60 s, from the old p93 D6 route budget.)
3434
+ */
3435
+ declare const AI_FUNCTION_RUN_TIMEOUT_MS = 310000;
3436
+ /** Descriptors used by the client-side check are cached per client for 60 s (D27c). */
3437
+ declare const AI_FUNCTION_DESCRIPTOR_TTL_MS = 60000;
3438
+ /**
3439
+ * Check `variables` against a descriptor's parameters (D27c). Returns the issues,
3440
+ * in parameter order, then unknown names. Empty array = OK.
3441
+ */
3442
+ declare function checkAiFunctionParameters(parameters: AiFunctionParameter[], variables: AiFunctionVariables): AiFunctionParameterIssue[];
3443
+ /**
3444
+ * AI Functions API
3445
+ */
3446
+ declare class AiFunctionsAPI extends BaseResourceAPI {
3447
+ private readonly descriptorCache;
3448
+ constructor(http: HttpClient);
3449
+ /**
3450
+ * List the functions this org can call — the index (D27a). Each entry carries
3451
+ * the live version's typed parameters; never prompt text.
3452
+ */
3453
+ list(): Promise<AiFunctionDescriptor[]>;
3454
+ /**
3455
+ * Get one function's descriptor by key (D27a).
3456
+ * `NotFoundError` (`FUNCTION_NOT_FOUND`) / `ConflictError` (`FUNCTION_NOT_PUBLISHED`).
3457
+ */
3458
+ get(functionKey: string): Promise<AiFunctionDescriptor>;
3459
+ /**
3460
+ * Read one of this org's own runs (safe projection, §6.5).
3461
+ */
3462
+ getRun(executionId: string): Promise<AiFunctionRun>;
3463
+ /** Forget cached descriptors (one key, or all). */
3464
+ clearDescriptorCache(functionKey?: string): void;
3465
+ /**
3466
+ * Run an AI function — one paid provider call.
3467
+ *
3468
+ * - `run('function_key', parameters, opts?)` — shorthand for `{ functionKey }`.
3469
+ * - `run({ functionKey | promptUuid | slot }, { variables, version?, idempotencyKey?, params?, validate? })`.
3470
+ *
3471
+ * For a `functionKey` ref without a pinned `version`, parameters are checked
3472
+ * against the live version first (D27c); a problem throws
3473
+ * `AiFunctionParameterError` and NO run request is sent. Paid runs are never
3474
+ * auto-retried; an idempotency key is generated when omitted.
3475
+ *
3476
+ * @throws AiFunctionParameterError — client-side check failed (nothing sent)
3477
+ * @throws AiFunctionDuplicateError — 409 `DUPLICATE_REQUEST`
3478
+ * @throws AiFunctionChargedError — the run was metered but its output failed (`details.charged`)
3479
+ */
3480
+ run<TOutput = unknown>(functionKey: string, parameters: AiFunctionVariables, opts?: AiFunctionRunShorthandOptions): Promise<AiFunctionRunResult<TOutput>>;
3481
+ run<TOutput = unknown>(ref: AiFunctionRef, options: AiFunctionRunOptions): Promise<AiFunctionRunResult<TOutput>>;
3482
+ private cacheDescriptor;
3483
+ private getCachedDescriptor;
3484
+ private mapRunError;
3485
+ }
3486
+
3257
3487
  /**
3258
3488
  * Cadra Client
3259
3489
  *
@@ -3398,6 +3628,10 @@ declare class CadraClient {
3398
3628
  * Remote runner operations (list)
3399
3629
  */
3400
3630
  readonly remoteRunners: RemoteRunnersAPI;
3631
+ /**
3632
+ * AI function operations (list, get, run, getRun) — p93
3633
+ */
3634
+ readonly aiFunctions: AiFunctionsAPI;
3401
3635
  /**
3402
3636
  * Create a new AI SaaS client
3403
3637
  *
@@ -3449,6 +3683,14 @@ declare class CadraError extends Error {
3449
3683
  readonly details?: Record<string, unknown>;
3450
3684
  /** Request ID from server (for debugging) */
3451
3685
  readonly requestId?: string;
3686
+ /**
3687
+ * The server's own `error.code` exactly as sent on the wire (e.g.
3688
+ * `FUNCTION_NOT_PUBLISHED`, `DUPLICATE_REQUEST`, `VARIABLE_TYPE`).
3689
+ * Populated by `parseApiError` for EVERY status. `code` keeps its historic
3690
+ * per-class values (`conflict`, `server_error`, `validation_error`, …) for
3691
+ * compatibility; branch on `serverCode` when you need the precise reason.
3692
+ */
3693
+ serverCode?: string;
3452
3694
  constructor(message: string, code: string, status: number, details?: Record<string, unknown>, requestId?: string);
3453
3695
  }
3454
3696
  /**
@@ -3525,4 +3767,40 @@ declare class NetworkError extends CadraError {
3525
3767
  constructor(message?: string, details?: Record<string, unknown>);
3526
3768
  }
3527
3769
 
3528
- export { CadraClient as AISaaSClient, type CadraClientOptions as AISaaSClientOptions, CadraError as AISaaSError, type Agent, type AgentConfig, type AgentConfigUpdateInput, type AgentExecution, type AgentListOptions, type AgentStatus, type AgentType, type AgentUpdateInput, type Artifact, type ArtifactDownloadOptions, type ArtifactListOptions, type ArtifactType, type ArtifactUploadInput, type AttachmentUploadUrlInput, type AttachmentUploadUrlResponse, AuthenticationError, AuthorizationError, CadraClient, type CadraClientOptions, CadraError, type CollectImagesOptions, type CompleteEvent, ConflictError, type ConnectionChangeEvent, type DelegationCompletedEvent, type DelegationStartedEvent, type ErrorEvent, type ExecuteInput, type ExecuteOptions, type ExecuteResponse, type ExecuteToolDirectRequest, type ExecuteToolDirectResponse, type ExecutionLog, type ExecutionStatus, type ExecutionStreamController, type ExecutionStreamControllerOptions, type ExtractContext, type ImageData, type ImageEvent, type JSONSchema, type ListOptions, NetworkError, NotFoundError, type PaginatedResponse, type PaginationInfo, type PausedEvent, type PlanEvent, type ProgressEvent, RateLimitError, type RemoteAgent, type RemoteAgentCreateInput, type RemoteAgentExecuteResponse, type RemoteAgentExecutionTargetKind, type RemoteAgentListOptions, type RemoteAgentStatus, type RemoteAgentUpdateInput, type RemoteAgentVisibility, type RemoteRunner, type RemoteRunnerListOptions, type SendMessageInput, ServerError, type Session, type SessionArtifact, type SessionArtifactListOptions, type SessionArtifactType, type SessionArtifactVariantType, type SessionCreateInput, type SessionHistory, type SessionListOptions, type SessionMessage, type SignedUrlResponse, type Skill, type SkillDetails, type SkillExecuteInput, type SkillExecution, type SkillListOptions, type SkillTool, type SkillUpdateInput, type SkillVariable, type StartedEvent, type StreamController, type StreamEventMap, type StreamImagesResult, type TeamMemberRef, type TextDeltaEvent, TimeoutError, type TokenUsage, type Tool, type ToolCallEvent, type ToolConfigUpdateInput, type ToolExecution, type ToolListOptions, type ToolResultEvent, type ToolUpdateInput, type ToolValidationResult, ValidationError, collectImagesFromStream, deriveImagesFromToolCalls, extractImagesFromExecutionOutput, extractImagesFromResult };
3770
+ /**
3771
+ * AI function errors (p93 AIF-010, specs §9 + D27c).
3772
+ *
3773
+ * All extend the existing hierarchy so `instanceof CadraError` (and, where it
3774
+ * applies, `ConflictError` / `ValidationError`) keeps working.
3775
+ */
3776
+
3777
+ /**
3778
+ * 409 `DUPLICATE_REQUEST`: a run with the same idempotency key already exists.
3779
+ * No provider call was made. A retry after `abandoned` or a failure needs a NEW key.
3780
+ */
3781
+ declare class AiFunctionDuplicateError extends ConflictError {
3782
+ /** The existing run's execution id. */
3783
+ readonly executionId?: string;
3784
+ /** The existing run's status (`running`, a terminal status, or `abandoned`). */
3785
+ readonly runStatus?: string;
3786
+ constructor(message: string, details?: Record<string, unknown>, requestId?: string);
3787
+ }
3788
+ /**
3789
+ * The provider answered 2xx and the run WAS metered, but the output then failed
3790
+ * (`OUTPUT_INVALID`, `DELIVERY_FAILED` — `details.charged: true`). Never retry
3791
+ * automatically: a retry is a second paid call.
3792
+ */
3793
+ declare class AiFunctionChargedError extends CadraError {
3794
+ constructor(source: CadraError);
3795
+ }
3796
+ /**
3797
+ * The client-side parameter check failed (D27c). No run request was sent.
3798
+ * Also a `ValidationError`, with one `errors[]` entry per issue.
3799
+ */
3800
+ declare class AiFunctionParameterError extends ValidationError {
3801
+ readonly functionKey: string;
3802
+ readonly issues: AiFunctionParameterIssue[];
3803
+ constructor(functionKey: string, issues: AiFunctionParameterIssue[]);
3804
+ }
3805
+
3806
+ export { CadraClient as AISaaSClient, type CadraClientOptions as AISaaSClientOptions, CadraError as AISaaSError, AI_FUNCTION_DESCRIPTOR_TTL_MS, AI_FUNCTION_RUN_TIMEOUT_MS, type Agent, type AgentConfig, type AgentConfigUpdateInput, type AgentExecution, type AgentListOptions, type AgentStatus, type AgentType, type AgentUpdateInput, type AiFunctionBilledTo, AiFunctionChargedError, type AiFunctionDescriptor, AiFunctionDuplicateError, type AiFunctionImage, type AiFunctionOutput, type AiFunctionOutputKind, type AiFunctionParameter, AiFunctionParameterError, type AiFunctionParameterIssue, type AiFunctionParameterIssueCode, type AiFunctionParameterType, type AiFunctionRef, type AiFunctionRun, type AiFunctionRunOptions, type AiFunctionRunResult, type AiFunctionRunShorthandOptions, type AiFunctionRunStatus, type AiFunctionRuntimeParams, type AiFunctionUsage, type AiFunctionVariableValue, type AiFunctionVariables, AiFunctionsAPI, type Artifact, type ArtifactDownloadOptions, type ArtifactListOptions, type ArtifactType, type ArtifactUploadInput, type AttachmentUploadUrlInput, type AttachmentUploadUrlResponse, AuthenticationError, AuthorizationError, CadraClient, type CadraClientOptions, CadraError, type CollectImagesOptions, type CompleteEvent, ConflictError, type ConnectionChangeEvent, type DelegationCompletedEvent, type DelegationStartedEvent, type ErrorEvent, type ExecuteInput, type ExecuteOptions, type ExecuteResponse, type ExecuteToolDirectRequest, type ExecuteToolDirectResponse, type ExecutionLog, type ExecutionStatus, type ExecutionStreamController, type ExecutionStreamControllerOptions, type ExtractContext, type ImageData, type ImageEvent, type JSONSchema, type ListOptions, NetworkError, NotFoundError, type PaginatedResponse, type PaginationInfo, type PausedEvent, type PlanEvent, type ProgressEvent, RateLimitError, type RemoteAgent, type RemoteAgentCreateInput, type RemoteAgentExecuteResponse, type RemoteAgentExecutionTargetKind, type RemoteAgentListOptions, type RemoteAgentStatus, type RemoteAgentUpdateInput, type RemoteAgentVisibility, type RemoteRunner, type RemoteRunnerListOptions, type SendMessageInput, ServerError, type Session, type SessionArtifact, type SessionArtifactListOptions, type SessionArtifactType, type SessionArtifactVariantType, type SessionCreateInput, type SessionHistory, type SessionListOptions, type SessionMessage, type SignedUrlResponse, type Skill, type SkillDetails, type SkillExecuteInput, type SkillExecution, type SkillListOptions, type SkillTool, type SkillUpdateInput, type SkillVariable, type StartedEvent, type StreamController, type StreamEventMap, type StreamImagesResult, type TeamMemberRef, type TextDeltaEvent, TimeoutError, type TokenUsage, type Tool, type ToolCallEvent, type ToolConfigUpdateInput, type ToolExecution, type ToolListOptions, type ToolResultEvent, type ToolUpdateInput, type ToolValidationResult, ValidationError, checkAiFunctionParameters, collectImagesFromStream, deriveImagesFromToolCalls, extractImagesFromExecutionOutput, extractImagesFromResult };
package/dist/index.js CHANGED
@@ -61,6 +61,14 @@ var CadraError = class extends Error {
61
61
  details;
62
62
  /** Request ID from server (for debugging) */
63
63
  requestId;
64
+ /**
65
+ * The server's own `error.code` exactly as sent on the wire (e.g.
66
+ * `FUNCTION_NOT_PUBLISHED`, `DUPLICATE_REQUEST`, `VARIABLE_TYPE`).
67
+ * Populated by `parseApiError` for EVERY status. `code` keeps its historic
68
+ * per-class values (`conflict`, `server_error`, `validation_error`, …) for
69
+ * compatibility; branch on `serverCode` when you need the precise reason.
70
+ */
71
+ serverCode;
64
72
  constructor(message, code, status, details, requestId) {
65
73
  super(message);
66
74
  this.name = "CadraError";
@@ -138,6 +146,12 @@ function parseApiError(status, body, requestId) {
138
146
  const message = errorBody?.error?.message ?? "An error occurred";
139
147
  const code = errorBody?.error?.code ?? "unknown_error";
140
148
  const details = errorBody?.error?.details;
149
+ const serverCode = typeof errorBody?.error?.code === "string" ? errorBody.error.code : void 0;
150
+ const error = buildApiError(status, message, code, details, requestId);
151
+ if (serverCode !== void 0) error.serverCode = serverCode;
152
+ return error;
153
+ }
154
+ function buildApiError(status, message, code, details, requestId) {
141
155
  switch (status) {
142
156
  case 400:
143
157
  case 422: {
@@ -173,6 +187,42 @@ function parseApiError(status, body, requestId) {
173
187
  }
174
188
  }
175
189
 
190
+ // src/errors/ai-function-errors.ts
191
+ var AiFunctionDuplicateError = class extends ConflictError {
192
+ /** The existing run's execution id. */
193
+ executionId;
194
+ /** The existing run's status (`running`, a terminal status, or `abandoned`). */
195
+ runStatus;
196
+ constructor(message, details, requestId) {
197
+ super(message, details, requestId);
198
+ this.name = "AiFunctionDuplicateError";
199
+ this.serverCode = "DUPLICATE_REQUEST";
200
+ this.executionId = typeof details?.executionId === "string" ? details.executionId : void 0;
201
+ this.runStatus = typeof details?.status === "string" ? details.status : void 0;
202
+ }
203
+ };
204
+ var AiFunctionChargedError = class extends CadraError {
205
+ constructor(source) {
206
+ super(source.message, source.code, source.status, source.details, source.requestId);
207
+ this.name = "AiFunctionChargedError";
208
+ this.serverCode = source.serverCode;
209
+ }
210
+ };
211
+ var AiFunctionParameterError = class extends ValidationError {
212
+ functionKey;
213
+ issues;
214
+ constructor(functionKey, issues) {
215
+ super(
216
+ `Invalid parameters for AI function "${functionKey}": ` + issues.map((i) => `${i.name} (${i.code})`).join(", "),
217
+ issues.map((i) => ({ field: i.name, message: i.code })),
218
+ { functionKey, issues }
219
+ );
220
+ this.name = "AiFunctionParameterError";
221
+ this.functionKey = functionKey;
222
+ this.issues = issues;
223
+ }
224
+ };
225
+
176
226
  // src/utils/retry.ts
177
227
  var DEFAULT_RETRY_CONFIG = {
178
228
  maxRetries: 3,
@@ -237,6 +287,10 @@ var HttpClient = class {
237
287
  constructor(config) {
238
288
  this.config = config;
239
289
  }
290
+ /** The client-wide request timeout (ms) this client was configured with. */
291
+ get timeoutMs() {
292
+ return this.config.timeout;
293
+ }
240
294
  /**
241
295
  * Get authorization header value
242
296
  */
@@ -291,7 +345,8 @@ var HttpClient = class {
291
345
  headers["Idempotency-Key"] = options.idempotencyKey;
292
346
  }
293
347
  const controller = new AbortController();
294
- const timeoutId = setTimeout(() => controller.abort(), this.config.timeout);
348
+ const timeoutMs = options.timeoutMs ?? this.config.timeout;
349
+ const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
295
350
  try {
296
351
  const doFetch = this.config.fetch ?? fetch;
297
352
  const response = await doFetch(url, {
@@ -327,7 +382,7 @@ var HttpClient = class {
327
382
  } catch (error) {
328
383
  clearTimeout(timeoutId);
329
384
  if (error instanceof Error && error.name === "AbortError") {
330
- throw new TimeoutError(`Request timed out after ${this.config.timeout}ms`);
385
+ throw new TimeoutError(`Request timed out after ${options.timeoutMs ?? this.config.timeout}ms`);
331
386
  }
332
387
  if (error instanceof TypeError && error.message.includes("fetch")) {
333
388
  throw new NetworkError(`Network error: ${error.message}`);
@@ -359,7 +414,8 @@ var HttpClient = class {
359
414
  path,
360
415
  body,
361
416
  idempotencyKey: options?.idempotencyKey,
362
- skipRetry: options?.skipRetry
417
+ skipRetry: options?.skipRetry,
418
+ timeoutMs: options?.timeoutMs
363
419
  });
364
420
  }
365
421
  /**
@@ -1118,6 +1174,10 @@ var ExecutionStreamControllerImpl = class {
1118
1174
  toolName,
1119
1175
  result: data.result,
1120
1176
  durationMs: data.durationMs ?? 0,
1177
+ // CAD-243: pass the producer's failure verdict through.
1178
+ ...data.isError === true ? { isError: true } : {},
1179
+ ...typeof data.status === "string" ? { status: data.status } : {},
1180
+ ...typeof data.error === "string" ? { error: data.error } : {},
1121
1181
  forwardedFrom: event.data._forwardedFrom,
1122
1182
  // CAD-87 S1-001 EventIdentity → (execId, seq) reducer dedup (S1-003).
1123
1183
  sourceExecutionId: data.sourceExecutionId ?? data.executionId,
@@ -3356,6 +3416,156 @@ var RemoteRunnersAPI = class extends BaseResourceAPI {
3356
3416
  }
3357
3417
  };
3358
3418
 
3419
+ // src/resources/ai-functions.ts
3420
+ var AI_FUNCTION_RUN_TIMEOUT_MS = 31e4;
3421
+ var AI_FUNCTION_DESCRIPTOR_TTL_MS = 6e4;
3422
+ function checkAiFunctionParameters(parameters, variables) {
3423
+ const issues = [];
3424
+ const declared = /* @__PURE__ */ new Set();
3425
+ for (const p of parameters) {
3426
+ declared.add(p.name);
3427
+ const has = Object.prototype.hasOwnProperty.call(variables, p.name);
3428
+ const value = has ? variables[p.name] : void 0;
3429
+ if (value === void 0 || value === null) {
3430
+ if (p.required) issues.push({ name: p.name, code: "missing" });
3431
+ continue;
3432
+ }
3433
+ switch (p.type) {
3434
+ case "number":
3435
+ if (typeof value !== "number" || !Number.isFinite(value)) {
3436
+ issues.push({ name: p.name, code: "type" });
3437
+ }
3438
+ break;
3439
+ case "boolean":
3440
+ if (typeof value !== "boolean") issues.push({ name: p.name, code: "type" });
3441
+ break;
3442
+ case "enum":
3443
+ if (typeof value !== "string") issues.push({ name: p.name, code: "type" });
3444
+ else if (p.options && !p.options.includes(value)) {
3445
+ issues.push({ name: p.name, code: "option" });
3446
+ }
3447
+ break;
3448
+ case "string":
3449
+ case "text":
3450
+ if (typeof value !== "string") issues.push({ name: p.name, code: "type" });
3451
+ else if (typeof p.maxLength === "number" && value.length > p.maxLength) {
3452
+ issues.push({ name: p.name, code: "too_long" });
3453
+ }
3454
+ break;
3455
+ case "image":
3456
+ if (typeof value !== "string") issues.push({ name: p.name, code: "type" });
3457
+ break;
3458
+ }
3459
+ }
3460
+ for (const name of Object.keys(variables)) {
3461
+ if (!declared.has(name)) issues.push({ name, code: "unknown" });
3462
+ }
3463
+ return issues;
3464
+ }
3465
+ var AiFunctionsAPI = class extends BaseResourceAPI {
3466
+ descriptorCache = /* @__PURE__ */ new Map();
3467
+ constructor(http) {
3468
+ super(http, "/api/v1/ai-functions");
3469
+ }
3470
+ /**
3471
+ * List the functions this org can call — the index (D27a). Each entry carries
3472
+ * the live version's typed parameters; never prompt text.
3473
+ */
3474
+ async list() {
3475
+ const data = await this.httpGet("");
3476
+ const functions = Array.isArray(data) ? data : data?.functions ?? [];
3477
+ for (const d of functions) this.cacheDescriptor(d);
3478
+ return functions;
3479
+ }
3480
+ /**
3481
+ * Get one function's descriptor by key (D27a).
3482
+ * `NotFoundError` (`FUNCTION_NOT_FOUND`) / `ConflictError` (`FUNCTION_NOT_PUBLISHED`).
3483
+ */
3484
+ async get(functionKey) {
3485
+ const data = await this.httpGet(
3486
+ `/${encodeURIComponent(functionKey)}`
3487
+ );
3488
+ const descriptor = data && typeof data === "object" && "function" in data && !("functionKey" in data) ? data.function : data;
3489
+ this.cacheDescriptor(descriptor, functionKey);
3490
+ return descriptor;
3491
+ }
3492
+ /**
3493
+ * Read one of this org's own runs (safe projection, §6.5).
3494
+ */
3495
+ async getRun(executionId) {
3496
+ return this.httpGet(`/runs/${encodeURIComponent(executionId)}`);
3497
+ }
3498
+ /** Forget cached descriptors (one key, or all). */
3499
+ clearDescriptorCache(functionKey) {
3500
+ if (functionKey) this.descriptorCache.delete(functionKey);
3501
+ else this.descriptorCache.clear();
3502
+ }
3503
+ async run(refOrKey, parametersOrOptions, shorthandOpts) {
3504
+ let ref;
3505
+ let options;
3506
+ if (typeof refOrKey === "string") {
3507
+ ref = { functionKey: refOrKey };
3508
+ options = { ...shorthandOpts ?? {}, variables: parametersOrOptions };
3509
+ } else {
3510
+ ref = refOrKey;
3511
+ options = parametersOrOptions;
3512
+ }
3513
+ const variables = options.variables ?? {};
3514
+ const functionKey = "functionKey" in ref ? ref.functionKey : void 0;
3515
+ const shouldCheck = functionKey !== void 0 && options.version === void 0 && options.validate !== false;
3516
+ if (shouldCheck) {
3517
+ const descriptor = await this.getCachedDescriptor(functionKey);
3518
+ const issues = checkAiFunctionParameters(descriptor.parameters, variables);
3519
+ if (issues.length > 0) {
3520
+ throw new AiFunctionParameterError(functionKey, issues);
3521
+ }
3522
+ }
3523
+ const body = {
3524
+ ref,
3525
+ variables,
3526
+ version: options.version,
3527
+ idempotencyKey: options.idempotencyKey ?? generateExecutionId(),
3528
+ params: options.params
3529
+ };
3530
+ try {
3531
+ return await this.httpPost("/run", body, {
3532
+ skipRetry: true,
3533
+ timeoutMs: Math.max(AI_FUNCTION_RUN_TIMEOUT_MS, this.http.timeoutMs ?? 0)
3534
+ });
3535
+ } catch (error) {
3536
+ throw this.mapRunError(error, functionKey);
3537
+ }
3538
+ }
3539
+ // ── internals ──────────────────────────────────────────────────────────────
3540
+ cacheDescriptor(descriptor, key) {
3541
+ if (!descriptor || typeof descriptor !== "object") return;
3542
+ const cacheKey = key ?? descriptor.functionKey;
3543
+ if (!cacheKey) return;
3544
+ this.descriptorCache.set(cacheKey, {
3545
+ descriptor,
3546
+ expiresAt: Date.now() + AI_FUNCTION_DESCRIPTOR_TTL_MS
3547
+ });
3548
+ }
3549
+ async getCachedDescriptor(functionKey) {
3550
+ const hit = this.descriptorCache.get(functionKey);
3551
+ if (hit && hit.expiresAt > Date.now()) return hit.descriptor;
3552
+ return this.get(functionKey);
3553
+ }
3554
+ mapRunError(error, functionKey) {
3555
+ if (!(error instanceof CadraError)) return error;
3556
+ if (error.serverCode === "DUPLICATE_REQUEST") {
3557
+ return new AiFunctionDuplicateError(error.message, error.details, error.requestId);
3558
+ }
3559
+ if (error.details?.charged === true) {
3560
+ return new AiFunctionChargedError(error);
3561
+ }
3562
+ if (functionKey && error.serverCode?.startsWith("VARIABLE_")) {
3563
+ this.descriptorCache.delete(functionKey);
3564
+ }
3565
+ return error;
3566
+ }
3567
+ };
3568
+
3359
3569
  // src/client.ts
3360
3570
  var DEFAULT_BASE_URL = "https://api.cadraos.com";
3361
3571
  var DEFAULT_TIMEOUT = 3e4;
@@ -3402,6 +3612,10 @@ var CadraClient = class {
3402
3612
  * Remote runner operations (list)
3403
3613
  */
3404
3614
  remoteRunners;
3615
+ /**
3616
+ * AI function operations (list, get, run, getRun) — p93
3617
+ */
3618
+ aiFunctions;
3405
3619
  /**
3406
3620
  * Create a new AI SaaS client
3407
3621
  *
@@ -3491,6 +3705,7 @@ var CadraClient = class {
3491
3705
  this.kanban = new KanbanAPI(this.httpClient, getStreamConfig);
3492
3706
  this.remoteAgents = new RemoteAgentsAPI(this.httpClient, getStreamConfig);
3493
3707
  this.remoteRunners = new RemoteRunnersAPI(this.httpClient);
3708
+ this.aiFunctions = new AiFunctionsAPI(this.httpClient);
3494
3709
  }
3495
3710
  /**
3496
3711
  * Validate client options
@@ -3513,6 +3728,6 @@ var CadraClient = class {
3513
3728
  }
3514
3729
  };
3515
3730
 
3516
- export { CadraClient as AISaaSClient, CadraError as AISaaSError, AuthenticationError, AuthorizationError, CadraClient, CadraError, ConflictError, NetworkError, NotFoundError, RateLimitError, ServerError, TimeoutError, ValidationError, collectImagesFromStream, deriveImagesFromToolCalls, extractImagesFromExecutionOutput, extractImagesFromResult };
3731
+ export { CadraClient as AISaaSClient, CadraError as AISaaSError, AI_FUNCTION_DESCRIPTOR_TTL_MS, AI_FUNCTION_RUN_TIMEOUT_MS, AiFunctionChargedError, AiFunctionDuplicateError, AiFunctionParameterError, AiFunctionsAPI, AuthenticationError, AuthorizationError, CadraClient, CadraError, ConflictError, NetworkError, NotFoundError, RateLimitError, ServerError, TimeoutError, ValidationError, checkAiFunctionParameters, collectImagesFromStream, deriveImagesFromToolCalls, extractImagesFromExecutionOutput, extractImagesFromResult };
3517
3732
  //# sourceMappingURL=index.js.map
3518
3733
  //# sourceMappingURL=index.js.map