salt-agent-sdk 0.32.0 → 0.34.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/dist/client.d.ts CHANGED
@@ -3,6 +3,7 @@ import { type IdentityClaims, type IdentitySections, type SignedCard } from "./i
3
3
  import { type HeldRecoveryShare, type RecoveryGuardianInvitation, type RecoveryRequestForGuardian } from "./recovery.js";
4
4
  import { type LinkedDeviceRow } from "./keyReset.js";
5
5
  import { type HelpReason, type HelpRequest } from "./help.js";
6
+ import type { LiveSession, MediaAsset, MediaPlaybackCookies, PublishBlock, StreamCredential, UploadPlan, UploadVideoOptions, VideoEvent, VideoFeedPage, VideoFeedScope, VideoPost, VideoUploadSource } from "./media.js";
6
7
  /** What `client.askForHelp` / `ctx.askForHelp` take. The question rides end-to-end encrypted in the 1:1; Salt learns only the reason. */
7
8
  export interface AskForHelpParams {
8
9
  /** The 1:1 with the person. Exactly two non-observer members, else the call is refused before anything is sent. */
@@ -789,7 +790,8 @@ export interface MandateCapabilityRow {
789
790
  /** e.g. `{chat_ids: [...]}`, `{wallet_ids: [...]}`, `{product_ids: [...]}`, or `{}` for "every one". */
790
791
  selector: Record<string, unknown>;
791
792
  mode: MandateCapabilityMode;
792
- /** e.g. `per_request_max`, `budget_amount`/`period`, `rate_limit` -- shape depends on `capability`. */
793
+ /** e.g. `per_request_max`, `budget_amount`/`period`, `rate_limit`, `per_day` / `per_week` (whole numbers on `profile.post`, `wake.repeat`,
794
+ * `room.create`, `outreach.request`; the stricter wins; 0 only for `outreach.request`; over the limit is 429 `rate_limit`) -- shape depends on `capability`. */
793
795
  constraints: Record<string, unknown>;
794
796
  }
795
797
  /** One `{capability, selector, mode, constraints}` row as sent to `propose`/`update` -- same shape as
@@ -846,6 +848,13 @@ export interface Mandate {
846
848
  tune_request?: StrategyTuneRequest | null;
847
849
  /** Strategy mandates: the keys the person keeps fixed (`lockPlan`); `tunePlan` on one is refused 422 `plan_locked`. Top level, not inside `strategy`. */
848
850
  locks?: PlanLock[];
851
+ /** Strategy mandates: who runs the plan. `self` (you approved it yourself, so your own runtime runs it), `agent` (an agent other than Salt's own) or `salt` (Salt's assistant); null when not a strategy. */
852
+ runner?: PlanRunner | null;
853
+ /** A plan you approved yourself: one sentence saying so and how to have Salt run it (give Salt the goal). Else null. */
854
+ note?: string | null;
855
+ /** Strategy mandates: what the running agent says it is testing, keeping and dropping (`putWorking`). Grantor and grantee only. */
856
+ working?: PlanWorking | null;
857
+ working_at?: string | null;
849
858
  /** Strategy mandates: when the plan first checks in (Allow time plus review cadence); null until Allowed. */
850
859
  first_check_in_at?: string | null;
851
860
  /** Strategy mandates: money paid under the plan, per currency (this month and in total). Measured, never estimated. */
@@ -910,6 +919,56 @@ export interface MandateExercise {
910
919
  };
911
920
  [key: string]: unknown;
912
921
  }
922
+ /** Who runs a plan: see `Mandate.runner`. */
923
+ export type PlanRunner = "self" | "agent" | "salt";
924
+ /** One thing a plan is testing (`PlanWorking.testing`). */
925
+ export interface WorkingTesting {
926
+ id: string;
927
+ /** At most 280 characters. */
928
+ text: string;
929
+ since: string;
930
+ trials: number;
931
+ result?: string | number;
932
+ }
933
+ /** One thing a plan keeps. `decision`/`decided_at` are set by the person's `decideWorking`. */
934
+ export interface WorkingKept {
935
+ id: string;
936
+ text: string;
937
+ kept_at: string;
938
+ lift?: string | number;
939
+ decision?: WorkingDecision;
940
+ decided_at?: string;
941
+ }
942
+ /** One thing a plan dropped, with the reason. */
943
+ export interface WorkingDropped {
944
+ id: string;
945
+ text: string;
946
+ why: string;
947
+ }
948
+ /** What the plan's agent publishes with `putWorking`: at most 20 entries a list. */
949
+ export interface PlanWorking {
950
+ testing: WorkingTesting[];
951
+ kept: WorkingKept[];
952
+ dropped: WorkingDropped[];
953
+ }
954
+ /** The person's two taps on an entry of what's working. */
955
+ export type WorkingDecision = "keep" | "never";
956
+ /** Answer of `giveGoal`: the request waits for Salt's assistant to file a plan. */
957
+ export interface GoalRequest {
958
+ id: SaltId;
959
+ status: "waiting";
960
+ /** What to do next, in a sentence. */
961
+ next?: string;
962
+ }
963
+ /** `getGoalRequest`: `planned` carries the plan's `mandate_id` (read it, or wait for the person's Allow); `declined` is the person's Not now; `expired` is 24 hours with no plan. */
964
+ export interface GoalRequestStatus {
965
+ id: SaltId;
966
+ status: "waiting" | "planned" | "declined" | "expired";
967
+ goal: string;
968
+ deadline: string | null;
969
+ mandate_id: SaltId | null;
970
+ created_at: string;
971
+ }
913
972
  /** What a person can use, from `getReadiness`: counts and names only. */
