@cadraos/sdk 0.3.14-p46.3 → 0.3.14

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 (52) 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/board-host/index.cjs +217 -129
  15. package/dist/board-host/index.cjs.map +1 -1
  16. package/dist/board-host/index.d.cts +96 -1
  17. package/dist/board-host/index.d.ts +96 -1
  18. package/dist/board-host/index.js +218 -131
  19. package/dist/board-host/index.js.map +1 -1
  20. package/dist/board-host/server/index.d.cts +44 -0
  21. package/dist/board-host/server/index.d.ts +44 -0
  22. package/dist/chat/index.cjs +299 -17
  23. package/dist/chat/index.cjs.map +1 -1
  24. package/dist/chat/index.d.cts +225 -0
  25. package/dist/chat/index.d.ts +225 -0
  26. package/dist/chat/index.js +299 -17
  27. package/dist/chat/index.js.map +1 -1
  28. package/dist/index.cjs +221 -3
  29. package/dist/index.cjs.map +1 -1
  30. package/dist/index.d.cts +286 -1
  31. package/dist/index.d.ts +286 -1
  32. package/dist/index.js +215 -4
  33. package/dist/index.js.map +1 -1
  34. package/dist/kanban/engine/index.cjs +774 -683
  35. package/dist/kanban/engine/index.cjs.map +1 -1
  36. package/dist/kanban/engine/index.d.cts +90 -1
  37. package/dist/kanban/engine/index.d.ts +90 -1
  38. package/dist/kanban/engine/index.js +774 -684
  39. package/dist/kanban/engine/index.js.map +1 -1
  40. package/dist/kanban/index.cjs +214 -3
  41. package/dist/kanban/index.cjs.map +1 -1
  42. package/dist/kanban/index.d.cts +252 -0
  43. package/dist/kanban/index.d.ts +252 -0
  44. package/dist/kanban/index.js +214 -3
  45. package/dist/kanban/index.js.map +1 -1
  46. package/dist/teams/index.cjs +214 -3
  47. package/dist/teams/index.cjs.map +1 -1
  48. package/dist/teams/index.d.cts +225 -0
  49. package/dist/teams/index.d.ts +225 -0
  50. package/dist/teams/index.js +214 -3
  51. package/dist/teams/index.js.map +1 -1
  52. package/package.json +21 -1
package/dist/index.d.ts CHANGED
@@ -62,6 +62,12 @@ 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
+ * may take up to 60 s while every other call keeps the 30 s default).
69
+ */
70
+ timeoutMs?: number;
65
71
  }
66
72
  /**
67
73
  * HTTP Client class
@@ -93,6 +99,7 @@ declare class HttpClient {
93
99
  post<T>(path: string, body?: unknown, options?: {
94
100
  idempotencyKey?: string;
95
101
  skipRetry?: boolean;
102
+ timeoutMs?: number;
96
103
  }): Promise<T>;
97
104
  /**
98
105
  * PATCH request
@@ -1146,6 +1153,16 @@ interface ToolResultEvent {
1146
1153
  result: unknown;
1147
1154
  /** Duration in milliseconds */
1148
1155
  durationMs: number;
1156
+ /**
1157
+ * CAD-243: true when the tool call FAILED (the producer stamps
1158
+ * `isError: true` + `status: 'failed'` on a thrown tool call). Absent on
1159
+ * older producers — consumers then fall back to the result shape.
1160
+ */
1161
+ isError?: boolean;
1162
+ /** CAD-243: producer verdict, `'failed'` for a failed call. */
1163
+ status?: string;
1164
+ /** CAD-243: error text for a failed call. */
1165
+ error?: string;
1149
1166
  /** See {@link ToolCallEvent.forwardedFrom} */
1150
1167
  forwardedFrom?: string;
1151
1168
  /** See {@link ToolCallEvent.sourceExecutionId} (CAD-87 S1-001). */
@@ -1529,6 +1546,140 @@ interface StreamingConfig {
1529
1546
  sseRetryIntervalMs?: number;
1530
1547
  }
