@happyvertical/smrt-ingestion 0.57.21 → 0.57.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/FEEDBACK.md +104 -0
  2. package/PROPOSALS.md +19 -0
  3. package/README.md +126 -0
  4. package/REVIEW.md +272 -4
  5. package/agents/execution.md +72 -0
  6. package/dist/chunks/{execution-9CfjxX8I.js → execution-BzVQax0n.js} +421 -23
  7. package/dist/chunks/execution-BzVQax0n.js.map +1 -0
  8. package/dist/chunks/{feedback-CuUzWKzP.js → feedback-D3UTF8fm.js} +119 -21
  9. package/dist/chunks/feedback-D3UTF8fm.js.map +1 -0
  10. package/dist/chunks/{extraction-CJ-zrbg0.js → proposal-contracts-77Uo1B1j.js} +39 -39
  11. package/dist/chunks/proposal-contracts-77Uo1B1j.js.map +1 -0
  12. package/dist/chunks/{reviewer-instruction-Db3jDN9a.js → reviewer-instruction-CEc3AOuU.js} +2 -2
  13. package/dist/chunks/{reviewer-instruction-Db3jDN9a.js.map → reviewer-instruction-CEc3AOuU.js.map} +1 -1
  14. package/dist/dto.d.ts +69 -0
  15. package/dist/dto.d.ts.map +1 -1
  16. package/dist/execution-contracts.d.ts +4 -1
  17. package/dist/execution-contracts.d.ts.map +1 -1
  18. package/dist/execution-dto.d.ts +16 -0
  19. package/dist/execution-dto.d.ts.map +1 -1
  20. package/dist/execution.d.ts +58 -3
  21. package/dist/execution.d.ts.map +1 -1
  22. package/dist/execution.js +2 -2
  23. package/dist/feedback-dto.d.ts +12 -4
  24. package/dist/feedback-dto.d.ts.map +1 -1
  25. package/dist/feedback-internal.d.ts +9 -0
  26. package/dist/feedback-internal.d.ts.map +1 -1
  27. package/dist/feedback.d.ts +3 -0
  28. package/dist/feedback.d.ts.map +1 -1
  29. package/dist/index.js +2 -2
  30. package/dist/manifest.json +321 -3
  31. package/dist/models.d.ts +15 -0
  32. package/dist/models.d.ts.map +1 -1
  33. package/dist/models.js +73 -2
  34. package/dist/models.js.map +1 -1
  35. package/dist/policy.d.ts +3 -0
  36. package/dist/policy.d.ts.map +1 -1
  37. package/dist/proposal-errors.d.ts +4 -0
  38. package/dist/proposal-errors.d.ts.map +1 -1
  39. package/dist/proposals.d.ts +1 -0
  40. package/dist/proposals.d.ts.map +1 -1
  41. package/dist/proposals.js +11 -6
  42. package/dist/proposals.js.map +1 -1
  43. package/dist/redaction.d.ts +9 -0
  44. package/dist/redaction.d.ts.map +1 -0
  45. package/dist/review-dto.d.ts +14 -4
  46. package/dist/review-dto.d.ts.map +1 -1
  47. package/dist/review-host.d.ts.map +1 -1
  48. package/dist/server.d.ts +82 -10
  49. package/dist/server.d.ts.map +1 -1
  50. package/dist/server.js +366 -47
  51. package/dist/server.js.map +1 -1
  52. package/dist/smrt-knowledge.json +124 -18
  53. package/dist/svelte/components/ActionReview.svelte +39 -9
  54. package/dist/svelte/components/ActionReview.svelte.d.ts +8 -1
  55. package/dist/svelte/components/ActionReview.svelte.d.ts.map +1 -1
  56. package/dist/svelte/components/EvidenceViewer.svelte +60 -4
  57. package/dist/svelte/components/EvidenceViewer.svelte.d.ts +12 -1
  58. package/dist/svelte/components/EvidenceViewer.svelte.d.ts.map +1 -1
  59. package/dist/svelte/components/InboxView.svelte +160 -18
  60. package/dist/svelte/components/InboxView.svelte.d.ts +28 -1
  61. package/dist/svelte/components/InboxView.svelte.d.ts.map +1 -1
  62. package/dist/svelte/components/IntakeWorkspace.svelte +27 -0
  63. package/dist/svelte/components/IntakeWorkspace.svelte.d.ts +19 -0
  64. package/dist/svelte/components/IntakeWorkspace.svelte.d.ts.map +1 -0
  65. package/dist/svelte/components/ReviewView.svelte +264 -23
  66. package/dist/svelte/components/ReviewView.svelte.d.ts +18 -1
  67. package/dist/svelte/components/ReviewView.svelte.d.ts.map +1 -1
  68. package/dist/svelte/components/TriageView.svelte +669 -0
  69. package/dist/svelte/components/TriageView.svelte.d.ts +16 -0
  70. package/dist/svelte/components/TriageView.svelte.d.ts.map +1 -0
  71. package/dist/svelte/i18n.d.ts +39 -0
  72. package/dist/svelte/i18n.d.ts.map +1 -1
  73. package/dist/svelte/i18n.js +39 -0
  74. package/dist/svelte/index.d.ts +1 -0
  75. package/dist/svelte/index.d.ts.map +1 -1
  76. package/dist/svelte/index.js +1 -0
  77. package/dist/svelte/view-utils.d.ts +65 -0
  78. package/dist/svelte/view-utils.d.ts.map +1 -1
  79. package/dist/svelte/view-utils.js +145 -0
  80. package/package.json +13 -13
  81. package/dist/chunks/execution-9CfjxX8I.js.map +0 -1
  82. package/dist/chunks/extraction-CJ-zrbg0.js.map +0 -1
  83. package/dist/chunks/feedback-CuUzWKzP.js.map +0 -1
