@orion-agents/orion-code 0.1.2 → 0.1.4
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 +96 -3
- package/README.zh-CN.md +109 -4
- package/dist/commands/index.d.ts.map +1 -1
- package/dist/commands/index.js +168 -54
- package/dist/commands/index.js.map +1 -1
- package/dist/commands/types.d.ts +3 -1
- package/dist/commands/types.d.ts.map +1 -1
- package/dist/commands/types.js.map +1 -1
- package/dist/framework/query.d.ts +3 -0
- package/dist/framework/query.d.ts.map +1 -1
- package/dist/framework/query.js +1 -0
- package/dist/framework/query.js.map +1 -1
- package/dist/framework/tool-scheduler.d.ts +61 -1
- package/dist/framework/tool-scheduler.d.ts.map +1 -1
- package/dist/framework/tool-scheduler.js +165 -47
- package/dist/framework/tool-scheduler.js.map +1 -1
- package/dist/framework/tool.d.ts +9 -0
- package/dist/framework/tool.d.ts.map +1 -1
- package/dist/framework/tool.js +2 -0
- package/dist/framework/tool.js.map +1 -1
- package/dist/ink-ui/screens/ReplScreen.d.ts +2 -1
- package/dist/ink-ui/screens/ReplScreen.d.ts.map +1 -1
- package/dist/ink-ui/screens/ReplScreen.js +65 -0
- package/dist/ink-ui/screens/ReplScreen.js.map +1 -1
- package/dist/memory/embeddings.d.ts.map +1 -1
- package/dist/memory/embeddings.js +3 -2
- package/dist/memory/embeddings.js.map +1 -1
- package/dist/memory/semantic-search.d.ts.map +1 -1
- package/dist/memory/semantic-search.js +2 -1
- package/dist/memory/semantic-search.js.map +1 -1
- package/dist/memory/vector-store.d.ts.map +1 -1
- package/dist/memory/vector-store.js +7 -3
- package/dist/memory/vector-store.js.map +1 -1
- package/dist/migration/migrate.d.ts.map +1 -1
- package/dist/migration/migrate.js +7 -11
- package/dist/migration/migrate.js.map +1 -1
- package/dist/print-ui/launch.d.ts +2 -1
- package/dist/print-ui/launch.d.ts.map +1 -1
- package/dist/print-ui/launch.js +7 -0
- package/dist/print-ui/launch.js.map +1 -1
- package/dist/runtime/agent-runtime-controller.d.ts +1 -0
- package/dist/runtime/agent-runtime-controller.d.ts.map +1 -1
- package/dist/runtime/agent-runtime-controller.js +24 -3
- package/dist/runtime/agent-runtime-controller.js.map +1 -1
- package/dist/runtime/agent-runtime-protocol.d.ts +16 -1
- package/dist/runtime/agent-runtime-protocol.d.ts.map +1 -1
- package/dist/runtime/agent-runtime-protocol.js +12 -0
- package/dist/runtime/agent-runtime-protocol.js.map +1 -1
- package/dist/runtime/chat-controller.d.ts +6 -0
- package/dist/runtime/chat-controller.d.ts.map +1 -1
- package/dist/runtime/chat-controller.js +65 -2
- package/dist/runtime/chat-controller.js.map +1 -1
- package/dist/runtime/goals/tools.d.ts.map +1 -1
- package/dist/runtime/goals/tools.js +14 -14
- package/dist/runtime/goals/tools.js.map +1 -1
- package/dist/runtime/goals/types.d.ts +6 -0
- package/dist/runtime/goals/types.d.ts.map +1 -1
- package/dist/runtime/goals/types.js.map +1 -1
- package/dist/runtime/model-coordinator.d.ts.map +1 -1
- package/dist/runtime/model-coordinator.js.map +1 -1
- package/dist/runtime/subagents/child-executor-guard.d.ts.map +1 -1
- package/dist/runtime/subagents/child-executor-guard.js +4 -0
- package/dist/runtime/subagents/child-executor-guard.js.map +1 -1
- package/dist/runtime/subagents/index.d.ts +10 -3
- package/dist/runtime/subagents/index.d.ts.map +1 -1
- package/dist/runtime/subagents/index.js +24 -1
- package/dist/runtime/subagents/index.js.map +1 -1
- package/dist/runtime/subagents/provider-gate.d.ts.map +1 -1
- package/dist/runtime/subagents/provider-gate.js +0 -1
- package/dist/runtime/subagents/provider-gate.js.map +1 -1
- package/dist/runtime/subagents/research-artifact.d.ts +94 -0
- package/dist/runtime/subagents/research-artifact.d.ts.map +1 -0
- package/dist/runtime/subagents/research-artifact.js +164 -0
- package/dist/runtime/subagents/research-artifact.js.map +1 -0
- package/dist/runtime/subagents/research-citation.d.ts +66 -0
- package/dist/runtime/subagents/research-citation.d.ts.map +1 -0
- package/dist/runtime/subagents/research-citation.js +185 -0
- package/dist/runtime/subagents/research-citation.js.map +1 -0
- package/dist/runtime/subagents/research-contract.d.ts +69 -0
- package/dist/runtime/subagents/research-contract.d.ts.map +1 -0
- package/dist/runtime/subagents/research-contract.js +232 -0
- package/dist/runtime/subagents/research-contract.js.map +1 -0
- package/dist/runtime/subagents/research-quality.d.ts +47 -0
- package/dist/runtime/subagents/research-quality.d.ts.map +1 -0
- package/dist/runtime/subagents/research-quality.js +125 -0
- package/dist/runtime/subagents/research-quality.js.map +1 -0
- package/dist/runtime/subagents/research-renderer.d.ts +79 -0
- package/dist/runtime/subagents/research-renderer.d.ts.map +1 -0
- package/dist/runtime/subagents/research-renderer.js +154 -0
- package/dist/runtime/subagents/research-renderer.js.map +1 -0
- package/dist/runtime/subagents/research-types.d.ts +105 -0
- package/dist/runtime/subagents/research-types.d.ts.map +1 -0
- package/dist/runtime/subagents/research-types.js +16 -0
- package/dist/runtime/subagents/research-types.js.map +1 -0
- package/dist/runtime/subagents/runtime-integration.d.ts +1 -1
- package/dist/runtime/subagents/runtime-integration.d.ts.map +1 -1
- package/dist/runtime/subagents/runtime-integration.js.map +1 -1
- package/dist/runtime/subagents/supervisor.d.ts +1 -1
- package/dist/runtime/subagents/supervisor.d.ts.map +1 -1
- package/dist/runtime/subagents/supervisor.js +1 -1
- package/dist/runtime/subagents/supervisor.js.map +1 -1
- package/dist/runtime/subagents/web-research-adapter.d.ts +83 -0
- package/dist/runtime/subagents/web-research-adapter.d.ts.map +1 -0
- package/dist/runtime/subagents/web-research-adapter.js +262 -0
- package/dist/runtime/subagents/web-research-adapter.js.map +1 -0
- package/dist/runtime/turn-controller.d.ts.map +1 -1
- package/dist/runtime/turn-controller.js +3 -1
- package/dist/runtime/turn-controller.js.map +1 -1
- package/dist/runtime/ui-events.d.ts +21 -0
- package/dist/runtime/ui-events.d.ts.map +1 -1
- package/dist/runtime/ui-events.js.map +1 -1
- package/dist/services/auth/auth.d.ts.map +1 -1
- package/dist/services/auth/auth.js +17 -4
- package/dist/services/auth/auth.js.map +1 -1
- package/dist/services/concurrent-sessions.d.ts.map +1 -1
- package/dist/services/concurrent-sessions.js +33 -17
- package/dist/services/concurrent-sessions.js.map +1 -1
- package/dist/services/config-dir.d.ts.map +1 -1
- package/dist/services/config-dir.js +19 -5
- package/dist/services/config-dir.js.map +1 -1
- package/dist/services/config.d.ts.map +1 -1
- package/dist/services/config.js +2 -1
- package/dist/services/config.js.map +1 -1
- package/dist/services/global-config.d.ts +31 -0
- package/dist/services/global-config.d.ts.map +1 -1
- package/dist/services/global-config.js.map +1 -1
- package/dist/services/goal-storage.d.ts.map +1 -1
- package/dist/services/goal-storage.js +22 -8
- package/dist/services/goal-storage.js.map +1 -1
- package/dist/services/llm.d.ts +17 -0
- package/dist/services/llm.d.ts.map +1 -1
- package/dist/services/llm.js +88 -31
- package/dist/services/llm.js.map +1 -1
- package/dist/services/model-catalog.d.ts +2 -0
- package/dist/services/model-catalog.d.ts.map +1 -1
- package/dist/services/model-catalog.js +25 -15
- package/dist/services/model-catalog.js.map +1 -1
- package/dist/services/model-context.d.ts.map +1 -1
- package/dist/services/model-context.js +36 -0
- package/dist/services/model-context.js.map +1 -1
- package/dist/services/model-registry.d.ts.map +1 -1
- package/dist/services/model-registry.js +32 -0
- package/dist/services/model-registry.js.map +1 -1
- package/dist/services/provider-resilience/coordinator.d.ts +1 -1
- package/dist/services/provider-resilience/coordinator.d.ts.map +1 -1
- package/dist/services/provider-resilience/coordinator.js +4 -4
- package/dist/services/provider-resilience/coordinator.js.map +1 -1
- package/dist/services/provider-resilience/error-classifier.js +20 -8
- package/dist/services/provider-resilience/error-classifier.js.map +1 -1
- package/dist/services/provider-resilience/stream-recovery.d.ts +1 -1
- package/dist/services/provider-resilience/stream-recovery.d.ts.map +1 -1
- package/dist/services/provider-resilience/stream-recovery.js +1 -1
- package/dist/services/provider-resilience/stream-recovery.js.map +1 -1
- package/dist/services/session-storage.d.ts.map +1 -1
- package/dist/services/session-storage.js +45 -14
- package/dist/services/session-storage.js.map +1 -1
- package/dist/services/storage-maintenance.d.ts.map +1 -1
- package/dist/services/storage-maintenance.js +44 -9
- package/dist/services/storage-maintenance.js.map +1 -1
- package/dist/services/task-manager.d.ts +3 -3
- package/dist/services/task-manager.d.ts.map +1 -1
- package/dist/services/tool-allowlist.d.ts +100 -0
- package/dist/services/tool-allowlist.d.ts.map +1 -0
- package/dist/services/tool-allowlist.js +250 -0
- package/dist/services/tool-allowlist.js.map +1 -0
- package/dist/services/web-search-adapters.d.ts.map +1 -1
- package/dist/services/web-search-adapters.js +48 -18
- package/dist/services/web-search-adapters.js.map +1 -1
- package/dist/services/web-search-mcp.d.ts.map +1 -1
- package/dist/services/web-search-mcp.js +27 -11
- package/dist/services/web-search-mcp.js.map +1 -1
- package/dist/services/yaml-config.d.ts.map +1 -1
- package/dist/services/yaml-config.js +2 -1
- package/dist/services/yaml-config.js.map +1 -1
- package/dist/skills/loader.d.ts.map +1 -1
- package/dist/skills/loader.js +3 -2
- package/dist/skills/loader.js.map +1 -1
- package/dist/terminal-ui/launch.d.ts +22 -2
- package/dist/terminal-ui/launch.d.ts.map +1 -1
- package/dist/terminal-ui/launch.js +150 -1
- package/dist/terminal-ui/launch.js.map +1 -1
- package/dist/terminal-ui/raw-editor.js.map +1 -1
- package/dist/tools/bash_security.d.ts +50 -18
- package/dist/tools/bash_security.d.ts.map +1 -1
- package/dist/tools/bash_security.js +394 -61
- package/dist/tools/bash_security.js.map +1 -1
- package/dist/tools/git.d.ts +4 -0
- package/dist/tools/git.d.ts.map +1 -1
- package/dist/tools/git.js +310 -3
- package/dist/tools/git.js.map +1 -1
- package/dist/tools/index.d.ts +1 -1
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +87 -25
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/mcp.d.ts +8 -2
- package/dist/tools/mcp.d.ts.map +1 -1
- package/dist/tools/mcp.js +44 -23
- package/dist/tools/mcp.js.map +1 -1
- package/dist/tools/sandbox.d.ts +139 -0
- package/dist/tools/sandbox.d.ts.map +1 -0
- package/dist/tools/sandbox.js +485 -0
- package/dist/tools/sandbox.js.map +1 -0
- package/dist/tools/web.d.ts.map +1 -1
- package/dist/tools/web.js +113 -42
- package/dist/tools/web.js.map +1 -1
- package/dist/tui-core/frame.js.map +1 -1
- package/dist/tui-ui/launch.d.ts.map +1 -1
- package/dist/tui-ui/launch.js +46 -8
- package/dist/tui-ui/launch.js.map +1 -1
- package/dist/tui-ui/layout.d.ts.map +1 -1
- package/dist/tui-ui/layout.js +62 -0
- package/dist/tui-ui/layout.js.map +1 -1
- package/dist/tui-ui/runner.d.ts +6 -0
- package/dist/tui-ui/runner.d.ts.map +1 -1
- package/dist/tui-ui/runner.js +81 -1
- package/dist/tui-ui/runner.js.map +1 -1
- package/dist/tui-ui/state.d.ts +19 -1
- package/dist/tui-ui/state.d.ts.map +1 -1
- package/dist/tui-ui/state.js +35 -7
- package/dist/tui-ui/state.js.map +1 -1
- package/dist/tui-ui/terminal-image.d.ts +3 -13
- package/dist/tui-ui/terminal-image.d.ts.map +1 -1
- package/dist/tui-ui/terminal-image.js +5 -160
- package/dist/tui-ui/terminal-image.js.map +1 -1
- package/dist/utils/debug-log.d.ts +52 -0
- package/dist/utils/debug-log.d.ts.map +1 -0
- package/dist/utils/debug-log.js +91 -0
- package/dist/utils/debug-log.js.map +1 -0
- package/dist/utils/errors.d.ts +25 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +47 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/mask.d.ts +28 -0
- package/dist/utils/mask.d.ts.map +1 -0
- package/dist/utils/mask.js +54 -0
- package/dist/utils/mask.js.map +1 -0
- package/package.json +2 -1
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Citation, conflict, and evidence-candidate resolution (v0.1.4, P0-R3).
|
|
3
|
+
*
|
|
4
|
+
* Turns a `ResearchPacket` (with its claims + sources) into:
|
|
5
|
+
* - resolved claim->source bindings (reference-integrity validated),
|
|
6
|
+
* - same-URL multi-version dedupe (older revisions marked `stale` on hash drift),
|
|
7
|
+
* - conflict records for contradictory sources (never auto-picked),
|
|
8
|
+
* - a verification classification per claim,
|
|
9
|
+
* - evidence candidates (only rule-compliant claims; research vs execution kept
|
|
10
|
+
* distinct so a web summary can never stand in for test/build/file facts),
|
|
11
|
+
* - a completion audit that stays `partial`/`unmet` for claims that have sources
|
|
12
|
+
* but no independent verification.
|
|
13
|
+
*
|
|
14
|
+
* This module is pure (no IO) so it is fully testable without network or disk.
|
|
15
|
+
*/
|
|
16
|
+
import type { ResearchPacket } from './research-types';
|
|
17
|
+
/** Normalize a URL for dedupe: drop fragment + trailing slash, lowercase host. */
|
|
18
|
+
export declare function urlKey(url: string | undefined): string;
|
|
19
|
+
export type BindingStatus = 'bound' | 'dangling' | 'stale_only' | 'conflicted';
|
|
20
|
+
export interface ClaimBinding {
|
|
21
|
+
claimId: string;
|
|
22
|
+
/** Resolved, non-stale source ids actually backing the claim. */
|
|
23
|
+
sourceIds: string[];
|
|
24
|
+
/** All source ids referenced by the claim (including stale/blocked). */
|
|
25
|
+
referencedSourceIds: string[];
|
|
26
|
+
status: BindingStatus;
|
|
27
|
+
}
|
|
28
|
+
export interface ConflictRecord {
|
|
29
|
+
claimId: string;
|
|
30
|
+
sourceIds: string[];
|
|
31
|
+
reason: string;
|
|
32
|
+
}
|
|
33
|
+
export interface EvidenceCandidate {
|
|
34
|
+
claimId: string;
|
|
35
|
+
/** 'research' = external/web source; 'execution' = file/verification fact. */
|
|
36
|
+
kind: 'research' | 'execution';
|
|
37
|
+
basis: 'file' | 'external';
|
|
38
|
+
summary: string;
|
|
39
|
+
}
|
|
40
|
+
export interface CompletionAudit {
|
|
41
|
+
status: 'met' | 'partial' | 'unmet';
|
|
42
|
+
/** Claims that have sources but no independent verification. */
|
|
43
|
+
unverifiedClaimIds: string[];
|
|
44
|
+
notes: string[];
|
|
45
|
+
}
|
|
46
|
+
export interface CitationResolution {
|
|
47
|
+
packetId: string;
|
|
48
|
+
bindings: ClaimBinding[];
|
|
49
|
+
conflicts: ConflictRecord[];
|
|
50
|
+
staleSourceIds: string[];
|
|
51
|
+
evidenceCandidates: EvidenceCandidate[];
|
|
52
|
+
audit: CompletionAudit;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Resolve citations for a packet.
|
|
56
|
+
*
|
|
57
|
+
* Reference integrity: a claim binding to an unknown source id is flagged
|
|
58
|
+
* `dangling` (and downgraded to `unverified`). Dedupe: sources sharing a
|
|
59
|
+
* canonical URL key are collapsed; the newest by `retrievedAt` wins and older
|
|
60
|
+
* revisions with a different content hash are marked `stale`. Conflict: a claim
|
|
61
|
+
* backed by both a `retrieved` source and a `failed`/`blocked` source (or two
|
|
62
|
+
* sources explicitly flagged contradictory) yields a conflict record and is
|
|
63
|
+
* never silently resolved in the model-favorable direction.
|
|
64
|
+
*/
|
|
65
|
+
export declare function resolveCitations(packet: ResearchPacket): CitationResolution;
|
|
66
|
+
//# sourceMappingURL=research-citation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"research-citation.d.ts","sourceRoot":"","sources":["../../../src/runtime/subagents/research-citation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAiB,cAAc,EAAgC,MAAM,kBAAkB,CAAC;AAEpG,kFAAkF;AAClF,wBAAgB,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAYtD;AAED,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,UAAU,GAAG,YAAY,GAAG,YAAY,CAAC;AAE/E,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,iEAAiE;IACjE,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,wEAAwE;IACxE,mBAAmB,EAAE,MAAM,EAAE,CAAC;IAC9B,MAAM,EAAE,aAAa,CAAC;CACvB;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,8EAA8E;IAC9E,IAAI,EAAE,UAAU,GAAG,WAAW,CAAC;IAC/B,KAAK,EAAE,MAAM,GAAG,UAAU,CAAC;IAC3B,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,KAAK,GAAG,SAAS,GAAG,OAAO,CAAC;IACpC,gEAAgE;IAChE,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAC7B,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB,SAAS,EAAE,cAAc,EAAE,CAAC;IAC5B,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,kBAAkB,EAAE,iBAAiB,EAAE,CAAC;IACxC,KAAK,EAAE,eAAe,CAAC;CACxB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,cAAc,GAAG,kBAAkB,CAsG3E"}
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Citation, conflict, and evidence-candidate resolution (v0.1.4, P0-R3).
|
|
4
|
+
*
|
|
5
|
+
* Turns a `ResearchPacket` (with its claims + sources) into:
|
|
6
|
+
* - resolved claim->source bindings (reference-integrity validated),
|
|
7
|
+
* - same-URL multi-version dedupe (older revisions marked `stale` on hash drift),
|
|
8
|
+
* - conflict records for contradictory sources (never auto-picked),
|
|
9
|
+
* - a verification classification per claim,
|
|
10
|
+
* - evidence candidates (only rule-compliant claims; research vs execution kept
|
|
11
|
+
* distinct so a web summary can never stand in for test/build/file facts),
|
|
12
|
+
* - a completion audit that stays `partial`/`unmet` for claims that have sources
|
|
13
|
+
* but no independent verification.
|
|
14
|
+
*
|
|
15
|
+
* This module is pure (no IO) so it is fully testable without network or disk.
|
|
16
|
+
*/
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
exports.urlKey = urlKey;
|
|
19
|
+
exports.resolveCitations = resolveCitations;
|
|
20
|
+
/** Normalize a URL for dedupe: drop fragment + trailing slash, lowercase host. */
|
|
21
|
+
function urlKey(url) {
|
|
22
|
+
if (!url)
|
|
23
|
+
return '';
|
|
24
|
+
try {
|
|
25
|
+
const u = new URL(url);
|
|
26
|
+
const host = u.host.toLowerCase();
|
|
27
|
+
let path = u.pathname;
|
|
28
|
+
if (path.length > 1 && path.endsWith('/'))
|
|
29
|
+
path = path.slice(0, -1);
|
|
30
|
+
const query = u.search;
|
|
31
|
+
return `${u.protocol}//${host}${path}${query}`;
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
return url;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Resolve citations for a packet.
|
|
39
|
+
*
|
|
40
|
+
* Reference integrity: a claim binding to an unknown source id is flagged
|
|
41
|
+
* `dangling` (and downgraded to `unverified`). Dedupe: sources sharing a
|
|
42
|
+
* canonical URL key are collapsed; the newest by `retrievedAt` wins and older
|
|
43
|
+
* revisions with a different content hash are marked `stale`. Conflict: a claim
|
|
44
|
+
* backed by both a `retrieved` source and a `failed`/`blocked` source (or two
|
|
45
|
+
* sources explicitly flagged contradictory) yields a conflict record and is
|
|
46
|
+
* never silently resolved in the model-favorable direction.
|
|
47
|
+
*/
|
|
48
|
+
function resolveCitations(packet) {
|
|
49
|
+
const sourceIds = new Set(packet.sources.map(s => s.id));
|
|
50
|
+
const byId = new Map(packet.sources.map(s => [s.id, s]));
|
|
51
|
+
// --- dedupe same-URL multi-version -> stale ---
|
|
52
|
+
const staleSourceIds = [];
|
|
53
|
+
const groups = new Map();
|
|
54
|
+
for (const s of packet.sources) {
|
|
55
|
+
const key = urlKey(s.canonicalUrl);
|
|
56
|
+
if (!key)
|
|
57
|
+
continue;
|
|
58
|
+
const arr = groups.get(key) ?? [];
|
|
59
|
+
arr.push(s);
|
|
60
|
+
groups.set(key, arr);
|
|
61
|
+
}
|
|
62
|
+
for (const [, group] of groups) {
|
|
63
|
+
if (group.length < 2)
|
|
64
|
+
continue;
|
|
65
|
+
// newest by retrievedAt wins; older ones with a different hash become stale.
|
|
66
|
+
const sorted = [...group].sort((a, b) => b.retrievedAt.localeCompare(a.retrievedAt));
|
|
67
|
+
const winner = sorted[0];
|
|
68
|
+
for (let i = 1; i < sorted.length; i++) {
|
|
69
|
+
const s = sorted[i];
|
|
70
|
+
if (s.contentHash && winner.contentHash && s.contentHash !== winner.contentHash) {
|
|
71
|
+
staleSourceIds.push(s.id);
|
|
72
|
+
s.status = 'stale';
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
const staleSet = new Set(staleSourceIds);
|
|
77
|
+
const bindings = [];
|
|
78
|
+
const conflicts = [];
|
|
79
|
+
const evidenceCandidates = [];
|
|
80
|
+
for (const claim of packet.claims) {
|
|
81
|
+
const referenced = claim.sourceIds.filter(id => sourceIds.has(id));
|
|
82
|
+
const danglingRefs = claim.sourceIds.filter(id => !sourceIds.has(id));
|
|
83
|
+
const active = referenced.filter(id => !staleSet.has(id));
|
|
84
|
+
const activeSources = active.map(id => byId.get(id)).filter(Boolean);
|
|
85
|
+
const hasRetrieved = activeSources.some(s => s.status === 'retrieved');
|
|
86
|
+
const hasFailed = activeSources.some(s => s.status === 'failed' || s.status === 'blocked');
|
|
87
|
+
let status;
|
|
88
|
+
if (danglingRefs.length > 0 && referenced.length === 0) {
|
|
89
|
+
status = 'dangling';
|
|
90
|
+
}
|
|
91
|
+
else if (hasRetrieved && hasFailed) {
|
|
92
|
+
status = 'conflicted';
|
|
93
|
+
}
|
|
94
|
+
else if (active.length === 0 && referenced.length > 0) {
|
|
95
|
+
status = 'stale_only';
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
status = 'bound';
|
|
99
|
+
}
|
|
100
|
+
if (status === 'conflicted') {
|
|
101
|
+
conflicts.push({
|
|
102
|
+
claimId: claim.id,
|
|
103
|
+
sourceIds: active,
|
|
104
|
+
reason: 'claim backed by both a retrieved source and a failed/blocked source',
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
bindings.push({
|
|
108
|
+
claimId: claim.id,
|
|
109
|
+
sourceIds: active,
|
|
110
|
+
referencedSourceIds: referenced,
|
|
111
|
+
status,
|
|
112
|
+
});
|
|
113
|
+
// Verification classification: conflicted -> contradicted.
|
|
114
|
+
const verification = status === 'conflicted'
|
|
115
|
+
? 'contradicted'
|
|
116
|
+
: classifyVerification(claim, hasRetrieved, activeSources);
|
|
117
|
+
claim.verification = verification;
|
|
118
|
+
// Evidence candidate: only rule-compliant claims.
|
|
119
|
+
if ((verification === 'observed' || verification === 'partially_observed') &&
|
|
120
|
+
claim.evidenceKind !== 'inference' &&
|
|
121
|
+
status !== 'conflicted') {
|
|
122
|
+
const primary = activeSources.find(s => s.status === 'retrieved');
|
|
123
|
+
const isFile = primary?.kind === 'file';
|
|
124
|
+
evidenceCandidates.push({
|
|
125
|
+
claimId: claim.id,
|
|
126
|
+
kind: isFile ? 'execution' : 'research',
|
|
127
|
+
basis: isFile ? 'file' : 'external',
|
|
128
|
+
summary: claim.text,
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
const audit = auditCompletion(packet, bindings);
|
|
133
|
+
return {
|
|
134
|
+
packetId: packet.packetId,
|
|
135
|
+
bindings,
|
|
136
|
+
conflicts,
|
|
137
|
+
staleSourceIds,
|
|
138
|
+
evidenceCandidates,
|
|
139
|
+
audit,
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
function classifyVerification(claim, hasRetrieved, activeSources) {
|
|
143
|
+
if (claim.evidenceKind === 'inference')
|
|
144
|
+
return 'unverified';
|
|
145
|
+
if (!hasRetrieved)
|
|
146
|
+
return 'unverified';
|
|
147
|
+
const onlyExcerpt = activeSources.every(s => !!s.excerpt && s.excerpt.length < 4000 && !s.contentHash);
|
|
148
|
+
return onlyExcerpt ? 'partially_observed' : 'observed';
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Completion audit. The key invariant (plan exit condition): a claim that HAS
|
|
152
|
+
* sources but no independent verification must keep the audit `partial`/`unmet`
|
|
153
|
+
* - never `met`. We therefore treat any claim with referenced sources whose
|
|
154
|
+
* verification is not `observed` as unverified for audit purposes.
|
|
155
|
+
*/
|
|
156
|
+
function auditCompletion(packet, bindings) {
|
|
157
|
+
const notes = [];
|
|
158
|
+
const unverifiedClaimIds = [];
|
|
159
|
+
for (const claim of packet.claims) {
|
|
160
|
+
const binding = bindings.find(b => b.claimId === claim.id);
|
|
161
|
+
const hasSources = (binding?.referencedSourceIds.length ?? 0) > 0;
|
|
162
|
+
const independentlyVerified = claim.verification === 'observed';
|
|
163
|
+
if (!independentlyVerified) {
|
|
164
|
+
if (hasSources) {
|
|
165
|
+
unverifiedClaimIds.push(claim.id);
|
|
166
|
+
notes.push(`claim ${claim.id} has sources but no independent verification (stays partial)`);
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
unverifiedClaimIds.push(claim.id);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
let status;
|
|
174
|
+
if (unverifiedClaimIds.length === 0) {
|
|
175
|
+
status = 'met';
|
|
176
|
+
}
|
|
177
|
+
else if (packet.claims.some(c => (bindings.find(b => b.claimId === c.id)?.referencedSourceIds.length ?? 0) > 0)) {
|
|
178
|
+
status = 'partial';
|
|
179
|
+
}
|
|
180
|
+
else {
|
|
181
|
+
status = 'unmet';
|
|
182
|
+
}
|
|
183
|
+
return { status, unverifiedClaimIds, notes };
|
|
184
|
+
}
|
|
185
|
+
//# sourceMappingURL=research-citation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"research-citation.js","sourceRoot":"","sources":["../../../src/runtime/subagents/research-citation.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Research contract and normalizer (v0.1.4, P0-R1).
|
|
3
|
+
*
|
|
4
|
+
* Responsibilities:
|
|
5
|
+
* - Validate a `ResearchRequest` before any work happens.
|
|
6
|
+
* - Map a legacy `SubtaskResult` (existing `research` role output) into a
|
|
7
|
+
* versioned `ResearchPacket` without rewriting the runtime.
|
|
8
|
+
* - Fail closed: missing summary, over-limit sources, or an `observed` claim
|
|
9
|
+
* without a source binding are rejected. Non-completed results never yield
|
|
10
|
+
* `observed` claims (no "looks researched" masquerading as verified).
|
|
11
|
+
* - Provide a deterministic serialization + content hash contract so packets
|
|
12
|
+
* are replayable and de-duplicable.
|
|
13
|
+
*/
|
|
14
|
+
import type { SubtaskResult } from './types';
|
|
15
|
+
import { type ResearchPacket, type ResearchRequest } from './research-types';
|
|
16
|
+
/** Hard caps independent of per-request budget, to bound abuse. */
|
|
17
|
+
export declare const RESEARCH_HARD_LIMITS: {
|
|
18
|
+
readonly maxSources: {
|
|
19
|
+
readonly min: 1;
|
|
20
|
+
readonly max: 200;
|
|
21
|
+
};
|
|
22
|
+
readonly maxFetchBytes: {
|
|
23
|
+
readonly min: 0;
|
|
24
|
+
readonly max: number;
|
|
25
|
+
};
|
|
26
|
+
readonly maxDurationMs: {
|
|
27
|
+
readonly min: 1000;
|
|
28
|
+
readonly max: 600000;
|
|
29
|
+
};
|
|
30
|
+
readonly maxClaims: 500;
|
|
31
|
+
readonly maxSummaryLen: 20000;
|
|
32
|
+
};
|
|
33
|
+
export interface ValidationResult {
|
|
34
|
+
ok: boolean;
|
|
35
|
+
errors: string[];
|
|
36
|
+
}
|
|
37
|
+
export interface PacketContext {
|
|
38
|
+
sessionId: string;
|
|
39
|
+
projectPath: string;
|
|
40
|
+
goalId?: string;
|
|
41
|
+
objectiveRevision?: number;
|
|
42
|
+
}
|
|
43
|
+
/** Validate a research request before scheduling any work. */
|
|
44
|
+
export declare function validateResearchRequest(req: Partial<ResearchRequest>): ValidationResult;
|
|
45
|
+
/** Convenience builder for a local-only research request (POC-1 default). */
|
|
46
|
+
export declare function createLocalResearchRequest(objective: string, projectRoot: string, overrides?: Partial<ResearchRequest>): ResearchRequest;
|
|
47
|
+
/**
|
|
48
|
+
* Map a legacy `SubtaskResult` into a versioned `ResearchPacket`.
|
|
49
|
+
*
|
|
50
|
+
* File findings become `observed` file claims bound to a `file` source. Findings
|
|
51
|
+
* without a file become `inference`/`unverified` claims. Failed/cancelled/timed
|
|
52
|
+
* out results downgrade every claim to `unverified` so a partial run can never
|
|
53
|
+
* report a verified conclusion.
|
|
54
|
+
*/
|
|
55
|
+
export declare function subtaskResultToPacket(result: SubtaskResult, request: ResearchRequest, ctx: PacketContext): ResearchPacket;
|
|
56
|
+
/**
|
|
57
|
+
* Fail-closed packet validation. An `observed`/`partially_observed` claim must
|
|
58
|
+
* bind to at least one existing source; an inference claim must not be marked
|
|
59
|
+
* `observed`; source counts must respect the request budget.
|
|
60
|
+
*/
|
|
61
|
+
export declare function validatePacket(packet: ResearchPacket): ValidationResult;
|
|
62
|
+
/** Deterministic JSON (sorted keys) for a value. */
|
|
63
|
+
export declare function stableStringify(value: unknown): string;
|
|
64
|
+
/**
|
|
65
|
+
* Content hash over the canonical packet body (timestamps excluded). Proves what
|
|
66
|
+
* was read, NOT that the content is true; used for dedupe and drift detection.
|
|
67
|
+
*/
|
|
68
|
+
export declare function hashPacket(packet: ResearchPacket): string;
|
|
69
|
+
//# sourceMappingURL=research-contract.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"research-contract.d.ts","sourceRoot":"","sources":["../../../src/runtime/subagents/research-contract.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAgB,MAAM,SAAS,CAAC;AAC3D,OAAO,EAIL,KAAK,cAAc,EACnB,KAAK,eAAe,EAGrB,MAAM,kBAAkB,CAAC;AAE1B,mEAAmE;AACnE,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;CAMvB,CAAC;AAEX,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAMD,8DAA8D;AAC9D,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,OAAO,CAAC,eAAe,CAAC,GAAG,gBAAgB,CA2BvF;AAED,6EAA6E;AAC7E,wBAAgB,0BAA0B,CACxC,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EACnB,SAAS,GAAE,OAAO,CAAC,eAAe,CAAM,GACvC,eAAe,CAWjB;AAQD;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,aAAa,EACrB,OAAO,EAAE,eAAe,EACxB,GAAG,EAAE,aAAa,GACjB,cAAc,CAgEhB;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,cAAc,GAAG,gBAAgB,CAoCvE;AAaD,oDAAoD;AACpD,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAEtD;AAWD;;;GAGG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CAEzD"}
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Research contract and normalizer (v0.1.4, P0-R1).
|
|
4
|
+
*
|
|
5
|
+
* Responsibilities:
|
|
6
|
+
* - Validate a `ResearchRequest` before any work happens.
|
|
7
|
+
* - Map a legacy `SubtaskResult` (existing `research` role output) into a
|
|
8
|
+
* versioned `ResearchPacket` without rewriting the runtime.
|
|
9
|
+
* - Fail closed: missing summary, over-limit sources, or an `observed` claim
|
|
10
|
+
* without a source binding are rejected. Non-completed results never yield
|
|
11
|
+
* `observed` claims (no "looks researched" masquerading as verified).
|
|
12
|
+
* - Provide a deterministic serialization + content hash contract so packets
|
|
13
|
+
* are replayable and de-duplicable.
|
|
14
|
+
*/
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
exports.RESEARCH_HARD_LIMITS = void 0;
|
|
17
|
+
exports.validateResearchRequest = validateResearchRequest;
|
|
18
|
+
exports.createLocalResearchRequest = createLocalResearchRequest;
|
|
19
|
+
exports.subtaskResultToPacket = subtaskResultToPacket;
|
|
20
|
+
exports.validatePacket = validatePacket;
|
|
21
|
+
exports.stableStringify = stableStringify;
|
|
22
|
+
exports.hashPacket = hashPacket;
|
|
23
|
+
const crypto_1 = require("crypto");
|
|
24
|
+
const research_types_1 = require("./research-types");
|
|
25
|
+
/** Hard caps independent of per-request budget, to bound abuse. */
|
|
26
|
+
exports.RESEARCH_HARD_LIMITS = {
|
|
27
|
+
maxSources: { min: 1, max: 200 },
|
|
28
|
+
maxFetchBytes: { min: 0, max: 32 * 1024 * 1024 },
|
|
29
|
+
maxDurationMs: { min: 1000, max: 600000 },
|
|
30
|
+
maxClaims: 500,
|
|
31
|
+
maxSummaryLen: 20000,
|
|
32
|
+
};
|
|
33
|
+
function nowIso() {
|
|
34
|
+
return new Date().toISOString();
|
|
35
|
+
}
|
|
36
|
+
/** Validate a research request before scheduling any work. */
|
|
37
|
+
function validateResearchRequest(req) {
|
|
38
|
+
const errors = [];
|
|
39
|
+
if (typeof req.schemaVersion !== 'number')
|
|
40
|
+
errors.push('schemaVersion is required');
|
|
41
|
+
if (req.schemaVersion !== undefined && req.schemaVersion !== research_types_1.RESEARCH_SCHEMA_VERSION) {
|
|
42
|
+
errors.push(`unsupported schemaVersion ${req.schemaVersion}`);
|
|
43
|
+
}
|
|
44
|
+
if (typeof req.objective !== 'string' || !req.objective.trim())
|
|
45
|
+
errors.push('objective is required');
|
|
46
|
+
if (!req.scope || typeof req.scope.projectRoot !== 'string')
|
|
47
|
+
errors.push('scope.projectRoot is required');
|
|
48
|
+
if (req.mode !== 'local' && req.mode !== 'web' && req.mode !== 'mixed') {
|
|
49
|
+
errors.push('mode must be local | web | mixed');
|
|
50
|
+
}
|
|
51
|
+
if (typeof req.maxSources !== 'number' || req.maxSources < exports.RESEARCH_HARD_LIMITS.maxSources.min) {
|
|
52
|
+
errors.push(`maxSources must be >= ${exports.RESEARCH_HARD_LIMITS.maxSources.min}`);
|
|
53
|
+
}
|
|
54
|
+
if (typeof req.maxFetchBytes !== 'number' || req.maxFetchBytes < 0) {
|
|
55
|
+
errors.push('maxFetchBytes must be >= 0');
|
|
56
|
+
}
|
|
57
|
+
if (typeof req.maxDurationMs !== 'number' || req.maxDurationMs <= 0) {
|
|
58
|
+
errors.push('maxDurationMs must be > 0');
|
|
59
|
+
}
|
|
60
|
+
if (req.goalBinding) {
|
|
61
|
+
if (typeof req.goalBinding.goalId !== 'string')
|
|
62
|
+
errors.push('goalBinding.goalId is required');
|
|
63
|
+
if (typeof req.goalBinding.objectiveRevision !== 'number') {
|
|
64
|
+
errors.push('goalBinding.objectiveRevision is required');
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return { ok: errors.length === 0, errors };
|
|
68
|
+
}
|
|
69
|
+
/** Convenience builder for a local-only research request (POC-1 default). */
|
|
70
|
+
function createLocalResearchRequest(objective, projectRoot, overrides = {}) {
|
|
71
|
+
return {
|
|
72
|
+
schemaVersion: research_types_1.RESEARCH_SCHEMA_VERSION,
|
|
73
|
+
objective,
|
|
74
|
+
scope: { projectRoot, ...(overrides.scope ?? {}) },
|
|
75
|
+
mode: overrides.mode ?? 'local',
|
|
76
|
+
maxSources: overrides.maxSources ?? 50,
|
|
77
|
+
maxFetchBytes: overrides.maxFetchBytes ?? 0,
|
|
78
|
+
maxDurationMs: overrides.maxDurationMs ?? 120000,
|
|
79
|
+
...overrides,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
function deriveVerification(status, hasFile) {
|
|
83
|
+
// Fail closed: a non-completed result can never produce an `observed` claim.
|
|
84
|
+
if (status !== 'completed')
|
|
85
|
+
return 'unverified';
|
|
86
|
+
return hasFile ? 'observed' : 'unverified';
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Map a legacy `SubtaskResult` into a versioned `ResearchPacket`.
|
|
90
|
+
*
|
|
91
|
+
* File findings become `observed` file claims bound to a `file` source. Findings
|
|
92
|
+
* without a file become `inference`/`unverified` claims. Failed/cancelled/timed
|
|
93
|
+
* out results downgrade every claim to `unverified` so a partial run can never
|
|
94
|
+
* report a verified conclusion.
|
|
95
|
+
*/
|
|
96
|
+
function subtaskResultToPacket(result, request, ctx) {
|
|
97
|
+
const sources = [];
|
|
98
|
+
const sourceByPath = new Map();
|
|
99
|
+
const ensureFileSource = (projectPath) => {
|
|
100
|
+
const existing = sourceByPath.get(projectPath);
|
|
101
|
+
if (existing)
|
|
102
|
+
return existing;
|
|
103
|
+
const source = {
|
|
104
|
+
id: `src-${sources.length + 1}`,
|
|
105
|
+
kind: 'file',
|
|
106
|
+
projectPath,
|
|
107
|
+
provider: 'local',
|
|
108
|
+
retrievedAt: nowIso(),
|
|
109
|
+
status: 'retrieved',
|
|
110
|
+
};
|
|
111
|
+
sourceByPath.set(projectPath, source);
|
|
112
|
+
sources.push(source);
|
|
113
|
+
return source;
|
|
114
|
+
};
|
|
115
|
+
for (const filePath of result.files)
|
|
116
|
+
ensureFileSource(filePath);
|
|
117
|
+
const claims = result.findings.map((finding, i) => {
|
|
118
|
+
const hasFile = typeof finding.file === 'string' && finding.file.length > 0;
|
|
119
|
+
const bound = hasFile ? ensureFileSource(finding.file) : undefined;
|
|
120
|
+
const evidenceKind = hasFile ? 'file' : 'inference';
|
|
121
|
+
const verification = deriveVerification(result.status, hasFile);
|
|
122
|
+
const text = finding.evidence ? `${finding.title}: ${finding.evidence}` : finding.title;
|
|
123
|
+
const claim = {
|
|
124
|
+
id: `clm-${i + 1}`,
|
|
125
|
+
text,
|
|
126
|
+
sourceIds: bound ? [bound.id] : [],
|
|
127
|
+
evidenceKind,
|
|
128
|
+
verification,
|
|
129
|
+
};
|
|
130
|
+
if (finding.severity) {
|
|
131
|
+
const confidence = finding.severity === 'critical' || finding.severity === 'high'
|
|
132
|
+
? 'high'
|
|
133
|
+
: finding.severity === 'medium'
|
|
134
|
+
? 'medium'
|
|
135
|
+
: 'low';
|
|
136
|
+
claim.confidence = confidence;
|
|
137
|
+
}
|
|
138
|
+
return claim;
|
|
139
|
+
});
|
|
140
|
+
const packet = {
|
|
141
|
+
schemaVersion: research_types_1.RESEARCH_SCHEMA_VERSION,
|
|
142
|
+
packetId: `pkt-${result.id}`,
|
|
143
|
+
projectPath: ctx.projectPath,
|
|
144
|
+
sessionId: ctx.sessionId,
|
|
145
|
+
...(ctx.goalId ? { goalId: ctx.goalId } : {}),
|
|
146
|
+
...(ctx.objectiveRevision !== undefined ? { objectiveRevision: ctx.objectiveRevision } : {}),
|
|
147
|
+
request,
|
|
148
|
+
summary: result.summary,
|
|
149
|
+
claims,
|
|
150
|
+
sources,
|
|
151
|
+
gaps: [],
|
|
152
|
+
risks: result.risks,
|
|
153
|
+
usage: result.usage,
|
|
154
|
+
createdAt: nowIso(),
|
|
155
|
+
};
|
|
156
|
+
return packet;
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Fail-closed packet validation. An `observed`/`partially_observed` claim must
|
|
160
|
+
* bind to at least one existing source; an inference claim must not be marked
|
|
161
|
+
* `observed`; source counts must respect the request budget.
|
|
162
|
+
*/
|
|
163
|
+
function validatePacket(packet) {
|
|
164
|
+
const errors = [];
|
|
165
|
+
if (!packet.summary || !packet.summary.trim())
|
|
166
|
+
errors.push('packet.summary is required');
|
|
167
|
+
if (packet.schemaVersion !== research_types_1.RESEARCH_SCHEMA_VERSION) {
|
|
168
|
+
errors.push(`unsupported schemaVersion ${packet.schemaVersion}`);
|
|
169
|
+
}
|
|
170
|
+
if (packet.summary.length > exports.RESEARCH_HARD_LIMITS.maxSummaryLen) {
|
|
171
|
+
errors.push('packet.summary exceeds max length');
|
|
172
|
+
}
|
|
173
|
+
if (packet.claims.length > exports.RESEARCH_HARD_LIMITS.maxClaims) {
|
|
174
|
+
errors.push(`claims ${packet.claims.length} exceed max ${exports.RESEARCH_HARD_LIMITS.maxClaims}`);
|
|
175
|
+
}
|
|
176
|
+
const sourceIds = new Set(packet.sources.map(s => s.id));
|
|
177
|
+
for (const source of packet.sources) {
|
|
178
|
+
if (!source.provider)
|
|
179
|
+
errors.push(`source ${source.id} missing provider`);
|
|
180
|
+
if (!source.status)
|
|
181
|
+
errors.push(`source ${source.id} missing status`);
|
|
182
|
+
}
|
|
183
|
+
if (packet.sources.length > packet.request.maxSources) {
|
|
184
|
+
errors.push(`sources ${packet.sources.length} exceed request.maxSources ${packet.request.maxSources}`);
|
|
185
|
+
}
|
|
186
|
+
for (const claim of packet.claims) {
|
|
187
|
+
for (const sid of claim.sourceIds) {
|
|
188
|
+
if (!sourceIds.has(sid))
|
|
189
|
+
errors.push(`claim ${claim.id} references unknown source ${sid}`);
|
|
190
|
+
}
|
|
191
|
+
const verified = claim.verification === 'observed' || claim.verification === 'partially_observed';
|
|
192
|
+
if (verified && claim.sourceIds.length === 0) {
|
|
193
|
+
errors.push(`claim ${claim.id} marked ${claim.verification} but has no source binding`);
|
|
194
|
+
}
|
|
195
|
+
if (claim.verification === 'observed' && claim.evidenceKind === 'inference') {
|
|
196
|
+
errors.push(`claim ${claim.id} is inference but marked observed`);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
return { ok: errors.length === 0, errors };
|
|
200
|
+
}
|
|
201
|
+
function sortDeep(value) {
|
|
202
|
+
if (Array.isArray(value))
|
|
203
|
+
return value.map(sortDeep);
|
|
204
|
+
if (value && typeof value === 'object') {
|
|
205
|
+
const obj = value;
|
|
206
|
+
const sorted = {};
|
|
207
|
+
for (const key of Object.keys(obj).sort())
|
|
208
|
+
sorted[key] = sortDeep(obj[key]);
|
|
209
|
+
return sorted;
|
|
210
|
+
}
|
|
211
|
+
return value;
|
|
212
|
+
}
|
|
213
|
+
/** Deterministic JSON (sorted keys) for a value. */
|
|
214
|
+
function stableStringify(value) {
|
|
215
|
+
return JSON.stringify(sortDeep(value));
|
|
216
|
+
}
|
|
217
|
+
/** Strip volatile timestamps so the content hash is reproducible across runs. */
|
|
218
|
+
function packetContentForHash(packet) {
|
|
219
|
+
return sortDeep({
|
|
220
|
+
...packet,
|
|
221
|
+
createdAt: undefined,
|
|
222
|
+
sources: packet.sources.map(s => ({ ...s, retrievedAt: undefined })),
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Content hash over the canonical packet body (timestamps excluded). Proves what
|
|
227
|
+
* was read, NOT that the content is true; used for dedupe and drift detection.
|
|
228
|
+
*/
|
|
229
|
+
function hashPacket(packet) {
|
|
230
|
+
return (0, crypto_1.createHash)('sha256').update(stableStringify(packetContentForHash(packet))).digest('hex');
|
|
231
|
+
}
|
|
232
|
+
//# sourceMappingURL=research-contract.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"research-contract.js","sourceRoot":"","sources":["../../../src/runtime/subagents/research-contract.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Research quality, cost, and recovery hardening (v0.1.4, P1-R6).
|
|
3
|
+
*
|
|
4
|
+
* - Source ranking is EXPLAINABLE ONLY: it returns an ordering plus a list of
|
|
5
|
+
* human-readable reasons (freshness / provider / scope match / dedup). It is
|
|
6
|
+
* never a verdict on truth - a higher rank does not mean a source is correct.
|
|
7
|
+
* - Cost diagnostics summarize model/tool/time/source usage for `npm run cost`
|
|
8
|
+
* reconciliation.
|
|
9
|
+
* - Recovery hints turn a structured failure reason into an actionable suggestion,
|
|
10
|
+
* without ever suggesting a generic MCP or a write path.
|
|
11
|
+
*/
|
|
12
|
+
import type { ResearchPacket, ResearchScope, ResearchSource } from './research-types';
|
|
13
|
+
export interface RankedSource {
|
|
14
|
+
sourceId: string;
|
|
15
|
+
rank: number;
|
|
16
|
+
score: number;
|
|
17
|
+
reasons: string[];
|
|
18
|
+
}
|
|
19
|
+
export interface RankOptions {
|
|
20
|
+
/** Preferred providers in priority order (higher index = lower preference). */
|
|
21
|
+
preferredProviders?: string[];
|
|
22
|
+
scope?: ResearchScope;
|
|
23
|
+
now?: Date;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Rank sources by explainable signals. Stale revisions are demoted. The returned
|
|
27
|
+
* `reasons` explain every contribution; the score is advisory, not truth.
|
|
28
|
+
*/
|
|
29
|
+
export declare function rankSources(sources: ResearchSource[], opts?: RankOptions): RankedSource[];
|
|
30
|
+
export interface ResearchCostSummary {
|
|
31
|
+
modelRequests: number;
|
|
32
|
+
toolCalls: number;
|
|
33
|
+
durationMs: number;
|
|
34
|
+
sourceCount: number;
|
|
35
|
+
retrievedCount: number;
|
|
36
|
+
notes: string[];
|
|
37
|
+
}
|
|
38
|
+
/** Summarize research cost from the packet usage + source counts. */
|
|
39
|
+
export declare function researchCostSummary(packet: ResearchPacket, opts?: {
|
|
40
|
+
fetchedBytes?: number;
|
|
41
|
+
}): ResearchCostSummary;
|
|
42
|
+
/**
|
|
43
|
+
* Turn a structured failure reason into an actionable recovery hint. Never
|
|
44
|
+
* suggests a generic MCP or a write/exec path.
|
|
45
|
+
*/
|
|
46
|
+
export declare function recoveryHint(reason: string | undefined): string;
|
|
47
|
+
//# sourceMappingURL=research-quality.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"research-quality.d.ts","sourceRoot":"","sources":["../../../src/runtime/subagents/research-quality.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAEtF,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAuBD,MAAM,WAAW,WAAW;IAC1B,+EAA+E;IAC/E,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC9B,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,GAAG,CAAC,EAAE,IAAI,CAAC;CACZ;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,cAAc,EAAE,EAAE,IAAI,GAAE,WAAgB,GAAG,YAAY,EAAE,CAwC7F;AAED,MAAM,WAAW,mBAAmB;IAClC,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,qEAAqE;AACrE,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,cAAc,EACtB,IAAI,GAAE;IAAE,YAAY,CAAC,EAAE,MAAM,CAAA;CAAO,GACnC,mBAAmB,CAiBrB;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAkB/D"}
|