@tai42/api-client 17.1.5 → 18.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/dist/client/backend-client.d.ts +1 -1
  2. package/dist/client/backup-client.d.ts +2 -2
  3. package/dist/client/channels-client.js +1 -1
  4. package/dist/client/channels-client.js.map +1 -1
  5. package/dist/client/config-client.d.ts +3 -3
  6. package/dist/client/connectors-client.d.ts +8 -8
  7. package/dist/client/conversations-client.d.ts +34 -4
  8. package/dist/client/conversations-client.d.ts.map +1 -1
  9. package/dist/client/hooks-client.d.ts +16 -1
  10. package/dist/client/hooks-client.d.ts.map +1 -1
  11. package/dist/client/index.d.ts +96 -45
  12. package/dist/client/index.d.ts.map +1 -1
  13. package/dist/client/manifest-client.d.ts +18 -18
  14. package/dist/client/profiles-client.d.ts +2 -2
  15. package/dist/client/schedules-client.d.ts +5 -0
  16. package/dist/client/schedules-client.d.ts.map +1 -1
  17. package/dist/client/schedules-client.js.map +1 -1
  18. package/dist/client/tool-extensions-client.d.ts +2 -2
  19. package/dist/client/tools-client.d.ts +9 -4
  20. package/dist/client/tools-client.d.ts.map +1 -1
  21. package/dist/client/tools-client.js +9 -4
  22. package/dist/client/tools-client.js.map +1 -1
  23. package/dist/generated/served-schemas.d.ts +67 -6
  24. package/dist/generated/served-schemas.d.ts.map +1 -1
  25. package/dist/generated/served-schemas.js +5 -5
  26. package/dist/generated/served-schemas.js.map +1 -1
  27. package/dist/index.d.ts +3 -3
  28. package/dist/index.d.ts.map +1 -1
  29. package/dist/index.js +1 -1
  30. package/dist/index.js.map +1 -1
  31. package/dist/schemas/backup.d.ts +2 -2
  32. package/dist/schemas/config.d.ts +5 -4
  33. package/dist/schemas/config.d.ts.map +1 -1
  34. package/dist/schemas/config.js +5 -4
  35. package/dist/schemas/config.js.map +1 -1
  36. package/dist/schemas/connectors.d.ts +8 -8
  37. package/dist/schemas/conversations.d.ts +34 -4
  38. package/dist/schemas/conversations.d.ts.map +1 -1
  39. package/dist/schemas/fleet.d.ts +6 -6
  40. package/dist/schemas/hooks.d.ts +16 -1
  41. package/dist/schemas/hooks.d.ts.map +1 -1
  42. package/dist/schemas/manifest-mcp.d.ts +2 -2
  43. package/dist/schemas/profiles.d.ts +2 -2
  44. package/dist/schemas/served.d.ts +66 -6
  45. package/dist/schemas/served.d.ts.map +1 -1
  46. package/dist/schemas/system-kinds.d.ts +3 -3
  47. package/dist/schemas/tools.d.ts +99 -0
  48. package/dist/schemas/tools.d.ts.map +1 -1
  49. package/dist/schemas/tools.js +41 -0
  50. package/dist/schemas/tools.js.map +1 -1
  51. package/dist/tool-runs.d.ts +50 -9
  52. package/dist/tool-runs.d.ts.map +1 -1
  53. package/dist/tool-runs.js +23 -7
  54. package/dist/tool-runs.js.map +1 -1
  55. package/package.json +1 -1
  56. package/src/client/channels-client.ts +1 -1
  57. package/src/client/schedules-client.ts +9 -0
  58. package/src/client/tools-client.ts +13 -4
  59. package/src/generated/served-schemas.ts +5 -5
  60. package/src/index.ts +7 -0
  61. package/src/schemas/config.ts +5 -4
  62. package/src/schemas/tools.ts +51 -0
  63. package/src/tool-runs.ts +29 -7
@@ -1,12 +1,16 @@
1
1
  /** Tool catalog, run, live-registry admin and tag sub-client. */
2
2
  import { encodeSegment } from '../http';
3
3
  import * as s from '../schemas';
4
+ import type { StateSubject } from '../schemas/states';
4
5
  import { getToolRun, listToolRuns, submitToolRun, type SubmitToolRunArgs } from '../tool-runs';
5
6
  import type { Transport } from './transport';
6
7
 