1531
1548
 
1549
+ /**
1550
+ * AI function types (p93 — specs §4 run contract, D27 discovery, §6.5 run reads).
1551
+ *
1552
+ * An AI function is a published prompt in the Cadra Prompts library that makes
1553
+ * ONE direct AI-provider call (never an agent). Callers reference it by its
1554
+ * `functionKey` (unique per org), by prompt uuid, or — for platform features —
1555
+ * by slot key.
1556
+ */
1557
+ /** Output kind of an AI function. */
1558
+ type AiFunctionOutputKind = 'text' | 'json' | 'image';
1559
+ /** Parameter (prompt variable) types — specs D10 + D26d. */
1560
+ type AiFunctionParameterType = 'string' | 'text' | 'number' | 'boolean' | 'enum' | 'image';
1561
+ /** A value passed for one parameter. `image` parameters take an artifact uuid (string). */
1562
+ type AiFunctionVariableValue = string | number | boolean;
1563
+ /** Parameters (variables) for one run, keyed by parameter name. */
1564
+ type AiFunctionVariables = Record<string, AiFunctionVariableValue>;
1565
+ /** How a run names its function (§4). */
1566
+ type AiFunctionRef = {
1567
+ slot: string;
1568
+ } | {
1569
+ functionKey: string;
1570
+ } | {
1571
+ promptUuid: string;
1572
+ };
1573
+ /** One declared parameter of a function's live (golden) version — D27a. */
1574
+ interface AiFunctionParameter {
1575
+ name: string;
1576
+ type: AiFunctionParameterType;
1577
+ required: boolean;
1578
+ defaultValue?: AiFunctionVariableValue;
1579
+ maxLength?: number;
1580
+ options?: string[];
1581
+ description?: string;
1582
+ }
1583
+ /**
1584
+ * The discovery "index" entry for one callable function — D27a. Built from the
1585
+ * golden version snapshot; never carries prompt or system text.
1586
+ */
1587
+ interface AiFunctionDescriptor {
1588
+ functionKey: string;
1589
+ title: string;
1590
+ description?: string | null;
1591
+ outputKind: AiFunctionOutputKind;
1592
+ /** The live (golden) version number. */
1593
+ liveVersion: number;
1594
+ parameters: AiFunctionParameter[];
1595
+ /** JSON schema of the output, for `json` functions. */
1596
+ outputSchema?: Record<string, unknown> | null;
1597
+ }
1598
+ /** Who paid for a run (D4). */
1599
+ type AiFunctionBilledTo = 'own_key' | 'credits' | 'platform_funded';
1600
+ /** Runtime params a slot may accept per run (D26d3). */
1601
+ interface AiFunctionRuntimeParams {
1602
+ aspect_ratio?: string;
1603
+ image_size?: string;
1604
+ }
1605
+ /** Options for the object form `run(ref, { variables, … })`. */
1606
+ interface AiFunctionRunOptions {
1607
+ /** Parameters for this run (sent as `variables`). */
1608
+ variables: AiFunctionVariables;
1609
+ /** Pin a published version number (D3d). Skips the client-side check. */
1610
+ version?: number;
1611
+ /** Idempotency key (uuid). Generated when omitted (D15). */
1612
+ idempotencyKey?: string;
1613
+ /** Slot runtime params (D26d3). */
1614
+ params?: AiFunctionRuntimeParams;
1615
+ /** `false` skips the client-side parameter check (D27c). Default true. */
1616
+ validate?: boolean;
1617
+ }
1618
+ /** Options for the shorthand `run('function_key', parameters, opts)`. */
1619
+ type AiFunctionRunShorthandOptions = Omit<AiFunctionRunOptions, 'variables'>;
1620
+ /** Image produced by an `image` function. Over HTTP only `url` (presigned, 1 h) is set. */
1621
+ interface AiFunctionImage {
1622
+ mimeType: string;
1623
+ url?: string;
1624
+ bytes?: Uint8Array;
1625
+ }
1626
+ /** Output of a run, by kind (§4). `TOutput` types `json`. */
1627
+ type AiFunctionOutput<TOutput = unknown> = {
1628
+ type: 'text';
1629
+ text: string;
1630
+ } | {
1631
+ type: 'json';
1632
+ json: TOutput;
1633
+ } | {
1634
+ type: 'image';
1635
+ images: AiFunctionImage[];
1636
+ };
1637
+ /** Token and billing usage of a run (§4). */
1638
+ interface AiFunctionUsage {
1639
+ promptTokens: number;
1640
+ completionTokens: number;
1641
+ imageCount: number;
1642
+ billedTo: AiFunctionBilledTo;
1643
+ }
1644
+ /** Result of a successful run (§4). */
1645
+ interface AiFunctionRunResult<TOutput = unknown> {
1646
+ /** = the run's execution uuid (usage-ledger executionUuid). */
1647
+ executionId: string;
1648
+ functionUuid: string;
1649
+ version: number;
1650
+ output: AiFunctionOutput<TOutput>;
1651
+ usage: AiFunctionUsage;
1652
+ latencyMs: number;
1653
+ }
1654
+ /** Run status as reported by run reads (D12; `abandoned` is computed on read). */
1655
+ type AiFunctionRunStatus = 'running' | 'succeeded' | 'failed_provider' | 'failed_timeout' | 'refused_billing' | 'failed_output' | 'failed_delivery' | 'abandoned';
1656
+ /** Safe projection of one of the caller org's own runs (§6.5). */
1657
+ interface AiFunctionRun {
1658
+ executionId: string;
1659
+ ref: {
1660
+ slot?: string;
1661
+ functionKey?: string;
1662
+ promptUuid?: string;
1663
+ };
1664
+ version: number | null;
1665
+ status: AiFunctionRunStatus;
1666
+ errorCode: string | null;
1667
+ promptTokens: number | null;
1668
+ completionTokens: number | null;
1669
+ imageCount: number | null;
1670
+ latencyMs: number | null;
1671
+ billedTo: AiFunctionBilledTo | null;
1672
+ createdAt: string;
1673
+ finishedAt: string | null;
1674
+ }
1675
+ /** Why a parameter failed the client-side check (D27c). */
1676
+ type AiFunctionParameterIssueCode = 'missing' | 'type' | 'option' | 'too_long' | 'unknown';
1677
+ /** One client-side parameter problem (D27c). */
1678
+ interface AiFunctionParameterIssue {
1679
+ name: string;
1680
+ code: AiFunctionParameterIssueCode;
1681
+ }
1682
+
1532
1683
  /**
1533
1684
  * Base Resource API
1534
1685
  *
@@ -1557,6 +1708,7 @@ declare abstract class BaseResourceAPI {
1557
1708
  protected httpPost<T>(path: string, body?: unknown, options?: {
1558
1709
  idempotencyKey?: string;
1559
1710
  skipRetry?: boolean;
1711
+ timeoutMs?: number;
1560
1712
  }): Promise<T>;
1561
1713
  /**
1562
1714
  * HTTP PATCH request helper
@@ -2897,6 +3049,11 @@ interface KanbanCard {
2897
3049
  configVersion?: number;
2898
3050
  /** Arbitrary shared context carried across transitions. */
