@parall/sdk 1.50.1 → 1.52.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/client.ts CHANGED
@@ -5,6 +5,8 @@ import type {
5
5
  ClaimDispatchResponse,
6
6
  SteerDispatchRequest,
7
7
  SteerDispatchResponse,
8
+ UpdateDispatchInputStateRequest,
9
+ UpdateDispatchInputStateResponse,
8
10
  CompleteDispatchByIDRequest,
9
11
  CompleteDispatchBySourceResult,
10
12
  CompleteDispatchLaneRequest,
@@ -240,14 +242,19 @@ import type {
240
242
  EdgeProfileProxyStatus,
241
243
  SetEdgeProfileProxyRequest,
242
244
  ClipConnection,
245
+ MCPConfigPutRequest,
246
+ MCPConfigResponse,
243
247
  EdgeOnboardingStatus,
244
248
  ExecEdgeClipRequest,
245
249
  EdgeClipExecResult,
246
250
  ReactionSummary,
247
251
  ToggleReactionResponse,
252
+ DependencyCheckResult,
248
253
  DeployTemplateRequest,
254
+ OnboardingProgress,
249
255
  Template,
250
256
  TemplateDeploymentReport,
257
+ UpdateOnboardingProgressRequest,
251
258
  } from './types.js';
252
259
 
253
260
  export interface ParallClientOptions {
@@ -707,7 +714,7 @@ export class ParallClient {
707
714
  data: Partial<
708
715
  Pick<
709
716
  Organization,
710
- 'name' | 'avatar_url' | 'smart_routing_strategy' | 'smart_routing_agent_id'
717
+ 'name' | 'avatar_url' | 'smart_routing_strategy' | 'smart_routing_agent_id' | 'timezone'
711
718
  >
712
719
  >,
713
720
  ): Promise<Organization> {
@@ -816,8 +823,10 @@ export class ParallClient {
816
823
  );
817
824
  }
818
825
 
819
- // Pending tasks (todo + in_progress) assigned to a member. Powers both
820
- // member profile Activity and the agent startup catch-up flow.
826
+ // Pending tasks (todo + in_progress) assigned to a member. On-demand listing
827
+ // (member profile Activity; agents via `parall tasks`) — startup catch-up
828
+ // runs on dispatch redrive, not this endpoint. Self-assigned tasks appear
829
+ // here without any dispatch WorkItem (self-assign is deliberately silent).
821
830
  async getMemberTasks(
822
831
  orgId: string,
823
832
  memberId: string,
@@ -1330,7 +1339,7 @@ export class ParallClient {
1330
1339
  async getAgentSessions(
1331
1340
  orgId: string,
1332
1341
  agentId: string,
1333
- params?: { limit?: number; status?: string; cursor?: string },
1342
+ params?: { limit?: number; status?: string; cursor?: string; sort?: 'finished_at' },
1334
1343
  ): Promise<PaginatedResponse<AgentSessionDB>> {
1335
1344
  return this.request('GET', ENDPOINTS.AGENT_SESSIONS(orgId, agentId), undefined, params);
1336
1345
  }
@@ -1452,7 +1461,12 @@ export class ParallClient {
1452
1461
  return this.request('GET', ENDPOINTS.AGENT_RUNTIME_RELEASE(orgId, agentId, tag));
1453
1462
  }
1454
1463
 
1455
- /** Fetch all pending tasks (todo/in_progress) assigned to an agent. Pages automatically. */
1464
+ /**
1465
+ * Fetch all pending tasks (todo/in_progress) assigned to an agent. Pages
1466
+ * automatically. On-demand listing only — not a dispatch source: startup
1467
+ * catch-up runs on dispatch redrive, and self-assigned tasks listed here
1468
+ * deliberately have no WorkItem behind them.
1469
+ */
1456
1470
  async getAgentTasks(orgId: string, agentId: string): Promise<Task[]> {
1457
1471
  const all: Task[] = [];
1458
1472
  let cursor: string | undefined;
@@ -2067,6 +2081,14 @@ export class ParallClient {
2067
2081
  return this.request('POST', ENDPOINTS.DISPATCH_STEER(orgId), req);
2068
2082
  }
2069
2083
 
2084
+ /** Advance exact runtime-input lifecycle for members of an explicit lane. */
2085
+ async updateDispatchInputState(
2086
+ orgId: string,
2087
+ req: UpdateDispatchInputStateRequest,
2088
+ ): Promise<UpdateDispatchInputStateResponse> {
2089
+ return this.request('POST', ENDPOINTS.DISPATCH_INPUT_STATE(orgId), req);
2090
+ }
2091
+
2070
2092
  /**
2071
2093
  * End a turn. Overloaded on the three mutually exclusive reference forms:
2072
2094
  * lane (no_action sweep + lane release + re-drive), source (the lane-less
@@ -3365,6 +3387,30 @@ export class ParallClient {
3365
3387
  return this.request('GET', ENDPOINTS.TEMPLATE_DEPLOYMENT(orgId, deploymentId));
3366
3388
  }
3367
3389
 
3390
+ /** Pre-deploy dependency connection state (wizard S3). Live answer, no
3391
+ * cache — poll it the way getTemplateDeployment is polled. */
3392
+ async checkClipDependencies(orgId: string, refs: string[]): Promise<DependencyCheckResult[]> {
3393
+ const response = await this.request<{ results: DependencyCheckResult[] }>(
3394
+ 'POST',
3395
+ ENDPOINTS.CLIP_DEPENDENCIES_CHECK(orgId),
3396
+ { refs },
3397
+ );
3398
+ return response.results ?? [];
3399
+ }
3400
+
3401
+ // ---- Onboarding wizard progress (org-scoped, self) ----
3402
+
3403
+ async getOnboardingProgress(orgId: string): Promise<OnboardingProgress> {
3404
+ return this.request('GET', ENDPOINTS.ONBOARDING_PROGRESS(orgId));
3405
+ }
3406
+
3407
+ async updateOnboardingProgress(
3408
+ orgId: string,
3409
+ request: UpdateOnboardingProgressRequest,
3410
+ ): Promise<OnboardingProgress> {
3411
+ return this.request('PATCH', ENDPOINTS.ONBOARDING_PROGRESS(orgId), request);
3412
+ }
3413
+
3368
3414
  // ---- Billing & Credits (org-scoped) ----
3369
3415
 
3370
3416
  async getBilling(orgId: string): Promise<BillingSummary> {
@@ -3802,12 +3848,17 @@ export class ParallClient {
3802
3848
  * command RAN and failed — `error`/`error_code` describe why). Everything
3803
3849
  * else throws a typed {@link ApiError}; match on `err.code`:
3804
3850
  *
3805
- * Safe to retry (guaranteed nothing was dispatched):
3806
- * - `EDGE_ACTIVATING` 503 + `Retry-After` — cold cloud profile is starting.
3807
- * Bounded backoff, same `correlation_id` across the loop.
3808
- * - `EDGE_BUSY` 409the device is executing another request.
3809
- * - `EDGE_CONCURRENCY_LIMIT` 429 org at its concurrent-session limit.
3810
- * - `EDGE_UNAVAILABLE` 503session torn down / replaced mid-dispatch.
3851
+ * Safe to retry (provably not executed). Exactly three carry `Retry-After`
3852
+ * pacing ({@link ApiError.retryAfterSeconds}) `EDGE_ACTIVATING`,
3853
+ * `EDGE_BUSY`, `EDGE_CONCURRENCY_LIMIT`:
3854
+ * - `EDGE_ACTIVATING` 503cold cloud profile is starting. Answered before
3855
+ * any dispatch. Bounded backoff, same `correlation_id` across the loop.
3856
+ * - `EDGE_BUSY` 409the device is executing another request; the pod
3857
+ * refused this one before starting any script.
3858
+ * - `EDGE_CONCURRENCY_LIMIT` 429 — org at its concurrent-session limit,
3859
+ * answered before any dispatch.
3860
+ * - `EDGE_UNAVAILABLE` 503 — session torn down / replaced mid-dispatch. No
3861
+ * `Retry-After` (no slot to wait for — retry re-resolves routing).
3811
3862
  *
3812
3863
  * NOT retryable:
3813
3864
  * - `OUTCOME_UNKNOWN` 504 — dispatched, but no result arrived. The command
@@ -3875,6 +3926,84 @@ export class ParallClient {
3875
3926
  async deleteClipConnection(orgId: string, connId: string): Promise<void> {
3876
3927
  return this.request('DELETE', ENDPOINTS.CLIP_CONNECTION(orgId, connId));
3877
3928
  }
3929
+
3930
+ // ---- MCP clip server config (cap:clip-mcp; publisher-org only) ----
3931
+
3932
+ /**
3933
+ * Read the redacted MCP config. 404 NOT_FOUND when the clip has none yet;
3934
+ * 403 MCP_CROSS_ORG_DISABLED for a cross-org installed clip (the whole
3935
+ * mcp-config family is publisher-org property, reads included). `version`
3936
+ * is the CAS token the mutations echo via If-Match.
3937
+ */
3938
+ async getClipMCPConfig(orgId: string, clipId: string): Promise<MCPConfigResponse> {
3939
+ return this.request('GET', ENDPOINTS.ORG_CLIP_MCP_CONFIG(orgId, clipId));
3940
+ }
3941
+
3942
+ /**
3943
+ * Upsert the MCP config (human org-admin JWT only). Pass `expectedVersion`
3944
+ * from the last GET; omit it ONLY on first create (no config exists yet).
3945
+ * Save probes the remote server first — a probe failure persists nothing and
3946
+ * surfaces as MCP_URL_FORBIDDEN / MCP_AUTH_FAILED / MCP_SERVER_UNREACHABLE /
3947
+ * MCP_PROTOCOL_ERROR. Other typed conflicts: MCP_CONFIG_STALE (reload, then
3948
+ * retry with the current version), MCP_CONFIG_BUSY (another change in
3949
+ * flight — retry), MCP_CONNECTION_CONFLICT (a device-targeted default
3950
+ * connection must be unbound first), SECRETBOX_UNCONFIGURED (503 — the
3951
+ * server cannot store credentials safely).
3952
+ */
3953
+ async putClipMCPConfig(
3954
+ orgId: string,
3955
+ clipId: string,
3956
+ req: MCPConfigPutRequest,
3957
+ expectedVersion?: string,
3958
+ ): Promise<MCPConfigResponse> {
3959
+ return this.request(
3960
+ 'PUT',
3961
+ ENDPOINTS.ORG_CLIP_MCP_CONFIG(orgId, clipId),
3962
+ req,
3963
+ undefined,
3964
+ false,
3965
+ {
3966
+ headers: expectedVersion ? { 'If-Match': `"${expectedVersion}"` } : undefined,
3967
+ // The server probes the remote MCP server inside the request on a fixed
3968
+ // 30s budget; give the HTTP layer headroom past it so a slow-but-valid
3969
+ // save isn't chopped locally into a fake transport error.
3970
+ timeoutMs: 40_000,
3971
+ },
3972
+ );
3973
+ }
3974
+
3975
+ /**
3976
+ * Delete the MCP config and every connection routed through it (one
3977
+ * transaction — no orphaned target-less connections). `expectedVersion` is
3978
+ * mandatory: deleting always mutates an existing config.
3979
+ */
3980
+ async deleteClipMCPConfig(orgId: string, clipId: string, expectedVersion: string): Promise<void> {
3981
+ return this.request(
3982
+ 'DELETE',
3983
+ ENDPOINTS.ORG_CLIP_MCP_CONFIG(orgId, clipId),
3984
+ undefined,
3985
+ undefined,
3986
+ false,
3987
+ { headers: { 'If-Match': `"${expectedVersion}"` } },
3988
+ );
3989
+ }
3990
+
3991
+ /**
3992
+ * Re-run tools/list and replace the cached snapshot (org-admin only).
3993
+ * Deliberately does NOT advance the CAS version, so an in-flight edit in
3994
+ * another tab stays valid; on probe failure the old snapshot survives.
3995
+ */
3996
+ async refreshClipMCPTools(orgId: string, clipId: string): Promise<MCPConfigResponse> {
3997
+ return this.request(
3998
+ 'POST',
3999
+ ENDPOINTS.ORG_CLIP_MCP_TOOLS_REFRESH(orgId, clipId),
4000
+ undefined,
4001
+ undefined,
4002
+ false,
4003
+ // Same fixed 30s server-side probe budget as PUT (see putClipMCPConfig).
4004
+ { timeoutMs: 40_000 },
4005
+ );
4006
+ }
3878
4007
  }
3879
4008
 
3880
4009
  function normalizeWikiChangeset(changeset: WikiChangeset): WikiChangeset {
package/src/constants.ts CHANGED
@@ -781,6 +781,7 @@ export const ENDPOINTS = {
781
781
  DISPATCH_BY_MESSAGES: (orgId: string) => `${API_BASE}/orgs/${orgId}/dispatch/by-messages`,
782
782
  DISPATCH_CLAIM: (orgId: string) => `${API_BASE}/orgs/${orgId}/dispatch/claim`,
783
783
  DISPATCH_STEER: (orgId: string) => `${API_BASE}/orgs/${orgId}/dispatch/steer`,
784
+ DISPATCH_INPUT_STATE: (orgId: string) => `${API_BASE}/orgs/${orgId}/dispatch/input-state`,
784
785
  DISPATCH_COMPLETE: (orgId: string) => `${API_BASE}/orgs/${orgId}/dispatch/complete`,
785
786
  DISPATCH_COMPLETE_SOURCES: (orgId: string) =>
786
787
  `${API_BASE}/orgs/${orgId}/dispatch/complete-sources`,
@@ -829,6 +830,10 @@ export const ENDPOINTS = {
829
830
  TEMPLATE_DEPLOYMENTS: (orgId: string) => `${API_BASE}/orgs/${orgId}/template-deployments`,
830
831
  TEMPLATE_DEPLOYMENT: (orgId: string, deploymentId: string) =>
831
832
  `${API_BASE}/orgs/${orgId}/template-deployments/${deploymentId}`,
833
+ CLIP_DEPENDENCIES_CHECK: (orgId: string) => `${API_BASE}/orgs/${orgId}/clip-dependencies/check`,
834
+
835
+ // Onboarding wizard progress (org-scoped, self)
836
+ ONBOARDING_PROGRESS: (orgId: string) => `${API_BASE}/orgs/${orgId}/onboarding`,
832
837
 
833
838
  // Billing & Credits (org-scoped)
834
839
  BILLING: (orgId: string) => `${API_BASE}/orgs/${orgId}/billing`,
@@ -917,6 +922,12 @@ export const ENDPOINTS = {
917
922
  ORG_CLIP_REGISTRY: (orgId: string) => `/api/v1/orgs/${orgId}/clip-registry`,
918
923
  ORG_CLIP_INSTALL: (orgId: string) => `/api/v1/orgs/${orgId}/clips/install`,
919
924
  ORG_CLIPS_INSTALLED: (orgId: string) => `/api/v1/orgs/${orgId}/clips/installed`,
925
+ // MCP clip server config (cap:clip-mcp; publisher-org only — cross-org gets
926
+ // 403 MCP_CROSS_ORG_DISABLED on the whole family, reads included)
927
+ ORG_CLIP_MCP_CONFIG: (orgId: string, clipId: string) =>
928
+ `/api/v1/orgs/${orgId}/clip-registry/${clipId}/mcp-config`,
929
+ ORG_CLIP_MCP_TOOLS_REFRESH: (orgId: string, clipId: string) =>
930
+ `/api/v1/orgs/${orgId}/clip-registry/${clipId}/mcp-config/tools/refresh`,
920
931
  } as const;
921
932
 
922
933
  /**
package/src/types.ts CHANGED
@@ -408,6 +408,8 @@ export interface Organization {
408
408
  /** Agent ID for strategy='agent'. NULL when strategy is 'llm' or unset. */
409
409
  smart_routing_agent_id: string | null;
410
410
  onboarding_agent_id: string | null;
411
+ /** Org-level IANA timezone (e.g. "America/New_York"). Defaults to "UTC". */
412
+ timezone: string;
411
413
  created_at: string;
412
414
  /** Per-member flag: true when the user has dismissed the onboarding popup for this org. */
413
415
  onboarding_dismissed: boolean;
@@ -746,6 +748,46 @@ export interface DeployTemplateRequest {
746
748
  template_id: string;
747
749
  template_revision: string;
748
750
  parameter_values?: Record<string, TemplateParameterValue>;
751
+ /** Hire-time per-agent adjustments (onboarding wizard S2). Keys are the
752
+ * template's agent keys; omitted agents keep template defaults. */
753
+ agent_overrides?: Record<string, DeployAgentOverride>;
754
+ }
755
+
756
+ /** Per-agent hire-time override. Substitutes values within the platform-legal
757
+ * surface; never adds capability. Dependencies may only disable (false)
758
+ * declared optional deps — required deps and undeclared refs are rejected. */
759
+ export interface DeployAgentOverride {
760
+ runtime_type?: string;
761
+ /** Model catalog id. Empty string clears the template's pin (platform default). */
762
+ model?: string;
763
+ compute?: { machine_type: 'cloud'; machine_label?: string };
764
+ dependencies?: Record<string, boolean>;
765
+ }
766
+
767
+ /** Pre-deploy dependency connection state (wizard S3 poll target). Same
768
+ * checker as the deployment report, so the two surfaces cannot disagree. */
769
+ export interface DependencyCheckResult {
770
+ ref: string;
771
+ connected: boolean;
772
+ name?: string;
773
+ }
774
+
775
+ /** Onboarding wizard progress (self-scoped). A member who never started
776
+ * reads step='s1', state={}, version=0 (missing-row semantics). */
777
+ export interface OnboardingProgress {
778
+ step: string;
779
+ state: Record<string, unknown>;
780
+ completed_at?: string;
781
+ version: number;
782
+ }
783
+
784
+ export interface UpdateOnboardingProgressRequest {
785
+ step: string;
786
+ state: Record<string, unknown>;
787
+ /** Stamps completed_at server-side (idempotent, never un-completes). */
788
+ completed?: boolean;
789
+ /** 0 = first write (no row yet). */
790
+ expected_version: number;
749
791
  }
750
792
 
751
793
  export type TemplateDeploymentAgentState = 'up' | 'provisioning' | 'error';
@@ -882,6 +924,13 @@ export interface DispatchSourceRef {
882
924
  */
883
925
  export interface CompleteDispatchSourcesRequest {
884
926
  sources: DispatchSourceRef[];
927
+ /**
928
+ * Optional session attribution for the swept no_action rows (message ↔
929
+ * session linking; effect-covered rows inherit their covering reply's
930
+ * session). Validated against (org, agent); a mismatch drops the
931
+ * attribution.
932
+ */
933
+ session_id?: string;
885
934
  }
886
935
 
887
936
  export interface CompleteDispatchSourcesResult {
@@ -3136,6 +3185,8 @@ export type DispatchEventType =
3136
3185
  | 'channel_message';
3137
3186
  export type DispatchStatus = 'pending' | 'received' | 'acked';
3138
3187
  export type DispatchDeliveryReason = 'mention' | 'watcher' | 'assignee' | 'creator';
3188
+ export type DispatchCoverageMode = 'implicit' | 'explicit';
3189
+ export type DispatchInputState = 'offered' | 'started' | 'completed' | 'failed';
3139
3190
 
3140
3191
  export interface DispatchEvent {
3141
3192
  id: string;
@@ -3170,6 +3221,7 @@ export interface DispatchEvent {
3170
3221
  */
3171
3222
  dedupe_key?: string | null;
3172
3223
  lease_owner?: string | null;
3224
+ input_state?: DispatchInputState | null;
3173
3225
  target_uri?: string | null;
3174
3226
  thread_root_id?: string | null;
3175
3227
  resolution_kind?:
@@ -3187,6 +3239,14 @@ export interface DispatchEvent {
3187
3239
  * redrive_exhausted. Absent on pre-budget servers.
3188
3240
  */
3189
3241
  redrive_count?: number;
3242
+ /**
3243
+ * Agent session that ultimately handled this WorkItem, stamped at resolve
3244
+ * time where deterministically known (reply commits + broad cover /
3245
+ * by-source contagion; complete endpoints' validated self-report).
3246
+ * NULL = unattributed: live rows, cancelled, legacy acks, typed effects
3247
+ * until their runtimes report it.
3248
+ */
3249
+ session_id?: string | null;
3190
3250
  /**
3191
3251
  * Reply-message provenance ("prll://msg_x") of the resolving Effect.
3192
3252
  * Populated only by GET /dispatch/by-messages (Effect join) on
@@ -3212,6 +3272,12 @@ export interface ClaimDispatchRequest {
3212
3272
  source_type?: string;
3213
3273
  source_id?: string;
3214
3274
  limit?: number;
3275
+ /**
3276
+ * Explicit requires the runtime to report exact per-WorkItem input
3277
+ * lifecycle before reply/no-action coverage. Omit for legacy implicit
3278
+ * fold-means-consumed behavior.
3279
+ */
3280
+ coverage_mode?: DispatchCoverageMode;
3215
3281
  }
3216
3282
 
3217
3283
  export interface ClaimDispatchResponse {
@@ -3225,6 +3291,7 @@ export interface ClaimDispatchResponse {
3225
3291
  reason?: 'held' | 'empty' | '';
3226
3292
  lane?: string;
3227
3293
  lease_until?: string;
3294
+ coverage_mode?: DispatchCoverageMode;
3228
3295
  events?: DispatchEvent[];
3229
3296
  }
3230
3297
 
@@ -3243,6 +3310,22 @@ export interface SteerDispatchResponse {
3243
3310
  dispatch_event_id: string;
3244
3311
  }
3245
3312
 
3313
+ /** POST /dispatch/input-state — advance exact explicit-lane input members. */
3314
+ export interface UpdateDispatchInputStateRequest {
3315
+ lane: string;
3316
+ target_uri: string;
3317
+ thread_root_id?: string;
3318
+ dispatch_event_ids: string[];
3319
+ state: Exclude<DispatchInputState, 'offered'>;
3320
+ }
3321
+
3322
+ export interface UpdateDispatchInputStateResponse {
3323
+ /** Exact IDs accepted, including idempotent same-state retries. */
3324
+ recognized: number;
3325
+ released: number;
3326
+ redriven: boolean;
3327
+ }
3328
+
3246
3329
  /**
3247
3330
  * POST /dispatch/complete — end a turn. Two mutually exclusive reference
3248
3331
  * forms (dispatch-convergence-design.md §3), each with its own result shape
@@ -3259,13 +3342,31 @@ export interface CompleteDispatchLaneRequest {
3259
3342
  target_uri: string;
3260
3343
  thread_root_id?: string;
3261
3344
  /**
3262
- * "ok" (default) or "error". An error turn's members are released back to
3263
- * pending on the redrive budget instead of being no_action-swept, so failed
3264
- * work is retried rather than silently resolved. Ignored by older servers.
3345
+ * "ok" (default), "error", or "deferred". An error turn's members are
3346
+ * released back to pending on the redrive budget instead of being
3347
+ * no_action-swept, so failed work is retried rather than silently
3348
+ * resolved. A deferred turn (self-healing LLM usage limit,
3349
+ * agent-turn-outcome-design.md §6) releases its members to pending with
3350
+ * next_redrive_at = retry_at WITHOUT burning redrive budget — the renotify
3351
+ * slow loop re-delivers them at reset time. Servers predating "deferred"
3352
+ * answer 400; the bridge falls back to "error".
3265
3353
  */
3266
- turn_outcome?: 'ok' | 'error';
3354
+ turn_outcome?: 'ok' | 'error' | 'deferred';
3355
+ /** Normalized failure class for the deferred form (observability only). */
3356
+ outcome_class?: 'usage_limit';
3357
+ /**
3358
+ * ISO 8601 re-delivery time for turn_outcome=deferred. The server clamps
3359
+ * it into [now+1min, now+6h] and defaults a missing value to now+30min.
3360
+ */
3361
+ retry_at?: string;
3267
3362
  sources?: never;
3268
3363
  dispatch_event_id?: never;
3364
+ /**
3365
+ * Optional session attribution for the swept no_action rows (message ↔
3366
+ * session linking). Validated against (org, agent); a mismatch drops the
3367
+ * attribution, never the sweep.
3368
+ */
3369
+ session_id?: string;
3269
3370
  }
3270
3371
 
3271
3372
  /**
@@ -3277,6 +3378,12 @@ export interface CompleteDispatchLaneRequest {
3277
3378
  export interface CompleteDispatchSourceFormRequest {
3278
3379
  sources: DispatchSourceRef[];
3279
3380
  turn_outcome?: 'ok' | 'error';
3381
+ /**
3382
+ * Optional session attribution for the turn's no_action rows
3383
+ * (effect-covered rows inherit their covering reply's session instead).
3384
+ * Validated against (org, agent); informational.
3385
+ */
3386
+ session_id?: string;
3280
3387
  lane?: never;
3281
3388
  target_uri?: never;
3282
3389
  thread_root_id?: never;
@@ -3304,6 +3411,8 @@ export interface CompleteDispatchByIDRequest {
3304
3411
  /** Lane-form result. */
3305
3412
  export interface CompleteDispatchResult {
3306
3413
  swept_no_action: number;
3414
+ /** Members not eligible for no-action coverage and released for retry. */
3415
+ released?: number;
3307
3416
  redriven: boolean;
3308
3417
  }
3309
3418
 
@@ -3344,9 +3453,10 @@ export interface DispatchReceivedData {
3344
3453
  /**
3345
3454
  * Terminal counterpart of DispatchReceivedData: published on org:{orgId} when
3346
3455
  * a message WorkItem reaches a terminal resolution, so the message-level
3347
- * Activity indicator flips active→done (or clears, for `cancelled` /
3348
- * `redrive_exhausted`) without inferring completion from agent session state.
3349
- * Message WorkItems only.
3456
+ * Activity indicator flips active→done or, per indicator v2.1, active→failed
3457
+ * for `redrive_exhausted` (persistent dead-letter row); only `cancelled`
3458
+ * clears the indicator — without inferring completion from agent session
3459
+ * state. Message WorkItems only.
3350
3460
  */
3351
3461
  export interface DispatchResolvedData {
3352
3462
  agent_id: string;
@@ -3362,6 +3472,12 @@ export interface DispatchResolvedData {
3362
3472
  * message. Absent for no_action / legacy_ack.
3363
3473
  */
3364
3474
  result_uri?: string | null;
3475
+ /**
3476
+ * Session attribution mirrored from the resolved rows — lets the
3477
+ * indicator's click-through open the exact session without a refetch.
3478
+ * Absent when the resolution is unattributed.
3479
+ */
3480
+ session_id?: string | null;
3365
3481
  }
3366
3482
 
3367
3483
  export type InboxNewData = InboxItem;
@@ -4158,15 +4274,31 @@ export type BrowserProfileStatus = 'pending' | 'running' | 'stopped' | 'error' |
4158
4274
  /**
4159
4275
  * Routing/identity discriminant: `byoc` runs on a user machine (machine_id
4160
4276
  * required), `hosted` runs on the platform pool (machine_id null).
4277
+ *
4278
+ * NOTE: `hosted` is RETIRED — its compute plane was removed, so creating a profile
4279
+ * with it is rejected (400 `HOSTED_PLACEMENT_RETIRED`) and existing hosted rows are
4280
+ * read-only (readable, proxy-editable, deletable; never startable). The value stays
4281
+ * in the union because those preserved rows still report it. For a platform-run
4282
+ * browser use a v3 Cloud Profile (`POST /orgs/{org}/edge`).
4161
4283
  */
4162
4284
  export type BrowserPlacement = 'byoc' | 'hosted';
4163
4285
 
4164
- /** Deployment-wide hosted browser runtime availability (the controller startup
4165
- * gate). Drives whether the create UI offers the platform-hosted placement; it
4166
- * is org-scoped only for auth the value itself is the same for every org.
4167
- * Fail-closed: the server reports `available: false` if it cannot verify. */
4286
+ /** Platform-hosted browser runtime availability.
4287
+ *
4288
+ * This now always reports `available: false`: the v2 hosted compute plane is
4289
+ * retired, so the answer is a constant rather than a probe of a controller that no
4290
+ * longer exists. Clients that already treat `available: false` as "offer BYOC
4291
+ * instead" degrade correctly with no change.
4292
+ *
4293
+ * `code` distinguishes PERMANENT retirement (`HOSTED_PLACEMENT_RETIRED`) from the
4294
+ * transient outage the old flag could also mean — do not retry on it. It is
4295
+ * optional so older servers, which sent only `{available, reason}`, still typecheck. */
4168
4296
  export interface BrowserRuntimeStatus {
4169
4297
  available: boolean;
4298
+ /** Present when `available` is false for a structural reason. Currently only
4299
+ * `HOSTED_PLACEMENT_RETIRED`; typed as string so a new server code is not a
4300
+ * breaking SDK change. */
4301
+ code?: string;
4170
4302
  reason?: string;
4171
4303
  }
4172
4304
 
@@ -4617,6 +4749,56 @@ export interface ClipConnection {
4617
4749
  updated_at: string;
4618
4750
  }
4619
4751
 
4752
+ /** v1 MCP clip auth modes. Server-side OAuth is a designed follow-up. */
4753
+ export type MCPAuthType = 'none' | 'bearer' | 'api_key';
4754
+
4755
+ /**
4756
+ * One tool from the cached tools/list snapshot. The full remote tool object is
4757
+ * snapshotted verbatim (inputSchema etc. ride along in the index signature).
4758
+ * Name/description are REMOTE-CONTROLLED UNTRUSTED TEXT — render as plain text
4759
+ * only, never as markdown/HTML and never into a privileged prompt.
4760
+ */
4761
+ export interface MCPToolInfo {
4762
+ name: string;
4763
+ description?: string;
4764
+ [key: string]: unknown;
4765
+ }
4766
+
4767
+ /**
4768
+ * Redacted MCP server config of an MCP clip
4769
+ * (`GET /orgs/{orgId}/clip-registry/{clipId}/mcp-config`). The whole
4770
+ * mcp-config family is publisher-org only: cross-org installs get
4771
+ * `403 MCP_CROSS_ORG_DISABLED`, reads included. The stored credential NEVER
4772
+ * appears in any response — `credential_set` is the only credential fact.
4773
+ */
4774
+ export interface MCPConfigResponse {
4775
+ server_url: string;
4776
+ auth_type: MCPAuthType;
4777
+ /** Whether a credential is stored (write-only; the value is never returned). */
4778
+ credential_set: boolean;
4779
+ /** Cached tools/list snapshot; untrusted remote metadata (see MCPToolInfo). */
4780
+ tools?: MCPToolInfo[];
4781
+ tools_refreshed_at?: string;
4782
+ /**
4783
+ * Opaque CAS token for If-Match on PUT/DELETE (lost-update protection).
4784
+ * Version mismatch answers `409 MCP_CONFIG_STALE`.
4785
+ */
4786
+ version: string;
4787
+ }
4788
+
4789
+ /**
4790
+ * PUT body for the MCP config. Credential semantics (server-enforced):
4791
+ * omitted keeps the stored one ONLY while auth_type is unchanged; switching
4792
+ * credentialed types requires a new credential; auth_type "none" clears it.
4793
+ * Saving probes the server (initialize + tools/list) first — a failed probe
4794
+ * persists nothing.
4795
+ */
4796
+ export interface MCPConfigPutRequest {
4797
+ server_url: string;
4798
+ auth_type: MCPAuthType;
4799
+ credential?: string;
4800
+ }
4801
+
4620
4802
  /**
4621
4803
  * A clip in the api-server org registry (`crg_…`, table `clip_registry`) — the
4622
4804
  * v3 registry that install and clip connections operate on. Distinct from