@inflexa-ai/harness 0.16.0 → 0.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. package/dist/agents/conversation-agent.d.ts +3 -0
  2. package/dist/agents/conversation-agent.js +5 -2
  3. package/dist/agents/sandbox/shared.d.ts +3 -0
  4. package/dist/agents/sandbox/shared.js +5 -0
  5. package/dist/agents/sandbox/types.d.ts +1 -1
  6. package/dist/app/chat-turn.d.ts +2 -0
  7. package/dist/app/chat-turn.js +11 -2
  8. package/dist/app/synthesize-run.d.ts +3 -0
  9. package/dist/app/synthesize-run.js +2 -1
  10. package/dist/citations/__fixtures__/resolver.d.ts +3 -0
  11. package/dist/citations/__fixtures__/resolver.js +9 -0
  12. package/dist/citations/aggregate.d.ts +3 -0
  13. package/dist/citations/aggregate.js +44 -0
  14. package/dist/citations/clients/arxiv.d.ts +6 -0
  15. package/dist/citations/clients/arxiv.js +34 -0
  16. package/dist/citations/clients/common.d.ts +11 -0
  17. package/dist/citations/clients/common.js +43 -0
  18. package/dist/citations/clients/crossref.d.ts +8 -0
  19. package/dist/citations/clients/crossref.js +98 -0
  20. package/dist/citations/clients/doi-registry.d.ts +3 -0
  21. package/dist/citations/clients/doi-registry.js +95 -0
  22. package/dist/citations/clients/pubmed.d.ts +6 -0
  23. package/dist/citations/clients/pubmed.js +83 -0
  24. package/dist/citations/clients/semantic-scholar.d.ts +6 -0
  25. package/dist/citations/clients/semantic-scholar.js +60 -0
  26. package/dist/citations/compare.d.ts +9 -0
  27. package/dist/citations/compare.js +72 -0
  28. package/dist/citations/match.d.ts +11 -0
  29. package/dist/citations/match.js +173 -0
  30. package/dist/citations/normalize.d.ts +31 -0
  31. package/dist/citations/normalize.js +187 -0
  32. package/dist/citations/plan.d.ts +2 -0
  33. package/dist/citations/plan.js +59 -0
  34. package/dist/citations/resolve.d.ts +28 -0
  35. package/dist/citations/resolve.js +238 -0
  36. package/dist/citations/types.d.ts +583 -0
  37. package/dist/citations/types.js +129 -0
  38. package/dist/contracts/schemas/chat-parts.d.ts +8 -8
  39. package/dist/contracts/target-dossier.d.ts +20 -20
  40. package/dist/execution/run-synthesis.d.ts +3 -0
  41. package/dist/execution/run-synthesis.js +1 -0
  42. package/dist/index.d.ts +6 -1
  43. package/dist/index.js +3 -0
  44. package/dist/lib/cache.d.ts +8 -0
  45. package/dist/lib/cache.js +35 -0
  46. package/dist/lib/rate-limit.d.ts +35 -0
  47. package/dist/lib/rate-limit.js +121 -0
  48. package/dist/literature/sources/arxiv.d.ts +22 -0
  49. package/dist/literature/sources/arxiv.js +103 -0
  50. package/dist/literature/sources/http.d.ts +28 -0
  51. package/dist/literature/sources/http.js +97 -0
  52. package/dist/literature/sources/pubmed.d.ts +68 -0
  53. package/dist/literature/sources/pubmed.js +266 -0
  54. package/dist/literature/sources/semantic-scholar.d.ts +24 -0
  55. package/dist/literature/sources/semantic-scholar.js +71 -0
  56. package/dist/memory/thread-store.d.ts +142 -25
  57. package/dist/memory/thread-store.js +228 -40
  58. package/dist/prompts/literature-reviewer.d.ts +1 -1
  59. package/dist/prompts/literature-reviewer.js +2 -0
  60. package/dist/runtime/assemble.d.ts +50 -4
  61. package/dist/runtime/assemble.js +47 -3
  62. package/dist/runtime/boot.js +7 -1
  63. package/dist/state/init.js +46 -1
  64. package/dist/state/schema.d.ts +2 -2
  65. package/dist/tools/bio/gene-preclinical-profile.d.ts +1 -1
  66. package/dist/tools/bio/keys.d.ts +1 -0
  67. package/dist/tools/bio/pubmed.js +4 -4
  68. package/dist/tools/lib/ncbi-utils.d.ts +3 -58
  69. package/dist/tools/lib/ncbi-utils.js +2 -286
  70. package/dist/tools/lib/pubmed-client.d.ts +5 -12
  71. package/dist/tools/lib/pubmed-client.js +20 -79
  72. package/dist/tools/research/generate-analogy-report.js +2 -2
  73. package/dist/tools/research/index.d.ts +1 -0
  74. package/dist/tools/research/index.js +1 -0
  75. package/dist/tools/research/inspect-run.d.ts +1 -1
  76. package/dist/tools/research/literature-reviewer.d.ts +3 -0
  77. package/dist/tools/research/literature-reviewer.js +2 -0
  78. package/dist/tools/research/resolve-citation.d.ts +3 -0
  79. package/dist/tools/research/resolve-citation.js +15 -0
  80. package/dist/tools/research/search-arxiv.d.ts +3 -19
  81. package/dist/tools/research/search-arxiv.js +9 -105
  82. package/dist/tools/research/search-semantic-scholar.d.ts +8 -33
  83. package/dist/tools/research/search-semantic-scholar.js +29 -88
  84. package/dist/tools/sandbox/list-available-refs.js +1 -2
  85. package/dist/workflows/execute-analysis.d.ts +3 -0
  86. package/dist/workflows/execute-analysis.js +1 -0
  87. package/dist/workflows/sandbox-step.d.ts +5 -0
  88. package/dist/workflows/sandbox-step.js +1 -0
  89. package/dist/workflows/target-assessment/phase4-assemble.d.ts +2 -2
  90. package/dist/workflows/target-assessment/schemas.d.ts +2 -2
  91. package/dist/workflows/target-assessment/steps/phase2-aggregate.d.ts +1 -1
  92. package/dist/workflows/target-assessment/steps/phase3-aggregate.d.ts +1 -1
  93. package/package.json +1 -1
