@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.
- package/dist/agents/conversation-agent.d.ts +3 -0
- package/dist/agents/conversation-agent.js +5 -2
- package/dist/agents/sandbox/shared.d.ts +3 -0
- package/dist/agents/sandbox/shared.js +5 -0
- package/dist/agents/sandbox/types.d.ts +1 -1
- package/dist/app/chat-turn.d.ts +2 -0
- package/dist/app/chat-turn.js +11 -2
- package/dist/app/synthesize-run.d.ts +3 -0
- package/dist/app/synthesize-run.js +2 -1
- package/dist/citations/__fixtures__/resolver.d.ts +3 -0
- package/dist/citations/__fixtures__/resolver.js +9 -0
- package/dist/citations/aggregate.d.ts +3 -0
- package/dist/citations/aggregate.js +44 -0
- package/dist/citations/clients/arxiv.d.ts +6 -0
- package/dist/citations/clients/arxiv.js +34 -0
- package/dist/citations/clients/common.d.ts +11 -0
- package/dist/citations/clients/common.js +43 -0
- package/dist/citations/clients/crossref.d.ts +8 -0
- package/dist/citations/clients/crossref.js +98 -0
- package/dist/citations/clients/doi-registry.d.ts +3 -0
- package/dist/citations/clients/doi-registry.js +95 -0
- package/dist/citations/clients/pubmed.d.ts +6 -0
- package/dist/citations/clients/pubmed.js +83 -0
- package/dist/citations/clients/semantic-scholar.d.ts +6 -0
- package/dist/citations/clients/semantic-scholar.js +60 -0
- package/dist/citations/compare.d.ts +9 -0
- package/dist/citations/compare.js +72 -0
- package/dist/citations/match.d.ts +11 -0
- package/dist/citations/match.js +173 -0
- package/dist/citations/normalize.d.ts +31 -0
- package/dist/citations/normalize.js +187 -0
- package/dist/citations/plan.d.ts +2 -0
- package/dist/citations/plan.js +59 -0
- package/dist/citations/resolve.d.ts +28 -0
- package/dist/citations/resolve.js +238 -0
- package/dist/citations/types.d.ts +583 -0
- package/dist/citations/types.js +129 -0
- package/dist/contracts/schemas/chat-parts.d.ts +8 -8
- package/dist/contracts/target-dossier.d.ts +20 -20
- package/dist/execution/run-synthesis.d.ts +3 -0
- package/dist/execution/run-synthesis.js +1 -0
- package/dist/index.d.ts +6 -1
- package/dist/index.js +3 -0
- package/dist/lib/cache.d.ts +8 -0
- package/dist/lib/cache.js +35 -0
- package/dist/lib/rate-limit.d.ts +35 -0
- package/dist/lib/rate-limit.js +121 -0
- package/dist/literature/sources/arxiv.d.ts +22 -0
- package/dist/literature/sources/arxiv.js +103 -0
- package/dist/literature/sources/http.d.ts +28 -0
- package/dist/literature/sources/http.js +97 -0
- package/dist/literature/sources/pubmed.d.ts +68 -0
- package/dist/literature/sources/pubmed.js +266 -0
- package/dist/literature/sources/semantic-scholar.d.ts +24 -0
- package/dist/literature/sources/semantic-scholar.js +71 -0
- package/dist/memory/thread-store.d.ts +142 -25
- package/dist/memory/thread-store.js +228 -40
- package/dist/prompts/literature-reviewer.d.ts +1 -1
- package/dist/prompts/literature-reviewer.js +2 -0
- package/dist/runtime/assemble.d.ts +50 -4
- package/dist/runtime/assemble.js +47 -3
- package/dist/runtime/boot.js +7 -1
- package/dist/state/init.js +46 -1
- package/dist/state/schema.d.ts +2 -2
- package/dist/tools/bio/gene-preclinical-profile.d.ts +1 -1
- package/dist/tools/bio/keys.d.ts +1 -0
- package/dist/tools/bio/pubmed.js +4 -4
- package/dist/tools/lib/ncbi-utils.d.ts +3 -58
- package/dist/tools/lib/ncbi-utils.js +2 -286
- package/dist/tools/lib/pubmed-client.d.ts +5 -12
- package/dist/tools/lib/pubmed-client.js +20 -79
- package/dist/tools/research/generate-analogy-report.js +2 -2
- package/dist/tools/research/index.d.ts +1 -0
- package/dist/tools/research/index.js +1 -0
- package/dist/tools/research/inspect-run.d.ts +1 -1
- package/dist/tools/research/literature-reviewer.d.ts +3 -0
- package/dist/tools/research/literature-reviewer.js +2 -0
- package/dist/tools/research/resolve-citation.d.ts +3 -0
- package/dist/tools/research/resolve-citation.js +15 -0
- package/dist/tools/research/search-arxiv.d.ts +3 -19
- package/dist/tools/research/search-arxiv.js +9 -105
- package/dist/tools/research/search-semantic-scholar.d.ts +8 -33
- package/dist/tools/research/search-semantic-scholar.js +29 -88
- package/dist/tools/sandbox/list-available-refs.js +1 -2
- package/dist/workflows/execute-analysis.d.ts +3 -0
- package/dist/workflows/execute-analysis.js +1 -0
- package/dist/workflows/sandbox-step.d.ts +5 -0
- package/dist/workflows/sandbox-step.js +1 -0
- package/dist/workflows/target-assessment/phase4-assemble.d.ts +2 -2
- package/dist/workflows/target-assessment/schemas.d.ts +2 -2
- package/dist/workflows/target-assessment/steps/phase2-aggregate.d.ts +1 -1
- package/dist/workflows/target-assessment/steps/phase3-aggregate.d.ts +1 -1
- package/package.json +1 -1
|
@@ -14,14 +14,18 @@
|
|
|
14
14
|
* `applicationVersion` stamp because all registration happens in this one call,
|
|
15
15
|
* before launch — a blue/green drain treats them as a single cohort.
|
|
16
16
|
*/
|
|
17
|
+
import { type Result } from "neverthrow";
|
|
17
18
|
import { type ConversationAgentDeps } from "../agents/conversation-agent.js";
|
|
18
19
|
import type { UsageRecorder } from "../billing/usage-recorder.js";
|
|
19
20
|
import type { ResourcePolicy } from "../config/resource-limits.js";
|
|
20
21
|
import type { AgentDefinition } from "../loop/types.js";
|
|
22
|
+
import type { ThreadType } from "../memory/thread-store.js";
|
|
21
23
|
import { type ExecuteAnalysisDeps, type ExecuteAnalysisInput, type ExecuteAnalysisResult } from "../workflows/execute-analysis.js";
|
|
22
24
|
import { type SandboxStepDeps, type SandboxStepInput, type SandboxStepResult } from "../workflows/sandbox-step.js";
|
|
23
25
|
import { type ExecuteTargetAssessmentDeps, type ExecuteTargetAssessmentInput, type ExecuteTargetAssessmentResult } from "../workflows/execute-target-assessment.js";
|
|
24
26
|
import { type DataProfileDeps, type DataProfileWorkflowInput } from "../tasks/data-profile.js";
|
|
27
|
+
import { type CitationResolverConfig } from "../citations/resolve.js";
|
|
28
|
+
import type { CitationResolver } from "../citations/types.js";
|
|
25
29
|
/** Registered child sandbox-step callable the parent's child dispatch closes over. */
|
|
26
30
|
export type SandboxStepCallable = (input: SandboxStepInput) => Promise<SandboxStepResult>;
|
|
27
31
|
/**
|
|
@@ -38,8 +42,8 @@ export type SandboxStepCallable = (input: SandboxStepInput) => Promise<SandboxSt
|
|
|
38
42
|
* conversation side.
|
|
39
43
|
*/
|
|
40
44
|
export interface CoreWorkflowDeps {
|
|
41
|
-
readonly sandboxStep: Omit<SandboxStepDeps, "usageRecorder">;
|
|
42
|
-
readonly buildExecuteAnalysis: (sandboxStep: SandboxStepCallable) => Omit<ExecuteAnalysisDeps, "usageRecorder">;
|
|
45
|
+
readonly sandboxStep: Omit<SandboxStepDeps, "usageRecorder" | "citationResolver">;
|
|
46
|
+
readonly buildExecuteAnalysis: (sandboxStep: SandboxStepCallable) => Omit<ExecuteAnalysisDeps, "usageRecorder" | "citationResolver">;
|
|
43
47
|
readonly executeTargetAssessment: Omit<ExecuteTargetAssessmentDeps, "usageRecorder">;
|
|
44
48
|
readonly dataProfile: Omit<DataProfileDeps, "usageRecorder">;
|
|
45
49
|
}
|
|
@@ -56,7 +60,7 @@ export interface RegisteredWorkflows {
|
|
|
56
60
|
* cannot wire a stale callable, a policy that diverges from the one the
|
|
57
61
|
* workflows see, or a recorder that only half the agent tree reports to.
|
|
58
62
|
*/
|
|
59
|
-
export type ConversationAssemblyDeps = Omit<ConversationAgentDeps, "executeAnalysisWorkflow" | "resourcePolicy" | "usageRecorder">;
|
|
63
|
+
export type ConversationAssemblyDeps = Omit<ConversationAgentDeps, "executeAnalysisWorkflow" | "resourcePolicy" | "usageRecorder" | "citationResolver">;
|
|
60
64
|
export interface CoreRuntimeDeps {
|
|
61
65
|
readonly conversation: ConversationAssemblyDeps;
|
|
62
66
|
readonly workflows: CoreWorkflowDeps;
|
|
@@ -72,9 +76,51 @@ export interface CoreRuntimeDeps {
|
|
|
72
76
|
* `createNoopUsageRecorder()`.
|
|
73
77
|
*/
|
|
74
78
|
readonly usageRecorder?: UsageRecorder;
|
|
79
|
+
/** Harness-owned citation capability configuration; no ambient lookup occurs. */
|
|
80
|
+
readonly citationResolverConfig?: CitationResolverConfig;
|
|
75
81
|
}
|
|
82
|
+
/**
|
|
83
|
+
* The refusal a thread type carries no agent yet. `report` is a valid
|
|
84
|
+
* `ThreadType` with no registered agent until its builder plugs in at assembly,
|
|
85
|
+
* so resolution has to have a typed way to say "not that one" without throwing.
|
|
86
|
+
* The channel is permanent, not interim: `ThreadType` grows over the product's
|
|
87
|
+
* life, and a bare-`AgentDefinition` return would force every future member to
|
|
88
|
+
* register an agent in the same commit that adds the member.
|
|
89
|
+
*/
|
|
90
|
+
export interface UnregisteredThreadType {
|
|
91
|
+
readonly type: "unregistered_thread_type";
|
|
92
|
+
readonly threadType: ThreadType;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* How a thread's type selects the agent that runs its turns. Resolution is a
|
|
96
|
+
* synchronous record lookup, so the channel is plain `Result`, never
|
|
97
|
+
* `ResultAsync`: a registered type resolves to its assembled singleton, an
|
|
98
|
+
* unregistered one refuses on the error channel.
|
|
99
|
+
*/
|
|
100
|
+
export interface ThreadAgentResolver {
|
|
101
|
+
forThread(type: ThreadType): Result<AgentDefinition, UnregisteredThreadType>;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Wrap a type→agent registry as the resolution surface. Held apart from
|
|
105
|
+
* `assembleCoreRuntime` so the resolution contract — a registered type resolves
|
|
106
|
+
* to the very object the registry holds, an unregistered one refuses — is
|
|
107
|
+
* exercisable without the DBOS registration `assembleCoreRuntime` performs.
|
|
108
|
+
*
|
|
109
|
+
* The registry holds assembled singletons, so `forThread` returns the same
|
|
110
|
+
* `AgentDefinition` object on every call for a given type: construction-time
|
|
111
|
+
* captures (an embedder's delegating provider handles, closure-wired tools)
|
|
112
|
+
* stay valid across every turn.
|
|
113
|
+
*/
|
|
114
|
+
export declare function createThreadAgentResolver(registry: Partial<Record<ThreadType, AgentDefinition>>): ThreadAgentResolver;
|
|
76
115
|
export interface CoreRuntime {
|
|
77
|
-
|
|
116
|
+
/**
|
|
117
|
+
* Thread→agent resolution — the only way to reach an assembled agent by
|
|
118
|
+
* thread type. Holds the singletons this call built; `conversation` resolves
|
|
119
|
+
* to the assembled conversation agent, every not-yet-registered type refuses
|
|
120
|
+
* on the `Result` channel.
|
|
121
|
+
*/
|
|
122
|
+
readonly agents: ThreadAgentResolver;
|
|
78
123
|
readonly workflows: RegisteredWorkflows;
|
|
124
|
+
readonly citationResolver: CitationResolver;
|
|
79
125
|
}
|
|
80
126
|
export declare function assembleCoreRuntime(deps: CoreRuntimeDeps): CoreRuntime;
|
package/dist/runtime/assemble.js
CHANGED
|
@@ -14,17 +14,50 @@
|
|
|
14
14
|
* `applicationVersion` stamp because all registration happens in this one call,
|
|
15
15
|
* before launch — a blue/green drain treats them as a single cohort.
|
|
16
16
|
*/
|
|
17
|
+
import { err, ok } from "neverthrow";
|
|
17
18
|
import { createConversationAgent } from "../agents/conversation-agent.js";
|
|
18
19
|
import { createNoopUsageRecorder } from "../billing/noop-usage-recorder.js";
|
|
19
20
|
import { registerExecuteAnalysis } from "../workflows/execute-analysis.js";
|
|
20
21
|
import { registerSandboxStep } from "../workflows/sandbox-step.js";
|
|
21
22
|
import { registerExecuteTargetAssessment, } from "../workflows/execute-target-assessment.js";
|
|
22
23
|
import { registerDataProfileWorkflow } from "../tasks/data-profile.js";
|
|
24
|
+
import { createCitationResolver } from "../citations/resolve.js";
|
|
25
|
+
const _assertDomainError = true;
|
|
26
|
+
/**
|
|
27
|
+
* Wrap a type→agent registry as the resolution surface. Held apart from
|
|
28
|
+
* `assembleCoreRuntime` so the resolution contract — a registered type resolves
|
|
29
|
+
* to the very object the registry holds, an unregistered one refuses — is
|
|
30
|
+
* exercisable without the DBOS registration `assembleCoreRuntime` performs.
|
|
31
|
+
*
|
|
32
|
+
* The registry holds assembled singletons, so `forThread` returns the same
|
|
33
|
+
* `AgentDefinition` object on every call for a given type: construction-time
|
|
34
|
+
* captures (an embedder's delegating provider handles, closure-wired tools)
|
|
35
|
+
* stay valid across every turn.
|
|
36
|
+
*/
|
|
37
|
+
export function createThreadAgentResolver(registry) {
|
|
38
|
+
return {
|
|
39
|
+
forThread: (type) => {
|
|
40
|
+
const agent = registry[type];
|
|
41
|
+
if (agent === undefined) {
|
|
42
|
+
const refusal = { type: "unregistered_thread_type", threadType: type };
|
|
43
|
+
return err(refusal);
|
|
44
|
+
}
|
|
45
|
+
return ok(agent);
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
}
|
|
23
49
|
export function assembleCoreRuntime(deps) {
|
|
24
50
|
const { conversation, workflows: wf, resourcePolicy } = deps;
|
|
25
51
|
const usageRecorder = deps.usageRecorder ?? createNoopUsageRecorder();
|
|
26
|
-
const
|
|
27
|
-
|
|
52
|
+
const citationResolver = createCitationResolver({
|
|
53
|
+
...(deps.citationResolverConfig ?? {}),
|
|
54
|
+
...(deps.citationResolverConfig?.ncbiApiKey !== undefined || conversation.bioKeys.ncbi === undefined ? {} : { ncbiApiKey: conversation.bioKeys.ncbi }),
|
|
55
|
+
...(deps.citationResolverConfig?.semanticScholarApiKey !== undefined || conversation.bioKeys.semanticScholar === undefined
|
|
56
|
+
? {}
|
|
57
|
+
: { semanticScholarApiKey: conversation.bioKeys.semanticScholar }),
|
|
58
|
+
});
|
|
59
|
+
const sandboxStep = registerSandboxStep({ ...wf.sandboxStep, citationResolver, usageRecorder });
|
|
60
|
+
const executeAnalysis = registerExecuteAnalysis({ ...wf.buildExecuteAnalysis(sandboxStep), citationResolver, usageRecorder });
|
|
28
61
|
const executeTargetAssessment = registerExecuteTargetAssessment({ ...wf.executeTargetAssessment, usageRecorder });
|
|
29
62
|
const dataProfile = registerDataProfileWorkflow({ ...wf.dataProfile, usageRecorder });
|
|
30
63
|
const conversationAgent = createConversationAgent({
|
|
@@ -32,14 +65,25 @@ export function assembleCoreRuntime(deps) {
|
|
|
32
65
|
executeAnalysisWorkflow: executeAnalysis,
|
|
33
66
|
resourcePolicy,
|
|
34
67
|
usageRecorder,
|
|
68
|
+
citationResolver,
|
|
35
69
|
});
|
|
70
|
+
// The single registration point for every typed agent. One entry today; a
|
|
71
|
+
// future thread type's agent plugs in here at assembly with no embedder
|
|
72
|
+
// change. `conversation` is required at the type level because boot resolves
|
|
73
|
+
// it unconditionally (`boot.ts` backfill) — a dropped registration must fail
|
|
74
|
+
// tsc here, not surface only as a boot-time throw. The `Partial` over the
|
|
75
|
+
// rest keeps the compiler honest that `report` has no agent yet.
|
|
76
|
+
const agents = {
|
|
77
|
+
conversation: conversationAgent,
|
|
78
|
+
};
|
|
36
79
|
return {
|
|
37
|
-
|
|
80
|
+
agents: createThreadAgentResolver(agents),
|
|
38
81
|
workflows: {
|
|
39
82
|
executeAnalysis,
|
|
40
83
|
sandboxStep,
|
|
41
84
|
executeTargetAssessment,
|
|
42
85
|
dataProfile,
|
|
43
86
|
},
|
|
87
|
+
citationResolver,
|
|
44
88
|
};
|
|
45
89
|
}
|
package/dist/runtime/boot.js
CHANGED
|
@@ -36,6 +36,7 @@
|
|
|
36
36
|
* releases whatever it acquired). Only `shutdown` swallows per-step failures —
|
|
37
37
|
* once shutdown starts, exiting takes precedence (see `runShutdownSequence`).
|
|
38
38
|
*/
|
|
39
|
+
import { unwrapOrThrow } from "../lib/result.js";
|
|
39
40
|
import { SANDBOX_AGENT_META } from "../agents/sandbox/index.js";
|
|
40
41
|
import { validateAgentSkills } from "../agents/sandbox/validate-skills.js";
|
|
41
42
|
import { initCortexState } from "../state/init.js";
|
|
@@ -54,10 +55,15 @@ export async function bootHarness(deps) {
|
|
|
54
55
|
await initCortexState(pool);
|
|
55
56
|
await assertConnectionBudget({ pool, logger, config: deps.connectionBudget });
|
|
56
57
|
const runtime = assembleCoreRuntime(core);
|
|
58
|
+
// Assembly registers `conversation` unconditionally, so this resolution can
|
|
59
|
+
// never refuse; `unwrapOrThrow` turns the impossible error branch into a
|
|
60
|
+
// boot-propagating throw rather than threading a Result through the boot
|
|
61
|
+
// sequence, whose steps already fail by propagation.
|
|
62
|
+
const conversationAgent = unwrapOrThrow(runtime.agents.forThread("conversation"));
|
|
57
63
|
await backfillConversationDisplayEnvelopes({
|
|
58
64
|
pool,
|
|
59
65
|
resolveWorkspaceRoot: core.conversation.resolveWorkspaceRoot,
|
|
60
|
-
tools:
|
|
66
|
+
tools: conversationAgent.tools,
|
|
61
67
|
});
|
|
62
68
|
await deps.beforeLaunch?.();
|
|
63
69
|
await launchDbos({ config: deps.dbos, logger });
|
package/dist/state/init.js
CHANGED
|
@@ -275,12 +275,57 @@ CREATE TABLE IF NOT EXISTS cortex_analysis_threads (
|
|
|
275
275
|
title TEXT,
|
|
276
276
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
277
277
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
278
|
-
deleted_at TIMESTAMPTZ
|
|
278
|
+
deleted_at TIMESTAMPTZ,
|
|
279
|
+
thread_type TEXT NOT NULL DEFAULT 'conversation',
|
|
280
|
+
-- The cascade on this self-reference is a BACKSTOP, never the deletion path.
|
|
281
|
+
-- messages carries no foreign key to this table, so a cascade firing on its
|
|
282
|
+
-- own drops a descendant's metadata row while leaving that descendant's
|
|
283
|
+
-- messages rows behind with nothing naming them, beyond the reach of any
|
|
284
|
+
-- later thread-scoped or analysis-scoped reclamation. purgeThread therefore
|
|
285
|
+
-- walks the subtree and deletes its messages rows explicitly, to the same
|
|
286
|
+
-- depth the cascade reaches.
|
|
287
|
+
parent_thread_id TEXT REFERENCES cortex_analysis_threads(thread_id) ON DELETE CASCADE,
|
|
288
|
+
parent_seq BIGINT
|
|
279
289
|
);
|
|
280
290
|
|
|
291
|
+
-- These three sit here, and not in the additive block further down, because the
|
|
292
|
+
-- index below reads one of them. CREATE TABLE IF NOT EXISTS adds no column to a
|
|
293
|
+
-- table that already exists, so on every database but a brand new one the column
|
|
294
|
+
-- arrives from an ALTER -- and the whole additive block runs after this text. An
|
|
295
|
+
-- index declared here over a column added there fails with 42703 on exactly the
|
|
296
|
+
-- databases a migration exists to serve. Additive with no backfill either way: an
|
|
297
|
+
-- existing row reads back as a root conversation thread with no anchor, which is
|
|
298
|
+
-- what it is.
|
|
299
|
+
ALTER TABLE cortex_analysis_threads
|
|
300
|
+
ADD COLUMN IF NOT EXISTS thread_type TEXT NOT NULL DEFAULT 'conversation';
|
|
301
|
+
|
|
302
|
+
ALTER TABLE cortex_analysis_threads
|
|
303
|
+
ADD COLUMN IF NOT EXISTS parent_thread_id TEXT REFERENCES cortex_analysis_threads(thread_id) ON DELETE CASCADE;
|
|
304
|
+
|
|
305
|
+
ALTER TABLE cortex_analysis_threads
|
|
306
|
+
ADD COLUMN IF NOT EXISTS parent_seq BIGINT;
|
|
307
|
+
|
|
281
308
|
CREATE INDEX IF NOT EXISTS idx_cortex_analysis_threads_analysis
|
|
282
309
|
ON cortex_analysis_threads(analysis_id) WHERE deleted_at IS NULL;
|
|
283
310
|
|
|
311
|
+
-- Not partial, unlike the analysis index above. Two of the three readers of
|
|
312
|
+
-- parent_thread_id carry no deleted_at predicate and cannot: the recursive
|
|
313
|
+
-- subtree walk in thread-store.ts must reach archived descendants, and the
|
|
314
|
+
-- referential trigger behind ON DELETE CASCADE is the database's own query.
|
|
315
|
+
-- Postgres uses a partial index only where it can prove the predicate holds, so
|
|
316
|
+
-- a partial index here leaves both to a sequential scan of the whole table.
|
|
317
|
+
-- Over 150k rows that measured 28 ms per walk and 20 ms per cascade, against
|
|
318
|
+
-- 0.06 ms and 0.10 ms with this one. The third reader, a listing filtered by
|
|
319
|
+
-- parent, keeps an index scan either way.
|
|
320
|
+
--
|
|
321
|
+
-- The old partial index goes by name: CREATE INDEX IF NOT EXISTS keeps whatever
|
|
322
|
+
-- definition already holds the name, so a database that built the partial one
|
|
323
|
+
-- would never see this.
|
|
324
|
+
DROP INDEX IF EXISTS idx_cortex_analysis_threads_parent;
|
|
325
|
+
|
|
326
|
+
CREATE INDEX IF NOT EXISTS idx_cortex_analysis_threads_parent_fk
|
|
327
|
+
ON cortex_analysis_threads(parent_thread_id);
|
|
328
|
+
|
|
284
329
|
-- Working memory — the harness WorkingMemory module's table, one row per
|
|
285
330
|
-- analysis. The data column holds a JSONB object with four sections (goal,
|
|
286
331
|
-- constraints, hypotheses, findings). Section updates are a read-modify-write
|
package/dist/state/schema.d.ts
CHANGED
|
@@ -46,10 +46,10 @@ export declare const ArtifactRowSchema: z.ZodObject<{
|
|
|
46
46
|
}, z.core.$strip>;
|
|
47
47
|
export type ArtifactRow = z.infer<typeof ArtifactRowSchema>;
|
|
48
48
|
export declare const RunStatus: z.ZodEnum<{
|
|
49
|
+
partial: "partial";
|
|
49
50
|
running: "running";
|
|
50
51
|
completed: "completed";
|
|
51
52
|
failed: "failed";
|
|
52
|
-
partial: "partial";
|
|
53
53
|
canceled: "canceled";
|
|
54
54
|
suspended_insufficient_funds: "suspended_insufficient_funds";
|
|
55
55
|
}>;
|
|
@@ -77,10 +77,10 @@ export declare const CortexRunRowSchema: z.ZodObject<{
|
|
|
77
77
|
threadId: z.ZodNullable<z.ZodString>;
|
|
78
78
|
workflowName: z.ZodString;
|
|
79
79
|
status: z.ZodEnum<{
|
|
80
|
+
partial: "partial";
|
|
80
81
|
running: "running";
|
|
81
82
|
completed: "completed";
|
|
82
83
|
failed: "failed";
|
|
83
|
-
partial: "partial";
|
|
84
84
|
canceled: "canceled";
|
|
85
85
|
suspended_insufficient_funds: "suspended_insufficient_funds";
|
|
86
86
|
}>;
|
|
@@ -51,7 +51,7 @@ export declare const genePreclinicalProfileTool: import("../define-tool.js").Too
|
|
|
51
51
|
geneSymbol: string;
|
|
52
52
|
include?: ("expression" | "knockout")[] | undefined;
|
|
53
53
|
species?: ("homo_sapiens" | "mus_musculus" | "rattus_norvegicus" | "canis_lupus_familiaris" | "macaca_mulatta")[] | undefined;
|
|
54
|
-
minRank?: "
|
|
54
|
+
minRank?: "absent" | "high" | "medium" | "low" | undefined;
|
|
55
55
|
tissueLimit?: number | undefined;
|
|
56
56
|
phenotypeLimit?: number | undefined;
|
|
57
57
|
}, PreclinicalOutput>;
|
package/dist/tools/bio/keys.d.ts
CHANGED
package/dist/tools/bio/pubmed.js
CHANGED
|
@@ -140,16 +140,16 @@ export function createPubMedTool(deps) {
|
|
|
140
140
|
return `fulltext ${input.pmcId ?? ""}`;
|
|
141
141
|
}
|
|
142
142
|
},
|
|
143
|
-
execute: async (input) => {
|
|
143
|
+
execute: async (input, context) => {
|
|
144
144
|
switch (input.action) {
|
|
145
145
|
case "search":
|
|
146
146
|
return ok(await searchPubmed(deps.ncbiApiKey, input.query, {
|
|
147
147
|
maxResults: input.maxResults ?? DEFAULTS.searchResults,
|
|
148
148
|
...(input.sort ? { sort: input.sort } : {}),
|
|
149
149
|
...(input.dateRange ? { dateRange: input.dateRange } : {}),
|
|
150
|
-
}));
|
|
150
|
+
}, context.signal));
|
|
151
151
|
case "details": {
|
|
152
|
-
const { articles, notFound } = await getArticleDetails(deps.ncbiApiKey, input.pmids);
|
|
152
|
+
const { articles, notFound } = await getArticleDetails(deps.ncbiApiKey, input.pmids, context.signal);
|
|
153
153
|
return ok({
|
|
154
154
|
articles: boundArticleDetails(articles, {
|
|
155
155
|
maxAuthors: input.maxAuthors ?? DEFAULTS.maxAuthors,
|
|
@@ -162,7 +162,7 @@ export function createPubMedTool(deps) {
|
|
|
162
162
|
const parsed = await getArticleFullText(deps.ncbiApiKey, input.pmcId, {
|
|
163
163
|
...(input.sections ? { sections: input.sections } : {}),
|
|
164
164
|
maxChars: input.maxChars ?? DEFAULTS.maxChars,
|
|
165
|
-
});
|
|
165
|
+
}, context.signal);
|
|
166
166
|
// "Not open-access" is an expected outcome — a data variant, not an error.
|
|
167
167
|
if (!parsed)
|
|
168
168
|
return ok({ pmcId: input.pmcId, available: false });
|
|
@@ -1,58 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
* Provides base URL constants, API key injection, and XML-to-article
|
|
5
|
-
* mapping functions for PubMed and PMC DTD structures.
|
|
6
|
-
*/
|
|
7
|
-
export declare const NCBI_BASE = "https://eutils.ncbi.nlm.nih.gov/entrez/eutils";
|
|
8
|
-
export declare const NCBI_IDCONV = "https://www.ncbi.nlm.nih.gov/pmc/utils/idconv/v1.0";
|
|
9
|
-
/**
|
|
10
|
-
* Append `api_key` and optional extra params to a base URL.
|
|
11
|
-
* Omits the key when `apiKey` is undefined.
|
|
12
|
-
*/
|
|
13
|
-
export declare function ncbiUrl(apiKey: string | undefined, base: string, params: Record<string, string | number | undefined>): string;
|
|
14
|
-
export interface PubMedSummary {
|
|
15
|
-
pmid: string;
|
|
16
|
-
title: string;
|
|
17
|
-
journal: string;
|
|
18
|
-
year: string;
|
|
19
|
-
authors: string;
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* Parse esummary XML into PubMedSummary records.
|
|
23
|
-
*/
|
|
24
|
-
export declare function parseEsummary(xml: string): PubMedSummary[];
|
|
25
|
-
export interface ArticleDetail {
|
|
26
|
-
pmid: string;
|
|
27
|
-
title: string;
|
|
28
|
-
abstract: string;
|
|
29
|
-
authors: string[];
|
|
30
|
-
journal: string;
|
|
31
|
-
year: string;
|
|
32
|
-
doi: string;
|
|
33
|
-
meshTerms: string[];
|
|
34
|
-
pmcId: string | null;
|
|
35
|
-
}
|
|
36
|
-
/**
|
|
37
|
-
* Parse efetch PubMed XML into ArticleDetail records.
|
|
38
|
-
* `pmcId` is left null here — resolved separately via ID Converter.
|
|
39
|
-
*/
|
|
40
|
-
export declare function parseEfetch(xml: string): ArticleDetail[];
|
|
41
|
-
/**
|
|
42
|
-
* Parse ID Converter JSON response into a PMID → PMC ID map.
|
|
43
|
-
* Returns only entries that have a PMC ID.
|
|
44
|
-
*/
|
|
45
|
-
export declare function parseIdConvResponse(data: unknown): Map<string, string>;
|
|
46
|
-
export interface ArticleSection {
|
|
47
|
-
heading: string;
|
|
48
|
-
text: string;
|
|
49
|
-
}
|
|
50
|
-
export interface FullTextResult {
|
|
51
|
-
fullText: string;
|
|
52
|
-
sections: ArticleSection[];
|
|
53
|
-
}
|
|
54
|
-
/**
|
|
55
|
-
* Parse PMC efetch XML into plain text with section structure.
|
|
56
|
-
* Omits figures, tables, and supplementary material markup.
|
|
57
|
-
*/
|
|
58
|
-
export declare function parsePmcFullText(xml: string): FullTextResult | null;
|
|
1
|
+
/** @deprecated Import NCBI authority contracts from literature/sources/pubmed. */
|
|
2
|
+
export { NCBI_BASE, NCBI_IDCONV, ncbiUrl, parseEfetch, parseEsummary, parseIdConvResponse, parsePmcFullText } from "../../literature/sources/pubmed.js";
|
|
3
|
+
export type { ArticleDetail, ArticleSection, FullTextResult, PubMedSummary } from "../../literature/sources/pubmed.js";
|