@chengxianglibra/dsh-data-analysis 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +72 -0
  3. package/cordis.patch.yml +11 -0
  4. package/lib/bin/environment.js +91 -0
  5. package/lib/bridges.js +11 -0
  6. package/lib/client.js +744 -0
  7. package/lib/compatibility.js +66 -0
  8. package/lib/datasource/access.js +60 -0
  9. package/lib/datasource/bridge-programs.js +80 -0
  10. package/lib/datasource/bridge.js +204 -0
  11. package/lib/datasource/credentials.js +24 -0
  12. package/lib/datasource/index.js +4 -0
  13. package/lib/datasource/shell-env.js +386 -0
  14. package/lib/datasource/test.js +65 -0
  15. package/lib/disclosure/activation.js +369 -0
  16. package/lib/disclosure/bridge-program.js +11 -0
  17. package/lib/disclosure/bridge.js +65 -0
  18. package/lib/disclosure/help.js +227 -0
  19. package/lib/disclosure/index.js +3 -0
  20. package/lib/environment/binding.js +273 -0
  21. package/lib/environment/doctor.js +123 -0
  22. package/lib/environment/errors.js +11 -0
  23. package/lib/environment/index.js +7 -0
  24. package/lib/environment/runtime.js +558 -0
  25. package/lib/environment/source.js +6 -0
  26. package/lib/environment/subprocess.js +178 -0
  27. package/lib/environment/summary.js +19 -0
  28. package/lib/environment/workspace.js +49 -0
  29. package/lib/evidence/bridge-program.js +153 -0
  30. package/lib/evidence/bridge.js +166 -0
  31. package/lib/evidence/index.js +2 -0
  32. package/lib/evidence/sources.js +263 -0
  33. package/lib/index.js +7 -0
  34. package/lib/plugin.js +179 -0
  35. package/lib/types/bridges.d.ts +11 -0
  36. package/lib/types/client.d.ts +125 -0
  37. package/lib/types/compatibility.d.ts +29 -0
  38. package/lib/types/datasource/access.d.ts +27 -0
  39. package/lib/types/datasource/bridge.d.ts +53 -0
  40. package/lib/types/datasource/index.d.ts +8 -0
  41. package/lib/types/datasource/shell-env.d.ts +38 -0
  42. package/lib/types/datasource/test.d.ts +32 -0
  43. package/lib/types/disclosure/activation.d.ts +73 -0
  44. package/lib/types/disclosure/bridge.d.ts +28 -0
  45. package/lib/types/disclosure/help.d.ts +64 -0
  46. package/lib/types/disclosure/index.d.ts +5 -0
  47. package/lib/types/environment/binding.d.ts +26 -0
  48. package/lib/types/environment/doctor.d.ts +8 -0
  49. package/lib/types/environment/errors.d.ts +7 -0
  50. package/lib/types/environment/index.d.ts +9 -0
  51. package/lib/types/environment/runtime.d.ts +17 -0
  52. package/lib/types/environment/source.d.ts +7 -0
  53. package/lib/types/environment/subprocess.d.ts +19 -0
  54. package/lib/types/environment/types.d.ts +96 -0
  55. package/lib/types/environment/workspace.d.ts +10 -0
  56. package/lib/types/evidence/bridge.d.ts +40 -0
  57. package/lib/types/evidence/index.d.ts +4 -0
  58. package/lib/types/evidence/sources.d.ts +57 -0
  59. package/lib/types/index.d.ts +9 -0
  60. package/lib/types/plugin.d.ts +43 -0
  61. package/package.json +149 -0
  62. package/python/report-kit/dist/dsh_data_analysis_report_kit-3.0.0-py3-none-any.whl +0 -0
  63. package/skills/dsh-data-analysis-report/SKILL.md +57 -0
  64. package/skills/dsh-data-analysis-report/assets/marivo-artifact.js +113 -0
  65. package/skills/dsh-data-analysis-report/assets/marivo-session-dag.js +1201 -0
  66. package/skills/dsh-data-analysis-report/assets/report-data.js +449 -0
