@uniformdev/automations-sdk 20.50.2-alpha.109 → 20.50.2-alpha.149

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.
@@ -1,6 +1,24 @@
1
1
  import { ApiClient, ClientOptions } from '@uniformdev/context/api';
2
2
  import { UIMessage } from 'ai';
3
+ import { StandardSchemaV1 } from '@standard-schema/spec';
3
4
 
5
+ /**
6
+ * Contract for a structured Scout result: a zod schema, or a plain JSON
7
+ * Schema object passed through verbatim.
8
+ */
9
+ type ScoutOutputSchema = StandardSchemaV1 | Record<string, unknown>;
10
+ /**
11
+ * Infers the structured-result type from a {@link ScoutOutputSchema}: a zod schema yields its
12
+ * inferred output type; a raw JSON Schema object yields `unknown` (no static type information).
13
+ */
14
+ type InferStructuredOutput<S> = S extends StandardSchemaV1 ? StandardSchemaV1.InferOutput<S> : unknown;
15
+
16
+ /**
17
+ * User turn for {@link ScoutClient.invoke}. `id` is optional — a UUID is generated when omitted.
18
+ */
19
+ type ScoutInvokeMessage = Omit<UIMessage, 'id'> & {
20
+ id?: string;
21
+ };
4
22
  /**
5
23
  * Options for {@link ScoutClient}.
6
24
  *
@@ -16,30 +34,49 @@ interface ScoutClientOptions extends ClientOptions {
16
34
  */
17
35
  aiApiHost?: string;
18
36
  }