2899
3051
  sharedContext?: Record<string, unknown>;
3052
+ /**
3053
+ * p46 (P46-002): the card's id in an external host (a Jira issue key).
3054
+ * Absent on native / crm / yobo cards.
3055
+ */
3056
+ externalRef?: string;
2900
3057
  /**
2901
3058
  * Execution UUID of the card's current/last run, if any.
2902
3059
  *
@@ -2959,6 +3116,18 @@ interface CreateCardInput {
2959
3116
  * in the lifecycle's initial lane.
2960
3117
  */
2961
3118
  lane?: string;
3119
+ /**
3120
+ * p46 (P46-002): the card's id in an EXTERNAL host (a Jira issue key, e.g.
3121
+ * `CAD-231`). Optional. When set, a card is created at most ONCE per
3122
+ * `(boardConfigUuid, externalRef)`: a repeat create returns the existing card
3123
+ * and dispatches nothing. Hosts that don't store it simply ignore it.
3124
+ */
3125
+ externalRef?: string;
3126
+ /**
3127
+ * p46 (P46-002): opaque host facts stored with the card (Jira `statusId`,
3128
+ * `mover`, `detached`, …). Passed through to `adapter.createCard` untouched.
3129
+ */
3130
+ externalMeta?: Record<string, unknown>;
2962
3131
  }
