@ai-matrx/agents 0.18.1 → 0.19.1

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.
@@ -60,6 +60,14 @@ interface SourceDraft {
60
60
  notes?: string[] | undefined;
61
61
  /** The person asked to wait for the clean version before anything runs. */
62
62
  waitForClean?: boolean | undefined;
63
+ /**
64
+ * Where the picked parts sit in the Source (label + pages), remembered when
65
+ * they are picked. A Source still being cleaned lists its raw pages; when the
66
+ * clean version lands its parts have NEW ids, and the pick is carried over by
67
+ * page from here (verify-3: "0 characters · 4 of 21 parts"). Persisted with
68
+ * the draft, so it survives a reload.
69
+ */
70
+ pickedParts?: SourcePickedPart[] | undefined;
63
71
  /**
64
72
  * What the person handed over, kept ONLY while the Source is still landing
65
73
  * (or failed) so a reload or a failure never loses it: the pasted text, the
@@ -68,6 +76,13 @@ interface SourceDraft {
68
76
  */
69
77
  input?: SourceIntakeInput | undefined;
70
78
  }
79
+ /** One picked part as the person saw it: its id, its label, and the pages it covers. */
80
+ interface SourcePickedPart {
81
+ id: string;
82
+ label: string;
83
+ /** First and last page it covers, when the Source has pages. */
84
+ pages?: [number, number] | undefined;
85
+ }
71
86
  type SourceCardStatus = "pending" | "resolving" | "ready" | "error";
72
87
  /** One card: the draft, its lifecycle, and what the server measured. */