19
- /** Parameters for a Scout invocation. */
20
- interface ScoutInvokeParams {
37
+ /** Shared invoke parameters. */
38
+ interface ScoutInvokeParamsCommon {
21
39
  /**
22
- * Stable thread id this turn belongs to. The caller owns it: generate one (e.g. `crypto.randomUUID()`)
23
- * for a one-shot invocation, or reuse the same id across calls to continue a multi-turn conversation
24
- * (history is kept server-side per thread).
40
+ * Thread this turn belongs to. Omit for a one-shot turn (a new thread id is generated).
41
+ * Reuse the same id across calls to continue a multi-turn conversation.
25
42
  */
26
- threadId: string;
43
+ threadId?: string;
27
44
  /**
28
- * Conversation messages in the Vercel AI SDK {@link UIMessage} shape. The server takes the
29
- * trailing entry as the new user turn; prior history is kept server-side per thread, so
30
- * multi-turn callers can send just the new message.
45
+ * The new user turn for this invocation. A string is shorthand for a user message with a single
46
+ * text part.
31
47
  */
32
- messages: UIMessage[];
48
+ message: string | ScoutInvokeMessage;
49
+ }
50
+ /** Parameters for a Scout invocation. */
51
+ interface ScoutInvokeParams<S extends ScoutOutputSchema = ScoutOutputSchema> extends ScoutInvokeParamsCommon {
52
+ /**
53
+ * Optional schema for a structured result — a zod schema (preferred; it also types
54
+ * {@link ScoutInvokeCompletedResult.structuredOutput}) or a plain JSON Schema object. When provided,
55
+ * Scout must record a result conforming to it as its final action; {@link ScoutClient.invoke} throws
56
+ * if Scout completes without recording structured output. Throws if the team is out of AI credits.
57
+ */
58
+ outputSchema?: S;
59
+ }
60
+ /** Parameters for a Scout invocation without structured output. */
61
+ interface ScoutInvokeParamsWithoutOutputSchema extends ScoutInvokeParamsCommon {
62
+ outputSchema?: undefined;
33
63
  }
34
- /** Aggregated result of {@link ScoutClient.invoke}. */
64
+ /** Parameters for a Scout invocation with structured output. */
65
+ interface ScoutInvokeParamsWithOutputSchema<S extends ScoutOutputSchema = ScoutOutputSchema> extends ScoutInvokeParamsCommon {
66
+ outputSchema: S;
67
+ }
68
+ /** Result of {@link ScoutClient.invoke} when no `outputSchema` was passed. */
35
69
  interface ScoutInvokeResult {
36
- /** `completed` on success; `over-credit-limit` when the team is out of AI credits. */
37
- outcome: 'completed' | 'skipped' | 'over-credit-limit';
38
70
  /** The final assistant message text. */
39
71
  text: string;
40
72
  /** The full thread messages after the turn (UI message shape). */
41
73
  messages: UIMessage[];
42
74
  }
75
+ /** Result when an `outputSchema` was passed and Scout completed the turn. */
76
+ interface ScoutInvokeCompletedResult<TStructured> extends ScoutInvokeResult {
77
+ /** Structured result conforming to the supplied `outputSchema`. */
78
+ structuredOutput: TStructured;
79
+ }
43
80
  /**
44
81
  * The raw HTTP request details for the headless Scout endpoint, for callers that want to drive
45
82
  * the request themselves (e.g. hand to a streaming transport). See {@link ScoutClient.getRequest}.
@@ -61,8 +98,7 @@ interface ScoutRequest {
61
98
  *
62
99
  * const scout = new ScoutClient(context.uniformCredentials);
63
100
  * const { text } = await scout.invoke({
64
- * threadId: crypto.randomUUID(),
65
- * messages: [{ id: crypto.randomUUID(), role: 'user', parts: [{ type: 'text', text: 'Review this entry for brand tone.' }] }],
101
+ * message: 'Review this entry for brand tone.',
66
102
  * });
67
103
  * ```
68
104
  */
@@ -79,9 +115,12 @@ declare class ScoutClient extends ApiClient<ScoutClientOptions> {
79
115
  * [Vercel AI SDK UI message stream](https://sdk.vercel.ai) backend when called with
80
116
  * `Accept: text/event-stream`, so point the AI SDK's transport / `readUIMessageStream` at it.
81
117
  *
82
- * @param params - The thread id and the conversation messages for this turn.
118
+ * @param params - The user message for this turn and optional thread id. Pass `outputSchema`
119
+ * (a zod schema or JSON Schema object) to also receive a structured result conforming to it; with a
120
+ * zod schema, `structuredOutput` is typed accordingly. Throws if the team is out of AI credits.
83
121
  */
84
- invoke(params: ScoutInvokeParams): Promise<ScoutInvokeResult>;
122
+ invoke(params: ScoutInvokeParamsWithoutOutputSchema): Promise<ScoutInvokeResult>;
123
+ invoke<S extends ScoutOutputSchema>(params: ScoutInvokeParamsWithOutputSchema<S>): Promise<ScoutInvokeCompletedResult<InferStructuredOutput<S>>>;
85
124
  /**
86
125
  * Returns the endpoint URL + auth headers for a thread's headless Scout endpoint, so you can
87
126
  * drive the request yourself.
@@ -105,4 +144,4 @@ declare class ScoutClient extends ApiClient<ScoutClientOptions> {
105
144
  getRequest(threadId: string): ScoutRequest;
106
145
  }
107
146
 
108
- export { ScoutClient, type ScoutClientOptions, type ScoutInvokeParams, type ScoutInvokeResult, type ScoutRequest };
147
+ export { ScoutClient, type ScoutClientOptions, type ScoutInvokeCompletedResult, type ScoutInvokeMessage, type ScoutInvokeParams, type ScoutInvokeParamsCommon, type ScoutInvokeParamsWithOutputSchema, type ScoutInvokeParamsWithoutOutputSchema, type ScoutInvokeResult, type ScoutRequest };
package/dist/ai/index.mjs CHANGED
@@ -7,6 +7,28 @@ import {
7
7
 
8
8
  // src/ai/ScoutClient.ts
9
9
  import { ApiClient } from "@uniformdev/context/api";
10
+
11
+ // src/ai/toOutputJsonSchema.ts
12
+ import { toJSONSchema } from "zod/v4/core";
13
+ function isZodSchema(value) {
14
+ return typeof value === "object" && value !== null && "_zod" in value;
15
+ }
16
+ function isStandardSchema(value) {
17
+ return typeof value === "object" && value !== null && "~standard" in value;
18
+ }
19
+ function toOutputJsonSchema(schema) {
20
+ if (isZodSchema(schema)) {
21
+ return toJSONSchema(schema);
22
+ }
23
+ if (isStandardSchema(schema)) {
24
+ throw new Error(
25
+ "`outputSchema` is a Standard Schema but not a zod schema. Conversion to JSON Schema currently supports zod only \u2014 provide a zod schema or a JSON Schema object."
26
+ );
27
+ }
28
+ return schema;
29
+ }
30
+
31
+ // src/ai/ScoutClient.ts
10
32
  var DEFAULT_AI_HOST = "https://ai.uniform.global";
11
33
  var _aiApiHost, _ScoutClient_instances, endpoint_fn;
12
34
  var ScoutClient = class extends ApiClient {
@@ -17,23 +39,28 @@ var ScoutClient = class extends ApiClient {
17
39
  __privateAdd(this, _aiApiHost);
18
40
  __privateSet(this, _aiApiHost, ((_a = options.aiApiHost) != null ? _a : DEFAULT_AI_HOST).replace(/\/+$/, ""));
19
41
  }
20
- /**
21
- * Invokes Scout and returns the aggregated result once the turn completes.
22
- *
23
- * This is the right fit for automations and other headless callers, where no user is watching
24
- * output stream in. If you do need to forward incremental output to a chat surface (a Slack
25
- * relay, a browser `useChat` app), don't reach for a bespoke client — the endpoint at
26
- * `POST {aiApiHost}/projects/:projectId/threads/:threadId/messages` is a standard
27
- * [Vercel AI SDK UI message stream](https://sdk.vercel.ai) backend when called with
28
- * `Accept: text/event-stream`, so point the AI SDK's transport / `readUIMessageStream` at it.
29
- *
30
- * @param params - The thread id and the conversation messages for this turn.
31
- */
32
42
  async invoke(params) {
33
- return this.apiClient(new URL(__privateMethod(this, _ScoutClient_instances, endpoint_fn).call(this, params.threadId)), {
34
- method: "POST",
35
- body: JSON.stringify({ messages: params.messages })
36
- });
43
+ var _a;
44
+ const threadId = (_a = params.threadId) != null ? _a : crypto.randomUUID();
45
+ const messages = [normalizeInvokeMessage(params.message)];
46
+ const outputSchema = params.outputSchema ? toOutputJsonSchema(params.outputSchema) : void 0;
47
+ const result = await this.apiClient(
48
+ new URL(__privateMethod(this, _ScoutClient_instances, endpoint_fn).call(this, threadId)),
49
+ {
50
+ method: "POST",
51
+ body: JSON.stringify({ messages, outputSchema })
52
+ }
53
+ );
54
+ if (result.outcome === "over-credit-limit") {
55
+ throw new Error("Scout is out of AI credits for this team.");
56
+ }
57
+ if (params.outputSchema && result.structuredOutput == null) {
58
+ throw new Error("Scout finished without recording structured output.");
59
+ }
60
+ if (params.outputSchema) {
61
+ return result;
62
+ }
63
+ return result;
37
64
  }
38
65
  /**
39
66
  * Returns the endpoint URL + auth headers for a thread's headless Scout endpoint, so you can
@@ -73,6 +100,13 @@ endpoint_fn = function(threadId) {
73
100
  __privateGet(this, _aiApiHost)
74
101
  ).toString();
75
102
  };
103
+ function normalizeInvokeMessage(message) {
104
+ var _a;
105
+ if (typeof message === "string") {
106
+ return { id: crypto.randomUUID(), role: "user", parts: [{ type: "text", text: message }] };
107
+ }
108
+ return { ...message, id: (_a = message.id) != null ? _a : crypto.randomUUID() };
109
+ }
76
110
  export {
77
111
  ScoutClient
78
112
  };
@@ -9,7 +9,12 @@ interface paths$2 {
9
9
  path?: never;
10
10
  cookie?: never;
11
11
  };
12
- /** @description Returns the log entries for a single automation run. */
12
+ /**
13
+ * @deprecated
14
+ * @description Returns the log entries for a single automation run.
15
+ *
16
+ * This is experimental functionality that is subject to change without notice.
17
+ */
13
18
  get: {
14
19
  parameters: {
15
20
  query: {
@@ -156,7 +161,12 @@ interface paths$1 {
156
161
  path?: never;
157
162
  cookie?: never;
158
163
  };
159
- /** @description Lists automation runs for a project, optionally filtered by automation and status. */
164
+ /**
165
+ * @deprecated
166
+ * @description Lists automation runs for a project, optionally filtered by automation and status.
167
+ *
168
+ * This is experimental functionality that is subject to change without notice.
169
+ */
160
170
  get: {
161
171
  parameters: {
162
172
  query: {
@@ -225,7 +235,64 @@ interface paths$1 {
225
235
  };
226
236
  };
227
237
  put?: never;
228
- post?: never;
238
+ /**
239
+ * @deprecated
240
+ * @description Triggers a one-off run of a scheduled automation, for testing.
241
+ *
242
+ * The run is identical to a real scheduled occurrence (same trigger context, no input, same machine
243
+ * identity) but is enqueued out of band: it does not advance the automation's schedule, and runs even
244
+ * when the automation is disabled. Only `schedule`-triggered automations can be run this way — other
245
+ * trigger types have a natural way to exercise them (fire the event, send the webhook, invoke the tool).
246
+ *
247
+ * The caller must hold every role the automation's identity holds (or be a team admin), since the run
248
+ * acts as that identity.
249
+ *
250
+ * This is experimental functionality that is subject to change without notice.
251
+ */
252
+ post: {
253
+ parameters: {
254
+ query?: never;
255
+ header?: never;
256
+ path?: never;
257
+ cookie?: never;
258
+ };
259
+ requestBody: {
260
+ content: {
261
+ "application/json": {
262
+ /** @description The project ID. */
263
+ projectId: string;
264
+ /** @description The automation public ID. */
265
+ publicId: string;
266
+ };
267
+ };
268
+ };
269
+ responses: {
270
+ /** @description 202 response */
271
+ 202: {
272
+ headers: {
273
+ [name: string]: unknown;
274
+ };
275
+ content: {
276
+ "application/json": {
277
+ /** @description ID of the enqueued run; poll the runs list to see its outcome. */
278
+ runId: string;
279
+ };
280
+ };
281
+ };
282
+ 400: components$1["responses"]["BadRequestError"];
283
+ 401: components$1["responses"]["UnauthorizedError"];
284
+ 403: components$1["responses"]["ForbiddenError"];
285
+ /** @description Automation not found. */
286
+ 404: {
287
+ headers: {
288
+ [name: string]: unknown;
289
+ };
290
+ content?: never;
291
+ };
292
+ 429: components$1["responses"]["RateLimitError"];
293
+ 500: components$1["responses"]["InternalServerError"];
294
+ };
295
+ };
229
296
  delete?: never;
230
297
  /** @description Handles preflight requests. This endpoint allows CORS. */
231
298
  options: {
@@ -315,7 +382,12 @@ interface paths {
315
382
  path?: never;
316
383
  cookie?: never;
317
384
  };
318
- /** @description Lists the automations for a project. */
385
+ /**
386
+ * @deprecated
387
+ * @description Lists the automations for a project.
388
+ *
389
+ * This is experimental functionality that is subject to change without notice.
390
+ */
319
391
  get: {
320
392
  parameters: {
321
393
  query: {
@@ -407,7 +479,12 @@ interface paths {
407
479
  500: components["responses"]["InternalServerError"];
408
480
  };
409
481
  };
410
- /** @description Deploys (creates or updates) an automation. */
482
+ /**
483
+ * @deprecated
484
+ * @description Deploys (creates or updates) an automation.
485
+ *
486
+ * This is experimental functionality that is subject to change without notice.
487
+ */
411
488
  put: {
412
489
  parameters: {
413
490
  query?: never;
@@ -483,7 +560,12 @@ interface paths {
483
560
  };
484
561
  };
485
562
  post?: never;
486
- /** @description Deletes an automation and its run history. */
563
+ /**
564
+ * @deprecated
565
+ * @description Deletes an automation and its run history.
566
+ *
567
+ * This is experimental functionality that is subject to change without notice.
568
+ */
487
569
  delete: {
488
570
  parameters: {
489
571
  query?: never;
@@ -543,7 +625,12 @@ interface paths {
543
625
  };
544
626
  };
545
627
  head?: never;
546
- /** @description Toggles the enabled state of an automation. Disabled automations do not run when their trigger occurs. */
628
+ /**
629
+ * @deprecated
630
+ * @description Toggles the enabled state of an automation. Disabled automations do not run when their trigger occurs.
631
+ *
632
+ * This is experimental functionality that is subject to change without notice.
633
+ */
547
634
  patch: {
548
635
  parameters: {
549
636
  query?: never;
@@ -653,6 +740,7 @@ type AutomationsDeployInput = Omit<AutomationsDeployBody, 'projectId'>;
653
740
  type AutomationRunsListResponse = paths$1['/api/v1/automation-runs']['get']['responses']['200']['content']['application/json'];
654
741
  type AutomationRunSummary = AutomationRunsListResponse['runs'][number];
655
742
  type AutomationRunStatus = AutomationRunSummary['status'];
743
+ type AutomationRunTriggerResponse = paths$1['/api/v1/automation-runs']['post']['responses']['202']['content']['application/json'];
656
744
  type AutomationRunLogEntry = paths$2['/api/v1/automation-run-logs']['get']['responses']['200']['content']['application/json']['logs'][number];
657
745
 
658
746
  type AutomationsClientOptions = Omit<ClientOptions, 'projectId'> & {
@@ -687,6 +775,15 @@ declare class AutomationsClient extends ApiClient<AutomationsClientOptions> {
687
775
  * @param publicId - The automation public ID.
688
776
  */
689
777
  remove(publicId: string): Promise<void>;
778
+ /**
779
+ * Triggers a one-off run of a scheduled automation, for testing. The run is identical to a real
780
+ * scheduled occurrence but is enqueued out of band: it does not advance the schedule and runs even
781
+ * when the automation is disabled. Only `schedule`-triggered automations may be run this way.
782
+ *
783
+ * @param publicId - The automation public ID.
784
+ * @returns The enqueued run ID; poll {@link listRuns} to observe its outcome.
785
+ */
786
+ run(publicId: string): Promise<AutomationRunTriggerResponse>;
690
787
  /**
691
788
  * Lists automation runs for the project, optionally filtered by automation and status.
692
789
  */
@@ -704,4 +801,4 @@ declare class AutomationsClient extends ApiClient<AutomationsClientOptions> {
704
801
  listRunLogs(runId: string): Promise<AutomationRunLogEntry[]>;
705
802
  }
706
803
 
707
- export { type AutomationRunLogEntry, type AutomationRunStatus, type AutomationRunSummary, type AutomationRunsListResponse, type AutomationSummary, type AutomationTriggerType, AutomationsClient, type AutomationsClientOptions, type AutomationsDeployBody, type AutomationsDeployInput, type AutomationsListResponse };
804
+ export { type AutomationRunLogEntry, type AutomationRunStatus, type AutomationRunSummary, type AutomationRunTriggerResponse, type AutomationRunsListResponse, type AutomationSummary, type AutomationTriggerType, AutomationsClient, type AutomationsClientOptions, type AutomationsDeployBody, type AutomationsDeployInput, type AutomationsListResponse };
@@ -59,6 +59,21 @@ var _AutomationsClient = class _AutomationsClient extends ApiClient {
59
59
  expectNoContent: true
60
60
  });
61
61
  }
62
+ /**
63
+ * Triggers a one-off run of a scheduled automation, for testing. The run is identical to a real
64
+ * scheduled occurrence but is enqueued out of band: it does not advance the schedule and runs even
65
+ * when the automation is disabled. Only `schedule`-triggered automations may be run this way.
66
+ *
67
+ * @param publicId - The automation public ID.
68
+ * @returns The enqueued run ID; poll {@link listRuns} to observe its outcome.
69
+ */
70
+ async run(publicId) {
71
+ const { projectId } = this.options;
72
+ return await this.apiClient(this.createUrl(__privateGet(_AutomationsClient, _runsUrl)), {
73
+ method: "POST",
74
+ body: JSON.stringify({ projectId, publicId })
75
+ });
76
+ }
62
77
  /**
63
78
  * Lists automation runs for the project, optionally filtered by automation and status.
64
79
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@uniformdev/automations-sdk",
3
- "version": "20.50.2-alpha.109+846837c66a",
3
+ "version": "20.50.2-alpha.149+913f0b7b57",
4
4
  "description": "Uniform Automations SDK",
5
5
  "license": "SEE LICENSE IN LICENSE.txt",
6
6
  "exports": {
@@ -40,8 +40,8 @@
40
40
  ],
41
41
  "dependencies": {
42
42
  "@standard-schema/spec": "^1.1.0",
43
- "@uniformdev/context": "20.50.2-alpha.109+846837c66a",
44
- "@uniformdev/webhooks": "20.50.2-alpha.109+846837c66a"
43
+ "@uniformdev/context": "20.50.2-alpha.149+913f0b7b57",
44
+ "@uniformdev/webhooks": "20.50.2-alpha.149+913f0b7b57"
45
45
  },
46
46
  "peerDependencies": {
47
47
  "ai": "^6.0.0",
@@ -62,5 +62,5 @@
62
62
  "publishConfig": {
63
63
  "access": "public"
64
64
  },
65
- "gitHead": "846837c66ad0f518683c100615b59b27f91498ba"
65
+ "gitHead": "913f0b7b57295ca79575810663c56a7a5deea9e4"
66
66
  }