7
8
  export interface RunToolArgs {
8
9
  readonly tool: string;
9
10
  readonly kwargs?: Record<string, unknown>;
11
+ /** The addressed subject an async park of this run indexes under. Omitted from
12
+ * the request body when unset, so a plain run (no subject) parks un-indexed. */
13
+ readonly subject?: StateSubject;
10
14
  }
11
15
 
12
16
  /**
@@ -32,11 +36,16 @@ export function toolsClient(t: Transport) {
32
36
  runTool: (args: RunToolArgs, signal?: AbortSignal) =>
33
37
  req('/api/run-tool', s.runToolResult, {
34
38
  method: 'POST',
35
- // The backend's `/api/run-tool` door reads `{tool_name, arguments}` (the
36
- // shape `read_tool_call` enforces and the background `/api/tool-runs`
39
+ // The backend's `/api/run-tool` door reads `{tool_name, arguments, subject}`
40
+ // (the shape `read_tool_call` enforces and the background `/api/tool-runs`
37
41
  // submit already sends). The SPA keeps `tool`/`kwargs` as its ergonomic
38
- // arg names; map them onto the wire fields here.
39
- body: { tool_name: args.tool, arguments: args.kwargs ?? {} },
42
+ // arg names; map them onto the wire fields here. `subject` rides only when
43
+ // set, so a plain run sends no subject.
44
+ body: {
45
+ tool_name: args.tool,
46
+ arguments: args.kwargs ?? {},
47
+ ...(args.subject !== undefined ? { subject: args.subject } : {}),
48
+ },
40
49
  signal,
41
50
  }),
42
51
 
@@ -60,7 +60,7 @@ export type UrlButtonParam = z.infer<typeof urlButtonParam>;
60
60
  export const accessPolicy = z.object({ "condition": z.union([templatedText, z.null()]).default(null), "policy_data": z.record(z.string(), z.unknown()).default({}), "scopes": z.array(z.string()).default([]) });
61
61
  export type AccessPolicy = z.infer<typeof accessPolicy>;
62
62
 
63
- export const callbackSchema = z.object({ "condition": z.union([templatedText, z.null()]).default(null), "expr": z.union([templatedText, z.null()]).default(null), "tool": z.string().default("") });
63
+ export const callbackSchema = z.object({ "carried_kwargs": z.record(z.string(), z.unknown()).default({}), "condition": z.union([templatedText, z.null()]).default(null), "expr": z.union([templatedText, z.null()]).default(null), "tool": z.string().default("") });
64
64
  export type CallbackSchema = z.infer<typeof callbackSchema>;
65
65
 
66
66
  export const channelTemplate = z.object({ "body_parameters": z.array(z.string()).default([]), "buttons": z.array(z.unknown().superRefine((x, ctx) => {
@@ -98,16 +98,16 @@ export const channelTemplate = z.object({ "body_parameters": z.array(z.string())
98
98
  })).default([]), "header_media": z.union([mediaItem, z.null()]).default(null), "language": z.string(), "name": z.string() });
99
99
  export type ChannelTemplate = z.infer<typeof channelTemplate>;
100
100
 
101
- export const conversationRoute = z.object({ "callback_secret": z.union([z.string(), z.null()]).default(null), "callback_url": z.union([z.string(), z.null()]).default(null), "channel": z.union([z.string(), z.null()]).default(null), "door": z.enum(["api","channel"]), "error_reply_text": z.union([z.string().min(1).max(2000), z.null()]).default(null), "execution_key": z.string().min(1), "execution_key_fingerprint": z.string().min(1), "initial_mode": z.enum(["agent","manual"]).default("agent"), "locale": z.union([z.string(), z.null()]).default(null), "our_identity": z.union([z.string(), z.null()]).default(null), "overlap": overlapPolicy.default({"deliver":"one","running":"continue","settle_seconds":0}), "payload_expr": z.union([templatedText, z.null()]).default(null), "reply_expr": z.union([templatedText, z.null()]).default(null), "route_name": z.string(), "target_kind": z.enum(["agent","tool"]), "target_name": z.string().min(1), "turns_per_hour_override": z.union([z.number().int().gt(0), z.null()]).default(null) });
101
+ export const conversationRoute = z.object({ "callback_secret": z.union([z.string(), z.null()]).default(null), "callback_url": z.union([z.string(), z.null()]).default(null), "cancel_expr": z.union([templatedText, z.null()]).default(null), "channel": z.union([z.string(), z.null()]).default(null), "door": z.enum(["api","channel"]), "error_reply_text": z.union([z.string().min(1).max(2000), z.null()]).default(null), "execution_key": z.string().min(1), "execution_key_fingerprint": z.string().min(1), "extras_expr": z.union([templatedText, z.null()]).default(null), "initial_mode": z.enum(["agent","manual"]).default("agent"), "locale": z.union([z.string(), z.null()]).default(null), "our_identity": z.union([z.string(), z.null()]).default(null), "overlap": overlapPolicy.default({"deliver":"one","running":"continue","settle_seconds":0}), "reply_expr": z.union([templatedText, z.null()]).default(null), "resume_expr": z.union([templatedText, z.null()]).default(null), "route_name": z.string(), "start_expr": z.union([templatedText, z.null()]).default(null), "target_kind": z.enum(["agent","tool"]), "target_name": z.string().min(1), "turns_per_hour_override": z.union([z.number().int().gt(0), z.null()]).default(null) });
102
102
  export type ConversationRoute = z.infer<typeof conversationRoute>;
103
103
 
104
- export const conversationRouteCreate = z.object({ "callback_url": z.union([z.string(), z.null()]).default(null), "channel": z.union([z.string(), z.null()]).default(null), "door": z.enum(["api","channel"]), "error_reply_text": z.union([z.string().min(1).max(2000), z.null()]).default(null), "execution_key": z.string().min(1), "initial_mode": z.enum(["agent","manual"]).default("agent"), "locale": z.union([z.string(), z.null()]).default(null), "our_identity": z.union([z.string(), z.null()]).default(null), "overlap": overlapPolicy.default({"deliver":"one","running":"continue","settle_seconds":0}), "payload_expr": z.union([templatedText, z.null()]).default(null), "reply_expr": z.union([templatedText, z.null()]).default(null), "route_name": z.string(), "target_kind": z.enum(["agent","tool"]), "target_name": z.string().min(1), "turns_per_hour_override": z.union([z.number().int().gt(0), z.null()]).default(null) });
104
+ export const conversationRouteCreate = z.object({ "callback_url": z.union([z.string(), z.null()]).default(null), "cancel_expr": z.union([templatedText, z.null()]).default(null), "channel": z.union([z.string(), z.null()]).default(null), "door": z.enum(["api","channel"]), "error_reply_text": z.union([z.string().min(1).max(2000), z.null()]).default(null), "execution_key": z.string().min(1), "extras_expr": z.union([templatedText, z.null()]).default(null), "initial_mode": z.enum(["agent","manual"]).default("agent"), "locale": z.union([z.string(), z.null()]).default(null), "our_identity": z.union([z.string(), z.null()]).default(null), "overlap": overlapPolicy.default({"deliver":"one","running":"continue","settle_seconds":0}), "reply_expr": z.union([templatedText, z.null()]).default(null), "resume_expr": z.union([templatedText, z.null()]).default(null), "route_name": z.string(), "start_expr": z.union([templatedText, z.null()]).default(null), "target_kind": z.enum(["agent","tool"]), "target_name": z.string().min(1), "turns_per_hour_override": z.union([z.number().int().gt(0), z.null()]).default(null) });
105
105
  export type ConversationRouteCreate = z.infer<typeof conversationRouteCreate>;
106
106
 
107
- export const hookParams = z.object({ "condition": z.union([templatedText, z.null()]).default(null), "execution_key": z.string().min(1), "execution_key_fingerprint": z.string().min(1), "expr": z.union([templatedText, z.null()]).default(null), "name": z.string().min(1), "state_binding": z.union([stateBinding, z.null()]).default(null), "subject": z.union([hookSubject, z.null()]).default(null), "tool": z.string().min(1), "tool_kwargs": z.record(z.string(), z.unknown()).default({}), "topic": z.string().min(1) });
107
+ export const hookParams = z.object({ "cancel_expr": z.union([templatedText, z.null()]).default(null), "condition": z.union([templatedText, z.null()]).default(null), "execution_key": z.string().min(1), "execution_key_fingerprint": z.string().min(1), "extras_expr": z.union([templatedText, z.null()]).default(null), "name": z.string().min(1), "resume_expr": z.union([templatedText, z.null()]).default(null), "start_expr": z.union([templatedText, z.null()]).default(null), "state_binding": z.union([stateBinding, z.null()]).default(null), "subject": z.union([hookSubject, z.null()]).default(null), "tool": z.string().min(1), "tool_kwargs": z.record(z.string(), z.unknown()).default({}), "topic": z.string().min(1) });
108
108
  export type HookParams = z.infer<typeof hookParams>;
109
109
 
110
- export const hookRegister = z.object({ "condition": z.union([templatedText, z.null()]).default(null), "execution_key": z.string().min(1), "expr": z.union([templatedText, z.null()]).default(null), "name": z.string().min(1), "state_binding": z.union([stateBinding, z.null()]).default(null), "subject": z.union([hookSubject, z.null()]).default(null), "tool": z.string().min(1), "tool_kwargs": z.record(z.string(), z.unknown()).default({}), "topic": z.string().min(1) });
110
+ export const hookRegister = z.object({ "cancel_expr": z.union([templatedText, z.null()]).default(null), "condition": z.union([templatedText, z.null()]).default(null), "execution_key": z.string().min(1), "extras_expr": z.union([templatedText, z.null()]).default(null), "name": z.string().min(1), "resume_expr": z.union([templatedText, z.null()]).default(null), "start_expr": z.union([templatedText, z.null()]).default(null), "state_binding": z.union([stateBinding, z.null()]).default(null), "subject": z.union([hookSubject, z.null()]).default(null), "tool": z.string().min(1), "tool_kwargs": z.record(z.string(), z.unknown()).default({}), "topic": z.string().min(1) });
111
111
  export type HookRegister = z.infer<typeof hookRegister>;
112
112
 
113
113
  export const presetBody = z.object({ "base_tool": z.string(), "description": z.string().default(""), "extensions": z.array(z.array(z.union([z.string(), z.record(z.string(), z.unknown())]))).default([]), "fixed_kwargs": z.record(z.string(), z.unknown()).default({}), "input_schema": z.union([templatedText, z.record(z.string(), z.unknown()), z.null()]).default(null), "output_schema": z.union([templatedText, z.record(z.string(), z.unknown()), z.null()]).default(null), "state_binding": z.union([stateBinding, z.null()]).default(null) });
package/src/index.ts CHANGED
@@ -76,6 +76,7 @@ export type {
76
76
  BackendInfo,
77
77
  BackupDocument,
78
78
  BackupImportReport,
79
+ CallerAsksEnvelope,
79
80
  Channels,
80
81
  ChannelTemplate,
81
82
  ClaimLinkCreated,
@@ -177,6 +178,8 @@ export type {
177
178
  Notification,
178
179
  Notifications,
179
180
  OAuthCompleteResult,
181
+ ParkedCallerAsk,
182
+ ParkedStatus,
180
183
  PatternEntry,
181
184
  PolicyBody,
182
185
  PolicyVersion,
@@ -235,6 +238,7 @@ export type {
235
238
  SubjectRow,
236
239
  SubMcpEntry,
237
240
  SubMcpMount,
241
+ SuspendedRunReceipt,
238
242
  TargetConversationConfig,
239
243
  TemplateDeclarations,
240
244
  TemplatedText,
@@ -257,6 +261,7 @@ export type {
257
261
  TriggerLinkList,
258
262
  TriggerLinkRecord,
259
263
  ValidateConditionResult,
264
+ VisitOutcome,
260
265
  WebEntryCode,
261
266
  WebEntryCodeMinted,
262
267
  WebEntryCodeRevoked,
@@ -274,6 +279,7 @@ export { readSseFrames, SseFrameParser } from './sse';
274
279
  export type {
275
280
  SubmitToolRunArgs,
276
281
  ToolRunListItem,
282
+ ToolRunParkAnswer,
277
283
  ToolRunRecord,
278
284
  ToolRunStatus,
279
285
  ToolRunSubmitResult,
@@ -282,6 +288,7 @@ export {
282
288
  isTerminalRunStatus,
283
289
  toolRunList,
284
290
  toolRunListItem,
291
+ toolRunParkAnswer,
285
292
  toolRunRecord,
286
293
  toolRunStatus,
287
294
  toolRunSubmitResult,
@@ -6,10 +6,11 @@ export const envConfig = z.object({
6
6
  secret_keys: z.array(z.string()),
7
7
  });
8
8
  /**
9
- * `GET /api/config/mode` — the active config backend mode (`file` / `k8s`). The
10
- * skeleton emits only `config_mode`; `read_only` is a UI-side gate, tolerated-absent
11
- * and defaulting to `false` (writable) so a normal response never drifts, while a
12
- * genuinely read-only deployment can opt in by emitting `read_only: true`.
9
+ * `GET /api/config/mode` — the active config backend mode: `file`, or an installed
10
+ * provider's mode name such as `kubernetes`. The skeleton emits only `config_mode`;
11
+ * `read_only` is a UI-side gate, tolerated-absent and defaulting to `false` (writable)
12
+ * so a normal response never drifts, while a genuinely read-only deployment can opt in
13
+ * by emitting `read_only: true`.
13
14
  */