73
88
  interface SourceCardModel {
@@ -131,7 +146,7 @@ declare function deliveryPatch(delivery: SourceDelivery): Pick<SourceRefOptions,
131
146
  interface DeliveryWords {
132
147
  /** The choice's name on a control. */
133
148
  label: string;
134
- /** One sentence under the control: what happens, in plain words. */
149
+ /** Two or three words under the control: what happens (copy law R9). */
135
150
  hint: string;
136
151
  /** The short phrase a summary line uses. */
137
152
  summary: string;
@@ -241,7 +256,7 @@ declare const MAX_KEPT_TEXT_KNOB: {
241
256
  readonly key: "max_kept_draft_chars";
242
257
  };
243
258
  /** Said on a pasted card whose text is too large (or the limit unreadable) to keep for a reload. */
244
- declare const NOT_KEPT_FOR_RELOAD = "Too large to keep on this device, so it will not come back if the page reloads before it is added.";
259
+ declare const NOT_KEPT_FOR_RELOAD = "Too large to restore if the page reloads before it is added.";
245
260
  /**
246
261
  * A landing stopped only because no organization is chosen yet. The card
247
262
  * waits; the moment one is set the intake lands every waiting card again from
@@ -356,7 +371,13 @@ interface SourcePlanEntry {
356
371
  formLabel: string;
357
372
  /** Characters of the chosen form before parts/cap. */
358
373
  formChars: number;
359
- /** Characters the model receives for this Source (grounding headers included). */
374
+ /**
375
+ * THE one size of this Source — the same number its card and the header show
376
+ * (`sourceEntryChars`: the chosen form or picked parts, capped). What a person
377
+ * sees; `sentChars` is only the budget's exact wire length.
378
+ */
379
+ chars: number;
380
+ /** Characters the model receives for this Source (grounding headers included) — the budget's measure. */
360
381
  sentChars: number;
361
382
  sentTokens: number;
362
383
  /** True when parts are known, so `sentChars` is exact; false = the text body only. */
@@ -370,6 +391,9 @@ interface SourcePlanEntry {
370
391
  type BudgetVerdict = "empty" | "fine" | "heavy" | "too_much";
371
392
  interface SourcePlan {
372
393
  entries: SourcePlanEntry[];
394
+ /** THE one size of what goes in (sum of `chars` of the Sources whose text goes in) — shown to the person. */
395
+ chars: number;
396
+ /** The exact wire length the budget is judged on (grounding headers included). */
373
397
  sentChars: number;
374
398
  sentTokens: number;
375
399
  /** Window the verdict is judged against. */
@@ -512,6 +536,10 @@ declare function createFetchSourcesTransport(options: FetchSourcesTransportOptio
512
536
  */
513
537
 
514
538
  declare const EMPTY_SOURCE_SET_STATE: SourceSetState;
539
+ /** Said when a Source's parts were re-read (the clean version landed) and the pick was carried over by page. */
540
+ declare const PARTS_MATCHED_BY_PAGE = "The clean version is ready \u2014 your parts were matched to it by page.";
541
+ /** Said when a pick could not be carried over to the Source's new parts: the whole Source goes in until parts are chosen again. */
542
+ declare const PARTS_NOT_MATCHED = "The clean version is ready, but your parts could not be matched to it \u2014 choose parts again. Until then the whole Source goes in.";
515
543
  /** Said on the one card kept when the same Source lands twice. */
516
544
  declare const SAME_SOURCE_AGAIN = "You added this again \u2014 it is the same Source, so it is listed once.";
517
545
  declare function isSourceDraft(value: unknown): value is SourceDraft;
@@ -540,6 +568,10 @@ declare function settleCard(state: SourceSetState, id: string, patch: Partial<So
540
568
  }, options?: {
541
569
  defaultForm?: string | undefined;
542
570
  }): SourceSetState;
571
+ /**
572
+ * A card that failed has ONE state — failed. Its last measurement goes, so it
573
+ * can never also say "Still being read" (verify-3: a stored PDF showed both).
574
+ */
543
575
  declare function failCard(state: SourceSetState, id: string, sentence: string): SourceSetState;
544
576
  /** Back to landing (after a reload or a failure). */
545
577
  declare function restartCard(state: SourceSetState, id: string): SourceSetState;
@@ -548,10 +580,35 @@ declare function updateCardDraft(state: SourceSetState, id: string, patch: Parti
548
580
  declare function removeCard(state: SourceSetState, id: string): SourceSetState;
549
581
  /** Change the pointer's choices (form, parts, cap, delivery). */
550
582
  declare function updateCardRef(state: SourceSetState, id: string, options: SourceRefOptions): SourceSetState;
583
+ /**
584
+ * Remember where the picked parts sit (label + pages) from the card's current
585
+ * measurement, so a pick survives the Source being re-split (raw pages → clean
586
+ * parts). No parts picked = nothing remembered.
587
+ */
588
+ declare function rememberPickedParts(card: SourceCardModel): SourceCardModel;
589
+ /**
590
+ * A fresh measurement listed NEW parts (the clean version landed, so the raw
591
+ * pages the person picked no longer exist by id). Carry the pick over by page:
592
+ * every new part that covers a page the old pick covered goes in. When the old
593
+ * pick's pages are unknown, the pick is cleared and the card says so — never
594
+ * "0 characters · 4 of 21 parts" with nothing ticked (verify-3, 11d/11e).
595
+ */
596
+ declare function carryPickedParts(card: SourceCardModel, entry: SourceManifestEntry): SourceCardModel;
551
597
  declare function setCardWaitForClean(state: SourceSetState, id: string, wait: boolean): SourceSetState;
552
598
  declare function setSourceTopic(state: SourceSetState, topic: string): SourceSetState;
553
- /** Apply a set the review returned (forms, parts, caps, delivery) — and its topic. */
554
- declare function applyReviewedSourceSet(state: SourceSetState, set: SourceSet): SourceSetState;
599
+ /**
600
+ * What the person removed in "Review what goes in": the Sources that went INTO
601
+ * the review (`reviewed`) and did not come back in its answer — keyed by
602
+ * `sourceKey`. A Source that landed while the review was open is never in
603
+ * `reviewed`, so it is never removed by it (verify-4 V4-F #3).
604
+ */
605
+ declare function removedInReview(reviewed: SourceSet, answer: SourceSet): Set<string>;
606
+ /**
607
+ * Apply a set the review returned (forms, parts, caps, delivery) — and its
608
+ * topic. Pass `reviewed` (the set that was sent INTO the review) and every
609
+ * Source removed there leaves the list, bound by its own card id.
610
+ */
611
+ declare function applyReviewedSourceSet(state: SourceSetState, set: SourceSet, reviewed?: SourceSet): SourceSetState;
555
612
  /** The server measured the ready Sources: each ready card takes its entry. */
556
613
  declare function applyManifest(state: SourceSetState, manifest: SourceManifest): SourceSetState;
557
614
  /**
@@ -581,6 +638,24 @@ declare function selectSourceSet(state: SourceSetState, options?: {
581
638
  * picked parts, capped — measured against each card's CURRENT pointer.
582
639
  */
583
640
  declare function selectTotalChars(state: SourceSetState): number;
641
+ /**
642
+ * THE one size of one Source (verify-3: one Source read 109k, 115k, 108k and
643
+ * 106k on four screens): the contract's rule — the chosen form, or the picked
644
+ * parts, capped by `max_chars` — measured against the card's CURRENT pointer.
645
+ * The card, the header total (`selectTotalChars`) and the review (`SourcePlanEntry.chars`)
646
+ * all read this. Null when it is not measured or cannot go in.
647
+ */
648
+ declare function sourceEntryChars(entry: SourceManifestEntry, ref: SourceRef): number | null;
649
+ declare function sourceCardChars(card: Pick<SourceCardModel, "draft" | "manifest">): number | null;
650
+ /**
651
+ * THE one state of one Source card, derived once: its own lifecycle wins
652
+ * (adding, waiting for an organization, failed); only a card that landed takes
653
+ * the server's measured state. Never two states at once.
654
+ */
655
+ type SourceCardState = "adding" | "waiting_for_organization" | "failed" | "unmeasured" | SourceManifestEntry["state"];
656
+ declare function sourceCardState(card: Pick<SourceCardModel, "status" | "error" | "manifest">): SourceCardState;
657
+ /** The server's measured state to show on a card — only for a card that landed (null otherwise). */
658
+ declare function sourceCardMeasuredState(card: Pick<SourceCardModel, "status" | "error" | "manifest">): SourceManifestEntry["state"] | null;
584
659
  /** Every Source finished landing (nothing pending) and none failed. */
585
660
  declare function selectSettled(state: SourceSetState): boolean;
586
661
  /** How many more Sources fit under the host's max (Infinity when there is none). */
@@ -690,8 +765,14 @@ interface SourceSetController extends SourceSetActions {
690
765
  toSourceSet(options?: {
691
766
  targetModelId?: string | undefined;
692
767
  }): SourceSet;
693
- /** Apply a set the review returned (forms, parts, caps, delivery). */
694
- applySourceSet(set: SourceSet): void;
768
+ /**
769
+ * Apply a set the review returned (forms, parts, caps, delivery). Pass
770
+ * `reviewed` — the set sent INTO the review — and every Source removed there
771
+ * leaves the list too (only those; one that landed meanwhile stays).
772
+ */
773
+ applySourceSet(set: SourceSet, options?: {
774
+ reviewed?: SourceSet | undefined;
775
+ }): void;
695
776
  /** POST /sources/resolve — the grounded text for a generator, named as the cards name them. */
696
777
  resolve(options?: {
697
778
  targetModelId?: string | undefined;
@@ -856,15 +937,33 @@ interface SourceIntakeDeps<Body extends SourceLandingBodyBase = SourceLandingBod
856
937
  interface SourceIntake {
857
938
  addPastedText(text: string, name?: string): Promise<void>;
858
939
  addWebPage(url: string): Promise<void>;
859
- /** A page the host's web picker already read (and the scraper landed); null id = land its text instead. */
940
+ /**
941
+ * A page the host's web picker already read (and the scraper landed); null id
942
+ * = land its text instead. `pendingId` = the card `beginWebPage` made when the
943
+ * read started — it is settled instead of a new card being added.
944
+ */
860
945
  addScrapedPage(page: {
861
946
  url: string;
862
947
  title: string;
863
948
  text: string;
864
949
  processedDocumentId: string | null;
865
- }): Promise<void>;
950
+ }, pendingId?: string | null): Promise<void>;
951
+ /**
952
+ * The host's web picker STARTED reading a link: a card with the link kept
953
+ * appears at once, so a reload mid-read brings it back and lands it (verify-3
954
+ * 12a/12b: a reload while a page was read lost it, link and all). Finish it
955
+ * with `addScrapedPage(page, id)`; if the person drops the preview, remove it;
956
+ * if the picker goes away mid-read, `resume(card)` lands it through the web door.
957
+ */
958
+ beginWebPage(url: string): string;
866
959
  /** Files the host's uploader already uploaded. */
867
960
  addUploaded(files: readonly UploadedSourceFile[], kind: SourceKindId): Promise<void>;
961
+ /**
962
+ * A recording made in place (the Voice Pad) that is already written out: it
963
+ * lands as text, but it IS a recording — its card and review say "Recording",
964
+ * never "Pasted text" — and it keeps its name ("Recording 3:41 PM").
965
+ */
966
+ addRecordedText(text: string, name?: string): Promise<void>;
868
967
  /** A recording already uploaded — written out, then landed. */
869
968
  addUploadedRecording(file: UploadedSourceFile): Promise<void>;
870
969
  /** Something the person already has (Use existing / search). Returns false when already picked. */
@@ -956,4 +1055,4 @@ declare function lookAtFileCards(cards: readonly SourceCardModel[], ctx: {
956
1055
  signal: AbortSignal;
957
1056
  } & FileRecoveryDeps): Promise<boolean>;
958
1057
 
959
- export { type BudgetVerdict, DELIVERY_CHOICES, DELIVERY_WORDS, type DeliveryWords, EMPTY_SOURCE_SET_STATE, type FetchSourcesTransportOptions, type FileRecoveryDeps, type FileSourceContext, type FileSourceStatus, type FileSourceStep, HEAVY_SHARE, KEEP_WAITING_FOR_ORGANIZATION, MAX_KEPT_TEXT_KNOB, NOT_KEPT_FOR_RELOAD, type PartMatchIds, type PersistedSourceCard, type PersistedSourceInput, type PlanInput, RELOADED_RESUMING, RELOADED_WHILE_ADDING, type ReloadedCard, SAME_SOURCE_AGAIN, SOURCE_CHARS_PER_TOKEN, type ScrapedSourcePage, type SourceAssociationEdge, type SourceAssociationResult, type SourceAttachTarget, type SourceAttachTo, type SourceCallOptions, type SourceCardModel, type SourceCardStatus, SourceDelivery, type SourceDoorCalls, SourceDoorError, type SourceDoorPath, type SourceDraft, type SourceDraftStorage, type SourceFileRunner, type SourceIntake, type SourceIntakeDeps, type SourceIntakeDoors, type SourceIntakeInput, type SourceKindId, type SourceLandingAnswer, type SourceLandingBodyBase, type SourceLandingNotice, type SourcePart, type SourcePartsSearchResult, type SourcePlan, type SourcePlanEntry, type SourcePlanStatus, type SourceSetActions, type SourceSetAdapter, type SourceSetConfig, type SourceSetController, type SourceSetMeta, type SourceSetState, type SourceSetStore, type SourceTileId, type SourceTransportOptions, type SourcesClient, type SourcesTransport, type UploadedSourceFile, WAITING_FOR_ORGANIZATION, type YouTubeTranscriptResult, addPendingCard, addReadyCard, allowedDeliveries, applyManifest, applyReviewedSourceSet, cardsToResume, cardsWaitingForOrganization, chosenForm, continueAfterOrganization, createFetchSourcesTransport, createMemorySourceDraftStorage, createMemorySourceSetStore, createSourceIntake, createSourceSetController, createSourcesClient, deliveryChoicesFor, deliveryPatch, deliverySwitchedNote, draftKindForToken, estimateSourceTokens, failCard, fileCardHeldForOrganization, fileSourcePollDelayMs, findParts, fitCardDeliveries, fitDelivery, hasSourceRef, isAskableFileCard, isSourceDraft, isWaitingFileCard, isWordQuery, lookAtFileCards, matchesPart, nextFileStep, partPages, planSourceReview, readPersistedSourceInput, readySourceRefs, registeredFileEdge, reloadedCard, removeCard, renderedPartChars, restartCard, restoredCards, resumableInput, resumeInterrupted, sameSourceRef, selectSettled, selectSourceSet, selectTotalChars, setCardWaitForClean, setSourceTopic, settleCard, sourceAttachTargets, sourceDelivery, sourceKey, sourceRecoveryGuards, sourceRoomLeft, toPersistedSourceInput, updateCardDraft, updateCardRef, uploadCutOffSentence, withDefaultForm, withDisplayNames };
1058
+ export { type BudgetVerdict, DELIVERY_CHOICES, DELIVERY_WORDS, type DeliveryWords, EMPTY_SOURCE_SET_STATE, type FetchSourcesTransportOptions, type FileRecoveryDeps, type FileSourceContext, type FileSourceStatus, type FileSourceStep, HEAVY_SHARE, KEEP_WAITING_FOR_ORGANIZATION, MAX_KEPT_TEXT_KNOB, NOT_KEPT_FOR_RELOAD, PARTS_MATCHED_BY_PAGE, PARTS_NOT_MATCHED, type PartMatchIds, type PersistedSourceCard, type PersistedSourceInput, type PlanInput, RELOADED_RESUMING, RELOADED_WHILE_ADDING, type ReloadedCard, SAME_SOURCE_AGAIN, SOURCE_CHARS_PER_TOKEN, type ScrapedSourcePage, type SourceAssociationEdge, type SourceAssociationResult, type SourceAttachTarget, type SourceAttachTo, type SourceCallOptions, type SourceCardModel, type SourceCardState, type SourceCardStatus, SourceDelivery, type SourceDoorCalls, SourceDoorError, type SourceDoorPath, type SourceDraft, type SourceDraftStorage, type SourceFileRunner, type SourceIntake, type SourceIntakeDeps, type SourceIntakeDoors, type SourceIntakeInput, type SourceKindId, type SourceLandingAnswer, type SourceLandingBodyBase, type SourceLandingNotice, type SourcePart, type SourcePartsSearchResult, type SourcePickedPart, type SourcePlan, type SourcePlanEntry, type SourcePlanStatus, type SourceSetActions, type SourceSetAdapter, type SourceSetConfig, type SourceSetController, type SourceSetMeta, type SourceSetState, type SourceSetStore, type SourceTileId, type SourceTransportOptions, type SourcesClient, type SourcesTransport, type UploadedSourceFile, WAITING_FOR_ORGANIZATION, type YouTubeTranscriptResult, addPendingCard, addReadyCard, allowedDeliveries, applyManifest, applyReviewedSourceSet, cardsToResume, cardsWaitingForOrganization, carryPickedParts, chosenForm, continueAfterOrganization, createFetchSourcesTransport, createMemorySourceDraftStorage, createMemorySourceSetStore, createSourceIntake, createSourceSetController, createSourcesClient, deliveryChoicesFor, deliveryPatch, deliverySwitchedNote, draftKindForToken, estimateSourceTokens, failCard, fileCardHeldForOrganization, fileSourcePollDelayMs, findParts, fitCardDeliveries, fitDelivery, hasSourceRef, isAskableFileCard, isSourceDraft, isWaitingFileCard, isWordQuery, lookAtFileCards, matchesPart, nextFileStep, partPages, planSourceReview, readPersistedSourceInput, readySourceRefs, registeredFileEdge, reloadedCard, rememberPickedParts, removeCard, removedInReview, renderedPartChars, restartCard, restoredCards, resumableInput, resumeInterrupted, sameSourceRef, selectSettled, selectSourceSet, selectTotalChars, setCardWaitForClean, setSourceTopic, settleCard, sourceAttachTargets, sourceCardChars, sourceCardMeasuredState, sourceCardState, sourceDelivery, sourceEntryChars, sourceKey, sourceRecoveryGuards, sourceRoomLeft, toPersistedSourceInput, updateCardDraft, updateCardRef, uploadCutOffSentence, withDefaultForm, withDisplayNames };
@@ -60,6 +60,14 @@ interface SourceDraft {
60
60
  notes?: string[] | undefined;
61
61
  /** The person asked to wait for the clean version before anything runs. */
62
62
  waitForClean?: boolean | undefined;
63
+ /**
64
+ * Where the picked parts sit in the Source (label + pages), remembered when
65
+ * they are picked. A Source still being cleaned lists its raw pages; when the
66
+ * clean version lands its parts have NEW ids, and the pick is carried over by
67
+ * page from here (verify-3: "0 characters · 4 of 21 parts"). Persisted with
68
+ * the draft, so it survives a reload.
69
+ */
70
+ pickedParts?: SourcePickedPart[] | undefined;
63
71
  /**
64
72
  * What the person handed over, kept ONLY while the Source is still landing
65
73
  * (or failed) so a reload or a failure never loses it: the pasted text, the
@@ -68,6 +76,13 @@ interface SourceDraft {
68
76
  */
69
77
  input?: SourceIntakeInput | undefined;
70
78
  }
79
+ /** One picked part as the person saw it: its id, its label, and the pages it covers. */
80
+ interface SourcePickedPart {
81
+ id: string;
82
+ label: string;
83
+ /** First and last page it covers, when the Source has pages. */
84
+ pages?: [number, number] | undefined;
85
+ }
71
86
  type SourceCardStatus = "pending" | "resolving" | "ready" | "error";
72
87
  /** One card: the draft, its lifecycle, and what the server measured. */
73
88
  interface SourceCardModel {
@@ -131,7 +146,7 @@ declare function deliveryPatch(delivery: SourceDelivery): Pick<SourceRefOptions,
131
146
  interface DeliveryWords {
132
147
  /** The choice's name on a control. */
133
148
  label: string;
134
- /** One sentence under the control: what happens, in plain words. */
149
+ /** Two or three words under the control: what happens (copy law R9). */
135
150
  hint: string;
136
151
  /** The short phrase a summary line uses. */
137
152
  summary: string;
@@ -241,7 +256,7 @@ declare const MAX_KEPT_TEXT_KNOB: {
241
256
  readonly key: "max_kept_draft_chars";
242
257
  };
243
258
  /** Said on a pasted card whose text is too large (or the limit unreadable) to keep for a reload. */
244
- declare const NOT_KEPT_FOR_RELOAD = "Too large to keep on this device, so it will not come back if the page reloads before it is added.";
259
+ declare const NOT_KEPT_FOR_RELOAD = "Too large to restore if the page reloads before it is added.";
245
260
  /**
246
261
  * A landing stopped only because no organization is chosen yet. The card
247
262
  * waits; the moment one is set the intake lands every waiting card again from
@@ -356,7 +371,13 @@ interface SourcePlanEntry {
356
371
  formLabel: string;
357
372
  /** Characters of the chosen form before parts/cap. */
358
373
  formChars: number;
359
- /** Characters the model receives for this Source (grounding headers included). */
374
+ /**
375
+ * THE one size of this Source — the same number its card and the header show
376
+ * (`sourceEntryChars`: the chosen form or picked parts, capped). What a person
377
+ * sees; `sentChars` is only the budget's exact wire length.
378
+ */
379
+ chars: number;
380
+ /** Characters the model receives for this Source (grounding headers included) — the budget's measure. */
360
381
  sentChars: number;
361
382
  sentTokens: number;
362
383
  /** True when parts are known, so `sentChars` is exact; false = the text body only. */
@@ -370,6 +391,9 @@ interface SourcePlanEntry {
370
391
  type BudgetVerdict = "empty" | "fine" | "heavy" | "too_much";
371
392
  interface SourcePlan {
372
393
  entries: SourcePlanEntry[];
394
+ /** THE one size of what goes in (sum of `chars` of the Sources whose text goes in) — shown to the person. */
395
+ chars: number;
396
+ /** The exact wire length the budget is judged on (grounding headers included). */
373
397
  sentChars: number;
374
398
  sentTokens: number;
375
399
  /** Window the verdict is judged against. */
@@ -512,6 +536,10 @@ declare function createFetchSourcesTransport(options: FetchSourcesTransportOptio
512
536
  */
513
537
 
514
538
  declare const EMPTY_SOURCE_SET_STATE: SourceSetState;
539
+ /** Said when a Source's parts were re-read (the clean version landed) and the pick was carried over by page. */
540
+ declare const PARTS_MATCHED_BY_PAGE = "The clean version is ready \u2014 your parts were matched to it by page.";
541
+ /** Said when a pick could not be carried over to the Source's new parts: the whole Source goes in until parts are chosen again. */
542
+ declare const PARTS_NOT_MATCHED = "The clean version is ready, but your parts could not be matched to it \u2014 choose parts again. Until then the whole Source goes in.";
515
543
  /** Said on the one card kept when the same Source lands twice. */
516
544
  declare const SAME_SOURCE_AGAIN = "You added this again \u2014 it is the same Source, so it is listed once.";
517
545
  declare function isSourceDraft(value: unknown): value is SourceDraft;
@@ -540,6 +568,10 @@ declare function settleCard(state: SourceSetState, id: string, patch: Partial<So
540
568
  }, options?: {
541
569
  defaultForm?: string | undefined;
542
570
  }): SourceSetState;
571
+ /**
572
+ * A card that failed has ONE state — failed. Its last measurement goes, so it
573
+ * can never also say "Still being read" (verify-3: a stored PDF showed both).
574
+ */
543
575
  declare function failCard(state: SourceSetState, id: string, sentence: string): SourceSetState;
544
576
  /** Back to landing (after a reload or a failure). */
545
577
  declare function restartCard(state: SourceSetState, id: string): SourceSetState;
@@ -548,10 +580,35 @@ declare function updateCardDraft(state: SourceSetState, id: string, patch: Parti
548
580
  declare function removeCard(state: SourceSetState, id: string): SourceSetState;
549
581
  /** Change the pointer's choices (form, parts, cap, delivery). */
550
582
  declare function updateCardRef(state: SourceSetState, id: string, options: SourceRefOptions): SourceSetState;
583
+ /**
584
+ * Remember where the picked parts sit (label + pages) from the card's current
585
+ * measurement, so a pick survives the Source being re-split (raw pages → clean
586
+ * parts). No parts picked = nothing remembered.
587
+ */
588
+ declare function rememberPickedParts(card: SourceCardModel): SourceCardModel;
589
+ /**
590
+ * A fresh measurement listed NEW parts (the clean version landed, so the raw
591
+ * pages the person picked no longer exist by id). Carry the pick over by page:
592
+ * every new part that covers a page the old pick covered goes in. When the old
593
+ * pick's pages are unknown, the pick is cleared and the card says so — never
594
+ * "0 characters · 4 of 21 parts" with nothing ticked (verify-3, 11d/11e).
595
+ */
596
+ declare function carryPickedParts(card: SourceCardModel, entry: SourceManifestEntry): SourceCardModel;
551
597
  declare function setCardWaitForClean(state: SourceSetState, id: string, wait: boolean): SourceSetState;
552
598
  declare function setSourceTopic(state: SourceSetState, topic: string): SourceSetState;
553
- /** Apply a set the review returned (forms, parts, caps, delivery) — and its topic. */
554
- declare function applyReviewedSourceSet(state: SourceSetState, set: SourceSet): SourceSetState;
599
+ /**
600
+ * What the person removed in "Review what goes in": the Sources that went INTO
601
+ * the review (`reviewed`) and did not come back in its answer — keyed by
602
+ * `sourceKey`. A Source that landed while the review was open is never in
603
+ * `reviewed`, so it is never removed by it (verify-4 V4-F #3).
604
+ */
605
+ declare function removedInReview(reviewed: SourceSet, answer: SourceSet): Set<string>;
606
+ /**
607
+ * Apply a set the review returned (forms, parts, caps, delivery) — and its
608
+ * topic. Pass `reviewed` (the set that was sent INTO the review) and every
609
+ * Source removed there leaves the list, bound by its own card id.
610
+ */
611
+ declare function applyReviewedSourceSet(state: SourceSetState, set: SourceSet, reviewed?: SourceSet): SourceSetState;
555
612
  /** The server measured the ready Sources: each ready card takes its entry. */
556
613
  declare function applyManifest(state: SourceSetState, manifest: SourceManifest): SourceSetState;
557
614
  /**
@@ -581,6 +638,24 @@ declare function selectSourceSet(state: SourceSetState, options?: {
581
638
  * picked parts, capped — measured against each card's CURRENT pointer.
582
639
  */
583
640
  declare function selectTotalChars(state: SourceSetState): number;
641
+ /**
642
+ * THE one size of one Source (verify-3: one Source read 109k, 115k, 108k and
643
+ * 106k on four screens): the contract's rule — the chosen form, or the picked
644
+ * parts, capped by `max_chars` — measured against the card's CURRENT pointer.
645
+ * The card, the header total (`selectTotalChars`) and the review (`SourcePlanEntry.chars`)
646
+ * all read this. Null when it is not measured or cannot go in.
647
+ */
648
+ declare function sourceEntryChars(entry: SourceManifestEntry, ref: SourceRef): number | null;
649
+ declare function sourceCardChars(card: Pick<SourceCardModel, "draft" | "manifest">): number | null;
650
+ /**
651
+ * THE one state of one Source card, derived once: its own lifecycle wins
652
+ * (adding, waiting for an organization, failed); only a card that landed takes
653
+ * the server's measured state. Never two states at once.
654
+ */
655
+ type SourceCardState = "adding" | "waiting_for_organization" | "failed" | "unmeasured" | SourceManifestEntry["state"];
656
+ declare function sourceCardState(card: Pick<SourceCardModel, "status" | "error" | "manifest">): SourceCardState;
657
+ /** The server's measured state to show on a card — only for a card that landed (null otherwise). */
658
+ declare function sourceCardMeasuredState(card: Pick<SourceCardModel, "status" | "error" | "manifest">): SourceManifestEntry["state"] | null;
584
659
  /** Every Source finished landing (nothing pending) and none failed. */
585
660
  declare function selectSettled(state: SourceSetState): boolean;
586
661
  /** How many more Sources fit under the host's max (Infinity when there is none). */
@@ -690,8 +765,14 @@ interface SourceSetController extends SourceSetActions {
690
765
  toSourceSet(options?: {
691
766
  targetModelId?: string | undefined;
692
767
  }): SourceSet;
693
- /** Apply a set the review returned (forms, parts, caps, delivery). */
694
- applySourceSet(set: SourceSet): void;
768
+ /**
769
+ * Apply a set the review returned (forms, parts, caps, delivery). Pass
770
+ * `reviewed` — the set sent INTO the review — and every Source removed there
771
+ * leaves the list too (only those; one that landed meanwhile stays).
772
+ */
773
+ applySourceSet(set: SourceSet, options?: {
774
+ reviewed?: SourceSet | undefined;
775
+ }): void;
695
776
  /** POST /sources/resolve — the grounded text for a generator, named as the cards name them. */
696
777
  resolve(options?: {
697
778
  targetModelId?: string | undefined;
@@ -856,15 +937,33 @@ interface SourceIntakeDeps<Body extends SourceLandingBodyBase = SourceLandingBod
856
937
  interface SourceIntake {
857
938
  addPastedText(text: string, name?: string): Promise<void>;
858
939
  addWebPage(url: string): Promise<void>;
859
- /** A page the host's web picker already read (and the scraper landed); null id = land its text instead. */
940
+ /**
941
+ * A page the host's web picker already read (and the scraper landed); null id
942
+ * = land its text instead. `pendingId` = the card `beginWebPage` made when the
943
+ * read started — it is settled instead of a new card being added.
944
+ */
860
945
  addScrapedPage(page: {
861
946
  url: string;
862
947
  title: string;
863
948
  text: string;
864
949
  processedDocumentId: string | null;
865
- }): Promise<void>;
950
+ }, pendingId?: string | null): Promise<void>;
951
+ /**
952
+ * The host's web picker STARTED reading a link: a card with the link kept
953
+ * appears at once, so a reload mid-read brings it back and lands it (verify-3
954
+ * 12a/12b: a reload while a page was read lost it, link and all). Finish it
955
+ * with `addScrapedPage(page, id)`; if the person drops the preview, remove it;
956
+ * if the picker goes away mid-read, `resume(card)` lands it through the web door.
957
+ */
958
+ beginWebPage(url: string): string;
866
959
  /** Files the host's uploader already uploaded. */
867
960
  addUploaded(files: readonly UploadedSourceFile[], kind: SourceKindId): Promise<void>;
961
+ /**
962
+ * A recording made in place (the Voice Pad) that is already written out: it
963
+ * lands as text, but it IS a recording — its card and review say "Recording",
964
+ * never "Pasted text" — and it keeps its name ("Recording 3:41 PM").
965
+ */
966
+ addRecordedText(text: string, name?: string): Promise<void>;
868
967
  /** A recording already uploaded — written out, then landed. */
869
968
  addUploadedRecording(file: UploadedSourceFile): Promise<void>;
870
969
  /** Something the person already has (Use existing / search). Returns false when already picked. */
@@ -956,4 +1055,4 @@ declare function lookAtFileCards(cards: readonly SourceCardModel[], ctx: {
956
1055
  signal: AbortSignal;
957
1056
  } & FileRecoveryDeps): Promise<boolean>;
958
1057
 
959
- export { type BudgetVerdict, DELIVERY_CHOICES, DELIVERY_WORDS, type DeliveryWords, EMPTY_SOURCE_SET_STATE, type FetchSourcesTransportOptions, type FileRecoveryDeps, type FileSourceContext, type FileSourceStatus, type FileSourceStep, HEAVY_SHARE, KEEP_WAITING_FOR_ORGANIZATION, MAX_KEPT_TEXT_KNOB, NOT_KEPT_FOR_RELOAD, type PartMatchIds, type PersistedSourceCard, type PersistedSourceInput, type PlanInput, RELOADED_RESUMING, RELOADED_WHILE_ADDING, type ReloadedCard, SAME_SOURCE_AGAIN, SOURCE_CHARS_PER_TOKEN, type ScrapedSourcePage, type SourceAssociationEdge, type SourceAssociationResult, type SourceAttachTarget, type SourceAttachTo, type SourceCallOptions, type SourceCardModel, type SourceCardStatus, SourceDelivery, type SourceDoorCalls, SourceDoorError, type SourceDoorPath, type SourceDraft, type SourceDraftStorage, type SourceFileRunner, type SourceIntake, type SourceIntakeDeps, type SourceIntakeDoors, type SourceIntakeInput, type SourceKindId, type SourceLandingAnswer, type SourceLandingBodyBase, type SourceLandingNotice, type SourcePart, type SourcePartsSearchResult, type SourcePlan, type SourcePlanEntry, type SourcePlanStatus, type SourceSetActions, type SourceSetAdapter, type SourceSetConfig, type SourceSetController, type SourceSetMeta, type SourceSetState, type SourceSetStore, type SourceTileId, type SourceTransportOptions, type SourcesClient, type SourcesTransport, type UploadedSourceFile, WAITING_FOR_ORGANIZATION, type YouTubeTranscriptResult, addPendingCard, addReadyCard, allowedDeliveries, applyManifest, applyReviewedSourceSet, cardsToResume, cardsWaitingForOrganization, chosenForm, continueAfterOrganization, createFetchSourcesTransport, createMemorySourceDraftStorage, createMemorySourceSetStore, createSourceIntake, createSourceSetController, createSourcesClient, deliveryChoicesFor, deliveryPatch, deliverySwitchedNote, draftKindForToken, estimateSourceTokens, failCard, fileCardHeldForOrganization, fileSourcePollDelayMs, findParts, fitCardDeliveries, fitDelivery, hasSourceRef, isAskableFileCard, isSourceDraft, isWaitingFileCard, isWordQuery, lookAtFileCards, matchesPart, nextFileStep, partPages, planSourceReview, readPersistedSourceInput, readySourceRefs, registeredFileEdge, reloadedCard, removeCard, renderedPartChars, restartCard, restoredCards, resumableInput, resumeInterrupted, sameSourceRef, selectSettled, selectSourceSet, selectTotalChars, setCardWaitForClean, setSourceTopic, settleCard, sourceAttachTargets, sourceDelivery, sourceKey, sourceRecoveryGuards, sourceRoomLeft, toPersistedSourceInput, updateCardDraft, updateCardRef, uploadCutOffSentence, withDefaultForm, withDisplayNames };
1058
+ export { type BudgetVerdict, DELIVERY_CHOICES, DELIVERY_WORDS, type DeliveryWords, EMPTY_SOURCE_SET_STATE, type FetchSourcesTransportOptions, type FileRecoveryDeps, type FileSourceContext, type FileSourceStatus, type FileSourceStep, HEAVY_SHARE, KEEP_WAITING_FOR_ORGANIZATION, MAX_KEPT_TEXT_KNOB, NOT_KEPT_FOR_RELOAD, PARTS_MATCHED_BY_PAGE, PARTS_NOT_MATCHED, type PartMatchIds, type PersistedSourceCard, type PersistedSourceInput, type PlanInput, RELOADED_RESUMING, RELOADED_WHILE_ADDING, type ReloadedCard, SAME_SOURCE_AGAIN, SOURCE_CHARS_PER_TOKEN, type ScrapedSourcePage, type SourceAssociationEdge, type SourceAssociationResult, type SourceAttachTarget, type SourceAttachTo, type SourceCallOptions, type SourceCardModel, type SourceCardState, type SourceCardStatus, SourceDelivery, type SourceDoorCalls, SourceDoorError, type SourceDoorPath, type SourceDraft, type SourceDraftStorage, type SourceFileRunner, type SourceIntake, type SourceIntakeDeps, type SourceIntakeDoors, type SourceIntakeInput, type SourceKindId, type SourceLandingAnswer, type SourceLandingBodyBase, type SourceLandingNotice, type SourcePart, type SourcePartsSearchResult, type SourcePickedPart, type SourcePlan, type SourcePlanEntry, type SourcePlanStatus, type SourceSetActions, type SourceSetAdapter, type SourceSetConfig, type SourceSetController, type SourceSetMeta, type SourceSetState, type SourceSetStore, type SourceTileId, type SourceTransportOptions, type SourcesClient, type SourcesTransport, type UploadedSourceFile, WAITING_FOR_ORGANIZATION, type YouTubeTranscriptResult, addPendingCard, addReadyCard, allowedDeliveries, applyManifest, applyReviewedSourceSet, cardsToResume, cardsWaitingForOrganization, carryPickedParts, chosenForm, continueAfterOrganization, createFetchSourcesTransport, createMemorySourceDraftStorage, createMemorySourceSetStore, createSourceIntake, createSourceSetController, createSourcesClient, deliveryChoicesFor, deliveryPatch, deliverySwitchedNote, draftKindForToken, estimateSourceTokens, failCard, fileCardHeldForOrganization, fileSourcePollDelayMs, findParts, fitCardDeliveries, fitDelivery, hasSourceRef, isAskableFileCard, isSourceDraft, isWaitingFileCard, isWordQuery, lookAtFileCards, matchesPart, nextFileStep, partPages, planSourceReview, readPersistedSourceInput, readySourceRefs, registeredFileEdge, reloadedCard, rememberPickedParts, removeCard, removedInReview, renderedPartChars, restartCard, restoredCards, resumableInput, resumeInterrupted, sameSourceRef, selectSettled, selectSourceSet, selectTotalChars, setCardWaitForClean, setSourceTopic, settleCard, sourceAttachTargets, sourceCardChars, sourceCardMeasuredState, sourceCardState, sourceDelivery, sourceEntryChars, sourceKey, sourceRecoveryGuards, sourceRoomLeft, toPersistedSourceInput, updateCardDraft, updateCardRef, uploadCutOffSentence, withDefaultForm, withDisplayNames };