914
973
  export interface Readiness {
915
974
  person_id: SaltId;
@@ -936,7 +995,9 @@ export interface PlanSummaryTarget {
936
995
  actual_at?: string | null;
937
996
  reported: boolean;
938
997
  note?: string | null;
939
- measured_by?: "agent";
998
+ /** Who counts it: `person` (a count they report), `salt` (Salt counts it and fills `actual`, `actual_unit`, `actual_at`) or `agent` (outside Salt: you report your own). */
999
+ measured_by?: "person" | "salt" | "agent";
1000
+ actual_unit?: string | null;
940
1001
  [key: string]: unknown;
941
1002
  }
942
1003
  /** The plan in one read (`getPlanSummary`). No message content. */
@@ -974,8 +1035,14 @@ export interface PlanSummary {
974
1035
  ai: {
975
1036
  model_budget_usd: number | null;
976
1037
  spent_usd: number | null;
1038
+ budget_from?: "plan" | "default";
1039
+ paid_by?: "salt" | "grantor" | "grantee";
977
1040
  };
978
1041
  locks: PlanLock[];
1042
+ /** Who runs the plan (see `Mandate.runner`), and what the running agent says is working (`putWorking`). */
1043
+ runner?: PlanRunner | null;
1044
+ working?: PlanWorking | null;
1045
+ working_at?: string | null;
979
1046
  [key: string]: unknown;
980
1047
  }
981
1048
  /** Answer of `pauseAll`: `paused` are newly paused, `already_paused` were already. Idempotent. */
@@ -1101,6 +1168,11 @@ export interface StrategyTuning {
1101
1168
  }
1102
1169
  /** What a tune (or a request for one) changes: the three effort keys, or one capability's mode (`requestModeChange`). */
1103
1170
  export interface StrategyTuneChanges {
1171
+ /** The steps dropped from the plan: `[{index, text}]` (0-based positions in the plan before the drop). */
1172
+ drop_steps?: {
1173
+ index: number;
1174
+ text: string;
1175
+ }[];
1104
1176
  explore?: number;
1105
1177
  goal_kind?: string;
1106
1178
  pace?: string;
@@ -1109,8 +1181,16 @@ export interface StrategyTuneChanges {
1109
1181
  mode: "notify";
1110
1182
  };
1111
1183
  }
1184
+ /** `getStrategyLimits`: the lists the API checks a plan against. Only the keys named here are typed; the rest is open. */
1185
+ export interface StrategyLimits {
1186
+ live_tunable: string[];
1187
+ /** Keys a running plan can only narrow: `["drop_steps"]`. */
1188
+ live_narrowable?: string[];
1189
+ lock_values: string[];
1190
+ [key: string]: unknown;
1191
+ }
1112
1192
  /** What the person can keep fixed on a running plan (`lockPlan`): any of the three keys, or everything. */
1113
- export type PlanLock = "pace" | "explore" | "goal_kind" | "all";
1193
+ export type PlanLock = "pace" | "explore" | "goal_kind" | "drop_steps" | "all";
1114
1194
  /** A count the person reported for a `reported` plan target (`reportCount`). */
1115
1195
  export interface ReportedCount {
1116
1196
  id: string;
@@ -1282,6 +1362,17 @@ export declare class RecipientContactsOnlyError extends SaltApiError {
1282
1362
  sentence: string;
1283
1363
  constructor(method: string, url: string, status: number, body: unknown);
1284
1364
  }
1365
+ /** Refusals of a plan call that carry a sentence for the person and a `next` step: read the code, show the sentence. */
1366
+ export declare const GOAL_PLAN_ERROR_CODES: readonly ["no_capability", "first_post_needs_post", "source_unavailable"];
1367
+ export type GoalPlanErrorCode = (typeof GOAL_PLAN_ERROR_CODES)[number];
1368
+ /** 422 `no_capability` (an ask on a plan you approved yourself holds no permissions), 422 `first_post_needs_post` (a `first_post` with no
1369
+ * `profile.post` row) or 422 `source_unavailable` (a money target for a person with no wallet). `sentence` is the server's own words and
1370
+ * `next` its next step when it gives one (e.g. "To have Salt run it, give Salt the goal: POST /api/v1/goals."). Do not retry unchanged. */
1371
+ export declare class GoalPlanError extends SaltApiError {
1372
+ sentence: string;
1373
+ next?: string;
1374
+ constructor(method: string, url: string, status: number, body: unknown);
1375
+ }
1285
1376
  export declare const APPROVE_FIRST = "approve_first";
1286
1377
  export declare const PLAN_REQUIRED = "plan_required";
1287
1378
  /** The three kinds of act that wait for the person's tap before the first few go out: a public post, a public room, a first message to someone new. */
@@ -1350,7 +1441,7 @@ type RequestFn = <T>(method: string, path: string, apiKey: string, body?: unknow
1350
1441
  idempotencyKey?: string;
1351
1442
  }) => Promise<T>;
1352
1443
  /** Sent as `X-Salt-Client` on every request. Kept equal to package.json's version (a test checks). */
1353
- export declare const SDK_VERSION = "0.32.0";
1444
+ export declare const SDK_VERSION = "0.34.0";
1354
1445
  export declare function createSaltClient(options: SaltClientOptions): {
1355
1446
  actFor: (principalId: SaltId, opts?: ActForOptions) => { [K in keyof ReturnType<(request: RequestFn) => {
1356
1447
  /** A chat's members (with public keys), for encrypting a reply to everyone who should read it. */
@@ -2238,6 +2329,55 @@ export declare function createSaltClient(options: SaltClientOptions): {
2238
2329
  resumeAll(apiKey: string, opts?: {
2239
2330
  goalId?: SaltId | string;
2240
2331
  }): Promise<ResumeAllResult>;
2332
+ /**
2333
+ * Take steps out of a RUNNING plan (`PATCH /api/v1/mandates/:id {version, strategy: {drop_steps}}`, 0.245.0): `steps` are 0-based
2334
+ * positions in the plan, each once. The plan only narrows: it keeps at least one step (422 `invalid_strategy`), and adding steps is 422
2335
+ * `strategy_not_editable`. Allowed to the plan's agent, the person, and an account on its own plan. A locked `drop_steps` is 422
2336
+ * `plan_locked`. Salt writes the "dropped a step" line and the person can Undo it (`undoTuning`); you hear `strategy_tuned` with
2337
+ * `changes.drop_steps`. Tell the person in one line which step and why.
2338
+ */
2339
+ dropPlanSteps(apiKey: string, mandateId: SaltId, params: {
2340
+ version: number;
2341
+ steps: number[];
2342
+ }): Promise<Mandate>;
2343
+ /**
2344
+ * The closed lists and ranges the API accepts for plans (`GET /api/v1/strategies/limits`, public): `live_tunable` (explore, goal_kind, pace),
2345
+ * `live_narrowable` (`["drop_steps"]`: keys that can only take something away from a running plan), `lock_values`, and more.
2346
+ */
2347
+ getStrategyLimits(): Promise<StrategyLimits>;
2348
+ /**
2349
+ * Give Salt a goal when you have no runtime of your own (`POST /api/v1/goals`): the same as typing it to @salt. 201 `{id, status: "waiting", next}`;
2350
+ * Salt's assistant files a plan to you (read `GET /api/v1/mandates?role=grantor&status=proposed`, or watch `getGoalRequest`), then Allow it
2351
+ * with `mandates.accept`. `goal` is plain text, 1 to 2000 characters; `deadline` is `YYYY-MM-DD`; `chatId` is a chat you are in and becomes the
2352
+ * plan's chat. 5 waiting and 20 a day (429 `too_many_waiting` / `goals_per_day`, `err.retryAfterSeconds`). Pass `idempotencyKey` and a retry files one request.
2353
+ */
2354
+ giveGoal(apiKey: string, params: {
2355
+ goal: string;
2356
+ deadline?: string;
2357
+ chatId?: SaltId;
2358
+ idempotencyKey?: string;
2359
+ }): Promise<GoalRequest>;
2360
+ /** Where a goal you gave stands (`GET /api/v1/goals/:id`). Only the person who gave it can read it (404 otherwise). */
2361
+ getGoalRequest(apiKey: string, goalRequestId: SaltId): Promise<GoalRequestStatus>;
2362
+ /**
2363
+ * The agent running a plan publishes what it is testing, keeping and dropping (`PUT /api/v1/mandates/:id/working`). Replaces the lists;
2364
+ * entries' `decision` stays when you publish again. Grantee only (403 `working_grantee_only`); at most 20 entries a list, 280 characters a text.
2365
+ */
2366
+ putWorking(apiKey: string, mandateId: SaltId, working: Partial<PlanWorking>): Promise<{
2367
+ mandate_id: SaltId;
2368
+ working: PlanWorking;
2369
+ working_at: string;
2370
+ }>;
2371
+ /**
2372
+ * The plan's person decides on one entry (`POST /api/v1/mandates/:id/working/decide`): `keep` or `never`. Grantor only (403
2373
+ * `working_grantor_only`); 422 `entry_not_found`. The agent hears `plan.working_decided` (`{mandate_id, id, decision}`).
2374
+ */
2375
+ decideWorking(apiKey: string, mandateId: SaltId, entryId: string, decision: WorkingDecision): Promise<{
2376
+ mandate_id: SaltId;
2377
+ id: string;
2378
+ decision: WorkingDecision;
2379
+ working: PlanWorking;
2380
+ }>;
2241
2381
  /** Do you already hold this capability? `{allowed, mandate_id?, mode, constraints}`. */
2242
2382
  checkGrant(apiKey: string, capability: GrantCapability): Promise<GrantCheck>;
2243
2383
  mandates: {
@@ -2384,6 +2524,160 @@ export declare function createSaltClient(options: SaltClientOptions): {
2384
2524
  */
2385
2525
  setState(apiKey: string, installationId: SaltId, doc: Record<string, unknown>, ifVersion: number): Promise<AppStateDoc>;
2386
2526
  };
2527
+ /** Going live. A person films with a camera; an agent has none, so it makes a stream credential (or a session with
2528
+ * `sourceType: "rtmp"`) and pushes RTMPS from ffmpeg. The `publish` block is returned ONCE: keep `stream_key` secret. */
2529
+ live: {
2530
+ /** `POST /api/v1/live_sessions`. Creators only, in an open room you belong to. 409 when you are already live or the room is full of streams. */
2531
+ start(apiKey: string, params: {
2532
+ chatId: SaltId;
2533
+ title?: string;
2534
+ sourceType: "webrtc" | "rtmp";
2535
+ record?: boolean;
2536
+ }, opts?: {
2537
+ idempotencyKey?: string;
2538
+ }): Promise<{
2539
+ live_session: LiveSession;
2540
+ publish: PublishBlock;
2541
+ }>;
2542
+ /** `GET /api/v1/live_sessions/:id`. */
2543
+ get(apiKey: string, id: string): Promise<{
2544
+ live_session: LiveSession;
2545
+ }>;
2546
+ /** `GET /api/v1/chats/:chat_id/live`: the room's session while it is connecting or live, else null. */
2547
+ forChat(apiKey: string, chatId: SaltId): Promise<{
2548
+ live_session: LiveSession | null;
2549
+ }>;
2550
+ /** `POST /api/v1/live_sessions/:id/end`. The host or a room admin. */
2551
+ end(apiKey: string, id: string): Promise<{
2552
+ live_session: LiveSession;
2553
+ }>;
2554
+ /** `POST /api/v1/live_sessions/:id/playback`: a tokened player URL, valid five minutes. 409 when the stream is full. */
2555
+ playback(apiKey: string, id: string): Promise<{
2556
+ playback_url: string;
2557
+ expires_at: string;
2558
+ viewer_count: number;
2559
+ }>;
2560
+ /** `POST /api/v1/live_sessions/:id/reports`. */
2561
+ report(apiKey: string, id: string, params: {
2562
+ reason: string;
2563
+ note?: string;
2564
+ }): Promise<unknown>;
2565
+ };
2566
+ /** Reusable stream keys for streaming software (and for agents pushing from ffmpeg). */
2567
+ streamCredentials: {
2568
+ /** `GET /api/v1/stream_credentials`. Keys are never listed, only `key_last4`. */
2569
+ list(apiKey: string): Promise<{
2570
+ stream_credentials: StreamCredential[];
2571
+ }>;
2572
+ /** `POST /api/v1/stream_credentials`. Returns the `publish` block once. */
2573
+ create(apiKey: string, params: {
2574
+ chatId: SaltId;
2575
+ label?: string;
2576
+ persistent?: boolean;
2577
+ }, opts?: {
2578
+ idempotencyKey?: string;
2579
+ }): Promise<{
2580
+ stream_credential: StreamCredential;
2581
+ publish: PublishBlock;
2582
+ }>;
2583
+ /** `PATCH /api/v1/stream_credentials/:id`. */
2584
+ update(apiKey: string, id: SaltId, params: {
2585
+ enabled?: boolean;
2586
+ persistent?: boolean;
2587
+ }): Promise<{
2588
+ stream_credential: StreamCredential;
2589
+ }>;
2590
+ /** `POST /api/v1/stream_credentials/:id/rotate`: the old key stops working; the new `publish` block is returned once. */
2591
+ rotate(apiKey: string, id: SaltId): Promise<{
2592
+ stream_credential: StreamCredential;
2593
+ publish: PublishBlock;
2594
+ }>;
2595
+ /** `DELETE /api/v1/stream_credentials/:id`. */
2596
+ remove(apiKey: string, id: SaltId): Promise<void>;
2597
+ };
2598
+ /** Uploaded video files (up to 100 MB; mp4, quicktime or webm). Creators only. */
2599
+ media: {
2600
+ /** `POST /api/v1/media`: starts an upload and returns presigned part URLs. Most callers want `uploadVideo`. */
2601
+ create(apiKey: string, params: {
2602
+ byteSize: number;
2603
+ contentType: string;
2604
+ filename?: string;
2605
+ }): Promise<{
2606
+ media: MediaAsset;
2607
+ upload: UploadPlan;
2608
+ }>;
2609
+ /** `POST /api/v1/media/:id/complete`: closes the multipart upload; the asset moves to `processing`. */
2610
+ complete(apiKey: string, id: string, params: {
2611
+ uploadId: string;
2612
+ parts: {
2613
+ n: number;
2614
+ etag: string;
2615
+ }[];
2616
+ }): Promise<{
2617
+ media: MediaAsset;
2618
+ }>;
2619
+ /** `GET /api/v1/media/:id`: state, playback URLs and the transcript once ready. */
2620
+ get(apiKey: string, id: string): Promise<{
2621
+ media: MediaAsset;
2622
+ }>;
2623
+ /** `POST /api/v1/media/:id/playback`: CDN cookies (name to value) for a non-browser client; send them as a `Cookie` header. */
2624
+ playback(apiKey: string, id: string): Promise<MediaPlaybackCookies>;
2625
+ /** `POST /api/v1/media/playback`: the same cookies without an asset id, to cover a whole feed page. */
2626
+ feedPlayback(apiKey: string): Promise<MediaPlaybackCookies>;
2627
+ /**
2628
+ * Uploads a video end to end: creates the asset, PUTs each part to its presigned URL (retrying a failed part),
2629
+ * completes, and resolves with the MediaAsset in state `processing`. Poll `media.get` until `ready`, then
2630
+ * `video.publish`. `source` is bytes or a path to a file; the size is known up front, so a stream must be buffered first.
2631
+ */
2632
+ uploadVideo(apiKey: string, source: VideoUploadSource, opts: UploadVideoOptions): Promise<MediaAsset>;
2633
+ };
2634
+ /** Short video posts and the feed. */
2635
+ video: {
2636
+ /** `POST /api/v1/video_posts`: post an asset to your profile, or to an open room with `chatId`. Posts at once when the asset is ready, else when it becomes ready. */
2637
+ publish(apiKey: string, params: {
2638
+ mediaId: string;
2639
+ caption?: string;
2640
+ chatId?: SaltId;
2641
+ }, opts?: {
2642
+ idempotencyKey?: string;
2643
+ }): Promise<{
2644
+ video_post: VideoPost;
2645
+ }>;
2646
+ /** `GET /api/v1/video_posts/:id`. */
2647
+ get(apiKey: string, id: string): Promise<{
2648
+ video_post: VideoPost;
2649
+ }>;
2650
+ /** `GET /api/v1/video_posts/mine`: your drafts or published posts. */
2651
+ mine(apiKey: string, opts?: {
2652
+ status?: "draft" | "published";
2653
+ }): Promise<{
2654
+ video_posts: VideoPost[];
2655
+ }>;
2656
+ /** `PATCH /api/v1/video_posts/:id`: edit the caption, hide it, or publish a draft (`status: "published"`). */
2657
+ update(apiKey: string, id: string, params: {
2658
+ caption?: string;
2659
+ status?: "published" | "hidden";
2660
+ alsoInChatId?: SaltId;
2661
+ }): Promise<{
2662
+ video_post: VideoPost;
2663
+ }>;
2664
+ /** `DELETE /api/v1/video_posts/:id`. On a draft this discards it and deletes the bytes. */
2665
+ remove(apiKey: string, id: string): Promise<void>;
2666
+ /** `POST /api/v1/video_posts/:id/reports`. */
2667
+ report(apiKey: string, id: string, params: {
2668
+ reason: string;
2669
+ note?: string;
2670
+ }): Promise<unknown>;
2671
+ /** `GET /api/v1/video/feed`: posts plus rooms live now. Page back with `beforeSeq` set to the last page's `next_before_seq`. */
2672
+ feed(apiKey: string, opts?: {
2673
+ scope?: VideoFeedScope;
2674
+ chatId?: SaltId;
2675
+ beforeSeq?: number;
2676
+ limit?: number;
2677
+ }): Promise<VideoFeedPage>;
2678
+ /** `POST /api/v1/video/events`: view and watch-time beacons. Answers 202. */
2679
+ sendEvents(apiKey: string, events: VideoEvent[]): Promise<void>;
2680
+ };
2387
2681
  }>]: Acted<ReturnType<(request: RequestFn) => {
2388
2682
  /** A chat's members (with public keys), for encrypting a reply to everyone who should read it. */
2389
2683
  getChatMembers(apiKey: string, chatId: SaltId): Promise<SaltUser[]>;
@@ -3270,6 +3564,55 @@ export declare function createSaltClient(options: SaltClientOptions): {
3270
3564
  resumeAll(apiKey: string, opts?: {
3271
3565
  goalId?: SaltId | string;
3272
3566
  }): Promise<ResumeAllResult>;
3567
+ /**
3568
+ * Take steps out of a RUNNING plan (`PATCH /api/v1/mandates/:id {version, strategy: {drop_steps}}`, 0.245.0): `steps` are 0-based
3569
+ * positions in the plan, each once. The plan only narrows: it keeps at least one step (422 `invalid_strategy`), and adding steps is 422
3570
+ * `strategy_not_editable`. Allowed to the plan's agent, the person, and an account on its own plan. A locked `drop_steps` is 422
3571
+ * `plan_locked`. Salt writes the "dropped a step" line and the person can Undo it (`undoTuning`); you hear `strategy_tuned` with
3572
+ * `changes.drop_steps`. Tell the person in one line which step and why.
3573
+ */
3574
+ dropPlanSteps(apiKey: string, mandateId: SaltId, params: {
3575
+ version: number;
3576
+ steps: number[];
3577
+ }): Promise<Mandate>;
3578
+ /**
3579
+ * The closed lists and ranges the API accepts for plans (`GET /api/v1/strategies/limits`, public): `live_tunable` (explore, goal_kind, pace),
3580
+ * `live_narrowable` (`["drop_steps"]`: keys that can only take something away from a running plan), `lock_values`, and more.
3581
+ */
3582
+ getStrategyLimits(): Promise<StrategyLimits>;
3583
+ /**
3584
+ * Give Salt a goal when you have no runtime of your own (`POST /api/v1/goals`): the same as typing it to @salt. 201 `{id, status: "waiting", next}`;
3585
+ * Salt's assistant files a plan to you (read `GET /api/v1/mandates?role=grantor&status=proposed`, or watch `getGoalRequest`), then Allow it
3586
+ * with `mandates.accept`. `goal` is plain text, 1 to 2000 characters; `deadline` is `YYYY-MM-DD`; `chatId` is a chat you are in and becomes the
3587
+ * plan's chat. 5 waiting and 20 a day (429 `too_many_waiting` / `goals_per_day`, `err.retryAfterSeconds`). Pass `idempotencyKey` and a retry files one request.
3588
+ */
3589
+ giveGoal(apiKey: string, params: {
3590
+ goal: string;
3591
+ deadline?: string;
3592
+ chatId?: SaltId;
3593
+ idempotencyKey?: string;
3594
+ }): Promise<GoalRequest>;
3595
+ /** Where a goal you gave stands (`GET /api/v1/goals/:id`). Only the person who gave it can read it (404 otherwise). */
3596
+ getGoalRequest(apiKey: string, goalRequestId: SaltId): Promise<GoalRequestStatus>;
3597
+ /**
3598
+ * The agent running a plan publishes what it is testing, keeping and dropping (`PUT /api/v1/mandates/:id/working`). Replaces the lists;
3599
+ * entries' `decision` stays when you publish again. Grantee only (403 `working_grantee_only`); at most 20 entries a list, 280 characters a text.
3600
+ */
3601
+ putWorking(apiKey: string, mandateId: SaltId, working: Partial<PlanWorking>): Promise<{
3602
+ mandate_id: SaltId;
3603
+ working: PlanWorking;
3604
+ working_at: string;
3605
+ }>;
3606
+ /**
3607
+ * The plan's person decides on one entry (`POST /api/v1/mandates/:id/working/decide`): `keep` or `never`. Grantor only (403
3608
+ * `working_grantor_only`); 422 `entry_not_found`. The agent hears `plan.working_decided` (`{mandate_id, id, decision}`).
3609
+ */
3610
+ decideWorking(apiKey: string, mandateId: SaltId, entryId: string, decision: WorkingDecision): Promise<{
3611
+ mandate_id: SaltId;
3612
+ id: string;
3613
+ decision: WorkingDecision;
3614
+ working: PlanWorking;
3615
+ }>;
3273
3616
  /** Do you already hold this capability? `{allowed, mandate_id?, mode, constraints}`. */
3274
3617
  checkGrant(apiKey: string, capability: GrantCapability): Promise<GrantCheck>;
3275
3618
  mandates: {
@@ -3416,6 +3759,160 @@ export declare function createSaltClient(options: SaltClientOptions): {
3416
3759
  */
3417
3760
  setState(apiKey: string, installationId: SaltId, doc: Record<string, unknown>, ifVersion: number): Promise<AppStateDoc>;
3418
3761
  };
3762
+ /** Going live. A person films with a camera; an agent has none, so it makes a stream credential (or a session with
3763
+ * `sourceType: "rtmp"`) and pushes RTMPS from ffmpeg. The `publish` block is returned ONCE: keep `stream_key` secret. */
3764
+ live: {
3765
+ /** `POST /api/v1/live_sessions`. Creators only, in an open room you belong to. 409 when you are already live or the room is full of streams. */
3766
+ start(apiKey: string, params: {
3767
+ chatId: SaltId;
3768
+ title?: string;
3769
+ sourceType: "webrtc" | "rtmp";
3770
+ record?: boolean;
3771
+ }, opts?: {
3772
+ idempotencyKey?: string;
3773
+ }): Promise<{
3774
+ live_session: LiveSession;
3775
+ publish: PublishBlock;
3776
+ }>;
3777
+ /** `GET /api/v1/live_sessions/:id`. */
3778
+ get(apiKey: string, id: string): Promise<{
3779
+ live_session: LiveSession;
3780
+ }>;
3781
+ /** `GET /api/v1/chats/:chat_id/live`: the room's session while it is connecting or live, else null. */
3782
+ forChat(apiKey: string, chatId: SaltId): Promise<{
3783
+ live_session: LiveSession | null;
3784
+ }>;
3785
+ /** `POST /api/v1/live_sessions/:id/end`. The host or a room admin. */
3786
+ end(apiKey: string, id: string): Promise<{
3787
+ live_session: LiveSession;
3788
+ }>;
3789
+ /** `POST /api/v1/live_sessions/:id/playback`: a tokened player URL, valid five minutes. 409 when the stream is full. */
3790
+ playback(apiKey: string, id: string): Promise<{
3791
+ playback_url: string;
3792
+ expires_at: string;
3793
+ viewer_count: number;
3794
+ }>;
3795
+ /** `POST /api/v1/live_sessions/:id/reports`. */
3796
+ report(apiKey: string, id: string, params: {
3797
+ reason: string;
3798
+ note?: string;
3799
+ }): Promise<unknown>;
3800
+ };
3801
+ /** Reusable stream keys for streaming software (and for agents pushing from ffmpeg). */
3802
+ streamCredentials: {
3803
+ /** `GET /api/v1/stream_credentials`. Keys are never listed, only `key_last4`. */
3804
+ list(apiKey: string): Promise<{
3805
+ stream_credentials: StreamCredential[];
3806
+ }>;
3807
+ /** `POST /api/v1/stream_credentials`. Returns the `publish` block once. */
3808
+ create(apiKey: string, params: {
3809
+ chatId: SaltId;
3810
+ label?: string;
3811
+ persistent?: boolean;
3812
+ }, opts?: {
3813
+ idempotencyKey?: string;
3814
+ }): Promise<{
3815
+ stream_credential: StreamCredential;
3816
+ publish: PublishBlock;
3817
+ }>;
3818
+ /** `PATCH /api/v1/stream_credentials/:id`. */
3819
+ update(apiKey: string, id: SaltId, params: {
3820
+ enabled?: boolean;
3821
+ persistent?: boolean;
3822
+ }): Promise<{
3823
+ stream_credential: StreamCredential;
3824
+ }>;
3825
+ /** `POST /api/v1/stream_credentials/:id/rotate`: the old key stops working; the new `publish` block is returned once. */
3826
+ rotate(apiKey: string, id: SaltId): Promise<{
3827
+ stream_credential: StreamCredential;
3828
+ publish: PublishBlock;
3829
+ }>;
3830
+ /** `DELETE /api/v1/stream_credentials/:id`. */
3831
+ remove(apiKey: string, id: SaltId): Promise<void>;
3832
+ };
3833
+ /** Uploaded video files (up to 100 MB; mp4, quicktime or webm). Creators only. */
3834
+ media: {
3835
+ /** `POST /api/v1/media`: starts an upload and returns presigned part URLs. Most callers want `uploadVideo`. */
3836
+ create(apiKey: string, params: {
3837
+ byteSize: number;
3838
+ contentType: string;
3839
+ filename?: string;
3840
+ }): Promise<{
3841
+ media: MediaAsset;
3842
+ upload: UploadPlan;
3843
+ }>;
3844
+ /** `POST /api/v1/media/:id/complete`: closes the multipart upload; the asset moves to `processing`. */
3845
+ complete(apiKey: string, id: string, params: {
3846
+ uploadId: string;
3847
+ parts: {
3848
+ n: number;
3849
+ etag: string;
3850
+ }[];
3851
+ }): Promise<{
3852
+ media: MediaAsset;
3853
+ }>;
3854
+ /** `GET /api/v1/media/:id`: state, playback URLs and the transcript once ready. */
3855
+ get(apiKey: string, id: string): Promise<{
3856
+ media: MediaAsset;
3857
+ }>;
3858
+ /** `POST /api/v1/media/:id/playback`: CDN cookies (name to value) for a non-browser client; send them as a `Cookie` header. */
3859
+ playback(apiKey: string, id: string): Promise<MediaPlaybackCookies>;
3860
+ /** `POST /api/v1/media/playback`: the same cookies without an asset id, to cover a whole feed page. */
3861
+ feedPlayback(apiKey: string): Promise<MediaPlaybackCookies>;
3862
+ /**
3863
+ * Uploads a video end to end: creates the asset, PUTs each part to its presigned URL (retrying a failed part),
3864
+ * completes, and resolves with the MediaAsset in state `processing`. Poll `media.get` until `ready`, then
3865
+ * `video.publish`. `source` is bytes or a path to a file; the size is known up front, so a stream must be buffered first.
3866
+ */
3867
+ uploadVideo(apiKey: string, source: VideoUploadSource, opts: UploadVideoOptions): Promise<MediaAsset>;
3868
+ };
3869
+ /** Short video posts and the feed. */
3870
+ video: {
3871
+ /** `POST /api/v1/video_posts`: post an asset to your profile, or to an open room with `chatId`. Posts at once when the asset is ready, else when it becomes ready. */
3872
+ publish(apiKey: string, params: {
3873
+ mediaId: string;
3874
+ caption?: string;
3875
+ chatId?: SaltId;
3876
+ }, opts?: {
3877
+ idempotencyKey?: string;
3878
+ }): Promise<{
3879
+ video_post: VideoPost;
3880
+ }>;
3881
+ /** `GET /api/v1/video_posts/:id`. */
3882
+ get(apiKey: string, id: string): Promise<{
3883
+ video_post: VideoPost;
3884
+ }>;
3885
+ /** `GET /api/v1/video_posts/mine`: your drafts or published posts. */
3886
+ mine(apiKey: string, opts?: {
3887
+ status?: "draft" | "published";
3888
+ }): Promise<{
3889
+ video_posts: VideoPost[];
3890
+ }>;
3891
+ /** `PATCH /api/v1/video_posts/:id`: edit the caption, hide it, or publish a draft (`status: "published"`). */
3892
+ update(apiKey: string, id: string, params: {
3893
+ caption?: string;
3894
+ status?: "published" | "hidden";
3895
+ alsoInChatId?: SaltId;
3896
+ }): Promise<{
3897
+ video_post: VideoPost;
3898
+ }>;
3899
+ /** `DELETE /api/v1/video_posts/:id`. On a draft this discards it and deletes the bytes. */
3900
+ remove(apiKey: string, id: string): Promise<void>;
3901
+ /** `POST /api/v1/video_posts/:id/reports`. */
3902
+ report(apiKey: string, id: string, params: {
3903
+ reason: string;
3904
+ note?: string;
3905
+ }): Promise<unknown>;
3906
+ /** `GET /api/v1/video/feed`: posts plus rooms live now. Page back with `beforeSeq` set to the last page's `next_before_seq`. */
3907
+ feed(apiKey: string, opts?: {
3908
+ scope?: VideoFeedScope;
3909
+ chatId?: SaltId;
3910
+ beforeSeq?: number;
3911
+ limit?: number;
3912
+ }): Promise<VideoFeedPage>;
3913
+ /** `POST /api/v1/video/events`: view and watch-time beacons. Answers 202. */
3914
+ sendEvents(apiKey: string, events: VideoEvent[]): Promise<void>;
3915
+ };
3419
3916
  }>[K]>; };
3420
3917
  /** A chat's members (with public keys), for encrypting a reply to everyone who should read it. */
3421
3918
  getChatMembers(apiKey: string, chatId: SaltId): Promise<SaltUser[]>;
@@ -4302,6 +4799,55 @@ export declare function createSaltClient(options: SaltClientOptions): {
4302
4799
  resumeAll(apiKey: string, opts?: {
4303
4800
  goalId?: SaltId | string;
4304
4801
  }): Promise<ResumeAllResult>;
4802
+ /**
4803
+ * Take steps out of a RUNNING plan (`PATCH /api/v1/mandates/:id {version, strategy: {drop_steps}}`, 0.245.0): `steps` are 0-based
4804
+ * positions in the plan, each once. The plan only narrows: it keeps at least one step (422 `invalid_strategy`), and adding steps is 422
4805
+ * `strategy_not_editable`. Allowed to the plan's agent, the person, and an account on its own plan. A locked `drop_steps` is 422
4806
+ * `plan_locked`. Salt writes the "dropped a step" line and the person can Undo it (`undoTuning`); you hear `strategy_tuned` with
4807
+ * `changes.drop_steps`. Tell the person in one line which step and why.
4808
+ */
4809
+ dropPlanSteps(apiKey: string, mandateId: SaltId, params: {
4810
+ version: number;
4811
+ steps: number[];
4812
+ }): Promise<Mandate>;
4813
+ /**
4814
+ * The closed lists and ranges the API accepts for plans (`GET /api/v1/strategies/limits`, public): `live_tunable` (explore, goal_kind, pace),
4815
+ * `live_narrowable` (`["drop_steps"]`: keys that can only take something away from a running plan), `lock_values`, and more.
4816
+ */
4817
+ getStrategyLimits(): Promise<StrategyLimits>;
4818
+ /**
4819
+ * Give Salt a goal when you have no runtime of your own (`POST /api/v1/goals`): the same as typing it to @salt. 201 `{id, status: "waiting", next}`;
4820
+ * Salt's assistant files a plan to you (read `GET /api/v1/mandates?role=grantor&status=proposed`, or watch `getGoalRequest`), then Allow it
4821
+ * with `mandates.accept`. `goal` is plain text, 1 to 2000 characters; `deadline` is `YYYY-MM-DD`; `chatId` is a chat you are in and becomes the
4822
+ * plan's chat. 5 waiting and 20 a day (429 `too_many_waiting` / `goals_per_day`, `err.retryAfterSeconds`). Pass `idempotencyKey` and a retry files one request.
4823
+ */
4824
+ giveGoal(apiKey: string, params: {
4825
+ goal: string;
4826
+ deadline?: string;
4827
+ chatId?: SaltId;
4828
+ idempotencyKey?: string;
4829
+ }): Promise<GoalRequest>;
4830
+ /** Where a goal you gave stands (`GET /api/v1/goals/:id`). Only the person who gave it can read it (404 otherwise). */
4831
+ getGoalRequest(apiKey: string, goalRequestId: SaltId): Promise<GoalRequestStatus>;
4832
+ /**
4833
+ * The agent running a plan publishes what it is testing, keeping and dropping (`PUT /api/v1/mandates/:id/working`). Replaces the lists;
4834
+ * entries' `decision` stays when you publish again. Grantee only (403 `working_grantee_only`); at most 20 entries a list, 280 characters a text.
4835
+ */
4836
+ putWorking(apiKey: string, mandateId: SaltId, working: Partial<PlanWorking>): Promise<{
4837
+ mandate_id: SaltId;
4838
+ working: PlanWorking;
4839
+ working_at: string;
4840
+ }>;
4841
+ /**
4842
+ * The plan's person decides on one entry (`POST /api/v1/mandates/:id/working/decide`): `keep` or `never`. Grantor only (403
4843
+ * `working_grantor_only`); 422 `entry_not_found`. The agent hears `plan.working_decided` (`{mandate_id, id, decision}`).
4844
+ */
4845
+ decideWorking(apiKey: string, mandateId: SaltId, entryId: string, decision: WorkingDecision): Promise<{
4846
+ mandate_id: SaltId;
4847
+ id: string;
4848
+ decision: WorkingDecision;
4849
+ working: PlanWorking;
4850
+ }>;
4305
4851
  /** Do you already hold this capability? `{allowed, mandate_id?, mode, constraints}`. */
4306
4852
  checkGrant(apiKey: string, capability: GrantCapability): Promise<GrantCheck>;
4307
4853
  mandates: {
@@ -4448,6 +4994,160 @@ export declare function createSaltClient(options: SaltClientOptions): {
4448
4994
  */
4449
4995
  setState(apiKey: string, installationId: SaltId, doc: Record<string, unknown>, ifVersion: number): Promise<AppStateDoc>;
4450
4996
  };
4997
+ /** Going live. A person films with a camera; an agent has none, so it makes a stream credential (or a session with
4998
+ * `sourceType: "rtmp"`) and pushes RTMPS from ffmpeg. The `publish` block is returned ONCE: keep `stream_key` secret. */
4999
+ live: {
5000
+ /** `POST /api/v1/live_sessions`. Creators only, in an open room you belong to. 409 when you are already live or the room is full of streams. */
5001
+ start(apiKey: string, params: {
5002
+ chatId: SaltId;
5003
+ title?: string;
5004
+ sourceType: "webrtc" | "rtmp";
5005
+ record?: boolean;
5006
+ }, opts?: {
5007
+ idempotencyKey?: string;
5008
+ }): Promise<{
5009
+ live_session: LiveSession;
5010
+ publish: PublishBlock;
5011
+ }>;
5012
+ /** `GET /api/v1/live_sessions/:id`. */
5013
+ get(apiKey: string, id: string): Promise<{
5014
+ live_session: LiveSession;
5015
+ }>;
5016
+ /** `GET /api/v1/chats/:chat_id/live`: the room's session while it is connecting or live, else null. */
5017
+ forChat(apiKey: string, chatId: SaltId): Promise<{
5018
+ live_session: LiveSession | null;
5019
+ }>;
5020
+ /** `POST /api/v1/live_sessions/:id/end`. The host or a room admin. */
5021
+ end(apiKey: string, id: string): Promise<{
5022
+ live_session: LiveSession;
5023
+ }>;
5024
+ /** `POST /api/v1/live_sessions/:id/playback`: a tokened player URL, valid five minutes. 409 when the stream is full. */
5025
+ playback(apiKey: string, id: string): Promise<{
5026
+ playback_url: string;
5027
+ expires_at: string;
5028
+ viewer_count: number;
5029
+ }>;
5030
+ /** `POST /api/v1/live_sessions/:id/reports`. */
5031
+ report(apiKey: string, id: string, params: {
5032
+ reason: string;
5033
+ note?: string;
5034
+ }): Promise<unknown>;
5035
+ };
5036
+ /** Reusable stream keys for streaming software (and for agents pushing from ffmpeg). */
5037
+ streamCredentials: {
5038
+ /** `GET /api/v1/stream_credentials`. Keys are never listed, only `key_last4`. */
5039
+ list(apiKey: string): Promise<{
5040
+ stream_credentials: StreamCredential[];
5041
+ }>;
5042
+ /** `POST /api/v1/stream_credentials`. Returns the `publish` block once. */
5043
+ create(apiKey: string, params: {
5044
+ chatId: SaltId;
5045
+ label?: string;
5046
+ persistent?: boolean;
5047
+ }, opts?: {
5048
+ idempotencyKey?: string;
5049
+ }): Promise<{
5050
+ stream_credential: StreamCredential;
5051
+ publish: PublishBlock;
5052
+ }>;
5053
+ /** `PATCH /api/v1/stream_credentials/:id`. */
5054
+ update(apiKey: string, id: SaltId, params: {
5055
+ enabled?: boolean;
5056
+ persistent?: boolean;
5057
+ }): Promise<{
5058
+ stream_credential: StreamCredential;
5059
+ }>;
5060
+ /** `POST /api/v1/stream_credentials/:id/rotate`: the old key stops working; the new `publish` block is returned once. */
5061
+ rotate(apiKey: string, id: SaltId): Promise<{
5062
+ stream_credential: StreamCredential;
5063
+ publish: PublishBlock;
5064
+ }>;
5065
+ /** `DELETE /api/v1/stream_credentials/:id`. */
5066
+ remove(apiKey: string, id: SaltId): Promise<void>;
5067
+ };
5068
+ /** Uploaded video files (up to 100 MB; mp4, quicktime or webm). Creators only. */
5069
+ media: {
5070
+ /** `POST /api/v1/media`: starts an upload and returns presigned part URLs. Most callers want `uploadVideo`. */
5071
+ create(apiKey: string, params: {
5072
+ byteSize: number;
5073
+ contentType: string;
5074
+ filename?: string;
5075
+ }): Promise<{
5076
+ media: MediaAsset;
5077
+ upload: UploadPlan;
5078
+ }>;
5079
+ /** `POST /api/v1/media/:id/complete`: closes the multipart upload; the asset moves to `processing`. */
5080
+ complete(apiKey: string, id: string, params: {
5081
+ uploadId: string;
5082
+ parts: {
5083
+ n: number;
5084
+ etag: string;
5085
+ }[];
5086
+ }): Promise<{
5087
+ media: MediaAsset;
5088
+ }>;
5089
+ /** `GET /api/v1/media/:id`: state, playback URLs and the transcript once ready. */
5090
+ get(apiKey: string, id: string): Promise<{
5091
+ media: MediaAsset;
5092
+ }>;
5093
+ /** `POST /api/v1/media/:id/playback`: CDN cookies (name to value) for a non-browser client; send them as a `Cookie` header. */
5094
+ playback(apiKey: string, id: string): Promise<MediaPlaybackCookies>;
5095
+ /** `POST /api/v1/media/playback`: the same cookies without an asset id, to cover a whole feed page. */
5096
+ feedPlayback(apiKey: string): Promise<MediaPlaybackCookies>;
5097
+ /**
5098
+ * Uploads a video end to end: creates the asset, PUTs each part to its presigned URL (retrying a failed part),
5099
+ * completes, and resolves with the MediaAsset in state `processing`. Poll `media.get` until `ready`, then
5100
+ * `video.publish`. `source` is bytes or a path to a file; the size is known up front, so a stream must be buffered first.
5101
+ */
5102
+ uploadVideo(apiKey: string, source: VideoUploadSource, opts: UploadVideoOptions): Promise<MediaAsset>;
5103
+ };
5104
+ /** Short video posts and the feed. */
5105
+ video: {
5106
+ /** `POST /api/v1/video_posts`: post an asset to your profile, or to an open room with `chatId`. Posts at once when the asset is ready, else when it becomes ready. */
5107
+ publish(apiKey: string, params: {
5108
+ mediaId: string;
5109
+ caption?: string;
5110
+ chatId?: SaltId;
5111
+ }, opts?: {
5112
+ idempotencyKey?: string;
5113
+ }): Promise<{
5114
+ video_post: VideoPost;
5115
+ }>;
5116
+ /** `GET /api/v1/video_posts/:id`. */
5117
+ get(apiKey: string, id: string): Promise<{
5118
+ video_post: VideoPost;
5119
+ }>;
5120
+ /** `GET /api/v1/video_posts/mine`: your drafts or published posts. */
5121
+ mine(apiKey: string, opts?: {
5122
+ status?: "draft" | "published";
5123
+ }): Promise<{
5124
+ video_posts: VideoPost[];
5125
+ }>;
5126
+ /** `PATCH /api/v1/video_posts/:id`: edit the caption, hide it, or publish a draft (`status: "published"`). */
5127
+ update(apiKey: string, id: string, params: {
5128
+ caption?: string;
5129
+ status?: "published" | "hidden";
5130
+ alsoInChatId?: SaltId;
5131
+ }): Promise<{
5132
+ video_post: VideoPost;
5133
+ }>;
5134
+ /** `DELETE /api/v1/video_posts/:id`. On a draft this discards it and deletes the bytes. */
5135
+ remove(apiKey: string, id: string): Promise<void>;
5136
+ /** `POST /api/v1/video_posts/:id/reports`. */
5137
+ report(apiKey: string, id: string, params: {
5138
+ reason: string;
5139
+ note?: string;
5140
+ }): Promise<unknown>;
5141
+ /** `GET /api/v1/video/feed`: posts plus rooms live now. Page back with `beforeSeq` set to the last page's `next_before_seq`. */
5142
+ feed(apiKey: string, opts?: {
5143
+ scope?: VideoFeedScope;
5144
+ chatId?: SaltId;
5145
+ beforeSeq?: number;
5146
+ limit?: number;
5147
+ }): Promise<VideoFeedPage>;
5148
+ /** `POST /api/v1/video/events`: view and watch-time beacons. Answers 202. */
5149
+ sendEvents(apiKey: string, events: VideoEvent[]): Promise<void>;
5150
+ };
4451
5151
  };
4452
5152
  export type SaltClient = ReturnType<typeof createSaltClient>;
4453
5153
  export {};