@@ -0,0 +1,263 @@
1
+ import { defineTool } from '@deepseek-ai/dsh-tools';
2
+ import { resolveMarivoEvidenceBridge, } from "./bridge.js";
3
+ export const MARIVO_EVIDENCE_SOURCES_TOOL_NAME = 'marivo_evidence_sources';
4
+ export const MARIVO_EVIDENCE_SOURCES_META_KIND = 'marivo-evidence-sources';
5
+ export const MARIVO_EVIDENCE_SOURCES_META_VERSION = 2;
6
+ export const MARIVO_EVIDENCE_SOURCES_DURABLE_CONTENT_KIND = 'marivo-evidence-sources-card';
7
+ export const MARIVO_EVIDENCE_SOURCES_MAX_PER_CALL = 20;
8
+ const nullableStringSchema = { oneOf: [{ type: 'string' }, { type: 'null' }] };
9
+ const evidenceSourceSchema = {
10
+ type: 'object',
11
+ additionalProperties: false,
12
+ properties: {
13
+ status: {
14
+ oneOf: [
15
+ { type: 'string', const: 'available' },
16
+ { type: 'string', const: 'missing' },
17
+ { type: 'string', const: 'unsupported' },
18
+ ],
19
+ required: true,
20
+ },
21
+ title: { type: 'string', required: true },
22
+ locator: { type: 'string', required: true },
23
+ excerpt: { ...nullableStringSchema, required: true },
24
+ truncated: { type: 'boolean', required: true },
25
+ environmentFingerprint: { type: 'string', required: true },
26
+ sessionId: { type: 'string', required: true },
27
+ findingId: { type: 'string', required: true },
28
+ findingType: { ...nullableStringSchema, required: true },
29
+ epistemicKind: { ...nullableStringSchema, required: true },
30
+ artifactRef: { type: 'string', required: true },
31
+ canonicalItemKey: { ...nullableStringSchema, required: true },
32
+ committedAt: { ...nullableStringSchema, required: true },
33
+ sourceRefs: { type: 'array', items: { type: 'string' }, required: true },
34
+ revalidation: {
35
+ oneOf: [
36
+ { type: 'null' },
37
+ {
38
+ type: 'object',
39
+ additionalProperties: false,
40
+ properties: {
41
+ status: { type: 'string', required: true },
42
+ semanticStatus: { ...nullableStringSchema, required: true },
43
+ evidenceStatus: { ...nullableStringSchema, required: true },
44
+ dependencyStatus: { ...nullableStringSchema, required: true },
45
+ },
46
+ },
47
+ ],
48
+ required: true,
49
+ },
50
+ },
51
+ };
52
+ const evidenceSourcesOutputSchema = {
53
+ type: 'object',
54
+ additionalProperties: false,
55
+ properties: {
56
+ status: { type: 'string', const: 'ok', required: true },
57
+ environment: {
58
+ type: 'object',
59
+ additionalProperties: false,
60
+ required: true,
61
+ properties: {
62
+ version: { type: 'string', required: true },
63
+ fingerprint: { type: 'string', required: true },
64
+ },
65
+ },
66
+ dshSessionId: { type: 'string', required: true },
67
+ sessionId: { type: 'string', required: true },
68
+ sources: { type: 'array', items: evidenceSourceSchema, required: true },
69
+ },
70
+ };
71
+ function nonEmptyString(value, field, maxLength = 2_048) {
72
+ if (typeof value !== 'string' || value.trim() === '' || value.length > maxLength) {
73
+ throw new TypeError(`${field} must be a non-empty string of at most ${maxLength} characters`);
74
+ }
75
+ return value;
76
+ }
77
+ function requestedSources(value) {
78
+ if (!Array.isArray(value) ||
79
+ value.length < 1 ||
80
+ value.length > MARIVO_EVIDENCE_SOURCES_MAX_PER_CALL) {
81
+ throw new TypeError(`marivo_evidence_sources sources must contain 1-${MARIVO_EVIDENCE_SOURCES_MAX_PER_CALL} items`);
82
+ }
83
+ const result = value.map((item, index) => {
84
+ if (typeof item !== 'object' || item === null || Array.isArray(item)) {
85
+ throw new TypeError(`marivo_evidence_sources sources[${index}] must be an object`);
86
+ }
87
+ const source = item;
88
+ if (Object.keys(source).length !== 2 ||
89
+ !Object.hasOwn(source, 'artifact_ref') ||
90
+ !Object.hasOwn(source, 'finding_id')) {
91
+ throw new TypeError(`marivo_evidence_sources sources[${index}] must contain exactly artifact_ref and finding_id`);
92
+ }
93
+ return {
94
+ artifactRef: nonEmptyString(source.artifact_ref, `marivo_evidence_sources sources[${index}].artifact_ref`, 512),
95
+ findingId: nonEmptyString(source.finding_id, `marivo_evidence_sources sources[${index}].finding_id`, 512),
96
+ };
97
+ });
98
+ if (new Set(result.map((item) => JSON.stringify(item))).size !== result.length) {
99
+ throw new TypeError('marivo_evidence_sources sources must be unique within one request');
100
+ }
101
+ return result;
102
+ }
103
+ function evidenceSource(environmentFingerprint, finding) {
104
+ return {
105
+ status: finding.status,
106
+ title: finding.title,
107
+ locator: finding.locator,
108
+ excerpt: finding.excerpt,
109
+ truncated: finding.truncated,
110
+ environmentFingerprint,
111
+ sessionId: finding.sessionId,
112
+ findingId: finding.findingId,
113
+ findingType: finding.findingType,
114
+ epistemicKind: finding.epistemicKind,
115
+ artifactRef: finding.artifactRef,
116
+ canonicalItemKey: finding.canonicalItemKey,
117
+ committedAt: finding.committedAt,
118
+ sourceRefs: [...finding.sourceRefs],
119
+ revalidation: finding.revalidation === null ? null : { ...finding.revalidation },
120
+ };
121
+ }
122
+ function renderSources(value) {
123
+ const lines = [
124
+ `Exact Marivo Evidence sources (${value.sources.length})`,
125
+ `Marivo Session: ${value.sessionId}`,
126
+ ];
127
+ value.sources.forEach((source, index) => {
128
+ lines.push('', `${index + 1}. ${source.title}`, ` status: ${source.status}`);
129
+ lines.push(` locator: ${source.locator}`);
130
+ lines.push(` excerpt: ${source.excerpt ?? 'unavailable'}`);
131
+ lines.push(` excerpt_state: ${source.truncated ? 'truncated' : 'complete'}`);
132
+ const revalidation = source.revalidation;
133
+ lines.push(` revalidation: ${revalidation === null ? 'unavailable' : revalidation.status}`);
134
+ if (revalidation !== null) {
135
+ lines.push(` semantic_status: ${revalidation.semanticStatus ?? 'unavailable'}`, ` evidence_status: ${revalidation.evidenceStatus ?? 'unavailable'}`, ` dependency_status: ${revalidation.dependencyStatus ?? 'unavailable'}`);
136
+ }
137
+ lines.push(` source_refs: ${source.sourceRefs.length === 0 ? 'none' : source.sourceRefs.join(', ')}`);
138
+ });
139
+ lines.push('', 'Boundary: source identity and availability do not prove that an entire conclusion, calculation, or business judgment is correct.');
140
+ return lines.join('\n');
141
+ }
142
+ export function evidenceSourcesMeta(value) {
143
+ return {
144
+ kind: MARIVO_EVIDENCE_SOURCES_META_KIND,
145
+ version: MARIVO_EVIDENCE_SOURCES_META_VERSION,
146
+ dshSessionId: value.dshSessionId,
147
+ sources: value.sources.map((source) => ({
148
+ ...source,
149
+ sourceRefs: [...source.sourceRefs],
150
+ revalidation: source.revalidation === null ? null : { ...source.revalidation },
151
+ })),
152
+ };
153
+ }
154
+ /** Build the exact-Finding source attachment Tool for one Agent and DSH Session. */
155
+ export function createMarivoEvidenceSourcesTool(bridgeSource, session) {
156
+ return defineTool({
157
+ name: MARIVO_EVIDENCE_SOURCES_TOOL_NAME,
158
+ description: 'Attach exact persisted Marivo Evidence sources to the current turn only when the user explicitly requests sources, provenance, or audit details. This identifies sources; it does not validate the surrounding conclusion.',
159
+ parameters: {
160
+ session_id: {
161
+ type: 'string',
162
+ required: true,
163
+ description: 'Exact Marivo analysis Session ID containing the Findings.',
164
+ },
165
+ sources: {
166
+ type: 'array',
167
+ required: true,
168
+ description: `1-${MARIVO_EVIDENCE_SOURCES_MAX_PER_CALL} unique exact Artifact/Finding pairs to attach.`,
169
+ items: {
170
+ type: 'object',
171
+ additionalProperties: false,
172
+ properties: {
173
+ artifact_ref: { type: 'string', required: true },
174
+ finding_id: { type: 'string', required: true },
175
+ },
176
+ },
177
+ },
178
+ },
179
+ output: {
180
+ schema: evidenceSourcesOutputSchema,
181
+ render: (_args, value) => [
182
+ { type: 'text', text: renderSources(value) },
183
+ ],
184
+ presentationMeta: (_args, value) => evidenceSourcesMeta(value),
185
+ },
186
+ timeoutMs: 35_000,
187
+ async execute(args, exec) {
188
+ const sessionId = nonEmptyString(args.session_id, 'marivo_evidence_sources session_id', 512);
189
+ const selections = requestedSources(args.sources);
190
+ const bridge = await resolveMarivoEvidenceBridge(bridgeSource);
191
+ const findings = await bridge.findings(sessionId, selections, exec.signal);
192
+ return {
193
+ status: 'ok',
194
+ environment: {
195
+ version: bridge.binding.marivoVersion,
196
+ fingerprint: bridge.binding.fingerprint,
197
+ },
198
+ dshSessionId: String(session.id),
199
+ sessionId,
200
+ sources: findings.map((finding) => evidenceSource(bridge.binding.fingerprint, finding)),
201
+ };
202
+ },
203
+ });
204
+ }
205
+ export function registerMarivoEvidenceSourcesTool(ctx, bridgeSource, session) {
206
+ return ctx.tools.register(createMarivoEvidenceSourcesTool(bridgeSource, session));
207
+ }
208
+ function sourceTurnForRootCall(dispatch) {
209
+ const rootCallId = String(dispatch.exec.rootCallId ?? '');
210
+ if (rootCallId === '' || !Array.isArray(dispatch.agent?.session?.events))
211
+ return null;
212
+ for (let index = dispatch.agent.session.events.length - 1; index >= 0; index--) {
213
+ const candidate = dispatch.agent.session.events[index];
214
+ if (typeof candidate !== 'object' || candidate === null || Array.isArray(candidate))
215
+ continue;
216
+ const event = candidate;
217
+ if (event.type !== 'tool/call' || String(event.data?.callId ?? '') !== rootCallId)
218
+ continue;
219
+ const turn = event.data?.turn;
220
+ return Number.isSafeInteger(turn) && turn >= 0 ? turn : null;
221
+ }
222
+ return null;
223
+ }
224
+ /** Preserve nested Code Mode source metadata on the durable sub-dispatch event. */
225
+ export function installMarivoEvidenceSourcesCodeDelivery(ctx) {
226
+ const pending = new Map();
227
+ const stopResult = ctx.on('tools/result', (exec, result) => {
228
+ if (exec.name !== MARIVO_EVIDENCE_SOURCES_TOOL_NAME ||
229
+ exec.parent === undefined ||
230
+ result.isError) {
231
+ return;
232
+ }
233
+ pending.set(String(exec.callId), evidenceSourcesMeta(result.value));
234
+ });
235
+ const stopDispatchLog = ctx.on('tools/code-dispatch-log', async (dispatch, next) => {
236
+ const content = await next();
237
+ if (dispatch.name !== MARIVO_EVIDENCE_SOURCES_TOOL_NAME)
238
+ return content;
239
+ const key = String(dispatch.subCallId);
240
+ const meta = pending.get(key);
241
+ pending.delete(key);
242
+ if (dispatch.isError || meta === undefined)
243
+ return content;
244
+ const turn = sourceTurnForRootCall(dispatch);
245
+ if (turn === null)
246
+ return content;
247
+ const card = {
248
+ type: MARIVO_EVIDENCE_SOURCES_DURABLE_CONTENT_KIND,
249
+ turn,
250
+ meta,
251
+ };
252
+ return [...content, card];
253
+ }, { prepend: true });
254
+ let active = true;
255
+ return () => {
256
+ if (!active)
257
+ return;
258
+ active = false;
259
+ stopDispatchLog();
260
+ stopResult();
261
+ pending.clear();
262
+ };
263
+ }
package/lib/index.js ADDED
@@ -0,0 +1,7 @@
1
+ export { createMarivoBridgeSet } from "./bridges.js";
2
+ export * from "./compatibility.js";
3
+ export * from "./datasource/index.js";
4
+ export * from "./disclosure/index.js";
5
+ export * from "./environment/index.js";
6
+ export * from "./evidence/index.js";
7
+ export { apply, Config, inject, installMarivoPlugin, name } from "./plugin.js";
package/lib/plugin.js ADDED
@@ -0,0 +1,179 @@
1
+ /** Cordis lifecycle adapter for the Web-profile shared Marivo Runtime. */
2
+ import path from 'node:path';
3
+ import process from 'node:process';
4
+ import { fileURLToPath } from 'node:url';
5
+ import { apply as installSkillFilesystem } from '@deepseek-ai/dsh-skill-filesystem';
6
+ import z from '@deepseek-ai/schemastery';
7
+ import { createMarivoBridgeSet } from "./bridges.js";
8
+ import { registerMarivoDatasourceAccessTool, registerMarivoDatasourceTestTool, } from "./datasource/index.js";
9
+ import { MarivoShellCredentialLeases, registerMarivoRuntimeShellEnvironment, } from "./datasource/shell-env.js";
10
+ import { MarivoHelpBridge } from "./disclosure/bridge.js";
11
+ import { installMarivoDisclosure, } from "./disclosure/index.js";
12
+ import { createSharedMarivoRuntimeRunner, DEFAULT_SHARED_RUNTIME_INSTALL_TIMEOUT_MS, ensureSharedMarivoRuntime, MarivoEnvironment, MarivoWorkspaceEnvironmentManager, resolveMarivoEnvironmentSource, } from "./environment/index.js";
13
+ import { installMarivoEvidenceSourcesCodeDelivery, registerMarivoEvidenceSourcesTool, } from "./evidence/index.js";
14
+ /** Cordis plugin name used by loader diagnostics and lifecycle logs. */
15
+ export const name = 'dsh-data-analysis';
16
+ /** Services that must exist before the plugin binds and watches Agent scopes. */
17
+ export const inject = ['agents', 'credentials', 'shellEnv', 'skills', 'systemPrompt', 'tools'];
18
+ export const MARIVO_DATASOURCE_CREDENTIAL_PROMPT = [
19
+ 'When marivo-semantic is active, every Marivo datasource *_env field must reference a valid POSIX environment name outside the reserved MARIVO_* and DSH_DATA_ANALYSIS_* namespaces and Host-owned DSH shell facts.',
20
+ 'Never ask the user to provide credential values in chat, and never place credential values in commands or project files.',
21
+ 'Immediately after md.register(...) or a manual datasource-file change, call marivo_datasource_test with that datasource name.',
22
+ 'If marivo_datasource_test returns needs-credentials, wait for the user to save the Web credential form, then retry marivo_datasource_test before continuing.',
23
+ 'Before datasource-backed analysis, call marivo_datasource_access once and reuse its exact bash_prelude or pwsh_prelude before each foreground analysis command until the bounded lease expires or is exhausted. The first # dsh-marivo-credential-lease: line is a required control marker; never remove or move it.',
24
+ 'Do not call marivo_datasource_test before each analysis script. Renew access with marivo_datasource_access; run another connection test only after datasource changes, credential rotation, a connection failure, or an explicit user request.',
25
+ 'Never use a lease with background or persistent Shell execution. Each admitted Shell consumes one use even if later credential resolution fails.',
26
+ 'If a datasource credential environment variable is missing, reacquire access and retry with the exact prelude in a foreground Shell. Never inspect or read DSH credential files, credential backups, or ~/.marivo/secrets.toml.',
27
+ ].join(' ');
28
+ export const MARIVO_EVIDENCE_SOURCES_PROMPT = [
29
+ 'Call marivo_evidence_sources only when the user explicitly requests sources, citations, provenance, or audit details.',
30
+ 'Request only exact persisted Findings by Marivo Session, Artifact, and Finding identity.',
31
+ 'Treat source existence as identity and availability evidence, not as proof that the whole conclusion, calculation, or business judgment is entailed or correct.',
32
+ 'If no exact Finding exists or its source cannot be recovered, say so instead of inventing or approximating a source.',
33
+ ].join(' ');
34
+ export const MARIVO_REPORT_PROMPT = [
35
+ 'Use dsh-data-analysis-report only when the user explicitly requests HTML/web or a durable report file, accepts an Agent proposal to create one, or asks to revise an existing Workspace report bundle.',
36
+ 'Answer ordinary analysis in the conversation even when it is long or contains multiple charts or tables.',
37
+ 'For existing analysis, recover and revalidate persisted Artifacts; never rerun observe only to create the report or fill DAG details.',
38
+ ].join(' ');
39
+ const integrationSkillsRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..', 'skills');
40
+ /** Cordis loader schema. Runtime defaults are resolved in {@link apply}. */
41
+ export const Config = z.object({
42
+ projectRoot: z.string(),
43
+ pythonExecutable: z.string(),
44
+ runtimeRoot: z.string(),
45
+ uvExecutable: z.string(),
46
+ installTimeoutMs: z.number().default(DEFAULT_SHARED_RUNTIME_INSTALL_TIMEOUT_MS),
47
+ });
48
+ function configuredProjectRoot(config, agent) {
49
+ return (config.projectRoot ??
50
+ process.env.DSH_DATA_ANALYSIS_PROJECT_ROOT ??
51
+ agent.session.header.cwd ??
52
+ process.env.DSH_CWD ??
53
+ process.cwd());
54
+ }
55
+ /**
56
+ * Install one already-bound environment into every live or subsequently published Agent scope.
57
+ * Installation is transactional for existing Agents and is disposed with the Cordis plugin.
58
+ */
59
+ export function installMarivoPlugin(ctx, environmentOrResolver, options = {}) {
60
+ const installed = new Map();
61
+ const credentials = options.credentials ?? ctx.credentials;
62
+ if (credentials === undefined) {
63
+ throw new Error('dsh-data-analysis requires the DSH credentials service');
64
+ }
65
+ const shellCredentials = new MarivoShellCredentialLeases(ctx, credentials);
66
+ const bridgeSets = new WeakMap();
67
+ const install = (agent) => {
68
+ if (installed.has(agent))
69
+ return;
70
+ const source = environmentOrResolver instanceof MarivoEnvironment
71
+ ? environmentOrResolver
72
+ : () => Promise.resolve(environmentOrResolver(agent));
73
+ const resolveBridgeSet = async () => {
74
+ const environment = await resolveMarivoEnvironmentSource(source);
75
+ let bridges = bridgeSets.get(environment);
76
+ if (bridges === undefined) {
77
+ bridges = createMarivoBridgeSet(environment);
78
+ bridgeSets.set(environment, bridges);
79
+ }
80
+ return bridges;
81
+ };
82
+ const helpSource = options.helpBridgeSource ?? (async () => (await resolveBridgeSet()).help);
83
+ const datasourceSource = async () => (await resolveBridgeSet()).datasource;
84
+ const evidenceSource = async () => (await resolveBridgeSet()).evidence;
85
+ const controller = installMarivoDisclosure(ctx, agent, helpSource, options);
86
+ controller.addDisposer(shellCredentials.installAgent(agent, datasourceSource));
87
+ controller.addDisposer(registerMarivoDatasourceTestTool(agent.ctx, datasourceSource, credentials, {
88
+ revokeShellLease: (bridge, datasourceName) => shellCredentials.revokeLease(agent, bridge, datasourceName),
89
+ }));
90
+ controller.addDisposer(registerMarivoDatasourceAccessTool(agent.ctx, datasourceSource, credentials, {
91
+ revokeShellLease: (bridge, datasourceName) => shellCredentials.revokeLease(agent, bridge, datasourceName),
92
+ issueShellLease: (bridge, datasourceName, refs) => shellCredentials.issueLease(agent, bridge, datasourceName, refs),
93
+ }));
94
+ controller.addDisposer(registerMarivoEvidenceSourcesTool(agent.ctx, evidenceSource, agent.session));
95
+ controller.addDisposer(installMarivoEvidenceSourcesCodeDelivery(agent.ctx));
96
+ controller.addDisposer(agent.ctx.systemPrompt.section({
97
+ name: 'marivo:datasource-credentials',
98
+ order: 170,
99
+ text: () => controller.activeSkills.includes('marivo-semantic')
100
+ ? MARIVO_DATASOURCE_CREDENTIAL_PROMPT
101
+ : '',
102
+ }));
103
+ controller.addDisposer(agent.ctx.systemPrompt.section({
104
+ name: 'marivo:evidence-sources',
105
+ order: 180,
106
+ text: () => controller.activeSkills.includes('marivo-analysis') ? MARIVO_EVIDENCE_SOURCES_PROMPT : '',
107
+ }));
108
+ controller.addDisposer(agent.ctx.systemPrompt.section({
109
+ name: 'marivo:report',
110
+ order: 185,
111
+ text: () => controller.activeSkills.includes('marivo-analysis') ? MARIVO_REPORT_PROMPT : '',
112
+ }));
113
+ installed.set(agent, controller);
114
+ };
115
+ try {
116
+ for (const agent of ctx.agents.list())
117
+ install(agent);
118
+ }
119
+ catch (error) {
120
+ for (const controller of installed.values())
121
+ controller.dispose();
122
+ shellCredentials.dispose();
123
+ throw error;
124
+ }
125
+ const stopCreated = ctx.on('agent/created', ({ agent }) => {
126
+ install(agent);
127
+ });
128
+ const stopDisposed = ctx.on('agent/disposed', ({ agent }) => {
129
+ installed.get(agent)?.dispose();
130
+ installed.delete(agent);
131
+ });
132
+ let active = true;
133
+ return () => {
134
+ if (!active)
135
+ return;
136
+ active = false;
137
+ stopCreated();
138
+ stopDisposed();
139
+ for (const controller of installed.values())
140
+ controller.dispose();
141
+ installed.clear();
142
+ shellCredentials.dispose();
143
+ };
144
+ }
145
+ /** Ensure the shared Runtime once, mount its skills, then bind each Workspace lazily. */
146
+ export async function apply(ctx, config = {}) {
147
+ const pythonExecutable = config.pythonExecutable ?? process.env.DSH_DATA_ANALYSIS_PYTHON;
148
+ const runtimeRoot = config.runtimeRoot ?? process.env.DSH_DATA_ANALYSIS_RUNTIME_ROOT;
149
+ const uvExecutable = config.uvExecutable ?? process.env.DSH_DATA_ANALYSIS_UV;
150
+ const runtime = await ensureSharedMarivoRuntime({
151
+ ...(pythonExecutable === undefined ? {} : { pythonExecutable }),
152
+ ...(runtimeRoot === undefined ? {} : { runtimeRoot }),
153
+ ...(uvExecutable === undefined ? {} : { uvExecutable }),
154
+ ...(config.installTimeoutMs === undefined ? {} : { installTimeoutMs: config.installTimeoutMs }),
155
+ });
156
+ const disposeRuntimeShellEnvironment = registerMarivoRuntimeShellEnvironment(ctx, runtime.pythonExecutable);
157
+ const manager = new MarivoWorkspaceEnvironmentManager(runtime);
158
+ let disposePlugin;
159
+ try {
160
+ installSkillFilesystem(ctx, {
161
+ providerName: 'dsh-data-analysis-marivo',
162
+ includeDefaultRoots: false,
163
+ customSkillDirs: [runtime.skillsRoot, integrationSkillsRoot],
164
+ watch: false,
165
+ });
166
+ const helpBridge = new MarivoHelpBridge(createSharedMarivoRuntimeRunner(runtime));
167
+ disposePlugin = installMarivoPlugin(ctx, (agent) => manager.resolve(configuredProjectRoot(config, agent)), { helpBridgeSource: helpBridge });
168
+ }
169
+ catch (error) {
170
+ manager.dispose();
171
+ disposeRuntimeShellEnvironment();
172
+ throw error;
173
+ }
174
+ return () => {
175
+ disposePlugin();
176
+ manager.dispose();
177
+ disposeRuntimeShellEnvironment();
178
+ };
179
+ }
@@ -0,0 +1,11 @@
1
+ import { MarivoDatasourceBridge } from './datasource/bridge.ts';
2
+ import { MarivoHelpBridge } from './disclosure/bridge.ts';
3
+ import type { MarivoEnvironment } from './environment/binding.ts';
4
+ import { MarivoEvidenceBridge } from './evidence/bridge.ts';
5
+ export interface MarivoBridgeSet {
6
+ readonly help: MarivoHelpBridge;
7
+ readonly datasource: MarivoDatasourceBridge;
8
+ readonly evidence: MarivoEvidenceBridge;
9
+ }
10
+ /** Compose domain adapters without adding domain methods back to the Environment. */
11
+ export declare function createMarivoBridgeSet(environment: MarivoEnvironment): MarivoBridgeSet;
@@ -0,0 +1,125 @@
1
+ import type { Context } from '@deepseek-ai/cordis';
2
+ export declare const MARIVO_CREDENTIAL_STORAGE_PREFIX = "DSH_DATA_ANALYSIS_CREDENTIAL_";
3
+ declare const EVIDENCE_SOURCES_META_KIND = "marivo-evidence-sources";
4
+ declare const EVIDENCE_SOURCES_META_VERSION = 2;
5
+ /** Browser-side copy of the Host mapping; contract tests keep both implementations identical. */
6
+ export declare function marivoCredentialStorageRef(ref: string): string;
7
+ export interface MarivoEvidenceSource {
8
+ status: 'available' | 'missing' | 'unsupported';
9
+ title: string;
10
+ locator: string;
11
+ excerpt: string | null;
12
+ truncated: boolean;
13
+ environmentFingerprint: string;
14
+ sessionId: string;
15
+ findingId: string;
16
+ findingType: string | null;
17
+ epistemicKind: string | null;
18
+ artifactRef: string;
19
+ canonicalItemKey: string | null;
20
+ committedAt: string | null;
21
+ sourceRefs: string[];
22
+ revalidation: {
23
+ status: string;
24
+ semanticStatus: string | null;
25
+ evidenceStatus: string | null;
26
+ dependencyStatus: string | null;
27
+ } | null;
28
+ }
29
+ export interface MarivoEvidenceSourcesMeta {
30
+ readonly kind: typeof EVIDENCE_SOURCES_META_KIND;
31
+ readonly version: typeof EVIDENCE_SOURCES_META_VERSION;
32
+ readonly dshSessionId: string;
33
+ readonly sources: readonly MarivoEvidenceSource[];
34
+ }
35
+ export interface MarivoEvidenceSourcesTurnDelivery {
36
+ readonly seq: number;
37
+ readonly sources: readonly MarivoEvidenceSource[];
38
+ }
39
+ export interface MarivoEvidenceSourcesTurnData {
40
+ readonly deliveries: readonly MarivoEvidenceSourcesTurnDelivery[];
41
+ }
42
+ interface MarivoEvidenceSourcesTurnState {
43
+ readonly turn: number;
44
+ readonly calls: ReadonlyMap<string, string>;
45
+ readonly deliveries: readonly MarivoEvidenceSourcesTurnDelivery[];
46
+ }
47
+ export interface MarivoEvidenceArtifactGroup {
48
+ readonly key: string;
49
+ readonly environmentFingerprint: string;
50
+ readonly sessionId: string;
51
+ readonly artifactRef: string;
52
+ readonly sources: readonly MarivoEvidenceSource[];
53
+ }
54
+ declare module '@deepseek-ai/dsh-client-runtime/client' {
55
+ interface ConversationTurnDataMap {
56
+ /** Explicitly requested Marivo Evidence sources collected from this exact Turn. */
57
+ 'marivo-evidence-sources-delivery': MarivoEvidenceSourcesTurnData;
58
+ }
59
+ }
60
+ /** Parse the closed per-call source attachment persisted in Tool result metadata. */
61
+ export declare function parseEvidenceSourcesMeta(value: unknown): MarivoEvidenceSourcesMeta | null;
62
+ /** Decode the Code Mode-only source attachment from a durable sub-dispatch result. */
63
+ export declare function parseEvidenceSourcesDurableContent(value: unknown): {
64
+ readonly turn: number;
65
+ readonly meta: MarivoEvidenceSourcesMeta;
66
+ } | null;
67
+ /** Recover one successful native or nested source attachment. */
68
+ export declare function evidenceSourcesDeliveryFromEvent(event: any, calls?: ReadonlyMap<string, string>): MarivoEvidenceSourcesTurnDelivery | null;
69
+ /** Aggregate explicit source attachments under one Harness-owned Turn key. */
70
+ export declare const marivoEvidenceSourcesDeliveryDefinition: {
71
+ kind: string;
72
+ match(event: any): {
73
+ id: string;
74
+ role: string;
75
+ } | null;
76
+ start(_context: any, match: any): MarivoEvidenceSourcesTurnState;
77
+ update(context: any, match: any): MarivoEvidenceSourcesTurnState;
78
+ buildLocationData(context: any, scope: string): {
79
+ kind: string;
80
+ turn: any;
81
+ key: string;
82
+ value: {
83
+ deliveries: any;
84
+ };
85
+ } | null;
86
+ };
87
+ /** Successful sources completed before this exact closing Assistant message. */
88
+ export declare function evidenceSourcesForClosing(owner: any): readonly MarivoEvidenceSource[];
89
+ export declare function selectMarivoEvidenceSources(owner: any): readonly MarivoEvidenceSource[] | null;
90
+ /** Group source presentation only; this does not infer Evidence equivalence or compatibility. */
91
+ export declare function groupMarivoEvidenceSources(sources: readonly MarivoEvidenceSource[]): readonly MarivoEvidenceArtifactGroup[];
92
+ export interface NeedsCredentialsResult {
93
+ status: 'needs-credentials';
94
+ name: string;
95
+ refs: string[];
96
+ }
97
+ export declare function parseNeedsCredentials(text: string): NeedsCredentialsResult | null;
98
+ export declare function shouldAutoOpen(sessionId: string, callId: string, result: NeedsCredentialsResult | null): boolean;
99
+ export declare function blankCredentialValues(refs: readonly string[]): Record<string, string>;
100
+ export declare class CredentialDialogController {
101
+ readonly api: any;
102
+ constructor(api: any);
103
+ describe(refs: readonly string[]): Promise<Record<string, {
104
+ configured: boolean;
105
+ }>>;
106
+ inspect(refs: readonly string[]): Promise<{
107
+ configured: Record<string, boolean>;
108
+ missing: string[];
109
+ shouldOpen: boolean;
110
+ }>;
111
+ save(values: Readonly<Record<string, string>>): Promise<{
112
+ ok: boolean;
113
+ saved: string[];
114
+ errors: Record<string, string>;
115
+ }>;
116
+ }
117
+ export declare function MarivoDatasourceTestToolView(props: any): import("react").JSX.Element;
118
+ export declare function MarivoDatasourceAccessToolView(props: any): import("react").JSX.Element;
119
+ export declare function MarivoEvidenceSourcesPanel({ matched: sources, t, }: {
120
+ matched: readonly MarivoEvidenceSource[];
121
+ t: (key: string, values?: Record<string, string>) => string;
122
+ }): import("react").JSX.Element;
123
+ export declare const inject: string[];
124
+ export declare function apply(ctx: Context): void;
125
+ export {};
@@ -0,0 +1,29 @@
1
+ export declare const COMPATIBILITY_SCHEMA: "dsh-data-analysis-compatibility/v2";
2
+ export interface DshDataAnalysisCompatibility {
3
+ readonly schema: typeof COMPATIBILITY_SCHEMA;
4
+ readonly dsh: {
5
+ readonly distribution: '@deepseek-ai/dsh';
6
+ readonly peerRange: string;
7
+ };
8
+ readonly marivo: {
9
+ readonly version: string;
10
+ readonly packageSpec: string;
11
+ };
12
+ readonly contracts: {
13
+ readonly runtimeInstallation: 'dsh-data-analysis-runtime/v2';
14
+ readonly subprocessPolicy: 'direct-argv-inherited-env-snapshot-overlay-v2';
15
+ };
16
+ }
17
+ /** The package semver and the compatibility contract shipped in this exact installation. */
18
+ export declare const PLUGIN_VERSION: string;
19
+ export declare const DSH_DATA_ANALYSIS_COMPATIBILITY: DshDataAnalysisCompatibility;
20
+ /** Every DSH peer is required and must use this one verified release. */
21
+ export declare const DSH_PEER_RANGE: string;
22
+ export declare const DSH_DISTRIBUTION: "@deepseek-ai/dsh";
23
+ export declare const DSH_PEER_DEPENDENCIES: Readonly<{
24
+ [k: string]: string;
25
+ }>;
26
+ export declare const MARIVO_VERSION: string;
27
+ export declare const MARIVO_PACKAGE_SPEC: string;
28
+ export declare const RUNTIME_INSTALLATION_VERSION: "dsh-data-analysis-runtime/v2";
29
+ export declare const SUBPROCESS_POLICY_VERSION: "direct-argv-inherited-env-snapshot-overlay-v2";
@@ -0,0 +1,27 @@
1
+ import type { Context } from '@deepseek-ai/cordis';
2
+ import type { CredentialProvider } from '@deepseek-ai/dsh-credentials';
3
+ import type { JsonValue } from '@deepseek-ai/dsh-session';
4
+ import { type ToolDefinition } from '@deepseek-ai/dsh-tools';
5
+ import { type MarivoDatasourceBridgePort, type MarivoDatasourceBridgeSource } from './bridge.ts';
6
+ import type { MarivoShellLeaseReceipt } from './shell-env.ts';
7
+ export declare const MARIVO_DATASOURCE_ACCESS_TOOL_NAME = "marivo_datasource_access";
8
+ interface JsonObject {
9
+ [key: string]: JsonValue;
10
+ }
11
+ export type MarivoDatasourceAccessValue = ({
12
+ status: 'needs-credentials';
13
+ name: string;
14
+ refs: string[];
15
+ } & JsonObject) | ({
16
+ status: 'ok';
17
+ name: string;
18
+ shell_lease: MarivoShellLeaseReceipt;
19
+ } & JsonObject);
20
+ export interface MarivoDatasourceAccessOptions {
21
+ revokeShellLease(bridge: MarivoDatasourceBridgePort, name: string): void;
22
+ issueShellLease(bridge: MarivoDatasourceBridgePort, name: string, refs: readonly string[]): MarivoShellLeaseReceipt;
23
+ }
24
+ /** Build the scoped datasource access Tool without performing a connection test. */
25
+ export declare function createMarivoDatasourceAccessTool(bridgeSource: MarivoDatasourceBridgeSource, credentials: Pick<CredentialProvider, 'resolve'>, options: MarivoDatasourceAccessOptions): ToolDefinition;
26
+ export declare function registerMarivoDatasourceAccessTool(ctx: Context, bridgeSource: MarivoDatasourceBridgeSource, credentials: Pick<CredentialProvider, 'resolve'>, options: MarivoDatasourceAccessOptions): () => void;
27
+ export {};