@@ -0,0 +1,129 @@
1
+ import { z } from "zod";
2
+ export const CitationKindSchema = z.enum(["doi", "pmid", "arxiv", "free_text", "auto"]);
3
+ export const CitationInputSchema = z.object({
4
+ citation: z.string().trim().min(1).max(5_000),
5
+ kind: CitationKindSchema.optional(),
6
+ title: z.string().trim().min(1).max(2_000).optional(),
7
+ authors: z.array(z.string().trim().min(1).max(500)).max(500).optional(),
8
+ year: z.number().int().min(1000).max(3000).optional(),
9
+ venue: z.string().trim().min(1).max(1_000).optional(),
10
+ volume: z.string().trim().min(1).max(100).optional(),
11
+ firstPage: z.string().trim().min(1).max(100).optional(),
12
+ });
13
+ export const CitationSourceSchema = z.enum(["doi_registry", "crossref", "pubmed", "arxiv", "semantic_scholar"]);
14
+ export const CitationSourceStatusSchema = z.enum(["ok", "no_data", "unavailable", "not_applicable"]);
15
+ export const CitationVerdictSchema = z.enum(["verified", "metadata_mismatch", "not_found", "unverifiable", "inconclusive"]);
16
+ export const CitationCoverageSchema = z.enum(["complete", "partial", "none"]);
17
+ export const ComparisonStatusSchema = z.enum(["match", "mismatch", "not_compared"]);
18
+ export const CitationFieldSchema = z.enum(["title", "authors", "year", "venue", "volume", "firstPage"]);
19
+ export const UnsupportedWorkKindSchema = z.enum(["personal_communication", "unpublished", "unregistered_in_press"]);
20
+ export const CitationIdentifiersSchema = z.object({
21
+ doi: z.string().optional(),
22
+ pmid: z.string().optional(),
23
+ arxiv: z.string().optional(),
24
+ corpusId: z.string().optional(),
25
+ });
26
+ export const NormalizedCitationMetadataSchema = z.object({
27
+ title: z.string().optional(),
28
+ authors: z.array(z.string()).optional(),
29
+ year: z.number().int().optional(),
30
+ venue: z.string().optional(),
31
+ volume: z.string().optional(),
32
+ firstPage: z.string().optional(),
33
+ });
34
+ export const NormalizedCitationSchema = z.object({
35
+ citation: z.string(),
36
+ query: z.string(),
37
+ kind: z.enum(["doi", "pmid", "arxiv", "free_text"]),
38
+ identifiers: CitationIdentifiersSchema,
39
+ supplied: NormalizedCitationMetadataSchema,
40
+ unsupportedWorkKind: UnsupportedWorkKindSchema.optional(),
41
+ });
42
+ export const CitationRecordSchema = z.object({
43
+ source: CitationSourceSchema,
44
+ sourceRecordId: z.string(),
45
+ identifiers: CitationIdentifiersSchema,
46
+ title: z.string().optional(),
47
+ authors: z.array(z.string()).optional(),
48
+ year: z.number().int().optional(),
49
+ venue: z.string().optional(),
50
+ volume: z.string().optional(),
51
+ firstPage: z.string().optional(),
52
+ registrationAgency: z.string().optional(),
53
+ url: z.string().optional(),
54
+ });
55
+ export const IdentifierEvidenceSchema = z.object({
56
+ type: z.enum(["doi", "pmid", "arxiv"]),
57
+ identifier: z.string(),
58
+ exists: z.boolean(),
59
+ registrationAgency: z.string().optional(),
60
+ metadataAvailable: z.boolean(),
61
+ });
62
+ export const CitationSourceOutcomeSchema = z.object({
63
+ source: CitationSourceSchema,
64
+ operation: z.string(),
65
+ status: CitationSourceStatusSchema,
66
+ requestCount: z.number().int().nonnegative(),
67
+ records: z.array(CitationRecordSchema),
68
+ detail: z.string().optional(),
69
+ identifierEvidence: IdentifierEvidenceSchema.optional(),
70
+ });
71
+ export const CitationFieldComparisonSchema = z.object({
72
+ field: CitationFieldSchema,
73
+ status: ComparisonStatusSchema,
74
+ supplied: z.union([z.string(), z.number(), z.array(z.string())]),
75
+ sourceValues: z.array(z.object({
76
+ source: CitationSourceSchema,
77
+ value: z.union([z.string(), z.number(), z.array(z.string())]),
78
+ })),
79
+ ruleVersion: z.string(),
80
+ });
81
+ export const CitationConflictSchema = z.object({
82
+ field: CitationFieldSchema,
83
+ values: z.array(z.object({
84
+ source: CitationSourceSchema,
85
+ value: z.union([z.string(), z.number(), z.array(z.string())]),
86
+ })),
87
+ });
88
+ export const CitationClusterRelationSchema = z.object({
89
+ clusterId: z.string(),
90
+ kind: z.enum(["preprint_of", "published_as", "related_version"]),
91
+ });
92
+ export const CitationCandidateClusterSchema = z.object({
93
+ id: z.string(),
94
+ score: z.number().min(0).max(1),
95
+ records: z.array(CitationRecordSchema).min(1),
96
+ relations: z.array(CitationClusterRelationSchema),
97
+ });
98
+ export const CitationResolutionResultSchema = z.object({
99
+ input: CitationInputSchema,
100
+ normalized: NormalizedCitationSchema,
101
+ sourceOutcomes: z.array(CitationSourceOutcomeSchema),
102
+ candidates: z.array(CitationCandidateClusterSchema),
103
+ selectedClusterId: z.string().optional(),
104
+ comparisons: z.array(CitationFieldComparisonSchema),
105
+ conflicts: z.array(CitationConflictSchema),
106
+ verdict: CitationVerdictSchema,
107
+ coverage: CitationCoverageSchema,
108
+ });
109
+ export const CitationSourceOperationSchema = z.enum([
110
+ "doi_exact",
111
+ "crossref_doi_if_owned",
112
+ "crossref_bibliographic",
113
+ "pubmed_exact",
114
+ "pubmed_doi",
115
+ "pubmed_structured",
116
+ "pubmed_title",
117
+ "arxiv_exact",
118
+ "arxiv_bibliographic",
119
+ "semantic_scholar_identifier",
120
+ "semantic_scholar_bibliographic",
121
+ "none",
122
+ ]);
123
+ export const CitationSourcePlanItemSchema = z.object({
124
+ source: CitationSourceSchema,
125
+ applicable: z.boolean(),
126
+ operation: CitationSourceOperationSchema,
127
+ candidateGeneration: z.boolean(),
128
+ reason: z.string(),
129
+ });
@@ -182,6 +182,7 @@ export declare const DagStatePartSchema: z.ZodObject<{
182
182
  }, z.core.$strict>>;