14
15
  export const configMode = z.object({
15
16
  config_mode: z.string(),
@@ -16,6 +16,57 @@ export const allToolSchemas = z.record(z.string(), toolSchema);
16
16
 
17
17
  export const runToolResult = jsonValue;
18
18
 
19
+ /** The lifecycle status a parked interaction on a run's subject carries: a pending ask, an
20
+ * ask whose continuation is resuming, or a resolved run's waiting outcome (clean/failed). */
21
+ export const parkedStatus = z.enum(['asking', 'running', 'finished', 'failed']);
22
+ export type ParkedStatus = z.infer<typeof parkedStatus>;
23
+
24
+ /**
25
+ * One parked caller-ask entry a synchronous run-tool call returns when the tool asked its
26
+ * CALLER (`to="caller"`) and parked. The full contract entry carries more fields; the panel
27
+ * reads the display subset here and tolerates the rest. `question` is the prompt, `payload`
28
+ * the structured value the ask handed the caller, `asked_by` the run chain that raised it.
29
+ */
30
+ export const parkedCallerAsk = z.object({
31
+ id: z.string(),
32
+ status: parkedStatus,
33
+ to: z.enum(['user', 'caller']).nullish(),
34
+ question: z.string().nullish(),
35
+ payload: z.record(z.string(), z.unknown()).nullish(),
36
+ asked_by: z.array(z.string()).nullish(),
37
+ });
38
+ export type ParkedCallerAsk = z.infer<typeof parkedCallerAsk>;
39
+
40
+ /** A synchronous run whose tool parked CALLER asks returns this envelope in place of a result:
41
+ * the full caller-ask entries under `asks`. An empty `asks` means the run parked with no open
42
+ * caller ask (only user asks remain). */
43
+ export const callerAsksEnvelope = z.object({
44
+ asks: z.array(parkedCallerAsk),
45
+ });
46
+ export type CallerAsksEnvelope = z.infer<typeof callerAsksEnvelope>;
47
+
48
+ /** The park receipt a synchronous run returns when its tool parked only USER asks: the
49
+ * suspension sentinel's ids, with no caller ask for the panel to act on. */
50
+ export const suspendedRunReceipt = z.object({
51
+ interaction_id: z.string(),
52
+ interaction_ids: z.array(z.string()),
53
+ caller_interaction_ids: z.array(z.string()).default([]),
54
+ });
55
+ export type SuspendedRunReceipt = z.infer<typeof suspendedRunReceipt>;
56
+
57
+ /** What one resume / take / cancel of a parked interaction did, as `resume_parked` /
58
+ * `cancel_parked` return it through run-tool. `kind` picks the payload: `result` (a final
59
+ * value in `result`), `asks` (new caller asks in `asks`), `parked` (only user asks remain),
60
+ * or `none` (nothing ran). `action` names the single non-cancel action taken. */
61
+ export const visitOutcome = z.object({
62
+ action: z.enum(['resumed', 'taken', 'started', 'none']),
63
+ cancelled: z.array(z.string()).default([]),
64
+ kind: z.enum(['result', 'asks', 'parked', 'none']),
65
+ result: z.unknown().optional(),
66
+ asks: z.array(parkedCallerAsk).default([]),
67
+ });
68
+ export type VisitOutcome = z.infer<typeof visitOutcome>;
69
+
19
70
  /**
20
71
  * The MEDIA content shape a direct tool run may return — fastmcp's serialized
21
72
  * `Image`/`Audio` MediaBlock (`{ type, data: <base64>, mimeType }`). One recognised
package/src/tool-runs.ts CHANGED
@@ -9,25 +9,30 @@
9
9
  *
10
10
  * The background surface detaches a run from its HTTP request: submit returns a
11
11
  * `run_id` immediately (202), then the caller POLLS the single-run GET until the
12
- * status is terminal (`succeeded | failed | lost`). The list GET returns the
13
- * recent runs for one tool — id/status/timestamps only, never `result`/`error`.
12
+ * status is terminal (`succeeded | failed | lost | parked`). The list GET returns
13
+ * the recent runs for one tool — id/status/timestamps only, never `result`/`error`.
14
14
  */
15
15
  import { z } from 'zod';
16
16
 
17
17
  import type { ApiConfig } from './http';
18
18
  import { apiRequest, encodeSegment } from './http';
19
+ import type { StateSubject } from './schemas/states';
20
+ import { callerAsksEnvelope, suspendedRunReceipt } from './schemas/tools';
19
21
 
20
22
  /** A run's lifecycle state. `lost` = the server restarted mid-run; the result is
21
- * unrecoverable. `running` is the only non-terminal state. */
22
- export const toolRunStatus = z.enum(['running', 'succeeded', 'failed', 'lost']);
23
+ * unrecoverable. `parked` = the run's tool async-parked; its `result` is the park
24
+ * answer (see {@link toolRunParkAnswer}). `running` is the only non-terminal state. */
25
+ export const toolRunStatus = z.enum(['running', 'succeeded', 'failed', 'lost', 'parked']);
23
26
 
24
27
  /** `POST /api/tool-runs` → the handle for the detached run. */
25
28
  export const toolRunSubmitResult = z.object({
26
29
  run_id: z.string(),
27
30
  });
28
31
 
29
- /** `GET /api/tool-runs/{run_id}` → the full record. `result` is arbitrary JSON
30
- * (present only on `succeeded`); `error` is present only on `failed`. */
32
+ /** `GET /api/tool-runs/{run_id}` → the full record. `result` is arbitrary JSON: the
33
+ * tool's own value on `succeeded`, the park answer ({@link toolRunParkAnswer}) on
34
+ * `parked`. `error` is present only on `failed`. `resumed_interactions` is the parked
35
+ * interaction ids the run resumed or took while it executed (`[]` when it resumed none). */
31
36
  export const toolRunRecord = z.object({
32
37
  run_id: z.string(),
33
38
  tool_name: z.string(),
@@ -36,6 +41,7 @@ export const toolRunRecord = z.object({
36
41
  finished_at: z.string().optional(),
37
42
  result: z.unknown().optional(),
38
43
  error: z.string().optional(),
44
+ resumed_interactions: z.array(z.string()).optional(),
39
45
  });
40
46
 
41
47
  /** One entry of `GET /api/tool-runs?tool_name=...` — id/status/timestamps only,
@@ -50,7 +56,16 @@ export const toolRunListItem = z.object({
50
56
 
51
57
  export const toolRunList = z.array(toolRunListItem);
52
58
 
59
+ /**
60
+ * The `result` a `parked` record carries — the SAME park answer the synchronous run-tool
61
+ * door returns: either the caller-ask envelope `{asks: [...]}` (the tool asked its CALLER
62
+ * and parked) or the suspension receipt (the run parked only USER asks, ids only). A poller
63
+ * reads it to tell a caller-ask park from a user-only one, exactly as the sync door's caller does.
64
+ */
65
+ export const toolRunParkAnswer = z.union([callerAsksEnvelope, suspendedRunReceipt]);
66
+
53
67
  export type ToolRunStatus = z.infer<typeof toolRunStatus>;
68
+ export type ToolRunParkAnswer = z.infer<typeof toolRunParkAnswer>;
54
69
  export type ToolRunSubmitResult = z.infer<typeof toolRunSubmitResult>;
55
70
  export type ToolRunRecord = z.infer<typeof toolRunRecord>;
56
71
  export type ToolRunListItem = z.infer<typeof toolRunListItem>;
@@ -59,6 +74,9 @@ export type ToolRunListItem = z.infer<typeof toolRunListItem>;
59
74
  export interface SubmitToolRunArgs {
60
75
  readonly tool_name: string;
61
76
  readonly arguments?: Record<string, unknown>;
77
+ /** The addressed subject an async park of the detached run indexes under. Omitted
78
+ * from the request body when unset. */
79
+ readonly subject?: StateSubject;
62
80
  }
63
81
 
64
82
  /** Submit a tool for detached background execution; resolves with its `run_id`. */
@@ -69,7 +87,11 @@ export function submitToolRun(
69
87
  ): Promise<ToolRunSubmitResult> {
70
88
  return apiRequest(config, '/api/tool-runs', toolRunSubmitResult, {
71
89
  method: 'POST',
72
- body: { tool_name: args.tool_name, arguments: args.arguments ?? {} },
90
+ body: {
91
+ tool_name: args.tool_name,
92
+ arguments: args.arguments ?? {},
93
+ ...(args.subject !== undefined ? { subject: args.subject } : {}),
94
+ },
73
95
  signal,
74
96
  });
75
97
  }