@@ -24,6 +24,16 @@ export declare const M: {
24
24
  readonly 'ingestion.deferred': "ingestion.deferred";
25
25
  readonly 'ingestion.partially_completed': "ingestion.partially_completed";
26
26
  readonly 'ingestion.completed': "ingestion.completed";
27
+ readonly 'ingestion.resolved': "ingestion.resolved";
28
+ readonly 'ingestion.startAs': "ingestion.startAs";
29
+ readonly 'ingestion.startHandler': "ingestion.startHandler";
30
+ readonly 'ingestion.startArgs': "ingestion.startArgs";
31
+ readonly 'ingestion.start': "ingestion.start";
32
+ readonly 'ingestion.startHelp': "ingestion.startHelp";
33
+ readonly 'ingestion.resolveNoAction': "ingestion.resolveNoAction";
34
+ readonly 'ingestion.resolveReason': "ingestion.resolveReason";
35
+ readonly 'ingestion.resolvedBy': "ingestion.resolvedBy";
36
+ readonly 'ingestion.reviewerSelected': "ingestion.reviewerSelected";
27
37
  readonly 'ingestion.evidence': "ingestion.evidence";
28
38
  readonly 'ingestion.original': "ingestion.original";
29
39
  readonly 'ingestion.noOriginal': "ingestion.noOriginal";
@@ -85,5 +95,34 @@ export declare const M: {
85
95
  readonly 'ingestion.state': "ingestion.state";
86
96
  readonly 'ingestion.reason': "ingestion.reason";
87
97
  readonly 'ingestion.feedbackSent': "ingestion.feedbackSent";
98
+ readonly 'ingestion.previousPage': "ingestion.previousPage";
99
+ readonly 'ingestion.nextPage': "ingestion.nextPage";
100
+ readonly 'ingestion.pageOf': "ingestion.pageOf";
101
+ readonly 'ingestion.previousOriginal': "ingestion.previousOriginal";
102
+ readonly 'ingestion.nextOriginal': "ingestion.nextOriginal";
103
+ readonly 'ingestion.originalOf': "ingestion.originalOf";
104
+ readonly 'ingestion.workspace': "ingestion.workspace";
105
+ readonly 'ingestion.selectedItem': "ingestion.selectedItem";
106
+ readonly 'ingestion.previousItem': "ingestion.previousItem";
107
+ readonly 'ingestion.nextItem': "ingestion.nextItem";
108
+ readonly 'ingestion.itemOf': "ingestion.itemOf";
109
+ readonly 'ingestion.selectItem': "ingestion.selectItem";
110
+ readonly 'ingestion.queueDone': "ingestion.queueDone";
111
+ readonly 'ingestion.unsavedLeave': "ingestion.unsavedLeave";
112
+ readonly 'ingestion.discardLeave': "ingestion.discardLeave";
113
+ readonly 'ingestion.stay': "ingestion.stay";
114
+ readonly 'ingestion.finishedUnsent': "ingestion.finishedUnsent";
115
+ readonly 'ingestion.advanceRetry': "ingestion.advanceRetry";
116
+ readonly 'ingestion.advanceFailed': "ingestion.advanceFailed";
117
+ readonly 'ingestion.keyboardHelp': "ingestion.keyboardHelp";
118
+ readonly 'ingestion.statusReason': "ingestion.statusReason";
119
+ readonly 'ingestion.backgroundUpdate': "ingestion.backgroundUpdate";
120
+ readonly 'ingestion.triage.pending': "ingestion.triage.pending";
121
+ readonly 'ingestion.triage.ready': "ingestion.triage.ready";
122
+ readonly 'ingestion.triage.needs_review': "ingestion.triage.needs_review";
123
+ readonly 'ingestion.triage.approval': "ingestion.triage.approval";
124
+ readonly 'ingestion.triage.apply': "ingestion.triage.apply";
125
+ readonly 'ingestion.triage.failed': "ingestion.triage.failed";
126
+ readonly 'ingestion.triage.missing': "ingestion.triage.missing";
88
127
  };
89
128
  //# sourceMappingURL=i18n.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"i18n.d.ts","sourceRoot":"","sources":["../../src/svelte/i18n.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkGZ,CAAC"}
1
+ {"version":3,"file":"i18n.d.ts","sourceRoot":"","sources":["../../src/svelte/i18n.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+IZ,CAAC"}
@@ -25,6 +25,16 @@ export const M = defineMessages({
25
25
  'ingestion.deferred': 'Deferred',
26
26
  'ingestion.partially_completed': 'Partially completed',
27
27
  'ingestion.completed': 'Completed',
28
+ 'ingestion.resolved': 'Handled, no action',
29
+ 'ingestion.startAs': 'Start action as…',
30
+ 'ingestion.startHandler': 'Handler',
31
+ 'ingestion.startArgs': 'Initial arguments (JSON)',
32
+ 'ingestion.start': 'Start action',
33
+ 'ingestion.startHelp': 'The handler previews these arguments; approval is a separate step.',
34
+ 'ingestion.resolveNoAction': 'Handled, no action',
35
+ 'ingestion.resolveReason': 'Reason for no action',
36
+ 'ingestion.resolvedBy': 'Closed without action by {reviewer}',
37
+ 'ingestion.reviewerSelected': 'Started by a reviewer',
28
38
  'ingestion.evidence': 'Original evidence',
29
39
  'ingestion.original': 'Open original',
30
40
  'ingestion.noOriginal': 'Original unavailable',
@@ -86,4 +96,33 @@ export const M = defineMessages({
86
96
  'ingestion.state': 'State',
87
97
  'ingestion.reason': 'Reason',
88
98
  'ingestion.feedbackSent': 'Feedback sent.',
99
+ 'ingestion.previousPage': 'Previous page',
100
+ 'ingestion.nextPage': 'Next page',
101
+ 'ingestion.pageOf': 'Page {page} of {count}',
102
+ 'ingestion.previousOriginal': 'Previous original',
103
+ 'ingestion.nextOriginal': 'Next original',
104
+ 'ingestion.originalOf': 'Original {index} of {count}',
105
+ 'ingestion.workspace': 'Intake triage',
106
+ 'ingestion.selectedItem': 'Selected item',
107
+ 'ingestion.previousItem': 'Previous item',
108
+ 'ingestion.nextItem': 'Next item',
109
+ 'ingestion.itemOf': 'Item {index} of {count}',
110
+ 'ingestion.selectItem': 'Choose an item from the list to review it here.',
111
+ 'ingestion.queueDone': 'Nothing else in this list needs review.',
112
+ 'ingestion.unsavedLeave': 'This item has input you have not sent. Leave it and discard that input?',
113
+ 'ingestion.discardLeave': 'Discard and open the other item',
114
+ 'ingestion.stay': 'Stay on this item',
115
+ 'ingestion.finishedUnsent': 'Finished. You have unsent input on this item; move on with Next item when ready.',
116
+ 'ingestion.advanceRetry': "Finished, but the next open item wasn't reached yet. Try Next item again.",
117
+ 'ingestion.advanceFailed': "Finished, but the list couldn't load more items. Refresh the list to continue.",
118
+ 'ingestion.keyboardHelp': 'Press J or K, or Alt+Down or Alt+Up, outside a text field to move between items.',
119
+ 'ingestion.statusReason': '{status}: {reason}',
120
+ 'ingestion.backgroundUpdate': '{label}: {status}',
121
+ 'ingestion.triage.pending': 'Interpreting…',
122
+ 'ingestion.triage.ready': 'Ready to review',
123
+ 'ingestion.triage.needs_review': 'Needs review',
124
+ 'ingestion.triage.approval': 'Awaiting approval',
125
+ 'ingestion.triage.apply': 'Approved, not yet applied',
126
+ 'ingestion.triage.failed': 'Failed',
127
+ 'ingestion.triage.missing': 'missing {fields}',
89
128
  });
@@ -2,4 +2,5 @@ export type { Assignment, EvidenceView, InboxEntry, InboxEvidence, InboxState, I
2
2
  export { default as EvidenceViewer } from './components/EvidenceViewer.svelte';
3
3
  export { default as IntakeInbox } from './components/IntakeInbox.svelte';
4
4
  export { default as IntakeReview } from './components/IntakeReview.svelte';
5
+ export { default as IntakeWorkspace } from './components/IntakeWorkspace.svelte';
5
6
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/svelte/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,UAAU,EACV,YAAY,EACZ,UAAU,EACV,aAAa,EACb,UAAU,EACV,gBAAgB,EAChB,cAAc,EACd,iBAAiB,EACjB,gBAAgB,EAChB,YAAY,EACZ,mBAAmB,EACnB,wBAAwB,EACxB,uBAAuB,EACvB,UAAU,GACX,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAC/E,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,iCAAiC,CAAC;AACzE,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,kCAAkC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/svelte/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,UAAU,EACV,YAAY,EACZ,UAAU,EACV,aAAa,EACb,UAAU,EACV,gBAAgB,EAChB,cAAc,EACd,iBAAiB,EACjB,gBAAgB,EAChB,YAAY,EACZ,mBAAmB,EACnB,wBAAwB,EACxB,uBAAuB,EACvB,UAAU,GACX,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAC/E,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,iCAAiC,CAAC;AACzE,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,kCAAkC,CAAC;AAC3E,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,qCAAqC,CAAC"}
@@ -1,3 +1,4 @@
1
1
  export { default as EvidenceViewer } from './components/EvidenceViewer.svelte';
2
2
  export { default as IntakeInbox } from './components/IntakeInbox.svelte';
3
3
  export { default as IntakeReview } from './components/IntakeReview.svelte';
4
+ export { default as IntakeWorkspace } from './components/IntakeWorkspace.svelte';
@@ -1,4 +1,14 @@
1
1
  import type { EvidenceLocation } from '../extraction-types.js';
2
+ import type { GeneratedSuggestion, ProposalCatalogEntry } from '../proposal-dto.js';
3
+ import type { InboxEntry, InboxState, ItemReviewView } from '../review-dto.js';
4
+ /**
5
+ * Initial arguments for a reviewer-chosen handler: a same-handler suggestion's
6
+ * arguments when one exists, otherwise evidence references for a single
7
+ * original. Nothing else is invented; the handler's preview validates them.
8
+ */
9
+ export declare function draftArguments(entry: ProposalCatalogEntry, suggestions: readonly GeneratedSuggestion[], evidenceIds: readonly string[]): Record<string, unknown>;
10
+ /** Required schema properties the draft does not supply yet. */
11
+ export declare function missingArguments(entry: ProposalCatalogEntry, args: Record<string, unknown>): string[];
2
12
  /** Only host-authorized same-origin HTTP URLs may reach original media elements. */
3
13
  export declare function evidenceUrl(value?: string, origin?: string): string | undefined;
4
14
  export declare function argumentsObject(value: string): Record<string, unknown>;
@@ -12,4 +22,59 @@ export declare function extractedContent(output: Record<string, unknown>): Array
12
22
  location?: EvidenceLocation;
13
23
  confidence?: number;
14
24
  }>;
25
+ /**
26
+ * True while a background stage for the item is queued or running, including
27
+ * the server-reported gap between a completed extraction and its not yet
28
+ * appended interpretation. Presentation only: it drives polling, never access.
29
+ */
30
+ export declare function reviewInFlight(view: ItemReviewView | undefined): boolean;
31
+ /**
32
+ * A row's triage status. `state` falls back to the listed inbox state when
33
+ * nothing more specific is known (a row the reviewer has not opened).
34
+ */
35
+ export type TriageStatus = {
36
+ kind: 'pending';
37
+ } | {
38
+ kind: 'ready';
39
+ } | {
40
+ kind: 'needs_review';
41
+ missing?: string[];
42
+ reason?: string;
43
+ } | {
44
+ kind: 'approval';
45
+ } | {
46
+ kind: 'apply';
47
+ } | {
48
+ kind: 'failed';
49
+ reason?: string;
50
+ } | {
51
+ kind: 'resolved';
52
+ } | {
53
+ kind: 'state';
54
+ state: InboxState;
55
+ };
56
+ /** Status from a listed row alone: it carries no generation, so no reasons. */
57
+ export declare function entryStatus(entry: InboxEntry): TriageStatus;
58
+ /**
59
+ * Status from a loaded review view: what the reviewer would do next and, for
60
+ * a suggestion that needs review or a failed stage, a safe reason (missing
61
+ * argument names, a generation outcome or a failure category; never server
62
+ * exception text).
63
+ */
64
+ export declare function viewStatus(view: ItemReviewView): TriageStatus;
65
+ /** Rows the queue is finished with: closed without action or fully completed. */
66
+ export declare function triageTerminal(status: TriageStatus): boolean;
67
+ /**
68
+ * True when a reviewer operation left nothing for the reviewer on the item:
69
+ * it was closed without action, or at least one action succeeded and none is
70
+ * waiting for approval, waiting to be applied, executing, unknown or failed.
71
+ * Stale, rejected and deferred actions do not hold the item open.
72
+ */
73
+ export declare function triageSettled(view: ItemReviewView): boolean;
74
+ /**
75
+ * Highest observed page per evidence part, from extraction locations and
76
+ * proposed page groups. Only observed pages are navigable; a part without
77
+ * any is shown without page navigation.
78
+ */
79
+ export declare function observedPages(view: ItemReviewView): Record<string, number>;
15
80
  //# sourceMappingURL=view-utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"view-utils.d.ts","sourceRoot":"","sources":["../../src/svelte/view-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,oFAAoF;AACpF,wBAAgB,WAAW,CACzB,KAAK,CAAC,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,MAAM,GACd,MAAM,GAAG,SAAS,CAmBpB;AACD,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAKtE;AACD,qGAAqG;AACrG,wBAAgB,eAAe,CAC7B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,KAAK,EAAE,MAAM,GACZ,MAAM,EAAE,CAWV;AACD,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,EAAE,CAcpD;AAED,+FAA+F;AAC/F,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,KAAK,CAAC;IACvE,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,gBAAgB,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC,CAsED"}
1
+ {"version":3,"file":"view-utils.d.ts","sourceRoot":"","sources":["../../src/svelte/view-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,KAAK,EACV,mBAAmB,EACnB,oBAAoB,EACrB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAE/E;;;;GAIG;AACH,wBAAgB,cAAc,CAC5B,KAAK,EAAE,oBAAoB,EAC3B,WAAW,EAAE,SAAS,mBAAmB,EAAE,EAC3C,WAAW,EAAE,SAAS,MAAM,EAAE,GAC7B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAkBzB;AACD,gEAAgE;AAChE,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,oBAAoB,EAC3B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,MAAM,EAAE,CAQV;AACD,oFAAoF;AACpF,wBAAgB,WAAW,CACzB,KAAK,CAAC,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,MAAM,GACd,MAAM,GAAG,SAAS,CAmBpB;AACD,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAKtE;AACD,qGAAqG;AACrG,wBAAgB,eAAe,CAC7B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,KAAK,EAAE,MAAM,GACZ,MAAM,EAAE,CAWV;AACD,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,EAAE,CAcpD;AAED,+FAA+F;AAC/F,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,KAAK,CAAC;IACvE,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,gBAAgB,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC,CAsED;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,cAAc,GAAG,SAAS,GAAG,OAAO,CAQxE;AAED;;;GAGG;AACH,MAAM,MAAM,YAAY,GACpB;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,GACnB;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,GACjB;IAAE,IAAI,EAAE,cAAc,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GAC7D;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,GACpB;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,GACjB;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GACnC;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,GACpB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,UAAU,CAAA;CAAE,CAAC;AAEzC,+EAA+E;AAC/E,wBAAgB,WAAW,CAAC,KAAK,EAAE,UAAU,GAAG,YAAY,CAU3D;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,cAAc,GAAG,YAAY,CAyC7D;AAED,iFAAiF;AACjF,wBAAgB,cAAc,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAK5D;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAkB3D;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAiB1E"}
@@ -1,3 +1,29 @@
1
+ /**
2
+ * Initial arguments for a reviewer-chosen handler: a same-handler suggestion's
3
+ * arguments when one exists, otherwise evidence references for a single
4
+ * original. Nothing else is invented; the handler's preview validates them.
5
+ */
6
+ export function draftArguments(entry, suggestions, evidenceIds) {
7
+ const suggestion = suggestions.find((candidate) => candidate.handlerId === entry.id &&
8
+ candidate.handlerVersion === entry.version);
9
+ // Plain JSON arguments; reactive state proxies cannot be structured-cloned.
10
+ const args = suggestion
11
+ ? JSON.parse(JSON.stringify(suggestion.args))
12
+ : {};
13
+ for (const [field, reference] of Object.entries(entry.references))
14
+ if (reference.kind === 'evidence' &&
15
+ !Object.hasOwn(args, field) &&
16
+ evidenceIds.length === 1)
17
+ args[field] = evidenceIds[0];
18
+ return args;
19
+ }
20
+ /** Required schema properties the draft does not supply yet. */
21
+ export function missingArguments(entry, args) {
22
+ const required = entry.argsSchema.required;
23
+ return Array.isArray(required)
24
+ ? required.filter((field) => typeof field === 'string' && !Object.hasOwn(args, field))
25
+ : [];
26
+ }
1
27
  /** Only host-authorized same-origin HTTP URLs may reach original media elements. */
2
28
  export function evidenceUrl(value, origin) {
3
29
  if (!value)
@@ -106,3 +132,122 @@ export function extractedContent(output) {
106
132
  }
107
133
  return content;
108
134
  }
135
+ /**
136
+ * True while a background stage for the item is queued or running, including
137
+ * the server-reported gap between a completed extraction and its not yet
138
+ * appended interpretation. Presentation only: it drives polling, never access.
139
+ */
140
+ export function reviewInFlight(view) {
141
+ return (view?.availability === 'available' &&
142
+ !view.entry.item.disposition &&
143
+ (view.entry.state === 'processing' ||
144
+ ['queued', 'running'].includes(view.entry.item.processingState) ||
145
+ !!view.instruction?.reinterpreting));
146
+ }
147
+ /** Status from a listed row alone: it carries no generation, so no reasons. */
148
+ export function entryStatus(entry) {
149
+ if (entry.item.disposition || entry.state === 'resolved')
150
+ return { kind: 'resolved' };
151
+ if (entry.state === 'processing' ||
152
+ ['queued', 'running'].includes(entry.item.processingState))
153
+ return { kind: 'pending' };
154
+ if (entry.state === 'failed')
155
+ return { kind: 'failed' };
156
+ return { kind: 'state', state: entry.state };
157
+ }
158
+ /**
159
+ * Status from a loaded review view: what the reviewer would do next and, for
160
+ * a suggestion that needs review or a failed stage, a safe reason (missing
161
+ * argument names, a generation outcome or a failure category; never server
162
+ * exception text).
163
+ */
164
+ export function viewStatus(view) {
165
+ if (view.availability !== 'available')
166
+ return entryStatus(view.entry);
167
+ if (view.entry.item.disposition)
168
+ return { kind: 'resolved' };
169
+ if (reviewInFlight(view))
170
+ return { kind: 'pending' };
171
+ const failure = view.instruction?.failure;
172
+ if (failure)
173
+ return { kind: 'failed', reason: failure };
174
+ const states = view.reviews.actions.map((action) => action.review.state);
175
+ if (states.includes('waiting_review'))
176
+ return { kind: 'approval' };
177
+ if (states.includes('authorized'))
178
+ return { kind: 'apply' };
179
+ if (['completed', 'partially_completed', 'deferred', 'failed'].includes(view.entry.state) &&
180
+ states.length)
181
+ return entryStatus(view.entry);
182
+ const generation = view.generation;
183
+ if (generation?.outcome === 'provider_error')
184
+ return { kind: 'failed', reason: generation.outcome };
185
+ if (view.analysis?.result.error)
186
+ return { kind: 'failed', reason: view.analysis.result.error };
187
+ if (generation) {
188
+ if (generation.suggestions.some((suggestion) => suggestion.disposition === 'ready_for_review'))
189
+ return { kind: 'ready' };
190
+ const missing = [
191
+ ...new Set(generation.suggestions.flatMap((suggestion) => suggestion.missingFields)),
192
+ ];
193
+ if (missing.length)
194
+ return { kind: 'needs_review', missing };
195
+ return generation.suggestions.length
196
+ ? { kind: 'needs_review' }
197
+ : { kind: 'needs_review', reason: generation.outcome };
198
+ }
199
+ return entryStatus(view.entry);
200
+ }
201
+ /** Rows the queue is finished with: closed without action or fully completed. */
202
+ export function triageTerminal(status) {
203
+ return (status.kind === 'resolved' ||
204
+ (status.kind === 'state' && status.state === 'completed'));
205
+ }
206
+ /**
207
+ * True when a reviewer operation left nothing for the reviewer on the item:
208
+ * it was closed without action, or at least one action succeeded and none is
209
+ * waiting for approval, waiting to be applied, executing, unknown or failed.
210
+ * Stale, rejected and deferred actions do not hold the item open.
211
+ */
212
+ export function triageSettled(view) {
213
+ if (view.availability !== 'available')
214
+ return false;
215
+ if (view.entry.item.disposition)
216
+ return true;
217
+ // An unloaded saved-review page can still contain work for the reviewer.
218
+ if (view.reviews.nextCursor || reviewInFlight(view))
219
+ return false;
220
+ const states = view.reviews.actions.map((action) => action.review.state);
221
+ return (states.includes('succeeded') &&
222
+ !states.some((state) => [
223
+ 'waiting_review',
224
+ 'authorized',
225
+ 'executing',
226
+ 'outcome_unknown',
227
+ 'failed',
228
+ ].includes(state)));
229
+ }
230
+ /**
231
+ * Highest observed page per evidence part, from extraction locations and
232
+ * proposed page groups. Only observed pages are navigable; a part without
233
+ * any is shown without page navigation.
234
+ */
235
+ export function observedPages(view) {
236
+ const pages = {};
237
+ const note = (evidenceId, page) => {
238
+ if (Number.isSafeInteger(page) && page > 0)
239
+ pages[evidenceId] = Math.max(pages[evidenceId] ?? 0, page);
240
+ };
241
+ if (view.analysis)
242
+ for (const segment of extractedContent(view.analysis.result.output)) {
243
+ if (segment.location?.kind === 'page')
244
+ note(segment.evidenceId, segment.location.page);
245
+ if (segment.location?.kind === 'pages')
246
+ note(segment.evidenceId, segment.location.endPage);
247
+ }
248
+ for (const split of view.generation?.splits ?? [])
249
+ for (const group of split.groups)
250
+ for (const page of group)
251
+ note(split.evidenceId, page);
252
+ return pages;
253
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@happyvertical/smrt-ingestion",
3
- "version": "0.57.21",
3
+ "version": "0.57.22",
4
4
  "description": "Durable tenant-scoped intake and evidence foundations",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -50,32 +50,32 @@
50
50
  }
51
51
  },
52
52
  "dependencies": {
53
- "@happyvertical/smrt-core": "0.57.21",
54
- "@happyvertical/smrt-types": "0.57.21",
55
- "@happyvertical/smrt-tenancy": "0.57.21",
56
- "@happyvertical/smrt-assets": "0.57.21",
57
- "@happyvertical/smrt-jobs": "0.57.21",
53
+ "@happyvertical/smrt-core": "0.57.22",
54
+ "@happyvertical/smrt-types": "0.57.22",
55
+ "@happyvertical/smrt-tenancy": "0.57.22",
56
+ "@happyvertical/smrt-assets": "0.57.22",
57
+ "@happyvertical/smrt-jobs": "0.57.22",
58
58
  "@happyvertical/sql": "^0.106.0",
59
59
  "@happyvertical/pdf": "^0.65.9",
60
60
  "@happyvertical/ocr": "^0.62.1",
61
61
  "@happyvertical/speech": "^0.106.0",
62
62
  "@happyvertical/ai": "^0.106.0",
63
63
  "sharp": "^0.35.5",
64
- "@happyvertical/smrt-agents": "0.57.21",
65
- "@happyvertical/smrt-playbooks": "0.57.21",
64
+ "@happyvertical/smrt-agents": "0.57.22",
65
+ "@happyvertical/smrt-playbooks": "0.57.22",
66
66
  "ajv": "8.20.0",
67
- "@happyvertical/smrt-ui": "0.57.21"
67
+ "@happyvertical/smrt-ui": "0.57.22"
68
68
  },
69
69
  "devDependencies": {
70
- "@happyvertical/smrt-vitest": "0.57.21",
70
+ "@happyvertical/smrt-vitest": "0.57.22",
71
71
  "@types/node": "24.13.6",
72
72
  "typescript": "6.0.3",
73
73
  "vite": "8.1.6",
74
74
  "vitest": "4.1.10",
75
- "@happyvertical/smrt-content": "0.57.21",
76
- "@happyvertical/smrt-messages": "0.57.21",
75
+ "@happyvertical/smrt-content": "0.57.22",
76
+ "@happyvertical/smrt-messages": "0.57.22",
77
77
  "@happyvertical/email": "^0.106.0",
78
- "@happyvertical/smrt-users": "0.57.21",
78
+ "@happyvertical/smrt-users": "0.57.22",
79
79
  "@sveltejs/package": "^2.5.8",
80
80
  "@sveltejs/vite-plugin-svelte": "^7.3.0",
81
81
  "svelte": "^5.57.1",