2963
3132
  /**
2964
3133
  * Input for transitioning a card to another lane.
@@ -3237,6 +3406,74 @@ declare class RemoteRunnersAPI extends BaseResourceAPI {
3237
3406
  list(options?: RemoteRunnerListOptions): Promise<PaginatedResponse<RemoteRunner>>;
3238
3407
  }
3239
3408
 
3409
+ /**
3410
+ * AI Functions API (p93 AIF-010 — specs §9, D27).
3411
+ *
3412
+ * @example
3413
+ * ```typescript
3414
+ * // Discover what the org can call, and with which parameters
3415
+ * const functions = await client.aiFunctions.list();
3416
+ * const fn = await client.aiFunctions.get('summarise_ticket');
3417
+ *
3418
+ * // Call it — parameters are checked against the live version before sending
3419
+ * const result = await client.aiFunctions.run('summarise_ticket', { ticket_text: '…' });
3420
+ * if (result.output.type === 'text') console.log(result.output.text);
3421
+ * ```
3422
+ */
3423
+
3424
+ /** Paid runs get their own 60 s budget (server `maxDuration = 60`, D6). */
3425
+ declare const AI_FUNCTION_RUN_TIMEOUT_MS = 60000;
3426
+ /** Descriptors used by the client-side check are cached per client for 60 s (D27c). */
3427
+ declare const AI_FUNCTION_DESCRIPTOR_TTL_MS = 60000;
3428
+ /**
3429
+ * Check `variables` against a descriptor's parameters (D27c). Returns the issues,
3430
+ * in parameter order, then unknown names. Empty array = OK.
3431
+ */
3432
+ declare function checkAiFunctionParameters(parameters: AiFunctionParameter[], variables: AiFunctionVariables): AiFunctionParameterIssue[];
3433
+ /**
3434
+ * AI Functions API
3435
+ */
3436
+ declare class AiFunctionsAPI extends BaseResourceAPI {
3437
+ private readonly descriptorCache;
3438
+ constructor(http: HttpClient);
3439
+ /**
3440
+ * List the functions this org can call — the index (D27a). Each entry carries
3441
+ * the live version's typed parameters; never prompt text.
3442
+ */
3443
+ list(): Promise<AiFunctionDescriptor[]>;
3444
+ /**
3445
+ * Get one function's descriptor by key (D27a).
3446
+ * `NotFoundError` (`FUNCTION_NOT_FOUND`) / `ConflictError` (`FUNCTION_NOT_PUBLISHED`).
3447
+ */
3448
+ get(functionKey: string): Promise<AiFunctionDescriptor>;
3449
+ /**
3450
+ * Read one of this org's own runs (safe projection, §6.5).
3451
+ */
3452
+ getRun(executionId: string): Promise<AiFunctionRun>;
3453
+ /** Forget cached descriptors (one key, or all). */
3454
+ clearDescriptorCache(functionKey?: string): void;
3455
+ /**
3456
+ * Run an AI function — one paid provider call.
3457
+ *
3458
+ * - `run('function_key', parameters, opts?)` — shorthand for `{ functionKey }`.
3459
+ * - `run({ functionKey | promptUuid | slot }, { variables, version?, idempotencyKey?, params?, validate? })`.
3460
+ *
3461
+ * For a `functionKey` ref without a pinned `version`, parameters are checked
3462
+ * against the live version first (D27c); a problem throws
3463
+ * `AiFunctionParameterError` and NO run request is sent. Paid runs are never
3464
+ * auto-retried; an idempotency key is generated when omitted.
3465
+ *
3466
+ * @throws AiFunctionParameterError — client-side check failed (nothing sent)
3467
+ * @throws AiFunctionDuplicateError — 409 `DUPLICATE_REQUEST`
3468
+ * @throws AiFunctionChargedError — the run was metered but its output failed (`details.charged`)
3469
+ */
3470
+ run<TOutput = unknown>(functionKey: string, parameters: AiFunctionVariables, opts?: AiFunctionRunShorthandOptions): Promise<AiFunctionRunResult<TOutput>>;
3471
+ run<TOutput = unknown>(ref: AiFunctionRef, options: AiFunctionRunOptions): Promise<AiFunctionRunResult<TOutput>>;
3472
+ private cacheDescriptor;
3473
+ private getCachedDescriptor;
3474
+ private mapRunError;
3475
+ }
3476
+
3240
3477
  /**
3241
3478
  * Cadra Client
3242
3479
  *
@@ -3381,6 +3618,10 @@ declare class CadraClient {
3381
3618
  * Remote runner operations (list)
3382
3619
  */
