@recursiv/sdk 0.7.70 → 0.7.72
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/README.md +85 -10
- package/dist/client.d.ts +5 -0
- package/dist/client.js +7 -1
- package/dist/index.d.ts +13 -3
- package/dist/index.js +11 -1
- package/dist/resources/agents.d.ts +48 -0
- package/dist/resources/agents.js +22 -0
- package/dist/resources/curator.d.ts +11 -4
- package/dist/resources/discovery-fallover.d.ts +8 -0
- package/dist/resources/discovery-fallover.js +26 -0
- package/dist/resources/discovery-first-screen.d.ts +30 -0
- package/dist/resources/discovery-first-screen.js +149 -0
- package/dist/resources/discovery-merge.d.ts +144 -0
- package/dist/resources/discovery-merge.js +479 -0
- package/dist/resources/discovery-progressive.d.ts +117 -0
- package/dist/resources/discovery-progressive.js +414 -0
- package/dist/resources/discovery-safety.d.ts +32 -0
- package/dist/resources/discovery-safety.js +521 -0
- package/dist/resources/discovery.d.ts +59 -16
- package/dist/resources/discovery.js +147 -47
- package/dist/resources/feeds.d.ts +3 -1
- package/dist/resources/judgments.d.ts +252 -0
- package/dist/resources/judgments.js +79 -0
- package/dist/resources/notifications.d.ts +7 -2
- package/dist/resources/protocols.d.ts +204 -17
- package/dist/resources/protocols.js +24 -5
- package/dist/resources/search.d.ts +9 -1
- package/dist/resources/settings.d.ts +8 -1
- package/dist/resources/settings.js +9 -0
- package/dist/resources/signals.d.ts +58 -0
- package/dist/resources/signals.js +32 -0
- package/dist/types.d.ts +67 -0
- package/llm.md +24 -7
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { HttpClient } from '../client.js';
|
|
2
|
-
import type { CompassFilterMeta, DiscoveryLayout, PaginatedResponse, PaginationParams, SingleResponse } from '../types.js';
|
|
2
|
+
import type { CompassFilterMeta, DiscoveryLayout, PaginatedResponse, PaginationParams, SingleResponse, StoryOutlets } from '../types.js';
|
|
3
3
|
/** Canonical protocol operation names returned by the adapter registry. */
|
|
4
4
|
export declare const PROTOCOL_CAPABILITY_OPERATIONS: readonly ["discover", "stream", "backfill", "search", "resolveIdentity", "fetchProfile", "fetchThread", "publish", "reply", "react", "repost", "follow", "delete", "health", "checkpoint"];
|
|
5
5
|
export declare const PROTOCOL_CAPABILITY_STATUSES: readonly ["supported", "planned", "unsupported"];
|
|
@@ -181,6 +181,134 @@ export interface ProtocolIngestionReplayResult {
|
|
|
181
181
|
job_id: string;
|
|
182
182
|
status: 'replayed';
|
|
183
183
|
}
|
|
184
|
+
/** A section of the ingestion health report that can fail to answer within its budget. */
|
|
185
|
+
export type ProtocolIngestionHealthSection = 'activity' | 'circuits' | 'dead_letters' | 'jobs' | 'kill_switch' | 'lanes';
|
|
186
|
+
/**
|
|
187
|
+
* Where a job is in its lane, read from its checkpoint: RSS reads one feed per page (feed_index); Hacker News and
|
|
188
|
+
* Event Registry walk term_index and page. Null when the checkpoint holds no such index.
|
|
189
|
+
*/
|
|
190
|
+
export interface ProtocolIngestionHealthPosition {
|
|
191
|
+
feed_index: number | null;
|
|
192
|
+
term_index: number | null;
|
|
193
|
+
page: number | null;
|
|
194
|
+
}
|
|
195
|
+
export interface ProtocolIngestionHealthRuntime {
|
|
196
|
+
mode: 'collector' | 'runtime';
|
|
197
|
+
enabled: boolean;
|
|
198
|
+
simulation: boolean;
|
|
199
|
+
global_kill_switch: boolean;
|
|
200
|
+
controls_valid: boolean;
|
|
201
|
+
project_allowed: boolean;
|
|
202
|
+
/** This app's operator kill switch; null when that read did not answer. */
|
|
203
|
+
kill_switch: boolean | null;
|
|
204
|
+
}
|
|
205
|
+
export interface ProtocolIngestionLaneJobs {
|
|
206
|
+
queued: number;
|
|
207
|
+
leased: number;
|
|
208
|
+
done: number;
|
|
209
|
+
dead: number;
|
|
210
|
+
}
|
|
211
|
+
/** The lane's open job (the worker keeps one open per lane). */
|
|
212
|
+
export interface ProtocolIngestionLaneCurrentJob {
|
|
213
|
+
status: 'queued' | 'leased';
|
|
214
|
+
position: ProtocolIngestionHealthPosition;
|
|
215
|
+
pages_committed: number;
|
|
216
|
+
consecutive_failures: number;
|
|
217
|
+
last_error: string | null;
|
|
218
|
+
retry_at: string | null;
|
|
219
|
+
/** A leased job's lease end; null while queued. */
|
|
220
|
+
lease_until: string | null;
|
|
221
|
+
/** Leased, but the lease ran out and no worker reclaimed it (the worker died mid-page). */
|
|
222
|
+
lease_expired: boolean;
|
|
223
|
+
/** Eligible to run since then; null while a live lease holds it or it waits out a retry. */
|
|
224
|
+
waiting_since: string | null;
|
|
225
|
+
/** waiting_since once the wait passes the worker's starvation threshold (30 minutes); otherwise null. */
|
|
226
|
+
starved_since: string | null;
|
|
227
|
+
}
|
|
228
|
+
export interface ProtocolIngestionActivityReason {
|
|
229
|
+
status: 'retry' | 'dead' | 'invalid_job' | 'deferred' | 'abandoned';
|
|
230
|
+
reason: string | null;
|
|
231
|
+
count: number;
|
|
232
|
+
}
|
|
233
|
+
/** Attempts over the last window_hours; last success, last failure and failing_since look back lookback_days. */
|
|
234
|
+
export interface ProtocolIngestionLaneActivity {
|
|
235
|
+
window_hours: number;
|
|
236
|
+
pages_committed: number;
|
|
237
|
+
/** Attempts that ended in a retry, a dead letter or an invalid job. */
|
|
238
|
+
failed: number;
|
|
239
|
+
deferred: number;
|
|
240
|
+
abandoned: number;
|
|
241
|
+
reasons: ProtocolIngestionActivityReason[];
|
|
242
|
+
lookback_days: number;
|
|
243
|
+
last_success_at: string | null;
|
|
244
|
+
last_failure_at: string | null;
|
|
245
|
+
/** The first failure after the last success; null when the newest finished attempt succeeded or none failed. */
|
|
246
|
+
failing_since: string | null;
|
|
247
|
+
}
|
|
248
|
+
export interface ProtocolIngestionDeadLetterGroup {
|
|
249
|
+
reason: string | null;
|
|
250
|
+
position: ProtocolIngestionHealthPosition;
|
|
251
|
+
count: number;
|
|
252
|
+
last_at: string | null;
|
|
253
|
+
}
|
|
254
|
+
/** Every dead job of the lane counted in total; the newest 20 (reason, position) groups listed. */
|
|
255
|
+
export interface ProtocolIngestionLaneDeadLetters {
|
|
256
|
+
total: number;
|
|
257
|
+
last_dead_at: string | null;
|
|
258
|
+
groups: ProtocolIngestionDeadLetterGroup[];
|
|
259
|
+
}
|
|
260
|
+
/** One ingestion lane. A section that did not answer reads as null here and is named in the report's `unavailable`. */
|
|
261
|
+
export interface ProtocolIngestionLaneHealth {
|
|
262
|
+
provider_id: string;
|
|
263
|
+
source_subscription_key: string;
|
|
264
|
+
active: boolean;
|
|
265
|
+
/** RSS only: the feeds this process reads, one page each, so a pass ends after feed_count pages. Null for other providers. */
|
|
266
|
+
feed_count: number | null;
|
|
267
|
+
jobs: ProtocolIngestionLaneJobs | null;
|
|
268
|
+
/** When a job of this lane last reached done (read every page of its pass). */
|
|
269
|
+
last_done_at: string | null;
|
|
270
|
+
/** Null when the lane has no open job or the jobs section is unavailable. */
|
|
271
|
+
current: ProtocolIngestionLaneCurrentJob | null;
|
|
272
|
+
activity: ProtocolIngestionLaneActivity | null;
|
|
273
|
+
dead_letters: ProtocolIngestionLaneDeadLetters | null;
|
|
274
|
+
}
|
|
275
|
+
/** A circuit row that is open, counting failures or killed: the provider's own, or (per-RSS-host circuit on) a fetch host's. */
|
|
276
|
+
export interface ProtocolIngestionCircuitHealth {
|
|
277
|
+
provider_id: string;
|
|
278
|
+
kind: 'provider' | 'host';
|
|
279
|
+
/**
|
|
280
|
+
* A host circuit's fetch host: read from a readable key, or for a hashed key the configured feed host (with any
|
|
281
|
+
* explicit port) it belongs to. Null for the provider's own circuit and for a hashed key no configured feed names.
|
|
282
|
+
*/
|
|
283
|
+
host: string | null;
|
|
284
|
+
/** The quota row key: `rss`, `rss--h-feeds_bbci_co_uk`, `rss--x-<hash>`. */
|
|
285
|
+
domain: string;
|
|
286
|
+
open: boolean;
|
|
287
|
+
open_until: string | null;
|
|
288
|
+
/**
|
|
289
|
+
* When the circuit last opened, or re-opened on a failed probe (open_until minus the open window). Null when it has
|
|
290
|
+
* not opened since it last closed.
|
|
291
|
+
*/
|
|
292
|
+
opened_at: string | null;
|
|
293
|
+
/** Failures in a row since the circuit last closed (a host circuit's: feeds whose host never accepted the connection). */
|
|
294
|
+
failures: number;
|
|
295
|
+
killed: boolean;
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* Counts-only ingestion health for the key's app (audit row 8a): per lane, job counts, the open job's position,
|
|
299
|
+
* the last done, success and failure, 24-hour attempts by reason and dead letters by reason and position; plus the
|
|
300
|
+
* open or counting circuits. Never a checkpoint, payload, candidate or feed body.
|
|
301
|
+
*/
|
|
302
|
+
export interface ProtocolIngestionHealthReport {
|
|
303
|
+
generated_at: string;
|
|
304
|
+
runtime: ProtocolIngestionHealthRuntime;
|
|
305
|
+
/** Null when the lanes section is unavailable. */
|
|
306
|
+
lanes: ProtocolIngestionLaneHealth[] | null;
|
|
307
|
+
/** Open first. Null when the circuits section is unavailable. */
|
|
308
|
+
circuits: ProtocolIngestionCircuitHealth[] | null;
|
|
309
|
+
/** Sections that did not answer within their statement budget; their fields read as null. */
|
|
310
|
+
unavailable: ProtocolIngestionHealthSection[];
|
|
311
|
+
}
|
|
184
312
|
/** App/network scope comes only from the authenticated project-bound key. */
|
|
185
313
|
export interface ListProtocolCandidatesParams {
|
|
186
314
|
protocol?: string;
|
|
@@ -250,6 +378,14 @@ export type NativeNostrPrepareInput = {
|
|
|
250
378
|
content: string;
|
|
251
379
|
/** Your own post in this app (sdk.posts) that this note copies, so deleting it can offer this copy. */
|
|
252
380
|
crossPostOf?: string;
|
|
381
|
+
/**
|
|
382
|
+
* A NIP-18 quote of one public note (0.7.71; accounts advertising `quote`). The server reads the note and adds its
|
|
383
|
+
* `q` and `p` tags and a `nostr:nevent` line after your text; review `quote` and the exact event before signing.
|
|
384
|
+
*/
|
|
385
|
+
quote?: {
|
|
386
|
+
protocol: 'nostr';
|
|
387
|
+
nativeId: string;
|
|
388
|
+
};
|
|
253
389
|
} | {
|
|
254
390
|
action: 'reply';
|
|
255
391
|
content: string;
|
|
@@ -662,13 +798,22 @@ export interface NativeReplyBatch {
|
|
|
662
798
|
/** Public text and Minds-hosted images; accounts are selected explicitly in the shared editor. */
|
|
663
799
|
export interface NativePostPrepareInput {
|
|
664
800
|
clientMutationId: string;
|
|
801
|
+
/**
|
|
802
|
+
* The exact public text. Pass '' for a photo-only post (no words), which needs at least one `media`
|
|
803
|
+
* item: Bluesky gets an empty text with the images and Mastodon a status with only the photos, each
|
|
804
|
+
* photo's `alt` as its description. '' without media, or only spaces, is refused. Replies always need text.
|
|
805
|
+
*/
|
|
665
806
|
text: string;
|
|
666
807
|
accountIds: string[];
|
|
667
808
|
/** Minds-hosted images attached to every selected destination. Omit for a text-only post. */
|
|
668
809
|
media?: NativeMediaInput[];
|
|
669
|
-
/**
|
|
810
|
+
/**
|
|
811
|
+
* A native quote: a Bluesky record (`at://` URI), or a Mastodon status by its public URI (0.7.71) on a server that
|
|
812
|
+
* creates quote posts (Mastodon API version 7). The server reads the source and permissions using each selected account;
|
|
813
|
+
* a server without quote posts answers `quote_not_supported`, never a plain link. Nostr quotes use `prepareNativeNostr`.
|
|
814
|
+
*/
|
|
670
815
|
quote?: {
|
|
671
|
-
protocol: 'bluesky';
|
|
816
|
+
protocol: 'bluesky' | 'activitypub';
|
|
672
817
|
nativeId: string;
|
|
673
818
|
};
|
|
674
819
|
/**
|
|
@@ -685,17 +830,24 @@ export interface NativePostBatch {
|
|
|
685
830
|
deliveries: Array<Omit<NativeReplyBatch['deliveries'][number], 'kind' | 'parent' | 'recoverable' | 'replacedBy'> & {
|
|
686
831
|
audience: 'public';
|
|
687
832
|
maxCharacters: number;
|
|
688
|
-
quote?:
|
|
689
|
-
protocol: 'bluesky';
|
|
690
|
-
nativeId: string;
|
|
691
|
-
cid: string;
|
|
692
|
-
authorId: string;
|
|
693
|
-
authorHandle: string;
|
|
694
|
-
sourceUrl: string;
|
|
695
|
-
text: string;
|
|
696
|
-
};
|
|
833
|
+
quote?: NativePostQuote;
|
|
697
834
|
}>;
|
|
698
835
|
}
|
|
836
|
+
/** The reviewed quote of a delivery: Bluesky binds the record's CID, Mastodon the status's id on the member's server and its revision. */
|
|
837
|
+
export type NativePostQuote = {
|
|
838
|
+
nativeId: string;
|
|
839
|
+
authorId: string;
|
|
840
|
+
authorHandle: string;
|
|
841
|
+
sourceUrl: string;
|
|
842
|
+
text: string;
|
|
843
|
+
} & ({
|
|
844
|
+
protocol: 'bluesky';
|
|
845
|
+
cid: string;
|
|
846
|
+
} | {
|
|
847
|
+
protocol: 'activitypub';
|
|
848
|
+
localId: string;
|
|
849
|
+
revision: string;
|
|
850
|
+
});
|
|
699
851
|
export interface NativeDelegatedPostHistoryItem {
|
|
700
852
|
id: string;
|
|
701
853
|
createdAt: string;
|
|
@@ -822,11 +974,22 @@ export interface NativeNostrPrepared {
|
|
|
822
974
|
text: string;
|
|
823
975
|
textTruncated?: boolean;
|
|
824
976
|
};
|
|
977
|
+
/** The quoted note (a publish with `quote`), and the relay hint its `q` tag and `nostr:nevent` carry. */
|
|
978
|
+
quote?: {
|
|
979
|
+
protocol: 'nostr';
|
|
980
|
+
nativeId: string;
|
|
981
|
+
authorId: string;
|
|
982
|
+
authorHandle: string;
|
|
983
|
+
sourceUrl: string;
|
|
984
|
+
text: string;
|
|
985
|
+
textTruncated: boolean;
|
|
986
|
+
relay: string;
|
|
987
|
+
};
|
|
825
988
|
}
|
|
826
989
|
export interface NativeNostrAccount {
|
|
827
990
|
enabled: boolean;
|
|
828
991
|
identity: HostedProtocolIdentity | null;
|
|
829
|
-
capabilities: Array<'publish_original_text' | 'request_own_post_deletion' | 'reply_text_note' | 'publish_linked_text' | 'like' | 'unlike' | 'repost' | 'unrepost' | 'follow' | 'unfollow'>;
|
|
992
|
+
capabilities: Array<'publish_original_text' | 'request_own_post_deletion' | 'reply_text_note' | 'publish_linked_text' | 'quote' | 'like' | 'unlike' | 'repost' | 'unrepost' | 'follow' | 'unfollow'>;
|
|
830
993
|
signing?: 'client';
|
|
831
994
|
}
|
|
832
995
|
export interface NativeNostrPostState {
|
|
@@ -1212,12 +1375,19 @@ export interface SocialRadarCluster {
|
|
|
1212
1375
|
* or a party or politician. Hide politics (`compass: 'hide'`) leaves these out. Absent from a server before it was served.
|
|
1213
1376
|
*/
|
|
1214
1377
|
political?: boolean;
|
|
1378
|
+
/** Members per source kind, counted before the member cap: `outlet` counts articles, not outlets (use `outlets`). */
|
|
1215
1379
|
sources: Partial<Record<SocialRadarSourceKind, number>>;
|
|
1216
1380
|
corroboration: number;
|
|
1381
|
+
/** Distinct outlets per lane; from 0.7.71's servers, `outlets`' two lanes. */
|
|
1217
1382
|
laneMix: {
|
|
1218
1383
|
mainstream: number;
|
|
1219
1384
|
independent: number;
|
|
1220
1385
|
};
|
|
1386
|
+
/**
|
|
1387
|
+
* How many outlets the story's coverage holds (StoryOutlets), from the members this read serves: the number its card,
|
|
1388
|
+
* page, the News section and World Today all name. Absent from a server older than 0.7.71.
|
|
1389
|
+
*/
|
|
1390
|
+
outlets?: StoryOutlets;
|
|
1221
1391
|
velocity: {
|
|
1222
1392
|
perHour: number;
|
|
1223
1393
|
normalized: number;
|
|
@@ -1288,7 +1458,7 @@ export interface SocialRadarPosts {
|
|
|
1288
1458
|
/** A story that has left the radar, as the radar's story archive keeps it (up to 30 days after it was last on the radar). */
|
|
1289
1459
|
export interface SocialRadarStoryArchive {
|
|
1290
1460
|
/** The story as the radar last published it. Articles keep their headline and link; a post is a member by reference only (no `title`). */
|
|
1291
|
-
cluster: Pick<SocialRadarCluster, 'id' | 'label' | 'kind' | 'seed' | 'theme' | 'political' | 'sources' | 'laneMix'> & {
|
|
1461
|
+
cluster: Pick<SocialRadarCluster, 'id' | 'label' | 'kind' | 'seed' | 'theme' | 'political' | 'sources' | 'laneMix' | 'outlets'> & {
|
|
1292
1462
|
members: Array<Pick<SocialRadarMember, 'kind' | 'key' | 'url' | 'publishedAt' | 'outlet'> & {
|
|
1293
1463
|
title?: string;
|
|
1294
1464
|
}>;
|
|
@@ -1598,7 +1768,11 @@ export declare class ProtocolsResource {
|
|
|
1598
1768
|
}): Promise<SingleResponse<SocialAuthorFeed>>;
|
|
1599
1769
|
/**
|
|
1600
1770
|
* Public, app-moderated discovery without account authority. Enrichment uses cached judgments only.
|
|
1601
|
-
* Every page, previews included, gets the safety floor; `discovery` only asks for a layout.
|
|
1771
|
+
* Every page, previews included, gets the safety floor; `discovery` only asks for a layout. `compass` (0.7.72): a
|
|
1772
|
+
* visitor's Politics choice, `all` or `hide` only (a side or Mix is refused, 400 `invalid_input`). Hide politics leaves
|
|
1773
|
+
* out the topics and posts whose cached browse category is politics, for every visitor, and the page says what it did
|
|
1774
|
+
* in `meta.compass_filter` (`basis: 'flags'` until the operator serves visitors the full filter). An API older than
|
|
1775
|
+
* 0.7.72 refuses `compass` here with a 400.
|
|
1602
1776
|
*/
|
|
1603
1777
|
getSharedTrends(projectId: string, params: {
|
|
1604
1778
|
protocol: string;
|
|
@@ -1607,6 +1781,7 @@ export declare class ProtocolsResource {
|
|
|
1607
1781
|
includePreviews?: boolean;
|
|
1608
1782
|
category?: string;
|
|
1609
1783
|
discovery?: boolean;
|
|
1784
|
+
compass?: string;
|
|
1610
1785
|
}): Promise<SingleResponse<SocialTrends>>;
|
|
1611
1786
|
/** Open a provider-listed topic through the same public-only app boundary, with the same safety floor. */
|
|
1612
1787
|
getSharedTrendFeed(projectId: string, params: {
|
|
@@ -1673,7 +1848,8 @@ export declare class ProtocolsResource {
|
|
|
1673
1848
|
* Current provider-ranked topics or posts, with explicit source and coverage. Does not ingest content.
|
|
1674
1849
|
* Every page, previews included, gets the safety floor; `discovery` only asks for a layout. `compass` (a Politics
|
|
1675
1850
|
* choice, spelled as `posts.list` takes it): Hide politics (`hide`) leaves out the topics and posts whose cached
|
|
1676
|
-
* browse category is politics,
|
|
1851
|
+
* browse category is politics, for every member (from 0.7.72; before, only where the filter was served to them), with
|
|
1852
|
+
* `meta.compass_filter.basis` 'flags' where the full filter is not served; a side or Mix is answered unfiltered. The
|
|
1677
1853
|
* page then says what it did in `meta.compass_filter`.
|
|
1678
1854
|
*/
|
|
1679
1855
|
getPublicTrends(params: {
|
|
@@ -1761,7 +1937,7 @@ export declare class ProtocolsResource {
|
|
|
1761
1937
|
}): Promise<SingleResponse<NativeRepostReview>>;
|
|
1762
1938
|
/** Reconcile the saved action without sending another native write. */
|
|
1763
1939
|
nativeRepostStatus(id: string): Promise<SingleResponse<NativeRepostReview>>;
|
|
1764
|
-
/** Prepare exact public text
|
|
1940
|
+
/** Prepare exact public text, reviewed images and an optional native quote for selected connected Bluesky/ActivityPub accounts. */
|
|
1765
1941
|
prepareNativePost(input: NativePostPrepareInput): Promise<SingleResponse<NativePostBatch>>;
|
|
1766
1942
|
/** Explicitly approve selected deliveries; never auto-retry an uncertain write. */
|
|
1767
1943
|
submitNativePost(id: string, input: {
|
|
@@ -2005,6 +2181,17 @@ export declare class ProtocolsResource {
|
|
|
2005
2181
|
* project-admin authorization as listCandidates.
|
|
2006
2182
|
*/
|
|
2007
2183
|
ingestionStatus(): Promise<SingleResponse<ProtocolIngestionStatus>>;
|
|
2184
|
+
/**
|
|
2185
|
+
* Read counts-only ingestion health for the key's app: per lane, whether it
|
|
2186
|
+
* reaches done or dies part way (the open job's position, failures in a row,
|
|
2187
|
+
* starvation, last success and failure, attempts by reason, dead letters by
|
|
2188
|
+
* reason and position), plus open or counting circuits. Read-only. Needs a
|
|
2189
|
+
* project-bound admin key and current project-admin authority, but not the
|
|
2190
|
+
* content_intelligence_admin binding. Scope comes only from the key, so no
|
|
2191
|
+
* query is sent (the API rejects one). A section that does not answer in its
|
|
2192
|
+
* budget reads as null and is listed in `unavailable`.
|
|
2193
|
+
*/
|
|
2194
|
+
ingestionHealth(): Promise<SingleResponse<ProtocolIngestionHealthReport>>;
|
|
2008
2195
|
/** Turn the app's ingestion kill switch on: no reservation, screening or approval proceeds. */
|
|
2009
2196
|
killIngestion(): Promise<SingleResponse<{
|
|
2010
2197
|
kill_switch: true;
|
|
@@ -123,11 +123,15 @@ export class ProtocolsResource {
|
|
|
123
123
|
}
|
|
124
124
|
/**
|
|
125
125
|
* Public, app-moderated discovery without account authority. Enrichment uses cached judgments only.
|
|
126
|
-
* Every page, previews included, gets the safety floor; `discovery` only asks for a layout.
|
|
126
|
+
* Every page, previews included, gets the safety floor; `discovery` only asks for a layout. `compass` (0.7.72): a
|
|
127
|
+
* visitor's Politics choice, `all` or `hide` only (a side or Mix is refused, 400 `invalid_input`). Hide politics leaves
|
|
128
|
+
* out the topics and posts whose cached browse category is politics, for every visitor, and the page says what it did
|
|
129
|
+
* in `meta.compass_filter` (`basis: 'flags'` until the operator serves visitors the full filter). An API older than
|
|
130
|
+
* 0.7.72 refuses `compass` here with a 400.
|
|
127
131
|
*/
|
|
128
132
|
getSharedTrends(projectId, params) {
|
|
129
133
|
return this.client.get(`/protocols/public/${encodeURIComponent(projectId)}/trends`, { protocol: params.protocol, limit: params.limit, cursor: params.cursor,
|
|
130
|
-
includePreviews: params.includePreviews, category: params.category, discovery: params.discovery });
|
|
134
|
+
includePreviews: params.includePreviews, category: params.category, discovery: params.discovery, compass: params.compass });
|
|
131
135
|
}
|
|
132
136
|
/** Open a provider-listed topic through the same public-only app boundary, with the same safety floor. */
|
|
133
137
|
getSharedTrendFeed(projectId, params) {
|
|
@@ -207,7 +211,8 @@ export class ProtocolsResource {
|
|
|
207
211
|
* Current provider-ranked topics or posts, with explicit source and coverage. Does not ingest content.
|
|
208
212
|
* Every page, previews included, gets the safety floor; `discovery` only asks for a layout. `compass` (a Politics
|
|
209
213
|
* choice, spelled as `posts.list` takes it): Hide politics (`hide`) leaves out the topics and posts whose cached
|
|
210
|
-
* browse category is politics,
|
|
214
|
+
* browse category is politics, for every member (from 0.7.72; before, only where the filter was served to them), with
|
|
215
|
+
* `meta.compass_filter.basis` 'flags' where the full filter is not served; a side or Mix is answered unfiltered. The
|
|
211
216
|
* page then says what it did in `meta.compass_filter`.
|
|
212
217
|
*/
|
|
213
218
|
getPublicTrends(params, options) {
|
|
@@ -327,7 +332,7 @@ export class ProtocolsResource {
|
|
|
327
332
|
hostedIdentityPath(id);
|
|
328
333
|
return this.client.get(`/protocols/social/reposts/${encodeURIComponent(id)}`);
|
|
329
334
|
}
|
|
330
|
-
/** Prepare exact public text
|
|
335
|
+
/** Prepare exact public text, reviewed images and an optional native quote for selected connected Bluesky/ActivityPub accounts. */
|
|
331
336
|
prepareNativePost(input) {
|
|
332
337
|
return this.client.post('/protocols/social/posts/prepare', { clientMutationId: input.clientMutationId,
|
|
333
338
|
text: input.text, accountIds: input.accountIds,
|
|
@@ -479,7 +484,8 @@ export class ProtocolsResource {
|
|
|
479
484
|
prepareNativeNostr(id, input) {
|
|
480
485
|
hostedIdentityPath(id);
|
|
481
486
|
const body = input.action === 'publish' ? { action: input.action, content: input.content,
|
|
482
|
-
...(input.crossPostOf !== undefined ? { crossPostOf: input.crossPostOf } : {})
|
|
487
|
+
...(input.crossPostOf !== undefined ? { crossPostOf: input.crossPostOf } : {}),
|
|
488
|
+
...(input.quote ? { quote: { protocol: input.quote.protocol, nativeId: input.quote.nativeId } } : {}) }
|
|
483
489
|
: input.action === 'reply' ? { action: input.action, content: input.content, parentId: input.parentId }
|
|
484
490
|
: input.action === 'linked_post' ? { action: input.action, content: input.content,
|
|
485
491
|
source: { protocol: input.source.protocol, nativeId: input.source.nativeId,
|
|
@@ -619,6 +625,19 @@ export class ProtocolsResource {
|
|
|
619
625
|
ingestionStatus() {
|
|
620
626
|
return this.client.get('/protocols/ingestion/status');
|
|
621
627
|
}
|
|
628
|
+
/**
|
|
629
|
+
* Read counts-only ingestion health for the key's app: per lane, whether it
|
|
630
|
+
* reaches done or dies part way (the open job's position, failures in a row,
|
|
631
|
+
* starvation, last success and failure, attempts by reason, dead letters by
|
|
632
|
+
* reason and position), plus open or counting circuits. Read-only. Needs a
|
|
633
|
+
* project-bound admin key and current project-admin authority, but not the
|
|
634
|
+
* content_intelligence_admin binding. Scope comes only from the key, so no
|
|
635
|
+
* query is sent (the API rejects one). A section that does not answer in its
|
|
636
|
+
* budget reads as null and is listed in `unavailable`.
|
|
637
|
+
*/
|
|
638
|
+
ingestionHealth() {
|
|
639
|
+
return this.client.get('/protocols/ingestion/health');
|
|
640
|
+
}
|
|
622
641
|
/** Turn the app's ingestion kill switch on: no reservation, screening or approval proceeds. */
|
|
623
642
|
killIngestion() {
|
|
624
643
|
return this.client.post('/protocols/ingestion/kill', {});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { HttpClient } from '../client.js';
|
|
2
|
-
import type { Post, ViewerModeration } from '../types.js';
|
|
2
|
+
import type { Post, StoryOutlets, ViewerModeration } from '../types.js';
|
|
3
3
|
import type { SocialPost } from './protocols.js';
|
|
4
4
|
/** The sections a blended search can answer, in no particular order (see `SearchAnswer.order`). */
|
|
5
5
|
export declare const SEARCH_SECTIONS: readonly ["top_posts", "latest_posts", "open_network", "people", "groups", "topics", "stories", "related", "trending"];
|
|
@@ -52,6 +52,12 @@ export interface SearchGroup {
|
|
|
52
52
|
member_count: number;
|
|
53
53
|
post_count: number;
|
|
54
54
|
is_member: boolean;
|
|
55
|
+
/** The group's description as one line (legacy entities decoded, cut at a word with an ellipsis), null when it has none. Absent from an older API. */
|
|
56
|
+
description?: string | null;
|
|
57
|
+
/** When the group was last posted in (ISO 8601), null when nobody has or the API had no time to read it. Absent from an older API. */
|
|
58
|
+
last_active_at?: string | null;
|
|
59
|
+
/** The group's own words label it adult: cover its avatar. Absent from an older API. */
|
|
60
|
+
is_nsfw?: boolean;
|
|
55
61
|
}
|
|
56
62
|
export type SearchTopic = {
|
|
57
63
|
kind: 'tag';
|
|
@@ -71,6 +77,8 @@ export interface SearchStory {
|
|
|
71
77
|
theme: string | null;
|
|
72
78
|
newest_at: string;
|
|
73
79
|
sources: Partial<Record<'outlet' | 'hackernews' | 'bluesky' | 'activitypub' | 'nostr' | 'minds', number>>;
|
|
80
|
+
/** How many outlets reported it (StoryOutlets): the number every surface names for the story. Absent from a server older than 0.7.71. */
|
|
81
|
+
outlets?: StoryOutlets;
|
|
74
82
|
lead: {
|
|
75
83
|
type: 'image' | 'video';
|
|
76
84
|
url: string;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { HttpClient } from '../client.js';
|
|
2
|
-
import type { ChangePasswordInput, ConfirmationCodePurpose, ConfirmationCodeSent, DeletionStatus, LoginHistoryEntry, PaginatedResponse, RequestEmailChangeInput, RevokeOtherSessionsInput, RevokeOtherSessionsResult, Session, SingleResponse, SuccessResponse, UpdateAppearanceInput, UpdateContentPreferencesInput, UpdateNotificationChannelsInput, UpdatePrivacyInput, UserPreferences } from '../types.js';
|
|
2
|
+
import type { ChangePasswordInput, ConfirmationCodePurpose, ConfirmationCodeSent, DeletionStatus, DisableAccountInput, LoginHistoryEntry, PaginatedResponse, RequestEmailChangeInput, RevokeOtherSessionsInput, RevokeOtherSessionsResult, Session, SingleResponse, SuccessResponse, UpdateAppearanceInput, UpdateContentPreferencesInput, UpdateNotificationChannelsInput, UpdatePrivacyInput, UserPreferences } from '../types.js';
|
|
3
3
|
export declare class SettingsResource {
|
|
4
4
|
private client;
|
|
5
5
|
constructor(client: HttpClient);
|
|
@@ -66,6 +66,13 @@ export declare class SettingsResource {
|
|
|
66
66
|
success: true;
|
|
67
67
|
new_email: string;
|
|
68
68
|
}>>;
|
|
69
|
+
/**
|
|
70
|
+
* Deactivate the account (POST /settings/account/disable): it is hidden and nothing is deleted; signing back in
|
|
71
|
+
* restores it. Confirmed with the password and asked once (`retry: false`), so a retried 5xx never lands after the
|
|
72
|
+
* first attempt already went through. An API that does not serve deactivation answers 404 (`NotFoundError`): keep
|
|
73
|
+
* the control hidden until the app's API serves it.
|
|
74
|
+
*/
|
|
75
|
+
disableAccount(input: DisableAccountInput): Promise<SuccessResponse>;
|
|
69
76
|
/** Request account deletion */
|
|
70
77
|
requestDeletion(input?: {
|
|
71
78
|
password?: string;
|
|
@@ -102,6 +102,15 @@ export class SettingsResource {
|
|
|
102
102
|
verifyEmailChange(token) {
|
|
103
103
|
return this.client.post('/settings/email-change/verify', { token });
|
|
104
104
|
}
|
|
105
|
+
/**
|
|
106
|
+
* Deactivate the account (POST /settings/account/disable): it is hidden and nothing is deleted; signing back in
|
|
107
|
+
* restores it. Confirmed with the password and asked once (`retry: false`), so a retried 5xx never lands after the
|
|
108
|
+
* first attempt already went through. An API that does not serve deactivation answers 404 (`NotFoundError`): keep
|
|
109
|
+
* the control hidden until the app's API serves it.
|
|
110
|
+
*/
|
|
111
|
+
disableAccount(input) {
|
|
112
|
+
return this.client.post('/settings/account/disable', input, { retry: false });
|
|
113
|
+
}
|
|
105
114
|
/** Request account deletion */
|
|
106
115
|
requestDeletion(input) {
|
|
107
116
|
return this.client.post('/settings/delete-account', input);
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { HttpClient } from '../client.js';
|
|
2
|
+
import type { SingleResponse } from '../types.js';
|
|
3
|
+
/**
|
|
4
|
+
* What a member did with a post. `more_like` ("More like this") and `unhide` ("Show the post again" after "Less like
|
|
5
|
+
* this") are stored as marked clicks; an API before they were accepted answers 400 for the whole batch that carries
|
|
6
|
+
* one, so send them in a request of their own if the API may be older.
|
|
7
|
+
*/
|
|
8
|
+
export type SignalEventType = 'view' | 'click' | 'dwell' | 'react_up' | 'react_down' | 'save' | 'hide' | 'share' | 'mute_source' | 'open_chat' | 'ask_agent' | 'more_like' | 'unhide';
|
|
9
|
+
/** One engagement signal. An open-network post has no Minds id: name it in `metadata` (e.g. `{ ref }`) instead. */
|
|
10
|
+
export interface SignalEventInput {
|
|
11
|
+
event_type: SignalEventType;
|
|
12
|
+
/** The Minds post's id (a UUID). */
|
|
13
|
+
post_id?: string;
|
|
14
|
+
/** Milliseconds on screen, for `dwell` (0 to one hour). */
|
|
15
|
+
dwell_ms?: number;
|
|
16
|
+
metadata?: Record<string, unknown>;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Why nothing was stored, on a 200: `no_project_scope` (the key is not bound to an app, so there is no app database
|
|
20
|
+
* for the signal) or `project_db_unavailable` (the app database did not take it; signals are best-effort).
|
|
21
|
+
*/
|
|
22
|
+
export type SignalNotRecordedReason = 'no_project_scope' | 'project_db_unavailable';
|
|
23
|
+
export interface SignalBatchResult {
|
|
24
|
+
/** Events stored. */
|
|
25
|
+
recorded: number;
|
|
26
|
+
reason?: SignalNotRecordedReason;
|
|
27
|
+
}
|
|
28
|
+
export interface SignalRecordResult {
|
|
29
|
+
recorded: boolean;
|
|
30
|
+
reason?: SignalNotRecordedReason;
|
|
31
|
+
}
|
|
32
|
+
export interface SignalSendOptions {
|
|
33
|
+
/**
|
|
34
|
+
* The request outlives the page (`fetch` keepalive), for a flush as the page is hidden or unloads: it is on the wire
|
|
35
|
+
* before the call returns and is asked once. Browsers cap keepalive bodies (about 64 KB in flight).
|
|
36
|
+
*/
|
|
37
|
+
keepalive?: boolean;
|
|
38
|
+
/** `false` asks once: a 429 or 5xx is the call's failure at once, not retried after Retry-After. */
|
|
39
|
+
retry?: boolean;
|
|
40
|
+
}
|
|
41
|
+
/** The most events one `signals.batch` call may carry; the server answers 400 for a larger array. */
|
|
42
|
+
export declare const SIGNAL_BATCH_MAX = 100;
|
|
43
|
+
/**
|
|
44
|
+
* Engagement signals (views, dwell, hides, "More like this") for the member's own ranking, under the member's
|
|
45
|
+
* app-bound key (`agents:write`). They land in the app's database and feed For You. Best-effort: a signal the server
|
|
46
|
+
* cannot store still answers 200 with `recorded` 0 or false and a `reason`.
|
|
47
|
+
*/
|
|
48
|
+
export declare class SignalsResource {
|
|
49
|
+
private client;
|
|
50
|
+
constructor(client: HttpClient);
|
|
51
|
+
/**
|
|
52
|
+
* Store up to SIGNAL_BATCH_MAX events in one request (POST /signals/batch). The server reads a post's newest hide or
|
|
53
|
+
* unhide, so send a batch only after the one before it has landed when order matters. An empty array stores nothing.
|
|
54
|
+
*/
|
|
55
|
+
batch(events: SignalEventInput[], options?: SignalSendOptions): Promise<SingleResponse<SignalBatchResult>>;
|
|
56
|
+
/** Store one event (POST /signals/post). Prefer `batch`; this is for an API that predates it (404 there). */
|
|
57
|
+
record(event: SignalEventInput, options?: SignalSendOptions): Promise<SingleResponse<SignalRecordResult>>;
|
|
58
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/** The most events one `signals.batch` call may carry; the server answers 400 for a larger array. */
|
|
2
|
+
export const SIGNAL_BATCH_MAX = 100;
|
|
3
|
+
/**
|
|
4
|
+
* Engagement signals (views, dwell, hides, "More like this") for the member's own ranking, under the member's
|
|
5
|
+
* app-bound key (`agents:write`). They land in the app's database and feed For You. Best-effort: a signal the server
|
|
6
|
+
* cannot store still answers 200 with `recorded` 0 or false and a `reason`.
|
|
7
|
+
*/
|
|
8
|
+
export class SignalsResource {
|
|
9
|
+
client;
|
|
10
|
+
constructor(client) {
|
|
11
|
+
this.client = client;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Store up to SIGNAL_BATCH_MAX events in one request (POST /signals/batch). The server reads a post's newest hide or
|
|
15
|
+
* unhide, so send a batch only after the one before it has landed when order matters. An empty array stores nothing.
|
|
16
|
+
*/
|
|
17
|
+
batch(events, options) {
|
|
18
|
+
return this.client.post('/signals/batch', { events }, sendOptions(options));
|
|
19
|
+
}
|
|
20
|
+
/** Store one event (POST /signals/post). Prefer `batch`; this is for an API that predates it (404 there). */
|
|
21
|
+
record(event, options) {
|
|
22
|
+
return this.client.post('/signals/post', event, sendOptions(options));
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
function sendOptions(options) {
|
|
26
|
+
if (!options)
|
|
27
|
+
return undefined;
|
|
28
|
+
return {
|
|
29
|
+
...(options.retry === false ? { retry: false } : {}),
|
|
30
|
+
...(options.keepalive ? { keepalive: true } : {}),
|
|
31
|
+
};
|
|
32
|
+
}
|