@inflexa-ai/harness 0.45.0 → 0.46.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -3
- package/dist/agents/conversation-agent.d.ts +19 -3
- package/dist/agents/conversation-agent.js +49 -30
- package/dist/agents/report-session-agent.d.ts +15 -15
- package/dist/agents/report-session-agent.js +23 -15
- package/dist/agents/sandbox/index.d.ts +1 -1
- package/dist/agents/sandbox/index.js +1 -1
- package/dist/agents/sandbox/shared.d.ts +35 -16
- package/dist/agents/sandbox/shared.js +63 -24
- package/dist/agents/sandbox/translational-safety-agent.js +26 -0
- package/dist/agents/sandbox/types.d.ts +26 -3
- package/dist/agents/sandbox/validate-skills.d.ts +2 -2
- package/dist/agents/sandbox/validate-skills.js +3 -1
- package/dist/agents/sandbox-catalog.d.ts +16 -2
- package/dist/agents/sandbox-catalog.js +22 -3
- package/dist/agents/system-prompt.d.ts +2 -2
- package/dist/app/approve-plan.d.ts +5 -2
- package/dist/app/approve-plan.js +1 -1
- package/dist/app/chat-turn-workflow.d.ts +114 -0
- package/dist/app/chat-turn-workflow.js +307 -0
- package/dist/app/chat-turn.d.ts +85 -57
- package/dist/app/chat-turn.js +125 -99
- package/dist/app/data-profile-orientation.js +10 -8
- package/dist/app/data-profile-view.d.ts +4 -4
- package/dist/app/data-profile-view.js +9 -8
- package/dist/app/in-process-turn.d.ts +42 -0
- package/dist/app/in-process-turn.js +139 -0
- package/dist/app/message-assembly.d.ts +10 -4
- package/dist/app/message-assembly.js +13 -8
- package/dist/app/report-session-runtime.d.ts +4 -4
- package/dist/app/report-session-runtime.js +36 -21
- package/dist/app/spawn-report-session.d.ts +33 -28
- package/dist/app/spawn-report-session.js +25 -40
- package/dist/app/synthesize-run.d.ts +22 -16
- package/dist/app/synthesize-run.js +41 -35
- package/dist/app/work.d.ts +96 -0
- package/dist/app/work.js +147 -0
- package/dist/auth/local-auth-context.d.ts +1 -3
- package/dist/auth/local-auth-context.js +1 -3
- package/dist/auth/local-run-authorizer.d.ts +1 -1
- package/dist/auth/local-run-authorizer.js +5 -3
- package/dist/auth/types.d.ts +26 -26
- package/dist/billing/cached-resolver.d.ts +4 -4
- package/dist/billing/run-charge.d.ts +5 -8
- package/dist/billing/run-charge.js +2 -2
- package/dist/billing/usage-recorder.d.ts +9 -9
- package/dist/citations/aggregate.js +1 -1
- package/dist/citations/clients/arxiv.d.ts +2 -2
- package/dist/citations/clients/arxiv.js +12 -4
- package/dist/citations/clients/common.js +4 -2
- package/dist/citations/clients/crossref.d.ts +2 -2
- package/dist/citations/clients/crossref.js +37 -37
- package/dist/citations/clients/doi-registry.js +15 -16
- package/dist/citations/clients/pubmed.d.ts +2 -2
- package/dist/citations/clients/pubmed.js +20 -13
- package/dist/citations/clients/semantic-scholar.d.ts +2 -2
- package/dist/citations/clients/semantic-scholar.js +9 -9
- package/dist/citations/compare.js +2 -2
- package/dist/citations/match.d.ts +2 -2
- package/dist/citations/match.js +12 -7
- package/dist/citations/normalize.js +35 -26
- package/dist/citations/plan.js +6 -2
- package/dist/citations/resolve.d.ts +6 -6
- package/dist/citations/resolve.js +34 -25
- package/dist/citations/types.d.ts +77 -77
- package/dist/config/environment-stores.d.ts +10 -8
- package/dist/config/resource-limits.js +1 -3
- package/dist/contracts/analogy-report.d.ts +7 -7
- package/dist/contracts/analogy-report.js +2 -2
- package/dist/contracts/chat-events.d.ts +46 -22
- package/dist/contracts/chat-events.js +1 -1
- package/dist/contracts/chat-frame.d.ts +15 -5
- package/dist/contracts/chat-frame.js +67 -40
- package/dist/contracts/chat-parts.d.ts +130 -67
- package/dist/contracts/chat-parts.js +1 -0
- package/dist/contracts/content-url.js +16 -2
- package/dist/contracts/data-profile.d.ts +38 -38
- package/dist/contracts/index.d.ts +3 -3
- package/dist/contracts/index.js +1 -1
- package/dist/contracts/message.d.ts +6 -6
- package/dist/contracts/organ-system.d.ts +11 -11
- package/dist/contracts/part-registry.d.ts +5 -4
- package/dist/contracts/part-registry.js +5 -0
- package/dist/contracts/profile-vocabulary.d.ts +11 -10
- package/dist/contracts/profile-vocabulary.js +10 -3
- package/dist/contracts/report-blocks.d.ts +329 -329
- package/dist/contracts/report-reference.d.ts +105 -81
- package/dist/contracts/report-reference.js +30 -13
- package/dist/contracts/schemas/chat-events.d.ts +45 -6
- package/dist/contracts/schemas/chat-events.js +16 -0
- package/dist/contracts/schemas/chat-parts.d.ts +214 -102
- package/dist/contracts/schemas/chat-parts.js +50 -7
- package/dist/contracts/schemas/index.d.ts +1 -1
- package/dist/contracts/schemas/index.js +1 -1
- package/dist/contracts/severity.d.ts +1 -1
- package/dist/contracts/structure-source.d.ts +3 -3
- package/dist/contracts/structure-source.js +6 -2
- package/dist/contracts/subagent-activity.d.ts +2 -2
- package/dist/contracts/subagent-activity.js +5 -3
- package/dist/contracts/usage.d.ts +2 -2
- package/dist/data/safety-panel-schema.d.ts +25 -25
- package/dist/data/safety-panel-schema.js +13 -4
- package/dist/execution/artifact-metadata.d.ts +23 -15
- package/dist/execution/artifact-metadata.js +33 -10
- package/dist/execution/artifact-record.d.ts +2 -2
- package/dist/execution/artifact-registration.d.ts +5 -5
- package/dist/execution/artifact-registry.d.ts +8 -8
- package/dist/execution/dbos-run-launcher.d.ts +24 -4
- package/dist/execution/dbos-run-launcher.js +58 -4
- package/dist/execution/dbos-workflow-purger.d.ts +7 -6
- package/dist/execution/dbos-workflow-purger.js +29 -21
- package/dist/execution/input-signature.d.ts +2 -2
- package/dist/execution/post-step-pipeline.d.ts +9 -9
- package/dist/execution/post-step-pipeline.js +1 -1
- package/dist/execution/post-step.js +2 -2
- package/dist/execution/reconcile-manifest.d.ts +4 -4
- package/dist/execution/reconcile-manifest.js +3 -2
- package/dist/execution/run-authorizer.d.ts +46 -37
- package/dist/execution/run-authorizer.js +8 -8
- package/dist/execution/run-canceler.d.ts +39 -17
- package/dist/execution/run-canceler.js +137 -28
- package/dist/execution/run-end-record.d.ts +29 -0
- package/dist/execution/run-end-record.js +27 -0
- package/dist/execution/run-event-parts.d.ts +0 -8
- package/dist/execution/run-event-parts.js +29 -24
- package/dist/execution/run-event-stream.d.ts +8 -8
- package/dist/execution/run-event-stream.js +3 -4
- package/dist/execution/run-launcher.d.ts +4 -4
- package/dist/execution/run-synthesis.d.ts +49 -48
- package/dist/execution/run-synthesis.js +96 -255
- package/dist/execution/staged-input.d.ts +2 -2
- package/dist/execution/step-summary.d.ts +6 -6
- package/dist/execution/step-summary.js +4 -8
- package/dist/execution/topo-sort.js +4 -3
- package/dist/execution/workflow-purger.d.ts +2 -2
- package/dist/index.d.ts +25 -24
- package/dist/index.js +36 -37
- package/dist/input-sanitization.js +9 -2
- package/dist/input-scan/clustering.d.ts +6 -6
- package/dist/input-scan/clustering.js +11 -5
- package/dist/input-scan/companions.js +3 -2
- package/dist/input-scan/detect-sets.d.ts +2 -2
- package/dist/input-scan/detect-sets.js +25 -21
- package/dist/input-scan/enrich.d.ts +6 -6
- package/dist/input-scan/enrich.js +29 -12
- package/dist/input-scan/formats.d.ts +2 -2
- package/dist/input-scan/formats.js +8 -2
- package/dist/input-scan/markers.d.ts +2 -2
- package/dist/input-scan/markers.js +14 -5
- package/dist/input-scan/menu.d.ts +10 -10
- package/dist/input-scan/menu.js +0 -0
- package/dist/input-scan/quarantine.d.ts +2 -2
- package/dist/input-scan/quarantine.js +23 -18
- package/dist/input-scan/readout-budget.d.ts +2 -2
- package/dist/input-scan/readout-budget.js +1 -1
- package/dist/input-scan/readout.d.ts +2 -2
- package/dist/input-scan/readout.js +47 -34
- package/dist/input-scan/scan.d.ts +2 -2
- package/dist/input-scan/scan.js +7 -5
- package/dist/input-scan/set-types.d.ts +28 -28
- package/dist/input-scan/shapes.d.ts +4 -4
- package/dist/input-scan/shapes.js +0 -0
- package/dist/input-scan/templates.d.ts +10 -10
- package/dist/input-scan/templates.js +30 -22
- package/dist/input-scan/tokens.d.ts +6 -4
- package/dist/input-scan/tokens.js +100 -38
- package/dist/input-scan/types.d.ts +22 -22
- package/dist/lib/async-utils.d.ts +3 -7
- package/dist/lib/async-utils.js +5 -9
- package/dist/lib/cache.js +1 -1
- package/dist/lib/chrome.d.ts +46 -6
- package/dist/lib/console-logger.js +2 -2
- package/dist/lib/db-result.d.ts +22 -6
- package/dist/lib/db-result.js +9 -13
- package/dist/lib/eyes.d.ts +4 -4
- package/dist/lib/eyes.js +1 -1
- package/dist/lib/fs-helpers.js +18 -6
- package/dist/lib/fs-result.d.ts +1 -0
- package/dist/lib/fs-result.js +5 -6
- package/dist/lib/hooks.d.ts +23 -7
- package/dist/lib/hooks.js +17 -3
- package/dist/lib/host-concurrency.js +3 -2
- package/dist/lib/logger.d.ts +2 -2
- package/dist/lib/logger.js +2 -1
- package/dist/lib/metrics.d.ts +1 -1
- package/dist/lib/null-proto.d.ts +6 -0
- package/dist/lib/null-proto.js +17 -0
- package/dist/lib/otel-spans.d.ts +1 -1
- package/dist/lib/otel-spans.js +9 -5
- package/dist/lib/otel.d.ts +4 -2
- package/dist/lib/otel.js +10 -2
- package/dist/lib/page-capture.d.ts +8 -8
- package/dist/lib/page-capture.js +9 -4
- package/dist/lib/parse-json.d.ts +5 -0
- package/dist/lib/parse-json.js +12 -0
- package/dist/lib/present.d.ts +12 -0
- package/dist/lib/present.js +39 -0
- package/dist/lib/rate-limit.d.ts +4 -4
- package/dist/lib/rate-limit.js +12 -13
- package/dist/lib/regulatory-corpus/fetch-fda-guidance.d.ts +4 -4
- package/dist/lib/regulatory-corpus/fetch-fda-guidance.js +4 -10
- package/dist/lib/regulatory-corpus/fetch-ich.d.ts +4 -4
- package/dist/lib/regulatory-corpus/fetch-ich.js +18 -14
- package/dist/lib/regulatory-corpus/normalize-whitespace.d.ts +6 -0
- package/dist/lib/regulatory-corpus/normalize-whitespace.js +41 -0
- package/dist/lib/regulatory-corpus.d.ts +10 -10
- package/dist/lib/regulatory-corpus.js +3 -1
- package/dist/lib/result.d.ts +10 -11
- package/dist/lib/result.js +15 -13
- package/dist/lib/storage.d.ts +2 -2
- package/dist/lib/test/async-iterable.d.ts +9 -0
- package/dist/lib/test/async-iterable.js +28 -0
- package/dist/lib/test/request-url.d.ts +5 -0
- package/dist/lib/test/request-url.js +7 -0
- package/dist/lib/test/result-assert.d.ts +12 -0
- package/dist/lib/test/result-assert.js +17 -0
- package/dist/lib/test/text-shapes.d.ts +24 -0
- package/dist/lib/test/text-shapes.js +63 -0
- package/dist/lib/text.d.ts +22 -0
- package/dist/lib/text.js +68 -0
- package/dist/lib/thrown.d.ts +18 -0
- package/dist/lib/thrown.js +30 -0
- package/dist/lib/unknown-array.d.ts +6 -0
- package/dist/lib/unknown-array.js +8 -0
- package/dist/lib/unknown-containers.d.ts +14 -0
- package/dist/lib/unknown-containers.js +17 -0
- package/dist/lib/unknown-text.d.ts +8 -0
- package/dist/lib/unknown-text.js +28 -0
- package/dist/lib/zod-issue-shape.d.ts +1 -1
- package/dist/lib/zod-issue-shape.js +31 -31
- package/dist/lib/zod-issues.d.ts +3 -3
- package/dist/lib/zod-issues.js +30 -17
- package/dist/literature/sources/arxiv.d.ts +6 -6
- package/dist/literature/sources/arxiv.js +92 -35
- package/dist/literature/sources/http.d.ts +2 -2
- package/dist/literature/sources/http.js +16 -15
- package/dist/literature/sources/pubmed.d.ts +16 -16
- package/dist/literature/sources/pubmed.js +96 -61
- package/dist/literature/sources/semantic-scholar.d.ts +8 -8
- package/dist/literature/sources/semantic-scholar.js +22 -13
- package/dist/loop/accounting.d.ts +63 -0
- package/dist/loop/accounting.js +141 -0
- package/dist/loop/call-policy.d.ts +73 -0
- package/dist/loop/call-policy.js +109 -0
- package/dist/loop/chat-stream.d.ts +62 -0
- package/dist/loop/chat-stream.js +237 -0
- package/dist/loop/compaction.d.ts +14 -9
- package/dist/loop/compaction.js +17 -0
- package/dist/loop/metrics.d.ts +12 -15
- package/dist/loop/metrics.js +14 -26
- package/dist/loop/run-loop.d.ts +233 -0
- package/dist/loop/run-loop.js +770 -0
- package/dist/loop/sub-agent.d.ts +61 -0
- package/dist/loop/sub-agent.js +161 -0
- package/dist/loop/tool-adapter.d.ts +98 -0
- package/dist/loop/tool-adapter.js +364 -0
- package/dist/loop/tool-detail.d.ts +1 -1
- package/dist/loop/tool-detail.js +6 -5
- package/dist/loop/tool-outcome.d.ts +1 -1
- package/dist/loop/tool-output.d.ts +4 -4
- package/dist/loop/tool-output.js +2 -2
- package/dist/loop/turn-credentials.d.ts +34 -0
- package/dist/loop/turn-credentials.js +73 -0
- package/dist/loop/types.d.ts +34 -37
- package/dist/loop/types.js +2 -7
- package/dist/memory/ai-sdk-message-storage.d.ts +5 -5
- package/dist/memory/ai-sdk-message-storage.js +13 -11
- package/dist/memory/card-builders.d.ts +14 -14
- package/dist/memory/card-builders.js +19 -15
- package/dist/memory/conversation-display-recorder.d.ts +22 -6
- package/dist/memory/conversation-display-recorder.js +64 -20
- package/dist/memory/conversation-display-replay.js +3 -2
- package/dist/memory/conversation-display-storage.d.ts +15 -7
- package/dist/memory/conversation-display-storage.js +141 -36
- package/dist/memory/conversation-view.d.ts +4 -4
- package/dist/memory/conversation-view.js +5 -4
- package/dist/memory/count-tokens.js +10 -8
- package/dist/memory/derive-thread-title.d.ts +0 -13
- package/dist/memory/derive-thread-title.js +2 -1
- package/dist/memory/message-backfill.d.ts +12 -5
- package/dist/memory/message-backfill.js +5 -3
- package/dist/memory/thread-history.d.ts +66 -24
- package/dist/memory/thread-history.js +212 -79
- package/dist/memory/thread-store.d.ts +26 -17
- package/dist/memory/thread-store.js +15 -9
- package/dist/memory/tool-call-integrity.d.ts +2 -2
- package/dist/memory/tool-call-integrity.js +4 -3
- package/dist/memory/working-memory.d.ts +16 -12
- package/dist/memory/working-memory.js +72 -61
- package/dist/prompts/briefing.d.ts +63 -9
- package/dist/prompts/briefing.js +130 -3
- package/dist/prompts/planner.js +13 -2
- package/dist/prompts/synthesis-agent.d.ts +1 -1
- package/dist/prompts/synthesis-agent.js +6 -14
- package/dist/provenance/collector.d.ts +6 -6
- package/dist/provenance/collector.js +15 -8
- package/dist/provenance/exec-frame.d.ts +2 -2
- package/dist/provenance/exec-frame.js +6 -1
- package/dist/provenance/seam.d.ts +24 -19
- package/dist/provenance/seam.js +7 -5
- package/dist/provenance/types.d.ts +6 -6
- package/dist/providers/ai-sdk.d.ts +113 -62
- package/dist/providers/ai-sdk.js +303 -458
- package/dist/providers/embedding.d.ts +2 -2
- package/dist/providers/embedding.js +1 -1
- package/dist/providers/errors.d.ts +22 -2
- package/dist/providers/errors.js +98 -50
- package/dist/providers/prompt-cache.d.ts +8 -8
- package/dist/providers/prompt-cache.js +13 -11
- package/dist/providers/reasoning.d.ts +2 -2
- package/dist/providers/reasoning.js +2 -2
- package/dist/providers/types.d.ts +59 -92
- package/dist/reference-data/catalog.d.ts +2 -15
- package/dist/reference-data/catalog.js +166 -10
- package/dist/reference-data/receipt.d.ts +2 -2
- package/dist/report-model/assert-rules.js +1 -1
- package/dist/report-model/authoring-grammar.d.ts +209 -231
- package/dist/report-model/block-walk.d.ts +10 -10
- package/dist/report-model/block-walk.js +2 -0
- package/dist/report-model/draft-finish.d.ts +8 -8
- package/dist/report-model/draft-finish.js +1 -1
- package/dist/report-model/draft-hash.js +8 -7
- package/dist/report-model/draft-operations.d.ts +22 -10
- package/dist/report-model/draft-operations.js +48 -30
- package/dist/report-model/draft-read.d.ts +19 -7
- package/dist/report-model/draft-read.js +16 -6
- package/dist/report-model/draft.d.ts +844 -2
- package/dist/report-model/draft.js +3 -1
- package/dist/report-model/fixture-resolver.js +39 -16
- package/dist/report-model/pin-snapshot.d.ts +2 -2
- package/dist/report-model/pin-snapshot.js +15 -15
- package/dist/report-model/production-resolver.d.ts +18 -18
- package/dist/report-model/production-resolver.js +50 -42
- package/dist/report-model/reference-resolver.d.ts +26 -10
- package/dist/report-model/reference-resolver.js +68 -5
- package/dist/report-model/reference-stamp.js +30 -38
- package/dist/report-model/structural-validation.js +12 -4
- package/dist/report-model/validate.d.ts +7 -7
- package/dist/report-model/validate.js +6 -6
- package/dist/report-render/assets.d.ts +2 -2
- package/dist/report-render/assets.js +27 -3
- package/dist/report-render/chart-export.d.ts +10 -2
- package/dist/report-render/chart-export.js +37 -11
- package/dist/report-render/chart-presets.d.ts +8 -8
- package/dist/report-render/chart-presets.js +3 -3
- package/dist/report-render/chart-renderers.d.ts +23 -16
- package/dist/report-render/chart-renderers.js +74 -53
- package/dist/report-render/chart-toolbox.d.ts +2 -2
- package/dist/report-render/chart-toolbox.js +7 -6
- package/dist/report-render/chart.d.ts +15 -16
- package/dist/report-render/chart.js +369 -252
- package/dist/report-render/design.d.ts +36 -297
- package/dist/report-render/design.js +0 -12
- package/dist/report-render/figures/common.d.ts +12 -12
- package/dist/report-render/figures/common.js +42 -31
- package/dist/report-render/figures/dendrogram.d.ts +3 -3
- package/dist/report-render/figures/dendrogram.js +10 -10
- package/dist/report-render/figures/dense.js +15 -8
- package/dist/report-render/figures/dotplot.js +46 -33
- package/dist/report-render/figures/embedding.js +52 -43
- package/dist/report-render/figures/equal-units.d.ts +10 -10
- package/dist/report-render/figures/equal-units.js +27 -27
- package/dist/report-render/figures/forest.js +9 -7
- package/dist/report-render/figures/gsea.js +21 -11
- package/dist/report-render/figures/heatmap.js +13 -9
- package/dist/report-render/figures/index.d.ts +10 -10
- package/dist/report-render/figures/index.js +4 -2
- package/dist/report-render/figures/km.js +10 -9
- package/dist/report-render/figures/label-room.d.ts +12 -12
- package/dist/report-render/figures/label-room.js +7 -2
- package/dist/report-render/figures/locuszoom.d.ts +2 -2
- package/dist/report-render/figures/locuszoom.js +59 -31
- package/dist/report-render/figures/lollipop.js +3 -2
- package/dist/report-render/figures/ma.js +8 -4
- package/dist/report-render/figures/manhattan.d.ts +1 -2
- package/dist/report-render/figures/manhattan.js +52 -34
- package/dist/report-render/figures/oncoprint.js +4 -5
- package/dist/report-render/figures/pca.js +25 -11
- package/dist/report-render/figures/qq.js +20 -9
- package/dist/report-render/figures/roc.js +1 -1
- package/dist/report-render/figures/sankey.d.ts +2 -2
- package/dist/report-render/figures/sankey.js +11 -10
- package/dist/report-render/figures/upset.d.ts +6 -6
- package/dist/report-render/figures/upset.js +7 -4
- package/dist/report-render/figures/volcano.js +12 -10
- package/dist/report-render/hybrid-svg.d.ts +4 -4
- package/dist/report-render/hybrid-svg.js +7 -5
- package/dist/report-render/number-format.d.ts +4 -4
- package/dist/report-render/number-format.js +62 -27
- package/dist/report-render/page.js +2 -1
- package/dist/report-render/provenance-data.d.ts +2 -2
- package/dist/report-render/references.d.ts +4 -4
- package/dist/report-render/render.d.ts +2 -2
- package/dist/report-render/render.js +10 -11
- package/dist/report-render/script-json.js +1 -1
- package/dist/report-render/table-data.d.ts +6 -6
- package/dist/report-render/test/options.d.ts +49 -0
- package/dist/report-render/test/options.js +143 -0
- package/dist/report-render/test/page-function.d.ts +19 -0
- package/dist/report-render/test/page-function.js +33 -0
- package/dist/report-render/types.d.ts +10 -10
- package/dist/report-render/value-bridge.d.ts +4 -4
- package/dist/report-render/value-bridge.js +27 -14
- package/dist/report-render/views/chart-view.d.ts +2 -2
- package/dist/report-render/views/chart-view.js +2 -2
- package/dist/report-render/views/lineage.d.ts +6 -6
- package/dist/report-render/views/lineage.js +2 -0
- package/dist/report-render/views/page-view.d.ts +2 -2
- package/dist/report-render/views/page-view.js +1 -0
- package/dist/report-render/views/prose.js +25 -8
- package/dist/report-render/views/references-view.js +12 -1
- package/dist/report-render/views/values.js +1 -1
- package/dist/runtime/assemble.d.ts +53 -26
- package/dist/runtime/assemble.js +103 -56
- package/dist/runtime/boot.d.ts +8 -7
- package/dist/runtime/boot.js +1 -1
- package/dist/runtime/connection-budget.d.ts +6 -6
- package/dist/runtime/connection-budget.js +1 -1
- package/dist/runtime/dbos.d.ts +29 -19
- package/dist/runtime/dbos.js +35 -20
- package/dist/runtime/result-serialization.js +18 -5
- package/dist/runtime/shutdown.d.ts +2 -2
- package/dist/sandbox/client.d.ts +7 -3
- package/dist/sandbox/cpu-files.d.ts +2 -2
- package/dist/sandbox/cpu-files.js +21 -4
- package/dist/sandbox/create-sandbox.d.ts +7 -8
- package/dist/sandbox/create-sandbox.js +6 -12
- package/dist/sandbox/docker-client.d.ts +48 -3
- package/dist/sandbox/docker-client.js +10 -6
- package/dist/sandbox/estimate-data-profile-resources.js +2 -7
- package/dist/sandbox/exec-outcome.d.ts +2 -2
- package/dist/sandbox/exec-outcome.js +1 -1
- package/dist/sandbox/exec.d.ts +10 -6
- package/dist/sandbox/exec.js +27 -12
- package/dist/sandbox/execution-id.js +14 -6
- package/dist/sandbox/farm.d.ts +2 -2
- package/dist/sandbox/farm.js +22 -27
- package/dist/sandbox/identity.d.ts +7 -0
- package/dist/sandbox/identity.js +14 -3
- package/dist/sandbox/image-packages.d.ts +26 -4
- package/dist/sandbox/image-packages.js +29 -27
- package/dist/sandbox/k8s-client.d.ts +35 -8
- package/dist/sandbox/k8s-client.js +6 -5
- package/dist/sandbox/labels.js +1 -0
- package/dist/sandbox/liveness.js +3 -1
- package/dist/sandbox/mount-plan.d.ts +10 -10
- package/dist/sandbox/mount-plan.js +13 -14
- package/dist/sandbox/notification-sweep.d.ts +4 -4
- package/dist/sandbox/notification-sweep.js +4 -7
- package/dist/sandbox/package-identity.d.ts +6 -13
- package/dist/sandbox/package-identity.js +46 -28
- package/dist/sandbox/reaper.d.ts +10 -10
- package/dist/sandbox/reaper.js +4 -6
- package/dist/sandbox/sandbox-error.d.ts +2 -9
- package/dist/sandbox/sandbox-error.js +21 -8
- package/dist/sandbox/sandbox-step-translate.d.ts +8 -5
- package/dist/sandbox/sandbox-step-translate.js +22 -8
- package/dist/sandbox/step-sandbox.d.ts +47 -0
- package/dist/sandbox/step-sandbox.js +53 -0
- package/dist/sandbox/types.d.ts +18 -19
- package/dist/sandbox/types.js +1 -1
- package/dist/schemas/artifact-manifest.d.ts +4 -4
- package/dist/schemas/data-profile-schemas.d.ts +351 -306
- package/dist/schemas/file-metadata.js +2 -4
- package/dist/schemas/plan-schemas.d.ts +79 -25
- package/dist/schemas/plan-schemas.js +1 -1
- package/dist/schemas/run-synthesis.d.ts +95 -26
- package/dist/schemas/run-synthesis.js +3 -1
- package/dist/schemas/validate-plan.d.ts +4 -4
- package/dist/schemas/validate-plan.js +17 -5
- package/dist/schemas/workflow-state.d.ts +127 -14
- package/dist/schemas/workflow-state.js +56 -2
- package/dist/state/active-turns.d.ts +36 -0
- package/dist/state/active-turns.js +67 -0
- package/dist/state/analyses-metrics.d.ts +8 -8
- package/dist/state/analyses-metrics.js +4 -4
- package/dist/state/analyses.d.ts +0 -14
- package/dist/state/analyses.js +0 -32
- package/dist/state/artifacts.d.ts +47 -18
- package/dist/state/artifacts.js +48 -7
- package/dist/state/data-profile.d.ts +2 -2
- package/dist/state/db.d.ts +12 -2
- package/dist/state/db.js +5 -0
- package/dist/state/edit-intents.d.ts +4 -0
- package/dist/state/edit-intents.js +71 -0
- package/dist/state/index.d.ts +5 -5
- package/dist/state/index.js +3 -3
- package/dist/state/init.d.ts +2 -1
- package/dist/state/init.js +5 -2
- package/dist/state/migrations/20260927120000_baseline.js +3 -1
- package/dist/state/migrations/20261026120000_add_the_edit_intents.d.ts +7 -0
- package/dist/state/migrations/20261026120000_add_the_edit_intents.js +21 -0
- package/dist/state/migrations/20261027120000_record_the_applied_memory_edits.d.ts +7 -0
- package/dist/state/migrations/20261027120000_record_the_applied_memory_edits.js +16 -0
- package/dist/state/migrations/20261027120100_store_the_authoring_results.d.ts +8 -0
- package/dist/state/migrations/20261027120100_store_the_authoring_results.js +20 -0
- package/dist/state/migrations/20261027120200_key_the_groups_of_a_turn.d.ts +7 -0
- package/dist/state/migrations/20261027120200_key_the_groups_of_a_turn.js +12 -0
- package/dist/state/migrations/20261027120300_mark_the_active_turn_of_a_thread.d.ts +7 -0
- package/dist/state/migrations/20261027120300_mark_the_active_turn_of_a_thread.js +11 -0
- package/dist/state/migrations/20261028120000_record_the_paused_work.d.ts +7 -0
- package/dist/state/migrations/20261028120000_record_the_paused_work.js +25 -0
- package/dist/state/migrations/20261028120100_end_the_suspended_runs.d.ts +8 -0
- package/dist/state/migrations/20261028120100_end_the_suspended_runs.js +13 -0
- package/dist/state/migrations/20261029120000_reference_the_run_mandate.d.ts +7 -0
- package/dist/state/migrations/20261029120000_reference_the_run_mandate.js +23 -0
- package/dist/state/migrations/20261029120100_record_the_run_session_of_a_pause.d.ts +7 -0
- package/dist/state/migrations/20261029120100_record_the_run_session_of_a_pause.js +11 -0
- package/dist/state/migrations/index.js +18 -0
- package/dist/state/paused-work.d.ts +52 -0
- package/dist/state/paused-work.js +105 -0
- package/dist/state/plans.d.ts +27 -8
- package/dist/state/plans.js +14 -11
- package/dist/state/purge-analysis.d.ts +6 -6
- package/dist/state/purge-analysis.js +10 -2
- package/dist/state/report-session-state.d.ts +43 -18
- package/dist/state/report-session-state.js +43 -4
- package/dist/state/report-versions.d.ts +16 -11
- package/dist/state/report-versions.js +5 -3
- package/dist/state/runs.d.ts +70 -25
- package/dist/state/runs.js +127 -64
- package/dist/state/schema.d.ts +18 -21
- package/dist/state/schema.js +4 -5
- package/dist/state/snapshot-parse.d.ts +2 -2
- package/dist/state/snapshot-parse.js +14 -8
- package/dist/state/step-executions.d.ts +29 -8
- package/dist/state/step-executions.js +28 -4
- package/dist/state/tool-outputs.d.ts +2 -2
- package/dist/state/tool-outputs.js +2 -1
- package/dist/state/vector-store.d.ts +16 -16
- package/dist/state/vector-store.js +11 -7
- package/dist/tasks/data-profile-absorb.d.ts +3 -3
- package/dist/tasks/data-profile-absorb.js +21 -16
- package/dist/tasks/data-profile-activity.d.ts +5 -5
- package/dist/tasks/data-profile-activity.js +5 -5
- package/dist/tasks/data-profile-index.d.ts +4 -4
- package/dist/tasks/data-profile-index.js +32 -17
- package/dist/tasks/data-profile-resolve.d.ts +8 -8
- package/dist/tasks/data-profile-resolve.js +88 -62
- package/dist/tasks/data-profile.d.ts +40 -31
- package/dist/tasks/data-profile.js +138 -95
- package/dist/tasks/extract-values.d.ts +26 -79
- package/dist/tasks/extract-values.js +48 -108
- package/dist/tasks/refresh-regulatory-corpus.d.ts +4 -20
- package/dist/tasks/refresh-regulatory-corpus.js +12 -8
- package/dist/tasks/regulatory-corpus-boot-refresh.d.ts +2 -2
- package/dist/tasks/regulatory-corpus-boot-refresh.js +12 -10
- package/dist/testing.d.ts +60 -0
- package/dist/testing.js +96 -0
- package/dist/tools/ad-hoc-router.d.ts +11 -9
- package/dist/tools/ad-hoc-router.js +80 -51
- package/dist/tools/analysis-invocation.d.ts +7 -0
- package/dist/tools/analysis-invocation.js +29 -5
- package/dist/tools/approval/contract.d.ts +8 -52
- package/dist/tools/approval/contract.js +7 -36
- package/dist/tools/approval/gateway.d.ts +27 -28
- package/dist/tools/approval/gateway.js +33 -130
- package/dist/tools/approval/queries.d.ts +6 -11
- package/dist/tools/approval/queries.js +43 -29
- package/dist/tools/approval/uuidv7.js +2 -2
- package/dist/tools/bio/chembl.d.ts +3 -3
- package/dist/tools/bio/chembl.js +10 -0
- package/dist/tools/bio/comptox.d.ts +25 -8
- package/dist/tools/bio/comptox.js +4 -2
- package/dist/tools/bio/drug-gene-interactions.d.ts +27 -17
- package/dist/tools/bio/drug-gene-interactions.js +11 -8
- package/dist/tools/bio/gene-disease-evidence.d.ts +61 -15
- package/dist/tools/bio/gene-disease-evidence.js +10 -6
- package/dist/tools/bio/gene-preclinical-profile.d.ts +11 -11
- package/dist/tools/bio/keys.d.ts +2 -2
- package/dist/tools/bio/keys.js +3 -3
- package/dist/tools/bio/lookup-annotation.d.ts +5 -5
- package/dist/tools/bio/lookup-annotation.js +3 -0
- package/dist/tools/bio/opentargets.d.ts +1 -1
- package/dist/tools/bio/opentargets.js +6 -0
- package/dist/tools/bio/pubchem.d.ts +2 -2
- package/dist/tools/bio/pubchem.js +6 -0
- package/dist/tools/bio/pubmed.d.ts +26 -16
- package/dist/tools/bio/pubmed.js +9 -3
- package/dist/tools/bio/search-clinical-trials.d.ts +4 -4
- package/dist/tools/bio/search-clinical-trials.js +5 -1
- package/dist/tools/bio/search-faers.d.ts +2 -2
- package/dist/tools/bio/search-faers.js +1 -1
- package/dist/tools/bio/search-gene.d.ts +2 -2
- package/dist/tools/bio/search-gene.js +1 -0
- package/dist/tools/bio/search-geo-datasets.d.ts +4 -4
- package/dist/tools/bio/search-geo-datasets.js +5 -5
- package/dist/tools/bio/search-interactions.d.ts +1 -1
- package/dist/tools/bio/search-patents.d.ts +28 -22
- package/dist/tools/bio/search-patents.js +20 -17
- package/dist/tools/bio/search-protein.d.ts +2 -2
- package/dist/tools/bio/search-protein.js +1 -1
- package/dist/tools/bio/search-regulatory-approvals.d.ts +64 -18
- package/dist/tools/bio/search-regulatory-approvals.js +21 -16
- package/dist/tools/bio/target-safety.d.ts +8 -8
- package/dist/tools/bio/target-safety.js +11 -6
- package/dist/tools/capability-data.d.ts +40 -0
- package/dist/tools/capability-data.js +74 -0
- package/dist/tools/define-tool.d.ts +55 -46
- package/dist/tools/define-tool.js +39 -27
- package/dist/tools/display/normalize-echart-spec.d.ts +2 -2
- package/dist/tools/display/normalize-echart-spec.js +51 -27
- package/dist/tools/display/show-user.d.ts +2 -2
- package/dist/tools/display/show-user.js +1 -1
- package/dist/tools/execute-analysis.d.ts +54 -17
- package/dist/tools/execute-analysis.js +193 -62
- package/dist/tools/knowledge/check.d.ts +182 -0
- package/dist/tools/knowledge/check.js +94 -0
- package/dist/tools/knowledge/client.d.ts +351 -0
- package/dist/tools/knowledge/client.js +319 -0
- package/dist/tools/knowledge/environment.d.ts +78 -0
- package/dist/tools/knowledge/environment.js +116 -0
- package/dist/tools/knowledge/index.d.ts +49 -0
- package/dist/tools/knowledge/index.js +70 -0
- package/dist/tools/knowledge/local-slots.d.ts +62 -0
- package/dist/tools/knowledge/local-slots.js +184 -0
- package/dist/tools/knowledge/pin.d.ts +14 -0
- package/dist/tools/knowledge/pin.js +17 -0
- package/dist/tools/knowledge/recommend.d.ts +67 -0
- package/dist/tools/knowledge/recommend.js +106 -0
- package/dist/tools/knowledge/situation.d.ts +143 -0
- package/dist/tools/knowledge/situation.js +157 -0
- package/dist/tools/knowledge/skeleton.d.ts +69 -0
- package/dist/tools/knowledge/skeleton.js +201 -0
- package/dist/tools/knowledge/template.d.ts +139 -0
- package/dist/tools/knowledge/template.js +273 -0
- package/dist/tools/lib/alphafold-client.js +2 -1
- package/dist/tools/lib/amass-client.d.ts +28 -28
- package/dist/tools/lib/amass-client.js +20 -10
- package/dist/tools/lib/api-utils.d.ts +13 -3
- package/dist/tools/lib/api-utils.js +17 -3
- package/dist/tools/lib/bgee-client.d.ts +6 -6
- package/dist/tools/lib/bgee-client.js +16 -10
- package/dist/tools/lib/cbioportal-client.d.ts +4 -4
- package/dist/tools/lib/cbioportal-client.js +9 -8
- package/dist/tools/lib/chembl-client.d.ts +14 -14
- package/dist/tools/lib/chembl-client.js +11 -4
- package/dist/tools/lib/clinical-benchmarks-client.d.ts +4 -4
- package/dist/tools/lib/clinical-benchmarks-client.js +4 -7
- package/dist/tools/lib/clinical-trials-client.d.ts +18 -18
- package/dist/tools/lib/clinical-trials-client.js +10 -10
- package/dist/tools/lib/clinvar-client.d.ts +2 -2
- package/dist/tools/lib/clinvar-client.js +6 -6
- package/dist/tools/lib/ctx-ops.d.ts +23 -23
- package/dist/tools/lib/ctx-ops.js +13 -10
- package/dist/tools/lib/dgidb-client.d.ts +6 -6
- package/dist/tools/lib/dgidb-client.js +10 -12
- package/dist/tools/lib/disgenet-client.d.ts +4 -4
- package/dist/tools/lib/ema-client.d.ts +2 -2
- package/dist/tools/lib/ensembl-client.d.ts +4 -4
- package/dist/tools/lib/ensembl-client.js +5 -4
- package/dist/tools/lib/gwas-catalog-client.d.ts +4 -4
- package/dist/tools/lib/gwas-catalog-client.js +17 -17
- package/dist/tools/lib/html-text.d.ts +6 -0
- package/dist/tools/lib/html-text.js +9 -0
- package/dist/tools/lib/identifier-resolver.d.ts +4 -4
- package/dist/tools/lib/identifier-resolver.js +7 -3
- package/dist/tools/lib/impc-client.d.ts +8 -8
- package/dist/tools/lib/impc-client.js +46 -35
- package/dist/tools/lib/iuphar-client.d.ts +2 -2
- package/dist/tools/lib/iuphar-client.js +7 -16
- package/dist/tools/lib/monarch-client.d.ts +4 -4
- package/dist/tools/lib/openfda-client.d.ts +22 -22
- package/dist/tools/lib/openfda-client.js +23 -22
- package/dist/tools/lib/opentargets-client.d.ts +12 -12
- package/dist/tools/lib/pathway-client.d.ts +4 -4
- package/dist/tools/lib/pathway-client.js +15 -19
- package/dist/tools/lib/pharmgkb-client.d.ts +2 -2
- package/dist/tools/lib/pharmgkb-client.js +1 -1
- package/dist/tools/lib/protein-family-modality.d.ts +2 -2
- package/dist/tools/lib/protein-family-modality.js +0 -2
- package/dist/tools/lib/protein-family-normalize.js +7 -0
- package/dist/tools/lib/pubchem-client.d.ts +2 -2
- package/dist/tools/lib/pubchem-client.js +1 -0
- package/dist/tools/lib/pubchem-ops.d.ts +4 -4
- package/dist/tools/lib/pubchem-ops.js +8 -0
- package/dist/tools/lib/pubmed-client.d.ts +9 -9
- package/dist/tools/lib/pubmed-client.js +1 -1
- package/dist/tools/lib/string-client.d.ts +6 -6
- package/dist/tools/lib/uniprot-client.d.ts +8 -8
- package/dist/tools/lib/uniprot-client.js +5 -1
- package/dist/tools/memory/update-working-memory.d.ts +16 -13
- package/dist/tools/memory/update-working-memory.js +21 -3
- package/dist/tools/read-tool-output.js +8 -2
- package/dist/tools/registry.d.ts +2 -2
- package/dist/tools/report-authoring/authoring-tools.d.ts +54 -23
- package/dist/tools/report-authoring/authoring-tools.js +128 -62
- package/dist/tools/report-session/derive-table.d.ts +19 -59
- package/dist/tools/report-session/derive-table.js +120 -122
- package/dist/tools/report-session/examine-page.d.ts +6 -6
- package/dist/tools/report-session/examine-page.js +14 -12
- package/dist/tools/report-session/list-artifacts.d.ts +6 -6
- package/dist/tools/report-session/list-artifacts.js +5 -5
- package/dist/tools/report-session/page-faults.d.ts +6 -6
- package/dist/tools/report-session/page-faults.js +3 -1
- package/dist/tools/report-session/preview-report.d.ts +4 -3
- package/dist/tools/report-session/preview-report.js +26 -7
- package/dist/tools/report-session/record-version.d.ts +9 -4
- package/dist/tools/report-session/record-version.js +16 -9
- package/dist/tools/report-session/session-page-publisher.d.ts +6 -6
- package/dist/tools/research/generate-analogy-report.d.ts +14 -7
- package/dist/tools/research/generate-analogy-report.js +80 -76
- package/dist/tools/research/generate-plan.d.ts +39 -16
- package/dist/tools/research/generate-plan.js +565 -338
- package/dist/tools/research/guarded-address.d.ts +20 -0
- package/dist/tools/research/guarded-address.js +149 -0
- package/dist/tools/research/inspect-data-profile.d.ts +27 -20
- package/dist/tools/research/inspect-data-profile.js +26 -25
- package/dist/tools/research/inspect-run.d.ts +54 -27
- package/dist/tools/research/inspect-run.js +50 -40
- package/dist/tools/research/literature-reviewer.d.ts +8 -7
- package/dist/tools/research/literature-reviewer.js +29 -28
- package/dist/tools/research/search-arxiv.d.ts +1 -1
- package/dist/tools/research/search-arxiv.js +1 -1
- package/dist/tools/research/search-github-repos.d.ts +10 -7
- package/dist/tools/research/search-github-repos.js +25 -22
- package/dist/tools/research/search-semantic-scholar.js +1 -1
- package/dist/tools/research/searxng-engine.d.ts +40 -0
- package/dist/tools/research/searxng-engine.js +122 -0
- package/dist/tools/research/web-fetch.d.ts +127 -0
- package/dist/tools/research/web-fetch.js +618 -0
- package/dist/tools/research/web-search.d.ts +84 -0
- package/dist/tools/research/web-search.js +117 -0
- package/dist/tools/sandbox/link-packages.d.ts +11 -7
- package/dist/tools/sandbox/link-packages.js +11 -8
- package/dist/tools/sandbox/list-available-packages.d.ts +24 -12
- package/dist/tools/sandbox/list-available-packages.js +43 -29
- package/dist/tools/sandbox/list-available-refs.d.ts +38 -14
- package/dist/tools/sandbox/list-available-refs.js +119 -37
- package/dist/tools/sandbox/report-blocker.d.ts +30 -37
- package/dist/tools/sandbox/report-blocker.js +22 -68
- package/dist/tools/sandbox/skills.d.ts +16 -12
- package/dist/tools/sandbox/skills.js +16 -12
- package/dist/tools/sandbox/submit-file-metadata.d.ts +12 -9
- package/dist/tools/sandbox/submit-file-metadata.js +18 -21
- package/dist/tools/start-report-session.d.ts +13 -5
- package/dist/tools/start-report-session.js +35 -8
- package/dist/tools/terminal-text.d.ts +14 -0
- package/dist/tools/terminal-text.js +51 -0
- package/dist/tools/workspace/decision-record.d.ts +81 -0
- package/dist/tools/workspace/decision-record.js +127 -0
- package/dist/tools/workspace/edit-file.d.ts +59 -18
- package/dist/tools/workspace/edit-file.js +98 -15
- package/dist/tools/workspace/execute-command.d.ts +31 -12
- package/dist/tools/workspace/execute-command.js +37 -8
- package/dist/tools/workspace/file-stat.d.ts +6 -3
- package/dist/tools/workspace/grep.d.ts +10 -7
- package/dist/tools/workspace/grep.js +9 -3
- package/dist/tools/workspace/index.d.ts +1 -0
- package/dist/tools/workspace/index.js +1 -0
- package/dist/tools/workspace/list-files.d.ts +6 -3
- package/dist/tools/workspace/mutator.d.ts +28 -15
- package/dist/tools/workspace/mutator.js +107 -53
- package/dist/tools/workspace/read-file.d.ts +8 -5
- package/dist/tools/workspace/result-bounds.d.ts +5 -5
- package/dist/tools/workspace/result-bounds.js +4 -2
- package/dist/tools/workspace/run-exec.d.ts +2 -2
- package/dist/tools/workspace/run-exec.js +3 -3
- package/dist/tools/workspace/scan-inputs.d.ts +8 -5
- package/dist/tools/workspace/scan-inputs.js +17 -5
- package/dist/tools/workspace/show-file.d.ts +1 -1
- package/dist/tools/workspace/show-file.js +2 -1
- package/dist/tools/workspace/show-plan.d.ts +8 -5
- package/dist/tools/workspace/show-plan.js +9 -8
- package/dist/tools/workspace/workspace-search.d.ts +41 -13
- package/dist/tools/workspace/workspace-search.js +27 -14
- package/dist/tools/workspace/write-file.d.ts +9 -7
- package/dist/workflows/execute-analysis-scheduler.d.ts +9 -9
- package/dist/workflows/execute-analysis-scheduler.js +6 -3
- package/dist/workflows/execute-analysis.d.ts +100 -76
- package/dist/workflows/execute-analysis.js +380 -247
- package/dist/workflows/pause.d.ts +71 -0
- package/dist/workflows/pause.js +173 -0
- package/dist/workflows/sandbox-step.d.ts +50 -61
- package/dist/workflows/sandbox-step.js +99 -106
- package/dist/workflows/test/sql-writes.d.ts +21 -0
- package/dist/workflows/test/sql-writes.js +36 -0
- package/dist/workspace/filesystem.d.ts +6 -6
- package/dist/workspace/filesystem.js +10 -8
- package/dist/workspace/paths.d.ts +1 -1
- package/dist/workspace/paths.js +15 -4
- package/dist/workspace/search-config.d.ts +2 -2
- package/dist/workspace/search-config.js +1 -1
- package/package.json +25 -22
- package/dist/loop/continue-agent.d.ts +0 -40
- package/dist/loop/continue-agent.js +0 -38
- package/dist/loop/genai-spans.d.ts +0 -47
- package/dist/loop/genai-spans.js +0 -134
- package/dist/loop/run-agent.d.ts +0 -236
- package/dist/loop/run-agent.js +0 -1110
- package/dist/loop/run-step.d.ts +0 -29
- package/dist/loop/run-step.js +0 -34
- package/dist/loop/run-to-terminal.d.ts +0 -66
- package/dist/loop/run-to-terminal.js +0 -90
- package/dist/loop/tool-mask.d.ts +0 -23
- package/dist/loop/tool-mask.js +0 -46
- package/dist/providers/streaming-chat.d.ts +0 -32
- package/dist/providers/streaming-chat.js +0 -91
- package/dist/tasks/derive-table-exec.d.ts +0 -54
- package/dist/tasks/derive-table-exec.js +0 -86
- package/dist/workflows/suspension.d.ts +0 -32
- package/dist/workflows/suspension.js +0 -38
|
@@ -22,15 +22,15 @@
|
|
|
22
22
|
*/
|
|
23
23
|
import type { ModelMessage } from "ai";
|
|
24
24
|
import { ResultAsync } from "neverthrow";
|
|
25
|
-
import type { Pool } from "pg";
|
|
26
25
|
import type { TokenUsageRollup } from "../contracts/usage.js";
|
|
27
|
-
import { type DbError } from "../lib/db-result.js";
|
|
26
|
+
import { type Connectable, type DbError, type TransactionQuerier } from "../lib/db-result.js";
|
|
28
27
|
import type { Logger } from "../lib/logger.js";
|
|
28
|
+
import type { Querier } from "../state/db.js";
|
|
29
29
|
import { type StoredMessageEnvelope } from "./ai-sdk-message-storage.js";
|
|
30
30
|
import type { MessagePart } from "../contracts/message.js";
|
|
31
31
|
import { type ConversationUIMessage, type StoredDisplayEnvelope } from "./conversation-display-storage.js";
|
|
32
|
-
/** One stored message, as returned by the display
|
|
33
|
-
export
|
|
32
|
+
/** One stored message, as returned by the display reads (`loadAll` and `loadPage`). */
|
|
33
|
+
export type StoredMessage = {
|
|
34
34
|
readonly seq: number;
|
|
35
35
|
readonly envelope: StoredMessageEnvelope;
|
|
36
36
|
readonly message: ModelMessage;
|
|
@@ -69,7 +69,7 @@ export interface StoredMessage {
|
|
|
69
69
|
* behind it.
|
|
70
70
|
*/
|
|
71
71
|
readonly createdAt?: Date;
|
|
72
|
-
}
|
|
72
|
+
};
|
|
73
73
|
/**
|
|
74
74
|
* One atomic group of rows: the exact provider-facing history, and the display
|
|
75
75
|
* projection of what the user was shown.
|
|
@@ -79,7 +79,7 @@ export interface StoredMessage {
|
|
|
79
79
|
* what the transcript replays. Neither is derived from the other, and a failed
|
|
80
80
|
* write commits neither.
|
|
81
81
|
*/
|
|
82
|
-
export
|
|
82
|
+
export type ConversationTurn = {
|
|
83
83
|
/** Exact provider-facing history; token accounting and model reads use only this projection. */
|
|
84
84
|
readonly modelMessages: readonly ModelMessage[];
|
|
85
85
|
/** Complete ordered AI SDK UI messages recorded from the live display event stream. */
|
|
@@ -94,7 +94,12 @@ export interface ConversationTurn {
|
|
|
94
94
|
* envelope, because a `text` parameter carrying 0x00 fails the statement.
|
|
95
95
|
*/
|
|
96
96
|
readonly author?: string;
|
|
97
|
-
|
|
97
|
+
/**
|
|
98
|
+
* The key of the group in its turn, stored on its first row. A turn workflow gives each group a key, thus a
|
|
99
|
+
* write that runs again after its commit finds the key and stores nothing.
|
|
100
|
+
*/
|
|
101
|
+
readonly key?: string;
|
|
102
|
+
};
|
|
98
103
|
/**
|
|
99
104
|
* The append a host uses to record out-of-band work in a thread — an analysis
|
|
100
105
|
* run's outcome, typically.
|
|
@@ -116,7 +121,7 @@ export declare function conversationRecordTurn(text: string, displayParts?: read
|
|
|
116
121
|
/** The status of a chat turn: `open` while it runs, then its outcome. */
|
|
117
122
|
export type TurnStatus = "open" | "done" | "aborted" | "failed";
|
|
118
123
|
/** The close of a chat turn. It sets the outcome on the turn record, one time. */
|
|
119
|
-
export
|
|
124
|
+
export type TurnClose = {
|
|
120
125
|
readonly status: Exclude<TurnStatus, "open">;
|
|
121
126
|
/** The reason of a failure. */
|
|
122
127
|
readonly reason?: string;
|
|
@@ -125,7 +130,7 @@ export interface TurnClose {
|
|
|
125
130
|
readonly turnDurationMs?: number;
|
|
126
131
|
/** The note of a failure or of an abort, stored after the rounds. */
|
|
127
132
|
readonly note?: ConversationTurn;
|
|
128
|
-
}
|
|
133
|
+
};
|
|
129
134
|
/**
|
|
130
135
|
* One write of a chat turn. The opening adds the turn record, and a later write names the turn by
|
|
131
136
|
* `startSeq`. The `never` members make a write with both keys fail to compile.
|
|
@@ -141,17 +146,17 @@ export type TurnWrite = {
|
|
|
141
146
|
readonly rounds: readonly ConversationTurn[];
|
|
142
147
|
readonly close?: TurnClose;
|
|
143
148
|
};
|
|
144
|
-
export
|
|
149
|
+
export type TurnWriteResult = {
|
|
145
150
|
/** The `seq` of the user row that opens the turn, which keys its turn record. */
|
|
146
151
|
readonly startSeq: number;
|
|
147
|
-
}
|
|
152
|
+
};
|
|
148
153
|
/** The turn record of a chat turn, as the display read gives it. */
|
|
149
|
-
export
|
|
154
|
+
export type StoredTurnRecord = {
|
|
150
155
|
readonly status: TurnStatus;
|
|
151
156
|
readonly reason?: string;
|
|
152
157
|
readonly usage?: TokenUsageRollup;
|
|
153
158
|
readonly durationMs?: number;
|
|
154
|
-
}
|
|
159
|
+
};
|
|
155
160
|
/**
|
|
156
161
|
* The result of `retractLastTurn`. `retracted` carries `messages` — the number
|
|
157
162
|
* of rows removed — so a caller can assert exactly what came off the tail. The
|
|
@@ -168,15 +173,34 @@ export type RetractOutcome = {
|
|
|
168
173
|
kind: "no-user-turn";
|
|
169
174
|
};
|
|
170
175
|
/** The read options of {@link ThreadHistory.loadRecent}. */
|
|
171
|
-
export
|
|
176
|
+
export type LoadRecentOptions = {
|
|
172
177
|
/** Keep the first turn of the thread, the seed of a report thread, in front of the latest summary. */
|
|
173
178
|
readonly keepFirstTurn?: boolean;
|
|
174
|
-
|
|
179
|
+
/**
|
|
180
|
+
* Read the rows up to this `seq` only. A row never changes after its write, thus a turn workflow that reads up
|
|
181
|
+
* to the last row before its turn reads the same view on a replay.
|
|
182
|
+
*/
|
|
183
|
+
readonly throughSeq?: number;
|
|
184
|
+
};
|
|
185
|
+
/** The options of {@link ThreadHistory.loadPage}. */
|
|
186
|
+
export type LoadPageOptions = {
|
|
187
|
+
/** The cursor that the previous page gave. Absent for the newest page. */
|
|
188
|
+
readonly before?: number;
|
|
189
|
+
/** The maximum count of turns in the page. */
|
|
190
|
+
readonly limit: number;
|
|
191
|
+
};
|
|
192
|
+
/** One page of the display read, as {@link ThreadHistory.loadPage} gives it. */
|
|
193
|
+
export type TurnPage = {
|
|
194
|
+
/** The whole turns of the page, oldest-first. */
|
|
195
|
+
readonly turns: StoredMessage[][];
|
|
196
|
+
/** The cursor of the next older page, or `null` when the page holds the oldest row of the thread. */
|
|
197
|
+
readonly before: number | null;
|
|
198
|
+
};
|
|
175
199
|
/**
|
|
176
200
|
* The conversation message store. Two methods, by design — no generic row
|
|
177
201
|
* insert (see the harness-thread-store spec). `threadId` is the conversation scope — one UI thread.
|
|
178
202
|
*/
|
|
179
|
-
export
|
|
203
|
+
export type ThreadHistory = {
|
|
180
204
|
/**
|
|
181
205
|
* Append one group, for example a record of a host — every message written in a
|
|
182
206
|
* single transaction with a `seq` monotonically increasing per thread.
|
|
@@ -195,12 +219,8 @@ export interface ThreadHistory {
|
|
|
195
219
|
/**
|
|
196
220
|
* Return a thread's messages oldest-first for UI display, grouped into turns.
|
|
197
221
|
* It gives each row, and the view of the agent loop is `loadRecent`'s job.
|
|
198
|
-
*
|
|
199
|
-
*
|
|
200
|
-
* selects and parses every row of the thread and would slice only afterwards,
|
|
201
|
-
* so a page saves no query and no parse. It would only truncate the answer,
|
|
202
|
-
* which is a way to lose turns and not a way to save work. A reader wanting a
|
|
203
|
-
* window takes one here, where it knows what it is bounding.
|
|
222
|
+
* It selects and parses every row of the thread, thus its work grows with the
|
|
223
|
+
* thread. {@link ThreadHistory.loadPage} bounds that work.
|
|
204
224
|
*
|
|
205
225
|
* Grouped rather than flat because the grouping is what the read computes and
|
|
206
226
|
* what a turn count means, and `.flat()` recovers the rows in `seq` order for
|
|
@@ -209,6 +229,23 @@ export interface ThreadHistory {
|
|
|
209
229
|
* this read already found.
|
|
210
230
|
*/
|
|
211
231
|
loadAll(threadId: string): ResultAsync<StoredMessage[][], DbError>;
|
|
232
|
+
/**
|
|
233
|
+
* Return the newest whole turns of a thread for UI display, up to `limit` turns, oldest-first.
|
|
234
|
+
* With `before`, it returns the newest whole turns below the turn that the cursor names.
|
|
235
|
+
* The rows are the same as the rows of {@link ThreadHistory.loadAll}.
|
|
236
|
+
*
|
|
237
|
+
* The read selects and parses only the rows of its page, thus its work does not grow with
|
|
238
|
+
* the turns before the page. The page edges inside the thread are turn starts, so the read
|
|
239
|
+
* never truncates a turn, also for a cursor that is not a turn start: the turn of the cursor
|
|
240
|
+
* row is then the newest turn of the page, and it is whole. The rows before the first turn
|
|
241
|
+
* start make one group, and the group counts as a turn.
|
|
242
|
+
*
|
|
243
|
+
* The cursor is the `seq` of the opening row of the oldest turn of the page. A `seq` never
|
|
244
|
+
* moves and a retract removes only the tail, thus a cursor stays correct across a later
|
|
245
|
+
* append and a later retract. A `limit` that is not finite reads as 1, and each other
|
|
246
|
+
* `limit` reads as its integer part with a minimum of 1.
|
|
247
|
+
*/
|
|
248
|
+
loadPage(threadId: string, options: LoadPageOptions): ResultAsync<TurnPage, DbError>;
|
|
212
249
|
/**
|
|
213
250
|
* Remove the thread's most recent turn — every row from the last
|
|
214
251
|
* genuine-user-start `seq` onward, and its turn record — in a single transaction.
|
|
@@ -259,7 +296,7 @@ export interface ThreadHistory {
|
|
|
259
296
|
* one adds to the count.
|
|
260
297
|
*/
|
|
261
298
|
countUserTurnsAfter(threadId: string, seq: number): ResultAsync<number, DbError>;
|
|
262
|
-
}
|
|
299
|
+
};
|
|
263
300
|
/**
|
|
264
301
|
* Drop the memoized instruments so the next `loadRecent` rebinds to a
|
|
265
302
|
* freshly-registered `MeterProvider`. Test-only.
|
|
@@ -275,4 +312,9 @@ export declare function __resetThreadHistoryMetricsForTest(): void;
|
|
|
275
312
|
* same messages either way — the drop reports a deploy, not a failed read — and
|
|
276
313
|
* requiring it would break every call site over a diagnostic.
|
|
277
314
|
*/
|
|
278
|
-
|
|
315
|
+
/** What this module reads of the pool: the direct `query` plus the transactional `connect`. */
|
|
316
|
+
type ThreadHistoryPool = Querier & Connectable;
|
|
317
|
+
/** `appendTurn` inside the transaction of the caller, thus another write of the caller commits with the turn or not at all. */
|
|
318
|
+
export declare function appendTurnIn(client: TransactionQuerier, threadId: string, turn: ConversationTurn): ResultAsync<void, DbError>;
|
|
319
|
+
export declare function createThreadHistory(pool: ThreadHistoryPool, logger?: Logger): ThreadHistory;
|
|
320
|
+
export {};
|
|
@@ -25,11 +25,12 @@ import { metrics } from "@opentelemetry/api";
|
|
|
25
25
|
import { ResultAsync, ok, okAsync } from "neverthrow";
|
|
26
26
|
import { stripNulCharacters } from "../input-sanitization.js";
|
|
27
27
|
import { tryMutation, tryQuery, withTransaction } from "../lib/db-result.js";
|
|
28
|
+
import { presentFirst } from "../lib/present.js";
|
|
28
29
|
import { hasReportedUsage } from "../loop/metrics.js";
|
|
29
30
|
import { countTokens } from "./count-tokens.js";
|
|
30
31
|
import { conversationView, groupTurns, isGenuineUserStart } from "./conversation-view.js";
|
|
31
32
|
import { HARNESS_PROVIDER_NAMESPACE, SYNTHETIC_MESSAGE_KEY, envelopeMessage, parseStoredMessageEnvelope, syntheticRecordMessage, } from "./ai-sdk-message-storage.js";
|
|
32
|
-
import { conversationDisplayPart, envelopeDisplayMessages, parseStoredDisplayEnvelope, } from "./conversation-display-storage.js";
|
|
33
|
+
import { conversationDisplayPart, envelopeDisplayMessages, isStoredSourcePart, parseStoredDisplayEnvelope, } from "./conversation-display-storage.js";
|
|
33
34
|
/** A resolved `ok(undefined)` ResultAsync — the empty/seed transaction step. */
|
|
34
35
|
function okVoid() {
|
|
35
36
|
return new ResultAsync(Promise.resolve(ok(undefined)));
|
|
@@ -56,7 +57,9 @@ export function conversationRecordTurn(text, displayParts) {
|
|
|
56
57
|
{
|
|
57
58
|
id: randomUUID(),
|
|
58
59
|
role: "system",
|
|
59
|
-
parts: displayParts !== undefined && displayParts.length > 0
|
|
60
|
+
parts: displayParts !== undefined && displayParts.length > 0
|
|
61
|
+
? displayParts.filter(isStoredSourcePart).map(conversationDisplayPart)
|
|
62
|
+
: [{ type: "text", text, state: "done" }],
|
|
60
63
|
},
|
|
61
64
|
],
|
|
62
65
|
};
|
|
@@ -128,12 +131,12 @@ function nextSeq(client, threadId, op) {
|
|
|
128
131
|
const { rows } = await client.query("SELECT COALESCE(MAX(seq), -1)::text AS max_seq FROM messages WHERE thread_id = $1", [
|
|
129
132
|
threadId,
|
|
130
133
|
]);
|
|
131
|
-
return Number(rows
|
|
134
|
+
return Number(presentFirst(rows, "the max-seq row").max_seq) + 1;
|
|
132
135
|
});
|
|
133
136
|
}
|
|
134
137
|
/** Insert the rows of one group, from `startSeq` on. */
|
|
135
138
|
function insertGroup(client, threadId, startSeq, group, op) {
|
|
136
|
-
const { modelMessages: messages, displayMessages, author } = group;
|
|
139
|
+
const { modelMessages: messages, displayMessages, author, key } = group;
|
|
137
140
|
// The display projection rides the group's FIRST row, so one SELECT of a
|
|
138
141
|
// thread's rows yields every envelope in order with no join and no grouping.
|
|
139
142
|
// Whichever row that is — a genuine user message opening a turn, or the lone
|
|
@@ -154,19 +157,21 @@ function insertGroup(client, threadId, startSeq, group, op) {
|
|
|
154
157
|
return messages.reduce((chain, message, i) => chain.andThen(() => tryMutation(`${op}.insert`, () => client.query(
|
|
155
158
|
// `message_envelope::json`, never `::jsonb`; `display_envelope::jsonb`,
|
|
156
159
|
// never `::json` — see the column comments in the state-init DDL.
|
|
157
|
-
`INSERT INTO messages (thread_id, seq, message_envelope, display_envelope, tokens, author)
|
|
158
|
-
VALUES ($1, $2, $3::json, $4::jsonb, $5, $6)
|
|
160
|
+
`INSERT INTO messages (thread_id, seq, message_envelope, display_envelope, tokens, author, round_key)
|
|
161
|
+
VALUES ($1, $2, $3::json, $4::jsonb, $5, $6, $7)
|
|
159
162
|
ON CONFLICT (thread_id, seq) DO UPDATE
|
|
160
163
|
SET message_envelope = EXCLUDED.message_envelope,
|
|
161
164
|
display_envelope = EXCLUDED.display_envelope,
|
|
162
165
|
tokens = EXCLUDED.tokens,
|
|
163
|
-
author = EXCLUDED.author
|
|
166
|
+
author = EXCLUDED.author,
|
|
167
|
+
round_key = EXCLUDED.round_key`, [
|
|
164
168
|
threadId,
|
|
165
169
|
startSeq + i,
|
|
166
170
|
serializeEnvelope(message),
|
|
167
171
|
i === 0 ? displayEnvelope : null,
|
|
168
172
|
countTokens(message.content),
|
|
169
173
|
i === authorRow ? turnAuthor : null,
|
|
174
|
+
i === 0 ? (key ?? null) : null,
|
|
170
175
|
])).map(() => undefined)), okVoid());
|
|
171
176
|
}
|
|
172
177
|
/** Move `cortex_analysis_threads.updated_at` forward inside the write transaction. */
|
|
@@ -209,6 +214,16 @@ function touchThread(client, threadId, op) {
|
|
|
209
214
|
.map(() => undefined)
|
|
210
215
|
.orElse(() => okVoid()));
|
|
211
216
|
}
|
|
217
|
+
/** The `seq` of the first row of a group that a write stored before, by the key of the group. */
|
|
218
|
+
function storedGroupSeq(client, threadId, key, op) {
|
|
219
|
+
if (key === undefined)
|
|
220
|
+
return okAsync(undefined);
|
|
221
|
+
return tryQuery(`${op}.storedKey`, async () => {
|
|
222
|
+
const { rows } = await client.query("SELECT seq::text AS seq FROM messages WHERE thread_id = $1 AND round_key = $2", [threadId, key]);
|
|
223
|
+
const row = rows[0];
|
|
224
|
+
return row === undefined ? undefined : Number(row.seq);
|
|
225
|
+
});
|
|
226
|
+
}
|
|
212
227
|
/** Add the `open` record of a turn. The upsert replaces a record whose rows are gone, because the opening row holds its key now. */
|
|
213
228
|
function openTurnRecord(client, threadId, startSeq) {
|
|
214
229
|
return tryMutation("thread-history.writeTurn.openRecord", () => client.query(`INSERT INTO cortex_thread_turns (thread_id, start_seq, status)
|
|
@@ -224,46 +239,146 @@ function closeTurnRecord(client, threadId, startSeq, close) {
|
|
|
224
239
|
SET status = $3, reason = $4, reported_usage = $5::jsonb, turn_duration_ms = $6, closed_at = NOW()
|
|
225
240
|
WHERE thread_id = $1 AND start_seq = $2 AND status = 'open'`, [threadId, startSeq, close.status, close.reason === undefined ? null : stripNulCharacters(close.reason), rollup, close.turnDurationMs ?? null])).map(() => undefined);
|
|
226
241
|
}
|
|
242
|
+
/** The columns of a display-read row, and the join that the turn record needs. Both display reads select them. */
|
|
243
|
+
const STORED_ROW_COLUMNS = `messages.seq::text AS seq, messages.message_envelope, messages.display_envelope, messages.reported_usage,
|
|
244
|
+
messages.turn_duration_ms::text AS turn_duration_ms, messages.author, messages.created_at,
|
|
245
|
+
turns.status AS turn_status, turns.reason AS turn_reason, turns.reported_usage AS turn_usage,
|
|
246
|
+
turns.turn_duration_ms::text AS turn_record_duration_ms`;
|
|
247
|
+
function storedRowFrom(turnJoinBounds = "") {
|
|
248
|
+
return `FROM messages
|
|
249
|
+
LEFT JOIN cortex_thread_turns turns ON turns.thread_id = messages.thread_id AND turns.start_seq = messages.seq${turnJoinBounds}`;
|
|
250
|
+
}
|
|
251
|
+
/** The largest `bigint`, the bound of a cursor that the caller did not give. */
|
|
252
|
+
const MAX_SEQ = "9223372036854775807";
|
|
253
|
+
/** The smallest `bigint`, below every `seq`. */
|
|
254
|
+
const MIN_SEQ = "'-9223372036854775808'";
|
|
255
|
+
const PAGE_LOWER_BOUND = `COALESCE((SELECT seq FROM page_lower), ${MIN_SEQ}::bigint)`;
|
|
256
|
+
const PAGE_UPPER_BOUND = `COALESCE((SELECT seq FROM page_upper), ${MAX_SEQ}::bigint)`;
|
|
227
257
|
/**
|
|
228
|
-
*
|
|
229
|
-
*
|
|
230
|
-
*
|
|
258
|
+
* The statement of one page of the display read (`$1` thread, `$2` cursor or `NULL`, `$3` limit).
|
|
259
|
+
*
|
|
260
|
+
* One statement reads one snapshot, thus an append or a retract cannot add a turn between the
|
|
261
|
+
* read of the page edges and the read of the rows. The parts:
|
|
231
262
|
*
|
|
232
|
-
* `
|
|
233
|
-
*
|
|
234
|
-
*
|
|
235
|
-
*
|
|
263
|
+
* - `page_walk`: a walk down from the cursor, one row for each step, that counts the turn starts
|
|
264
|
+
* and stops at the `$3`-th. Each step is a `LIMIT 1` read of the primary key `(thread_id, seq)`
|
|
265
|
+
* that evaluates the start predicate in the select list.
|
|
266
|
+
* - `page_lower`: the row where the walk reached `$3` starts, else `NULL`. A page that is not
|
|
267
|
+
* full reaches the start of the thread and holds the rows before the first turn start.
|
|
268
|
+
* - `page_climb` and `page_upper`: a walk up from the cursor to the first turn start at or above
|
|
269
|
+
* it, else `NULL`. For a cursor that a page gave this is the cursor row. For a cursor inside a
|
|
270
|
+
* turn it is the start of the next turn, thus the turn of the cursor stays whole.
|
|
271
|
+
* - `page_next`: `page_lower` when a row lies below it. The `EXISTS` reads no envelope.
|
|
272
|
+
*
|
|
273
|
+
* The start predicate is never a `WHERE` condition of a scan that has an `ORDER BY` and a `LIMIT`.
|
|
274
|
+
* The planner has no statistics for a JSON path, so it estimates that very few rows match. It then
|
|
275
|
+
* chooses a bitmap scan and a sort of each row of the thread, and it evaluates the predicate on the
|
|
276
|
+
* envelope of each row (a tool result can be many KB). A walk of `LIMIT 1` reads of the key does
|
|
277
|
+
* not depend on that estimate, and its work grows with the rows of the page.
|
|
278
|
+
*
|
|
279
|
+
* An absent cursor, `page_lower`, and `page_upper` each become a `bigint` extreme through
|
|
280
|
+
* `COALESCE`, never a `NULL` in a comparison: `seq >= NULL` matches no row, and a form such as
|
|
281
|
+
* `($2 IS NULL OR seq < $2)` is a filter, which would visit each newer row. Each bound is an
|
|
282
|
+
* index condition on `(thread_id, seq)`. The join to the turn records carries the same bounds,
|
|
283
|
+
* because the planner estimates a bounded range as a fixed fraction of the thread and then reads
|
|
284
|
+
* each turn record of the thread through a hash join.
|
|
236
285
|
*/
|
|
286
|
+
const PAGE_SQL = `WITH RECURSIVE page_walk(seq, starts) AS (
|
|
287
|
+
SELECT COALESCE($2::bigint, ${MAX_SEQ}::bigint), 0::bigint
|
|
288
|
+
UNION ALL
|
|
289
|
+
SELECT below.seq, page_walk.starts + below.is_start::int
|
|
290
|
+
FROM page_walk
|
|
291
|
+
CROSS JOIN LATERAL (
|
|
292
|
+
SELECT messages.seq, COALESCE(${GENUINE_USER_START_SQL}, false) AS is_start FROM messages
|
|
293
|
+
WHERE messages.thread_id = $1 AND messages.seq < page_walk.seq
|
|
294
|
+
ORDER BY messages.seq DESC
|
|
295
|
+
LIMIT 1
|
|
296
|
+
) below
|
|
297
|
+
WHERE page_walk.starts < $3::bigint
|
|
298
|
+
),
|
|
299
|
+
page_lower AS (
|
|
300
|
+
SELECT (SELECT page_walk.seq FROM page_walk WHERE page_walk.starts = $3::bigint) AS seq
|
|
301
|
+
),
|
|
302
|
+
page_climb(seq, is_start) AS (
|
|
303
|
+
SELECT above.seq, above.is_start FROM (
|
|
304
|
+
SELECT messages.seq, COALESCE(${GENUINE_USER_START_SQL}, false) AS is_start FROM messages
|
|
305
|
+
WHERE messages.thread_id = $1 AND messages.seq >= COALESCE($2::bigint, ${MAX_SEQ}::bigint)
|
|
306
|
+
ORDER BY messages.seq ASC
|
|
307
|
+
LIMIT 1
|
|
308
|
+
) above
|
|
309
|
+
UNION ALL
|
|
310
|
+
SELECT above.seq, above.is_start
|
|
311
|
+
FROM page_climb
|
|
312
|
+
CROSS JOIN LATERAL (
|
|
313
|
+
SELECT messages.seq, COALESCE(${GENUINE_USER_START_SQL}, false) AS is_start FROM messages
|
|
314
|
+
WHERE messages.thread_id = $1 AND messages.seq > page_climb.seq
|
|
315
|
+
ORDER BY messages.seq ASC
|
|
316
|
+
LIMIT 1
|
|
317
|
+
) above
|
|
318
|
+
WHERE NOT page_climb.is_start
|
|
319
|
+
),
|
|
320
|
+
page_upper AS (
|
|
321
|
+
SELECT page_climb.seq FROM page_climb WHERE page_climb.is_start
|
|
322
|
+
),
|
|
323
|
+
page_next AS (
|
|
324
|
+
SELECT page_lower.seq FROM page_lower
|
|
325
|
+
WHERE page_lower.seq IS NOT NULL
|
|
326
|
+
AND EXISTS (SELECT 1 FROM messages WHERE thread_id = $1 AND seq < page_lower.seq)
|
|
327
|
+
)
|
|
328
|
+
SELECT ${STORED_ROW_COLUMNS}, (SELECT seq::text FROM page_next) AS next_before
|
|
329
|
+
${storedRowFrom(` AND turns.start_seq >= ${PAGE_LOWER_BOUND} AND turns.start_seq < ${PAGE_UPPER_BOUND}`)}
|
|
330
|
+
WHERE messages.thread_id = $1
|
|
331
|
+
AND messages.seq >= ${PAGE_LOWER_BOUND}
|
|
332
|
+
AND messages.seq < ${PAGE_UPPER_BOUND}
|
|
333
|
+
ORDER BY messages.seq ASC`;
|
|
334
|
+
/** The limit that the page statement receives: an integer, at least 1, and a bigint-safe size. */
|
|
335
|
+
function pageLimit(limit) {
|
|
336
|
+
return Number.isFinite(limit) ? Math.min(Math.max(1, Math.trunc(limit)), Number.MAX_SAFE_INTEGER) : 1;
|
|
337
|
+
}
|
|
338
|
+
/** `appendTurn` inside the transaction of the caller, thus another write of the caller commits with the turn or not at all. */
|
|
339
|
+
export function appendTurnIn(client, threadId, turn) {
|
|
340
|
+
if (turn.modelMessages.length === 0)
|
|
341
|
+
return okVoid();
|
|
342
|
+
return lockThread(client, threadId, "thread-history.appendTurn")
|
|
343
|
+
.andThen(() => nextSeq(client, threadId, "thread-history.appendTurn"))
|
|
344
|
+
.andThen((startSeq) => insertGroup(client, threadId, startSeq, turn, "thread-history.appendTurn"))
|
|
345
|
+
.andThen(() => touchThread(client, threadId, "thread-history.appendTurn"));
|
|
346
|
+
}
|
|
237
347
|
export function createThreadHistory(pool, logger) {
|
|
238
348
|
function appendTurn(threadId, turn) {
|
|
239
349
|
if (turn.modelMessages.length === 0)
|
|
240
350
|
return okVoid();
|
|
241
|
-
return withTransaction(pool, "thread-history.appendTurn", (client) =>
|
|
242
|
-
.andThen(() => nextSeq(client, threadId, "thread-history.appendTurn"))
|
|
243
|
-
.andThen((startSeq) => insertGroup(client, threadId, startSeq, turn, "thread-history.appendTurn"))
|
|
244
|
-
.andThen(() => touchThread(client, threadId, "thread-history.appendTurn")));
|
|
351
|
+
return withTransaction(pool, "thread-history.appendTurn", (client) => appendTurnIn(client, threadId, turn));
|
|
245
352
|
}
|
|
246
353
|
function writeTurn(threadId, write) {
|
|
247
354
|
const { close } = write;
|
|
248
355
|
const groups = [...(write.opening === undefined ? [] : [write.opening]), ...write.rounds, ...(close?.note === undefined ? [] : [close.note])];
|
|
249
356
|
return withTransaction(pool, "thread-history.writeTurn", (client) => lockThread(client, threadId, "thread-history.writeTurn")
|
|
250
|
-
|
|
251
|
-
.andThen((
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
const groupSeq = seq;
|
|
257
|
-
seq += group.modelMessages.length;
|
|
258
|
-
steps.push(() => insertGroup(client, threadId, groupSeq, group, "thread-history.writeTurn"));
|
|
259
|
-
if (index === 0 && write.opening !== undefined)
|
|
260
|
-
steps.push(() => openTurnRecord(client, threadId, startSeq));
|
|
261
|
-
}
|
|
262
|
-
if (close !== undefined)
|
|
263
|
-
steps.push(() => closeTurnRecord(client, threadId, startSeq, close));
|
|
264
|
-
steps.push(() => touchThread(client, threadId, "thread-history.writeTurn"));
|
|
265
|
-
return steps.reduce((chain, step) => chain.andThen(step), okVoid()).map(() => ({ startSeq }));
|
|
357
|
+
// One transaction stores each group of a write, thus a stored first group means a stored write.
|
|
358
|
+
.andThen(() => storedGroupSeq(client, threadId, groups[0]?.key, "thread-history.writeTurn"))
|
|
359
|
+
.andThen((storedSeq) => {
|
|
360
|
+
if (storedSeq === undefined)
|
|
361
|
+
return writeGroups(client);
|
|
362
|
+
return okAsync({ startSeq: write.opening === undefined ? write.startSeq : storedSeq });
|
|
266
363
|
}));
|
|
364
|
+
function writeGroups(client) {
|
|
365
|
+
return nextSeq(client, threadId, "thread-history.writeTurn").andThen((firstSeq) => {
|
|
366
|
+
const startSeq = write.opening === undefined ? write.startSeq : firstSeq;
|
|
367
|
+
const steps = [];
|
|
368
|
+
let seq = firstSeq;
|
|
369
|
+
for (const [index, group] of groups.entries()) {
|
|
370
|
+
const groupSeq = seq;
|
|
371
|
+
seq += group.modelMessages.length;
|
|
372
|
+
steps.push(() => insertGroup(client, threadId, groupSeq, group, "thread-history.writeTurn"));
|
|
373
|
+
if (index === 0 && write.opening !== undefined)
|
|
374
|
+
steps.push(() => openTurnRecord(client, threadId, startSeq));
|
|
375
|
+
}
|
|
376
|
+
if (close !== undefined)
|
|
377
|
+
steps.push(() => closeTurnRecord(client, threadId, startSeq, close));
|
|
378
|
+
steps.push(() => touchThread(client, threadId, "thread-history.writeTurn"));
|
|
379
|
+
return steps.reduce((chain, step) => chain.andThen(step), okVoid()).map(() => ({ startSeq }));
|
|
380
|
+
});
|
|
381
|
+
}
|
|
267
382
|
}
|
|
268
383
|
function loadRecent(threadId, options) {
|
|
269
384
|
return tryQuery("thread-history.loadRecent", async () => {
|
|
@@ -279,7 +394,7 @@ export function createThreadHistory(pool, logger) {
|
|
|
279
394
|
// nothing has no rollup at all. The two are different measurements
|
|
280
395
|
// sharing a unit; see the column comments.
|
|
281
396
|
`SELECT seq::text AS seq, message_envelope, tokens
|
|
282
|
-
FROM messages WHERE thread_id = $1 ORDER BY messages.seq ASC`, [threadId]);
|
|
397
|
+
FROM messages WHERE thread_id = $1 AND ($2::bigint IS NULL OR messages.seq <= $2::bigint) ORDER BY messages.seq ASC`, [threadId, options?.throughSeq ?? null]);
|
|
283
398
|
const parsed = rows.map((row, index) => ({
|
|
284
399
|
index,
|
|
285
400
|
message: parseStoredMessageEnvelope(row.message_envelope, `${threadId}/${row.seq}`).message,
|
|
@@ -296,59 +411,77 @@ export function createThreadHistory(pool, logger) {
|
|
|
296
411
|
return view.messages;
|
|
297
412
|
});
|
|
298
413
|
}
|
|
299
|
-
//
|
|
300
|
-
// turn is persisted as one row per step (plus its tool_result
|
|
301
|
-
//
|
|
302
|
-
//
|
|
303
|
-
//
|
|
304
|
-
//
|
|
414
|
+
// A display read is turn-bounded, not row-bounded. A serial-tool assistant
|
|
415
|
+
// turn is persisted as one row per step (plus its tool_result rows), so a
|
|
416
|
+
// row-windowed read could split a turn and truncate the trailing report
|
|
417
|
+
// card or text out of what the UI fetches. Both reads group rows into turns,
|
|
418
|
+
// so a turn always reloads intact.
|
|
419
|
+
// Spread rather than `usage: r.reported_usage ?? undefined`, so a row with
|
|
420
|
+
// no rollup carries no `usage` KEY at all — absent, not present-and-undefined.
|
|
421
|
+
// The duration and the author obey the same rule, each from its own column.
|
|
422
|
+
// The creation time is unconditional: its column is NOT NULL, thus it has no
|
|
423
|
+
// absence to represent.
|
|
424
|
+
async function toStoredMessage(threadId, r) {
|
|
425
|
+
const envelope = parseStoredMessageEnvelope(r.message_envelope, `${threadId}/${r.seq}`);
|
|
426
|
+
const displayEnvelope = r.display_envelope == null ? undefined : await parseStoredDisplayEnvelope(r.display_envelope, `${threadId}/${r.seq}/display`, logger);
|
|
427
|
+
const row = {
|
|
428
|
+
seq: Number(r.seq),
|
|
429
|
+
envelope,
|
|
430
|
+
message: envelope.message,
|
|
431
|
+
displayEnvelope,
|
|
432
|
+
createdAt: r.created_at,
|
|
433
|
+
};
|
|
434
|
+
if (r.reported_usage !== null)
|
|
435
|
+
row.usage = r.reported_usage;
|
|
436
|
+
if (r.turn_duration_ms !== null)
|
|
437
|
+
row.durationMs = Number(r.turn_duration_ms);
|
|
438
|
+
if (r.author !== null)
|
|
439
|
+
row.author = r.author;
|
|
440
|
+
if (r.turn_status !== null) {
|
|
441
|
+
const turn = { status: r.turn_status };
|
|
442
|
+
if (r.turn_reason !== null)
|
|
443
|
+
turn.reason = r.turn_reason;
|
|
444
|
+
if (r.turn_usage !== null)
|
|
445
|
+
turn.usage = r.turn_usage;
|
|
446
|
+
if (r.turn_record_duration_ms !== null)
|
|
447
|
+
turn.durationMs = Number(r.turn_record_duration_ms);
|
|
448
|
+
row.turn = turn;
|
|
449
|
+
}
|
|
450
|
+
return row;
|
|
451
|
+
}
|
|
452
|
+
async function toTurns(threadId, rows) {
|
|
453
|
+
const stored = await Promise.all(rows.map((row) => toStoredMessage(threadId, row)));
|
|
454
|
+
return groupTurns(stored, (row) => isGenuineUserStart(row.message));
|
|
455
|
+
}
|
|
305
456
|
async function readTurns(threadId) {
|
|
306
457
|
const { rows } = await pool.query(
|
|
307
458
|
// ORDER BY must qualify `messages.seq` — a bare `seq` would bind to the
|
|
308
459
|
// `seq::text AS seq` output alias (Postgres resolves an unqualified
|
|
309
460
|
// ORDER BY name to the output column), sorting the bigint as text:
|
|
310
461
|
// "10" before "2". The qualified name forces the bigint column.
|
|
311
|
-
`SELECT
|
|
312
|
-
|
|
313
|
-
turns.status AS turn_status, turns.reason AS turn_reason, turns.reported_usage AS turn_usage,
|
|
314
|
-
turns.turn_duration_ms::text AS turn_record_duration_ms
|
|
315
|
-
FROM messages
|
|
316
|
-
LEFT JOIN cortex_thread_turns turns ON turns.thread_id = messages.thread_id AND turns.start_seq = messages.seq
|
|
462
|
+
`SELECT ${STORED_ROW_COLUMNS}
|
|
463
|
+
${storedRowFrom()}
|
|
317
464
|
WHERE messages.thread_id = $1
|
|
318
465
|
ORDER BY messages.seq ASC`, [threadId]);
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
...(r.turn_reason === null ? {} : { reason: r.turn_reason }),
|
|
332
|
-
...(r.turn_usage === null ? {} : { usage: r.turn_usage }),
|
|
333
|
-
...(r.turn_record_duration_ms === null ? {} : { durationMs: Number(r.turn_record_duration_ms) }),
|
|
334
|
-
};
|
|
335
|
-
return {
|
|
336
|
-
seq: Number(r.seq),
|
|
337
|
-
envelope,
|
|
338
|
-
message: envelope.message,
|
|
339
|
-
...(displayEnvelope ? { displayEnvelope } : {}),
|
|
340
|
-
...(r.reported_usage === null ? {} : { usage: r.reported_usage }),
|
|
341
|
-
...(r.turn_duration_ms === null ? {} : { durationMs: Number(r.turn_duration_ms) }),
|
|
342
|
-
...(turn === undefined ? {} : { turn }),
|
|
343
|
-
...(r.author === null ? {} : { author: r.author }),
|
|
344
|
-
createdAt: r.created_at,
|
|
345
|
-
};
|
|
346
|
-
}));
|
|
347
|
-
return groupTurns(stored, (row) => isGenuineUserStart(row.message));
|
|
466
|
+
return toTurns(threadId, rows);
|
|
467
|
+
}
|
|
468
|
+
async function readPage(threadId, options) {
|
|
469
|
+
const { rows } = await pool.query(PAGE_SQL, [
|
|
470
|
+
threadId,
|
|
471
|
+
options.before === undefined ? null : String(options.before),
|
|
472
|
+
pageLimit(options.limit),
|
|
473
|
+
]);
|
|
474
|
+
// The cursor rides each row, and an empty page has no row. An empty page has no cursor either:
|
|
475
|
+
// `page_lower` is set only when its row is in the page.
|
|
476
|
+
const next = rows[0]?.next_before ?? null;
|
|
477
|
+
return { turns: await toTurns(threadId, rows), before: next === null ? null : Number(next) };
|
|
348
478
|
}
|
|
349
479
|
function loadAll(threadId) {
|
|
350
480
|
return tryQuery("thread-history.loadAll", () => readTurns(threadId));
|
|
351
481
|
}
|
|
482
|
+
function loadPage(threadId, options) {
|
|
483
|
+
return tryQuery("thread-history.loadPage", () => readPage(threadId, options));
|
|
484
|
+
}
|
|
352
485
|
function retractLastTurn(threadId) {
|
|
353
486
|
return withTransaction(pool, "thread-history.retractLastTurn", (client) =>
|
|
354
487
|
// Take the SAME per-thread advisory lock `appendTurn` takes, and take it
|
|
@@ -379,7 +512,7 @@ export function createThreadHistory(pool, logger) {
|
|
|
379
512
|
(SELECT MAX(seq)::text FROM messages
|
|
380
513
|
WHERE thread_id = $1
|
|
381
514
|
AND ${GENUINE_USER_START_SQL}) AS boundary`, [threadId]);
|
|
382
|
-
return rows
|
|
515
|
+
return presentFirst(rows, "the thread boundary row");
|
|
383
516
|
}))
|
|
384
517
|
.andThen(({ has_rows, boundary }) => {
|
|
385
518
|
if (!has_rows)
|
|
@@ -424,7 +557,7 @@ export function createThreadHistory(pool, logger) {
|
|
|
424
557
|
return tryQuery("thread-history.countUserTurnsAfter", () => pool.query(`SELECT COUNT(*)::text AS turns FROM messages
|
|
425
558
|
WHERE thread_id = $1
|
|
426
559
|
AND seq > $2::bigint
|
|
427
|
-
AND ${GENUINE_USER_START_SQL}`, [threadId, seq])).map(({ rows }) => Number(rows
|
|
560
|
+
AND ${GENUINE_USER_START_SQL}`, [threadId, seq])).map(({ rows }) => Number(presentFirst(rows, "the user-turn count row").turns));
|
|
428
561
|
}
|
|
429
|
-
return { appendTurn, writeTurn, loadRecent, loadAll, retractLastTurn, latestSeq, latestTurnAt, countUserTurnsAfter };
|
|
562
|
+
return { appendTurn, writeTurn, loadRecent, loadAll, loadPage, retractLastTurn, latestSeq, latestTurnAt, countUserTurnsAfter };
|
|
430
563
|
}
|