3383
3620
  readonly remoteRunners: RemoteRunnersAPI;
3621
+ /**
3622
+ * AI function operations (list, get, run, getRun) — p93
3623
+ */
3624
+ readonly aiFunctions: AiFunctionsAPI;
3384
3625
  /**
3385
3626
  * Create a new AI SaaS client
3386
3627
  *
@@ -3432,6 +3673,14 @@ declare class CadraError extends Error {
3432
3673
  readonly details?: Record<string, unknown>;
3433
3674
  /** Request ID from server (for debugging) */
3434
3675
  readonly requestId?: string;
3676
+ /**
3677
+ * The server's own `error.code` exactly as sent on the wire (e.g.
3678
+ * `FUNCTION_NOT_PUBLISHED`, `DUPLICATE_REQUEST`, `VARIABLE_TYPE`).
3679
+ * Populated by `parseApiError` for EVERY status. `code` keeps its historic
3680
+ * per-class values (`conflict`, `server_error`, `validation_error`, …) for
3681
+ * compatibility; branch on `serverCode` when you need the precise reason.
3682
+ */
3683
+ serverCode?: string;
3435
3684
  constructor(message: string, code: string, status: number, details?: Record<string, unknown>, requestId?: string);
3436
3685
  }
3437
3686
  /**
@@ -3508,4 +3757,40 @@ declare class NetworkError extends CadraError {
3508
3757
  constructor(message?: string, details?: Record<string, unknown>);
3509
3758
  }
3510
3759
 
3511
- 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 };
3760
+ /**
3761
+ * AI function errors (p93 AIF-010, specs §9 + D27c).
3762
+ *
3763
+ * All extend the existing hierarchy so `instanceof CadraError` (and, where it
3764
+ * applies, `ConflictError` / `ValidationError`) keeps working.
3765
+ */
3766
+
3767
+ /**
3768
+ * 409 `DUPLICATE_REQUEST`: a run with the same idempotency key already exists.
3769
+ * No provider call was made. A retry after `abandoned` or a failure needs a NEW key.
3770
+ */
3771
+ declare class AiFunctionDuplicateError extends ConflictError {
3772
+ /** The existing run's execution id. */
3773
+ readonly executionId?: string;
3774
+ /** The existing run's status (`running`, a terminal status, or `abandoned`). */
3775
+ readonly runStatus?: string;
3776
+ constructor(message: string, details?: Record<string, unknown>, requestId?: string);
3777
+ }
3778
+ /**
3779
+ * The provider answered 2xx and the run WAS metered, but the output then failed
3780
+ * (`OUTPUT_INVALID`, `DELIVERY_FAILED` — `details.charged: true`). Never retry
3781
+ * automatically: a retry is a second paid call.
3782
+ */
3783
+ declare class AiFunctionChargedError extends CadraError {
3784
+ constructor(source: CadraError);
3785
+ }
3786
+ /**
3787
+ * The client-side parameter check failed (D27c). No run request was sent.
3788
+ * Also a `ValidationError`, with one `errors[]` entry per issue.
3789
+ */
3790
+ declare class AiFunctionParameterError extends ValidationError {
3791
+ readonly functionKey: string;
3792
+ readonly issues: AiFunctionParameterIssue[];
3793
+ constructor(functionKey: string, issues: AiFunctionParameterIssue[]);
3794
+ }
3795
+
3796
+ 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,
@@ -291,7 +341,8 @@ var HttpClient = class {
291
341
  headers["Idempotency-Key"] = options.idempotencyKey;
292
342
  }