183
183
  }, z.core.$strict>;
184
184
  export declare const StepPhaseSchema: z.ZodEnum<{
185
+ complete: "complete";
185
186
  failed: "failed";
186
187
  warning: "warning";
187
188
  "sandbox-init": "sandbox-init";
@@ -190,7 +191,6 @@ export declare const StepPhaseSchema: z.ZodEnum<{
190
191
  "generating-summary": "generating-summary";
191
192
  indexing: "indexing";
192
193
  persisting: "persisting";
193
- complete: "complete";
194
194
  retrying: "retrying";
195
195
  }>;
196
196
  export declare const StepActivityPartSchema: z.ZodObject<{
@@ -199,6 +199,7 @@ export declare const StepActivityPartSchema: z.ZodObject<{
199
199
  runId: z.ZodString;
200
200
  stepId: z.ZodString;
201
201
  phase: z.ZodEnum<{
202
+ complete: "complete";
202
203
  failed: "failed";
203
204
  warning: "warning";
204
205
  "sandbox-init": "sandbox-init";
@@ -207,7 +208,6 @@ export declare const StepActivityPartSchema: z.ZodObject<{
207
208
  "generating-summary": "generating-summary";
208
209
  indexing: "indexing";
209
210
  persisting: "persisting";
210
- complete: "complete";
211
211
  retrying: "retrying";
212
212
  }>;
213
213
  activity: z.ZodString;
@@ -314,8 +314,8 @@ export declare const RunCompletedPartSchema: z.ZodObject<{
314
314
  type: z.ZodLiteral<"data-run-completed">;
315
315
  runId: z.ZodString;
316
316
  status: z.ZodEnum<{
317
- completed: "completed";
318
317
  partial: "partial";
318
+ completed: "completed";
319
319
  }>;
320
320
  completedSteps: z.ZodNumber;
321
321
  totalSteps: z.ZodNumber;
@@ -403,11 +403,11 @@ export declare const RunSynthesisPartSchema: z.ZodObject<{
403
403
  }, z.core.$strip>>;
404
404
  }, z.core.$strip>;
405
405
  export declare const SynthesisPhaseSchema: z.ZodEnum<{
406
+ complete: "complete";
406
407
  failed: "failed";
407
408
  skipped: "skipped";
408
409
  indexing: "indexing";
409
410
  persisting: "persisting";
410
- complete: "complete";
411
411
  starting: "starting";
412
412
  researching: "researching";
413
413
  drafting: "drafting";
@@ -419,11 +419,11 @@ export declare const SynthesisProgressPartSchema: z.ZodObject<{
419
419
  id: z.ZodString;
420
420
  runId: z.ZodString;
421
421
  phase: z.ZodEnum<{
422
+ complete: "complete";
422
423
  failed: "failed";
423
424
  skipped: "skipped";
424
425
  indexing: "indexing";
425
426
  persisting: "persisting";
426
- complete: "complete";
427
427
  starting: "starting";
428
428
  researching: "researching";
429
429
  drafting: "drafting";
@@ -574,6 +574,7 @@ export declare const CortexChatPartSchema: z.ZodDiscriminatedUnion<[z.ZodObject<
574
574
  runId: z.ZodString;
575
575
  stepId: z.ZodString;
576
576
  phase: z.ZodEnum<{
577
+ complete: "complete";
577
578
  failed: "failed";
578
579
  warning: "warning";
579
580
  "sandbox-init": "sandbox-init";
@@ -582,7 +583,6 @@ export declare const CortexChatPartSchema: z.ZodDiscriminatedUnion<[z.ZodObject<
582
583
  "generating-summary": "generating-summary";
583
584
  indexing: "indexing";
584
585
  persisting: "persisting";
585
- complete: "complete";
586
586
  retrying: "retrying";
587
587
  }>;
588
588
  activity: z.ZodString;
@@ -693,11 +693,11 @@ export declare const CortexChatPartSchema: z.ZodDiscriminatedUnion<[z.ZodObject<
693
693
  id: z.ZodString;
694
694
  runId: z.ZodString;
695
695
  phase: z.ZodEnum<{
696
+ complete: "complete";
696
697
  failed: "failed";
697
698
  skipped: "skipped";
698
699
  indexing: "indexing";
699
700
  persisting: "persisting";
700
- complete: "complete";
701
701
  starting: "starting";
702
702
  researching: "researching";
703
703
  drafting: "drafting";
@@ -712,8 +712,8 @@ export declare const CortexChatPartSchema: z.ZodDiscriminatedUnion<[z.ZodObject<
712
712
  type: z.ZodLiteral<"data-run-completed">;
713
713
  runId: z.ZodString;
714
714
  status: z.ZodEnum<{
715
- completed: "completed";
716
715
  partial: "partial";
716
+ completed: "completed";
717
717
  }>;
718
718
  completedSteps: z.ZodNumber;
719
719
  totalSteps: z.ZodNumber;
@@ -1785,11 +1785,11 @@ export declare const ExpressionHeatmapCellSchema: z.ZodObject<{
1785
1785
  dog: "dog";
1786
1786
  }>;
1787
1787
  rank: z.ZodEnum<{
1788
+ no_data: "no_data";
1789
+ absent: "absent";
1788
1790
  high: "high";
1789
1791
  medium: "medium";
1790
1792
  low: "low";
1791
- absent: "absent";
1792
- no_data: "no_data";
1793
1793
  not_loaded: "not_loaded";
1794
1794
  }>;
1795
1795
  }, z.core.$strip>;
@@ -1804,11 +1804,11 @@ export declare const ExpressionHeatmapSchema: z.ZodObject<{
1804
1804
  dog: "dog";
1805
1805
  }>;
1806
1806
  rank: z.ZodEnum<{
1807
+ no_data: "no_data";
1808
+ absent: "absent";
1807
1809
  high: "high";
1808
1810
  medium: "medium";
1809
1811
  low: "low";
1810
- absent: "absent";
1811
- no_data: "no_data";
1812
1812
  not_loaded: "not_loaded";
1813
1813
  }>;
1814
1814
  }, z.core.$strip>>;
@@ -1911,11 +1911,11 @@ export declare const PreclinicalProfileSchema: z.ZodObject<{
1911
1911
  dog: "dog";
1912
1912
  }>;
1913
1913
  rank: z.ZodEnum<{
1914
+ no_data: "no_data";
1915
+ absent: "absent";
1914
1916
  high: "high";
1915
1917
  medium: "medium";
1916
1918
  low: "low";
1917
- absent: "absent";
1918
- no_data: "no_data";
1919
1919
  not_loaded: "not_loaded";
1920
1920
  }>;
1921
1921
  }, z.core.$strip>>;
@@ -4229,11 +4229,11 @@ export declare const DossierSchema: z.ZodObject<{
4229
4229
  dog: "dog";
4230
4230
  }>;
4231
4231
  rank: z.ZodEnum<{
4232
+ no_data: "no_data";
4233
+ absent: "absent";
4232
4234
  high: "high";
4233
4235
  medium: "medium";
4234
4236
  low: "low";
4235
- absent: "absent";
4236
- no_data: "no_data";
4237
4237
  not_loaded: "not_loaded";
4238
4238
  }>;
4239
4239
  }, z.core.$strip>>;
@@ -5482,11 +5482,11 @@ export declare const ReferenceBiologyV4Shape: z.ZodObject<{
5482
5482
  dog: "dog";
5483
5483
  }>;
5484
5484
  rank: z.ZodEnum<{
5485
+ no_data: "no_data";
5486
+ absent: "absent";
5485
5487
  high: "high";
5486
5488
  medium: "medium";
5487
5489
  low: "low";
5488
- absent: "absent";
5489
- no_data: "no_data";
5490
5490
  not_loaded: "not_loaded";
5491
5491
  }>;
5492
5492
  }, z.core.$strip>>;
@@ -6914,11 +6914,11 @@ export declare const DossierV4Schema: z.ZodObject<{
6914
6914
  dog: "dog";
6915
6915
  }>;
6916
6916
  rank: z.ZodEnum<{
6917
+ no_data: "no_data";
6918
+ absent: "absent";
6917
6919
  high: "high";
6918
6920
  medium: "medium";
6919
6921
  low: "low";
6920
- absent: "absent";
6921
- no_data: "no_data";
6922
6922
  not_loaded: "not_loaded";
6923
6923
  }>;
6924
6924
  }, z.core.$strip>>;
@@ -9131,11 +9131,11 @@ export declare const DossierV4BodySchema: z.ZodObject<{
9131
9131
  dog: "dog";
9132
9132
  }>;
9133
9133
  rank: z.ZodEnum<{
9134
+ no_data: "no_data";
9135
+ absent: "absent";
9134
9136
  high: "high";
9135
9137
  medium: "medium";
9136
9138
  low: "low";
9137
- absent: "absent";
9138
- no_data: "no_data";
9139
9139
  not_loaded: "not_loaded";
9140
9140
  }>;
9141
9141
  }, z.core.$strip>>;
@@ -12206,11 +12206,11 @@ export declare const DossierV5Schema: z.ZodObject<{
12206
12206
  dog: "dog";
12207
12207
  }>;
12208
12208
  rank: z.ZodEnum<{
12209
+ no_data: "no_data";
12210
+ absent: "absent";
12209
12211
  high: "high";
12210
12212
  medium: "medium";
12211
12213
  low: "low";
12212
- absent: "absent";
12213
- no_data: "no_data";
12214
12214
  not_loaded: "not_loaded";
12215
12215
  }>;
12216
12216
  }, z.core.$strip>>;
@@ -14928,11 +14928,11 @@ export declare const DossierV5BodySchema: z.ZodObject<{
14928
14928
  dog: "dog";
14929
14929
  }>;
14930
14930
  rank: z.ZodEnum<{
14931
+ no_data: "no_data";
14932
+ absent: "absent";
14931
14933
  high: "high";
14932
14934
  medium: "medium";
14933
14935
  low: "low";
14934
- absent: "absent";
14935
- no_data: "no_data";
14936
14936
  not_loaded: "not_loaded";
14937
14937
  }>;
14938
14938
  }, z.core.$strip>>;
@@ -16557,11 +16557,11 @@ export declare const DossierSchemaV3Legacy: z.ZodObject<{
16557
16557
  dog: "dog";
16558
16558
  }>;
16559
16559
  rank: z.ZodEnum<{
16560
+ no_data: "no_data";
16561
+ absent: "absent";
16560
16562
  high: "high";
16561
16563
  medium: "medium";
16562
16564
  low: "low";
16563
- absent: "absent";
16564
- no_data: "no_data";
16565
16565
  not_loaded: "not_loaded";
16566
16566
  }>;
16567
16567
  }, z.core.$strip>>;
@@ -31,6 +31,7 @@ import type { UsageRecorder } from "../billing/usage-recorder.js";
31
31
  import type { RunSession } from "../auth/types.js";
32
32
  import { type Tool } from "../tools/define-tool.js";
33
33
  import type { BioToolKeys } from "../tools/bio/keys.js";
34
+ import type { CitationResolver } from "../citations/types.js";
34
35
  /**
35
36
  * The synthesizer's agent identity — the `source.agentId` on its loop events
36
37
  * and the `agent_id` of the run-phase `synthesis` row `executeAnalysis` writes
@@ -67,6 +68,8 @@ export interface GenerateRunSynthesisInput {
67
68
  readonly model: string;
68
69
  /** API keys for the bio/chem tools the embedded literature reviewer uses. */
69
70
  readonly bioKeys: BioToolKeys;
71
+ /** Shared resolver used by the embedded literature reviewer. */
72
+ readonly citationResolver: CitationResolver;
70
73
  /** LLM usage-accounting seam for the synthesizer + reviewer loops; omitted falls back to the no-op recorder. */
71
74
  readonly usageRecorder?: UsageRecorder;
72
75
  /** Step summaries from the completed run. Non-empty. */
@@ -349,6 +349,7 @@ export async function generateRunSynthesis(input) {
349
349
  provider: input.provider,
350
350
  model: input.model,
351
351
  bioKeys: input.bioKeys,
352
+ citationResolver: input.citationResolver,
352
353
  usageRecorder: input.usageRecorder,
353
354
  });
354
355
  const validateTool = buildValidateTool(innerCtx);
package/dist/index.d.ts CHANGED
@@ -6,6 +6,7 @@
6
6
  */
7
7
  export { assembleCoreRuntime } from "./runtime/assemble.js";
8
8
  export type { CoreRuntime, CoreRuntimeDeps, CoreWorkflowDeps, RegisteredWorkflows, ConversationAssemblyDeps, SandboxStepCallable } from "./runtime/assemble.js";
9
+ export type { ThreadAgentResolver, UnregisteredThreadType } from "./runtime/assemble.js";
9
10
  export { bootHarness } from "./runtime/boot.js";
10
11
  export type { BootHarnessDeps, BootedHarness } from "./runtime/boot.js";
11
12
  export { createConversationAgent } from "./agents/conversation-agent.js";
@@ -31,6 +32,10 @@ export type { DbosWorkflowPurgerDeps } from "./execution/dbos-workflow-purger.js
31
32
  export type { WorkflowPurger } from "./execution/workflow-purger.js";
32
33
  export { defineTool, isToolError } from "./tools/define-tool.js";
33
34
  export type { Tool, ToolDefinition, ToolContext, ToolError } from "./tools/define-tool.js";
35
+ export { createCitationResolver } from "./citations/resolve.js";
36
+ export type { CitationResolverConfig, CitationResolverDependencies, CitationResolverSourceConfig } from "./citations/resolve.js";
37
+ export { CitationKindSchema, CitationInputSchema, CitationSourceSchema, CitationSourceStatusSchema, CitationResolutionResultSchema, CitationVerdictSchema, CitationCoverageSchema, ComparisonStatusSchema, CitationFieldSchema, UnsupportedWorkKindSchema, CitationIdentifiersSchema, NormalizedCitationMetadataSchema, NormalizedCitationSchema, CitationRecordSchema, IdentifierEvidenceSchema, CitationSourceOutcomeSchema, CitationFieldComparisonSchema, CitationConflictSchema, CitationCandidateClusterSchema, CitationClusterRelationSchema, CitationSourceOperationSchema, CitationSourcePlanItemSchema, } from "./citations/types.js";
38
+ export type { CitationKind, CitationInput, CitationSource, CitationSourceStatus, CitationResolver, CitationResolveOptions, CitationResolutionResult, CitationVerdict, CitationCoverage, ComparisonStatus, CitationField, UnsupportedWorkKind, CitationIdentifiers, NormalizedCitationMetadata, NormalizedCitation, CitationSourceOutcome, CitationRecord, IdentifierEvidence, CitationFieldComparison, CitationConflict, CitationCandidateCluster, CitationSourceClient, CitationSourceRequest, CitationSourceOperation, CitationSourcePlanItem, RegistrationAgencyEvidence, } from "./citations/types.js";
34
39
  export { createAskGateway } from "./tools/approval/gateway.js";
35
40
  export type { AskGateway, AskGatewayDeps, AskContext, AnswerOutcome, PendingAsk } from "./tools/approval/gateway.js";
36
41
  export { UnavailableAsk, AskRejectedError } from "./tools/approval/contract.js";
@@ -56,7 +61,7 @@ export { createStreamingChat } from "./providers/streaming-chat.js";
56
61
  export { prepareChatTurn } from "./app/chat-turn.js";
57
62
  export type { PrepareChatTurnDeps, PrepareChatTurnParams, PrepareChatTurnResult } from "./app/chat-turn.js";
58
63
  export { createThreadStore } from "./memory/thread-store.js";
59
- export type { ThreadStore, Thread, CreateThreadInput, ListThreadsInput, ThreadPage } from "./memory/thread-store.js";
64
+ export type { ThreadStore, Thread, ThreadType, ThreadInputError, CreateThreadInput, ListThreadsInput, ThreadPage } from "./memory/thread-store.js";
60
65
  export { createThreadHistory, conversationRecordTurn } from "./memory/thread-history.js";
61
66
  export type { ThreadHistory, StoredMessage, MessagePage, RetractOutcome, ConversationTurn } from "./memory/thread-history.js";
62
67
  export { syntheticUserMessage, syntheticRecordMessage, isSyntheticUserMessage, isSyntheticRecordMessage } from "./memory/ai-sdk-message-storage.js";
package/dist/index.js CHANGED
@@ -33,6 +33,9 @@ export { createDbosRunLauncher } from "./execution/dbos-run-launcher.js";
33
33
  export { createDbosWorkflowPurger } from "./execution/dbos-workflow-purger.js";
34
34
  // Tool primitive.
35
35
  export { defineTool, isToolError } from "./tools/define-tool.js";
36
+ // Host-agnostic citation verification service and its public contracts.
37
+ export { createCitationResolver } from "./citations/resolve.js";
38
+ export { CitationKindSchema, CitationInputSchema, CitationSourceSchema, CitationSourceStatusSchema, CitationResolutionResultSchema, CitationVerdictSchema, CitationCoverageSchema, ComparisonStatusSchema, CitationFieldSchema, UnsupportedWorkKindSchema, CitationIdentifiersSchema, NormalizedCitationMetadataSchema, NormalizedCitationSchema, CitationRecordSchema, IdentifierEvidenceSchema, CitationSourceOutcomeSchema, CitationFieldComparisonSchema, CitationConflictSchema, CitationCandidateClusterSchema, CitationClusterRelationSchema, CitationSourceOperationSchema, CitationSourcePlanItemSchema, } from "./citations/types.js";
36
39
  // Seam: tool approval (`ctx.ask`). `createAskGateway` realizes the `Ask` seam
37
40
  // over the injected `Pool` and carries the outward `answer`/`pending` API plus
38
41
  // the boot-time `sweepExpired`; `UnavailableAsk` is the shipped deny-by-default
@@ -0,0 +1,8 @@
1
+ export declare class BoundedTtlCache<Value> {
2
+ private readonly maximum;
3
+ private readonly now;
4
+ private readonly entries;
5
+ constructor(maximum: number, now?: () => number);
6
+ get(key: string): Value | undefined;
7
+ set(key: string, value: Value, ttlMs: number): void;
8
+ }
@@ -0,0 +1,35 @@
1
+ export class BoundedTtlCache {
2
+ maximum;
3
+ now;
4
+ entries = new Map();
5
+ constructor(maximum, now = Date.now) {
6
+ this.maximum = maximum;
7
+ this.now = now;
8
+ if (!Number.isInteger(maximum) || maximum < 0)
9
+ throw new Error("cache maximum must be a non-negative integer");
10
+ }
11
+ get(key) {
12
+ const entry = this.entries.get(key);
13
+ if (entry === undefined)
14
+ return undefined;
15
+ if (entry.expiresAt <= this.now()) {
16
+ this.entries.delete(key);
17
+ return undefined;
18
+ }
19
+ this.entries.delete(key);
20
+ this.entries.set(key, entry);
21
+ return entry.value;
22
+ }
23
+ set(key, value, ttlMs) {
24
+ if (this.maximum === 0 || ttlMs <= 0)
25
+ return;
26
+ this.entries.delete(key);
27
+ this.entries.set(key, { value, expiresAt: this.now() + ttlMs });
28
+ while (this.entries.size > this.maximum) {
29
+ const oldest = this.entries.keys().next().value;
30
+ if (oldest === undefined)
31
+ break;
32
+ this.entries.delete(oldest);
33
+ }
34
+ }
35
+ }
@@ -0,0 +1,35 @@
1
+ export interface RateLimitConfig {
2
+ readonly maxConcurrency: number;
3
+ readonly requestsPerSecond: number;
4
+ /**
5
+ * Retry policy for the source's HTTP layer. Retries re-enter the limiter as
6
+ * fresh attempts, so they are paced like any other request; the limiter
7
+ * itself does not read these two fields.
8
+ */
9
+ readonly maxRetries: number;
10
+ readonly maxRetryDelayMs: number;
11
+ }
12
+ export interface RateLimitRuntime {
13
+ readonly now?: () => number;
14
+ readonly sleep?: (milliseconds: number, signal?: AbortSignal) => Promise<void>;
15
+ }
16
+ export declare function sleepWithSignal(milliseconds: number, signal?: AbortSignal): Promise<void>;
17
+ export declare class BoundedRateLimiter {
18
+ private readonly config;
19
+ private readonly semaphore;
20
+ private readonly now;
21
+ private readonly sleep;
22
+ private reservationTail;
23
+ private nextStartAt;
24
+ constructor(config: RateLimitConfig, runtime?: RateLimitRuntime);
25
+ private reserveStart;
26
+ run<T>(operation: () => Promise<T>, signal?: AbortSignal): Promise<T>;
27
+ }
28
+ /**
29
+ * Admission gate for a source's HTTP layer (`SourceHttpOptions.schedule`).
30
+ *
31
+ * It gates the network call alone: the caller arms its request timeout inside
32
+ * the admitted operation, so a request held behind pacing or a concurrency
33
+ * ceiling cannot be reported as a timeout before it ever reaches the network.
34
+ */
35
+ export declare function createRateLimitSchedule(config: RateLimitConfig, runtime?: RateLimitRuntime): <T>(operation: () => Promise<T>, signal?: AbortSignal) => Promise<T>;
@@ -0,0 +1,121 @@
1
+ function abortReason(signal) {
2
+ return signal.reason instanceof Error ? signal.reason : new DOMException("The operation was aborted", "AbortError");
3
+ }
4
+ export function sleepWithSignal(milliseconds, signal) {
5
+ if (milliseconds <= 0)
6
+ return Promise.resolve();
7
+ if (signal?.aborted)
8
+ return Promise.reject(abortReason(signal));
9
+ return new Promise((resolve, reject) => {
10
+ const timeout = setTimeout(() => {
11
+ signal?.removeEventListener("abort", onAbort);
12
+ resolve();
13
+ }, milliseconds);
14
+ const onAbort = () => {
15
+ clearTimeout(timeout);
16
+ reject(abortReason(signal));
17
+ };
18
+ signal?.addEventListener("abort", onAbort, { once: true });
19
+ });
20
+ }
21
+ class Semaphore {
22
+ maximum;
23
+ active = 0;
24
+ waiters = [];
25
+ constructor(maximum) {
26
+ this.maximum = maximum;
27
+ }
28
+ async acquire(signal) {
29
+ if (signal?.aborted)
30
+ throw abortReason(signal);
31
+ if (this.active < this.maximum) {
32
+ this.active += 1;
33
+ return;
34
+ }
35
+ await new Promise((resolve, reject) => {
36
+ const waiter = { resolve, reject, ...(signal === undefined ? {} : { signal }) };
37
+ if (signal !== undefined) {
38
+ waiter.onAbort = () => {
39
+ const index = this.waiters.indexOf(waiter);
40
+ if (index >= 0)
41
+ this.waiters.splice(index, 1);
42
+ reject(abortReason(signal));
43
+ };
44
+ signal.addEventListener("abort", waiter.onAbort, { once: true });
45
+ }
46
+ this.waiters.push(waiter);
47
+ });
48
+ }
49
+ release() {
50
+ const waiter = this.waiters.shift();
51
+ if (waiter === undefined) {
52
+ this.active -= 1;
53
+ return;
54
+ }
55
+ if (waiter.signal !== undefined && waiter.onAbort !== undefined)
56
+ waiter.signal.removeEventListener("abort", waiter.onAbort);
57
+ waiter.resolve();
58
+ }
59
+ }
60
+ export class BoundedRateLimiter {
61
+ config;
62
+ semaphore;
63
+ now;
64
+ sleep;
65
+ reservationTail = Promise.resolve();
66
+ nextStartAt = 0;
67
+ constructor(config, runtime = {}) {
68
+ this.config = config;
69
+ if (!Number.isInteger(config.maxConcurrency) || config.maxConcurrency < 1)
70
+ throw new Error("maxConcurrency must be a positive integer");
71
+ if (!(config.requestsPerSecond > 0))
72
+ throw new Error("requestsPerSecond must be positive");
73
+ this.semaphore = new Semaphore(config.maxConcurrency);
74
+ this.now = runtime.now ?? Date.now;
75
+ this.sleep = runtime.sleep ?? sleepWithSignal;
76
+ }
77
+ async reserveStart(signal) {
78
+ let release;
79
+ const predecessor = this.reservationTail;
80
+ this.reservationTail = new Promise((resolve) => {
81
+ release = resolve;
82
+ });
83
+ if (signal?.aborted) {
84
+ release();
85
+ throw abortReason(signal);
86
+ }
87
+ await predecessor;
88
+ try {
89
+ if (signal?.aborted)
90
+ throw abortReason(signal);
91
+ const startAt = Math.max(this.now(), this.nextStartAt);
92
+ this.nextStartAt = startAt + 1000 / this.config.requestsPerSecond;
93
+ return startAt;
94
+ }
95
+ finally {
96
+ release();
97
+ }
98
+ }
99
+ async run(operation, signal) {
100
+ const startAt = await this.reserveStart(signal);
101
+ await this.sleep(Math.max(0, startAt - this.now()), signal);
102
+ await this.semaphore.acquire(signal);
103
+ try {
104
+ return await operation();
105
+ }
106
+ finally {
107
+ this.semaphore.release();
108
+ }
109
+ }
110
+ }
111
+ /**
112
+ * Admission gate for a source's HTTP layer (`SourceHttpOptions.schedule`).
113
+ *
114
+ * It gates the network call alone: the caller arms its request timeout inside
115
+ * the admitted operation, so a request held behind pacing or a concurrency
116
+ * ceiling cannot be reported as a timeout before it ever reaches the network.
117
+ */
118
+ export function createRateLimitSchedule(config, runtime = {}) {
119
+ const limiter = new BoundedRateLimiter(config, runtime);
120
+ return (operation, signal) => limiter.run(operation, signal);
121
+ }
@@ -0,0 +1,22 @@
1
+ import { type SourceHttpOptions, type SourceHttpResult } from "./http.js";
2
+ export interface ArxivPaper {
3
+ id: string;
4
+ title: string;
5
+ abstract: string;
6
+ authors: string[];
7
+ published: string;
8
+ categories: string[];
9
+ url: string;
10
+ pdfUrl?: string;
11
+ }
12
+ export interface ArxivSearchInput {
13
+ readonly query: string;
14
+ readonly categories?: readonly string[];
15
+ readonly limit: number;
16
+ }
17
+ export interface ArxivSource {
18
+ search(input: ArxivSearchInput, signal?: AbortSignal): Promise<SourceHttpResult<ArxivPaper[]>>;
19
+ lookupExact(id: string, limit: number, signal?: AbortSignal): Promise<SourceHttpResult<ArxivPaper[]>>;
20
+ }
21
+ export declare function parseArxivAtom(xml: string): ArxivPaper[];
22
+ export declare function createArxivSource(options?: SourceHttpOptions): ArxivSource;