293
343
  const controller = new AbortController();
294
- const timeoutId = setTimeout(() => controller.abort(), this.config.timeout);
344
+ const timeoutMs = options.timeoutMs ?? this.config.timeout;
345
+ const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
295
346
  try {
296
347
  const doFetch = this.config.fetch ?? fetch;
297
348
  const response = await doFetch(url, {
@@ -327,7 +378,7 @@ var HttpClient = class {
327
378
  } catch (error) {
328
379
  clearTimeout(timeoutId);
329
380
  if (error instanceof Error && error.name === "AbortError") {
330
- throw new TimeoutError(`Request timed out after ${this.config.timeout}ms`);
381
+ throw new TimeoutError(`Request timed out after ${options.timeoutMs ?? this.config.timeout}ms`);
331
382
  }
332
383
  if (error instanceof TypeError && error.message.includes("fetch")) {
333
384
  throw new NetworkError(`Network error: ${error.message}`);
@@ -359,7 +410,8 @@ var HttpClient = class {
359
410
  path,
360
411
  body,
361
412
  idempotencyKey: options?.idempotencyKey,
362
- skipRetry: options?.skipRetry
413
+ skipRetry: options?.skipRetry,
414
+ timeoutMs: options?.timeoutMs
363
415
  });
364
416
  }
365
417
  /**
@@ -1118,6 +1170,10 @@ var ExecutionStreamControllerImpl = class {
1118
1170
  toolName,
1119
1171
  result: data.result,
1120
1172
  durationMs: data.durationMs ?? 0,
1173
+ // CAD-243: pass the producer's failure verdict through.
1174
+ ...data.isError === true ? { isError: true } : {},
1175
+ ...typeof data.status === "string" ? { status: data.status } : {},
1176
+ ...typeof data.error === "string" ? { error: data.error } : {},
1121
1177
  forwardedFrom: event.data._forwardedFrom,
1122
1178
  // CAD-87 S1-001 EventIdentity → (execId, seq) reducer dedup (S1-003).
1123
1179
  sourceExecutionId: data.sourceExecutionId ?? data.executionId,
@@ -3356,6 +3412,156 @@ var RemoteRunnersAPI = class extends BaseResourceAPI {
3356
3412
  }
3357
3413
  };
3358
3414
 
3415
+ // src/resources/ai-functions.ts
3416
+ var AI_FUNCTION_RUN_TIMEOUT_MS = 6e4;
3417
+ var AI_FUNCTION_DESCRIPTOR_TTL_MS = 6e4;
3418
+ function checkAiFunctionParameters(parameters, variables) {
3419
+ const issues = [];
3420
+ const declared = /* @__PURE__ */ new Set();
3421
+ for (const p of parameters) {
3422
+ declared.add(p.name);
3423
+ const has = Object.prototype.hasOwnProperty.call(variables, p.name);
3424
+ const value = has ? variables[p.name] : void 0;
3425
+ if (value === void 0 || value === null) {
3426
+ if (p.required) issues.push({ name: p.name, code: "missing" });
3427
+ continue;
3428
+ }
3429
+ switch (p.type) {
3430
+ case "number":
3431
+ if (typeof value !== "number" || !Number.isFinite(value)) {
3432
+ issues.push({ name: p.name, code: "type" });
3433
+ }
3434
+ break;
3435
+ case "boolean":
3436
+ if (typeof value !== "boolean") issues.push({ name: p.name, code: "type" });
3437
+ break;
3438
+ case "enum":
3439
+ if (typeof value !== "string") issues.push({ name: p.name, code: "type" });
3440
+ else if (p.options && !p.options.includes(value)) {
3441
+ issues.push({ name: p.name, code: "option" });
3442
+ }
3443
+ break;
3444
+ case "string":
3445
+ case "text":
3446
+ if (typeof value !== "string") issues.push({ name: p.name, code: "type" });
3447
+ else if (typeof p.maxLength === "number" && value.length > p.maxLength) {
3448
+ issues.push({ name: p.name, code: "too_long" });
3449
+ }
3450
+ break;
3451
+ case "image":
3452
+ if (typeof value !== "string") issues.push({ name: p.name, code: "type" });
3453
+ break;
3454
+ }
3455
+ }
3456
+ for (const name of Object.keys(variables)) {
3457
+ if (!declared.has(name)) issues.push({ name, code: "unknown" });
3458
+ }
3459
+ return issues;
3460
+ }
3461
+ var AiFunctionsAPI = class extends BaseResourceAPI {
3462
+ descriptorCache = /* @__PURE__ */ new Map();
3463
+ constructor(http) {
3464
+ super(http, "/api/v1/ai-functions");
3465
+ }
3466
+ /**
3467
+ * List the functions this org can call — the index (D27a). Each entry carries
3468
+ * the live version's typed parameters; never prompt text.
3469
+ */
3470
+ async list() {
3471
+ const data = await this.httpGet("");
3472
+ const functions = Array.isArray(data) ? data : data?.functions ?? [];
3473
+ for (const d of functions) this.cacheDescriptor(d);
3474
+ return functions;
3475
+ }
3476
+ /**
3477
+ * Get one function's descriptor by key (D27a).
3478
+ * `NotFoundError` (`FUNCTION_NOT_FOUND`) / `ConflictError` (`FUNCTION_NOT_PUBLISHED`).
3479
+ */
3480
+ async get(functionKey) {
3481
+ const data = await this.httpGet(
3482
+ `/${encodeURIComponent(functionKey)}`
3483
+ );
3484
+ const descriptor = data && typeof data === "object" && "function" in data && !("functionKey" in data) ? data.function : data;
3485
+ this.cacheDescriptor(descriptor, functionKey);
3486
+ return descriptor;
3487
+ }
3488
+ /**
3489
+ * Read one of this org's own runs (safe projection, §6.5).
3490
+ */
3491
+ async getRun(executionId) {
3492
+ return this.httpGet(`/runs/${encodeURIComponent(executionId)}`);
3493
+ }
3494
+ /** Forget cached descriptors (one key, or all). */
3495
+ clearDescriptorCache(functionKey) {
3496
+ if (functionKey) this.descriptorCache.delete(functionKey);
3497
+ else this.descriptorCache.clear();
3498
+ }
3499
+ async run(refOrKey, parametersOrOptions, shorthandOpts) {
3500
+ let ref;
3501
+ let options;
3502
+ if (typeof refOrKey === "string") {
3503
+ ref = { functionKey: refOrKey };
3504
+ options = { ...shorthandOpts ?? {}, variables: parametersOrOptions };
3505
+ } else {
3506
+ ref = refOrKey;
3507
+ options = parametersOrOptions;
3508
+ }
3509
+ const variables = options.variables ?? {};
3510
+ const functionKey = "functionKey" in ref ? ref.functionKey : void 0;
3511
+ const shouldCheck = functionKey !== void 0 && options.version === void 0 && options.validate !== false;
3512
+ if (shouldCheck) {
3513
+ const descriptor = await this.getCachedDescriptor(functionKey);
3514
+ const issues = checkAiFunctionParameters(descriptor.parameters, variables);
3515
+ if (issues.length > 0) {
3516
+ throw new AiFunctionParameterError(functionKey, issues);
3517
+ }
3518
+ }
3519
+ const body = {
3520
+ ref,
3521
+ variables,
3522
+ version: options.version,
3523
+ idempotencyKey: options.idempotencyKey ?? generateExecutionId(),
3524
+ params: options.params
3525
+ };
3526
+ try {
3527
+ return await this.httpPost("/run", body, {
3528
+ skipRetry: true,
3529
+ timeoutMs: AI_FUNCTION_RUN_TIMEOUT_MS
3530
+ });
3531
+ } catch (error) {
3532
+ throw this.mapRunError(error, functionKey);
3533
+ }
3534
+ }
3535
+ // ── internals ──────────────────────────────────────────────────────────────
3536
+ cacheDescriptor(descriptor, key) {
3537
+ if (!descriptor || typeof descriptor !== "object") return;
3538
+ const cacheKey = key ?? descriptor.functionKey;
3539
+ if (!cacheKey) return;
3540
+ this.descriptorCache.set(cacheKey, {
3541
+ descriptor,
3542
+ expiresAt: Date.now() + AI_FUNCTION_DESCRIPTOR_TTL_MS
3543
+ });
3544
+ }
3545
+ async getCachedDescriptor(functionKey) {
3546
+ const hit = this.descriptorCache.get(functionKey);
3547
+ if (hit && hit.expiresAt > Date.now()) return hit.descriptor;
3548
+ return this.get(functionKey);
3549
+ }
3550
+ mapRunError(error, functionKey) {
3551
+ if (!(error instanceof CadraError)) return error;
3552
+ if (error.serverCode === "DUPLICATE_REQUEST") {
3553
+ return new AiFunctionDuplicateError(error.message, error.details, error.requestId);
3554
+ }
3555
+ if (error.details?.charged === true) {
3556
+ return new AiFunctionChargedError(error);
3557
+ }
3558
+ if (functionKey && error.serverCode?.startsWith("VARIABLE_")) {
3559
+ this.descriptorCache.delete(functionKey);
3560
+ }
3561
+ return error;
3562
+ }
3563
+ };
3564
+
3359
3565
  // src/client.ts
3360
3566
  var DEFAULT_BASE_URL = "https://api.cadraos.com";
3361
3567
  var DEFAULT_TIMEOUT = 3e4;
@@ -3402,6 +3608,10 @@ var CadraClient = class {
3402
3608
  * Remote runner operations (list)
3403
3609
  */
3404
3610
  remoteRunners;
3611
+ /**
3612
+ * AI function operations (list, get, run, getRun) — p93
3613
+ */
3614
+ aiFunctions;
3405
3615
  /**
3406
3616
  * Create a new AI SaaS client
3407
3617
  *
@@ -3491,6 +3701,7 @@ var CadraClient = class {
3491
3701
  this.kanban = new KanbanAPI(this.httpClient, getStreamConfig);
3492
3702
  this.remoteAgents = new RemoteAgentsAPI(this.httpClient, getStreamConfig);
3493
3703
  this.remoteRunners = new RemoteRunnersAPI(this.httpClient);
3704
+ this.aiFunctions = new AiFunctionsAPI(this.httpClient);
3494
3705
  }
3495
3706
  /**
3496
3707
  * Validate client options
@@ -3513,6 +3724,6 @@ var CadraClient = class {
3513
3724
  }
3514
3725
  };
3515
3726
 
3516
- export { CadraClient as AISaaSClient, CadraError as AISaaSError, AuthenticationError, AuthorizationError, CadraClient, CadraError, ConflictError, NetworkError, NotFoundError, RateLimitError, ServerError, TimeoutError, ValidationError, collectImagesFromStream, deriveImagesFromToolCalls, extractImagesFromExecutionOutput, extractImagesFromResult };
3727
+ 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
3728
  //# sourceMappingURL=index.js.map
3518
3729
  //# sourceMappingURL=index.js.map