@chengxianglibra/dsh-data-analysis 0.2.0 → 0.2.2
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.en.md +138 -0
- package/README.md +55 -82
- package/lib/client/credentials/install.js +3 -3
- package/lib/client/i18n/copy.js +4 -1
- package/lib/client/i18n/host.js +1 -0
- package/lib/client/i18n/settings.js +30 -0
- package/lib/client/input-context.js +1 -1
- package/lib/client/python-tool/card.js +2 -2
- package/lib/client/python-tool/model.js +1 -1
- package/lib/client/right-tabs/install.js +10 -7
- package/lib/client/settings/card.js +90 -0
- package/lib/client/settings/install.js +14 -0
- package/lib/client.js +104 -70
- package/lib/datasource/changes-contract.js +6 -2
- package/lib/datasource/configure.js +1 -1
- package/lib/datasource/python-options.js +1 -7
- package/lib/datasource/python.js +12 -7
- package/lib/datasource/test.js +1 -1
- package/lib/disclosure/execution-guidance.js +5 -8
- package/lib/plugin-agents.js +2 -2
- package/lib/plugin.js +14 -4
- package/lib/presentation/assets/portable.js +1 -1
- package/lib/presentation/assets/static.js +47 -47
- package/lib/presentation/execution-policy.js +5 -0
- package/lib/presentation/projection/index.js +27 -10
- package/lib/presentation/tool.js +2 -1
- package/lib/settings.js +17 -0
- package/lib/types/client/i18n/copy.d.ts +15 -0
- package/lib/types/client/i18n/host.d.ts +1 -0
- package/lib/types/client/i18n/settings.d.ts +16 -0
- package/lib/types/client/settings/card.d.ts +9 -0
- package/lib/types/client/settings/install.d.ts +2 -0
- package/lib/types/client.d.ts +2 -2
- package/lib/types/datasource/python-options.d.ts +1 -2
- package/lib/types/datasource/python.d.ts +2 -2
- package/lib/types/disclosure/execution-guidance.d.ts +8 -0
- package/lib/types/plugin-agents.d.ts +2 -0
- package/lib/types/plugin.d.ts +23 -3
- package/lib/types/presentation/execution-policy.d.ts +5 -0
- package/lib/types/rpc.d.ts +2 -2
- package/lib/types/semantic-reference/rpc.d.ts +2 -2
- package/lib/types/settings.d.ts +14 -0
- package/package.json +85 -65
- package/python/presentation-kit/dist/dsh_data_analysis_presentation_kit-1.1.0-py3-none-any.whl +0 -0
- package/skills/dsh-data-analysis-files/SKILL.md +22 -10
- package/skills/dsh-data-analysis-files/references/delivery.md +15 -0
- package/skills/dsh-data-analysis-presentation/SKILL.md +15 -19
- package/skills/dsh-data-analysis-presentation/references/schema.md +4 -1
|
@@ -18,14 +18,18 @@ const descriptor = {
|
|
|
18
18
|
name: 'sessionId',
|
|
19
19
|
wire: 'sessionId',
|
|
20
20
|
source: 'json',
|
|
21
|
-
codec: {
|
|
21
|
+
codec: {
|
|
22
|
+
mode: 'strict',
|
|
23
|
+
typeSymbol: `${owner}#CredentialSessionId`,
|
|
24
|
+
create: () => sessionId,
|
|
25
|
+
},
|
|
22
26
|
},
|
|
23
27
|
],
|
|
24
28
|
cancellation: { parameter: 'signal' },
|
|
25
29
|
result: {
|
|
26
30
|
mode: 'strict',
|
|
27
31
|
typeSymbol: `${owner}#CredentialRevision`,
|
|
28
|
-
|
|
32
|
+
create: () => credentialRevisionSchema,
|
|
29
33
|
},
|
|
30
34
|
};
|
|
31
35
|
export const credentialChangesHost = {
|
|
@@ -5,7 +5,7 @@ export const MARIVO_DATASOURCE_CONFIGURE_TOOL_NAME = 'marivo_datasource_configur
|
|
|
5
5
|
export function createMarivoDatasourceConfigureTool(source, service) {
|
|
6
6
|
return defineTool({
|
|
7
7
|
name: MARIVO_DATASOURCE_CONFIGURE_TOOL_NAME,
|
|
8
|
-
description: '
|
|
8
|
+
description: 'When a requested remote table has no usable configured datasource, use mode=create to let the user create/select one; repair connection configuration with mode=edit and its exact name. The user configures it in the owning Web session right tab; never write connection configuration on their behalf or pass credentials or configuration values. Waits for successful save and connection test, cancellation or failure. Only status=ok permits continuation: rediscover the datasource and verify the requested table and read access before analysis. Success already includes a connection test; do not repeat it unless configuration or credentials change, a connection fails, or the user requests one. Local files need no remote datasource setup.',
|
|
9
9
|
parameters: {
|
|
10
10
|
mode: {
|
|
11
11
|
type: 'string',
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
export const DEFAULT_PYTHON_TIMEOUT_MS = 120_000;
|
|
2
|
-
export const DEFAULT_PYTHON_MAX_TIMEOUT_MS = 600_000;
|
|
3
2
|
const MAX_TIMER_DELAY_MS = 2_147_483_647;
|
|
4
3
|
/** Do not echo rejected inputs: tool arguments and configuration are not trusted diagnostics. */
|
|
5
4
|
export function pythonTimeout(value, name) {
|
|
@@ -12,10 +11,5 @@ export function pythonTimeout(value, name) {
|
|
|
12
11
|
}
|
|
13
12
|
export function resolvePythonOptions(options) {
|
|
14
13
|
const pythonTimeoutMs = pythonTimeout(options.pythonTimeoutMs === undefined ? DEFAULT_PYTHON_TIMEOUT_MS : options.pythonTimeoutMs, 'pythonTimeoutMs');
|
|
15
|
-
|
|
16
|
-
? DEFAULT_PYTHON_MAX_TIMEOUT_MS
|
|
17
|
-
: options.pythonMaxTimeoutMs, 'pythonMaxTimeoutMs');
|
|
18
|
-
if (pythonTimeoutMs > pythonMaxTimeoutMs)
|
|
19
|
-
throw new Error('pythonTimeoutMs must not exceed pythonMaxTimeoutMs');
|
|
20
|
-
return { pythonTimeoutMs, pythonMaxTimeoutMs };
|
|
14
|
+
return { pythonTimeoutMs };
|
|
21
15
|
}
|
package/lib/datasource/python.js
CHANGED
|
@@ -4,7 +4,7 @@ import { defineTool } from '@deepseek-ai/dsh-tools';
|
|
|
4
4
|
import { savePythonExecution } from "../python-execution.js";
|
|
5
5
|
import { registerMarivoTool } from "../tool-lifecycle.js";
|
|
6
6
|
import { resolveMarivoDatasourceBridge } from "./bridge.js";
|
|
7
|
-
import { pythonTimeout, resolvePythonOptions } from "./python-options.js";
|
|
7
|
+
import { pythonTimeout, resolvePythonOptions, } from "./python-options.js";
|
|
8
8
|
import { PYTHON_LAUNCHER, PYTHON_WORKER } from "./resolver-program.js";
|
|
9
9
|
import { CredentialServiceError, } from "./service.js";
|
|
10
10
|
import { datasourceToolValue } from "./test.js";
|
|
@@ -33,10 +33,11 @@ function quote(value) {
|
|
|
33
33
|
: `'${value.replaceAll("'", "'\\''")}'`;
|
|
34
34
|
}
|
|
35
35
|
export function registerMarivoPythonTool(ctx, source, service, options = {}) {
|
|
36
|
-
const
|
|
36
|
+
const readOptions = typeof options === 'function' ? options : () => options;
|
|
37
|
+
resolvePythonOptions(readOptions());
|
|
37
38
|
return registerMarivoTool(ctx, defineTool({
|
|
38
39
|
name: 'marivo_python',
|
|
39
|
-
description: 'Execute foreground Python in the bound Runtime and Workspace, including local pandas and native DuckDB file analysis.
|
|
40
|
+
description: 'Execute foreground Python in the bound Runtime and Workspace, including local pandas and native DuckDB file analysis. Waits for missing credentials for every declared datasource before starting code once; no automatic connection test or execution replay. No background execution or secret environment variables. Success returns codeRef for the submitted code; associate it with presentation datasets through draft codeRefs when needed. codeCaptureError leaves the execution outcome unchanged; do not rerun to recover the code record. Inspect execution phase, outcome and nextAction after failure; timeout does not prove remote query cancellation or absence of saved results.',
|
|
40
41
|
parameters: {
|
|
41
42
|
code: {
|
|
42
43
|
type: 'string',
|
|
@@ -51,7 +52,7 @@ export function registerMarivoPythonTool(ctx, source, service, options = {}) {
|
|
|
51
52
|
},
|
|
52
53
|
timeoutMs: {
|
|
53
54
|
type: 'number',
|
|
54
|
-
description:
|
|
55
|
+
description: 'Optional foreground Shell timeout in milliseconds, a positive integer at most 2147483647. Defaults to the current plugin pythonTimeoutMs setting. Credential waiting precedes this budget; Harness Shell limits, outer Code Mode deadlines and cancellation remain independent.',
|
|
55
56
|
},
|
|
56
57
|
},
|
|
57
58
|
output: {
|
|
@@ -83,7 +84,9 @@ export function registerMarivoPythonTool(ctx, source, service, options = {}) {
|
|
|
83
84
|
};
|
|
84
85
|
try {
|
|
85
86
|
try {
|
|
86
|
-
requestedTimeoutMs = pythonTimeout(args.timeoutMs === undefined
|
|
87
|
+
requestedTimeoutMs = pythonTimeout(args.timeoutMs === undefined
|
|
88
|
+
? resolvePythonOptions(readOptions()).pythonTimeoutMs
|
|
89
|
+
: args.timeoutMs, 'timeoutMs');
|
|
87
90
|
}
|
|
88
91
|
catch {
|
|
89
92
|
rejectInput('timeoutMs must be a positive integer no greater than 2147483647');
|
|
@@ -112,7 +115,8 @@ export function registerMarivoPythonTool(ctx, source, service, options = {}) {
|
|
|
112
115
|
const spec = shell.resolve({
|
|
113
116
|
command: `${process.platform === 'win32' ? '& ' : ''}${quote(binding.pythonExecutable)} -c ${quote(PYTHON_LAUNCHER)}`,
|
|
114
117
|
workdir: binding.projectRoot,
|
|
115
|
-
timeoutMs:
|
|
118
|
+
timeoutMs: requestedTimeoutMs,
|
|
119
|
+
onExpiry: 'kill',
|
|
116
120
|
signal: prepared.signal,
|
|
117
121
|
stdin: JSON.stringify({
|
|
118
122
|
identity: binding,
|
|
@@ -132,7 +136,8 @@ export function registerMarivoPythonTool(ctx, source, service, options = {}) {
|
|
|
132
136
|
const startedAt = new Date().toISOString();
|
|
133
137
|
phase = 'executing';
|
|
134
138
|
shellStartedAt = performance.now();
|
|
135
|
-
const
|
|
139
|
+
const execution = await service.track(shell.execute(spec));
|
|
140
|
+
const result = await service.track(execution.result());
|
|
136
141
|
executionElapsedMs = performance.now() - shellStartedAt;
|
|
137
142
|
const finishedAt = new Date().toISOString();
|
|
138
143
|
const credentialValues = prepared.values;
|
package/lib/datasource/test.js
CHANGED
|
@@ -5,7 +5,7 @@ export const MARIVO_DATASOURCE_TEST_TOOL_NAME = 'marivo_datasource_test';
|
|
|
5
5
|
export function createMarivoDatasourceTestTool(source, service) {
|
|
6
6
|
return defineTool({
|
|
7
7
|
name: MARIVO_DATASOURCE_TEST_TOOL_NAME,
|
|
8
|
-
description: 'Test a Marivo datasource through Host credentials. Missing credentials wait for the Web form while this call remains alive; configured connection failures return directly.',
|
|
8
|
+
description: 'Test a Marivo datasource through Host credentials after datasource changes, credential rotation, connection failures, or explicit user requests. Normal analysis with configured credentials needs no preliminary test; successful marivo_datasource_configure already tested that configuration. Missing credentials wait for the Web form only while this call remains alive; configured connection failures return directly. Only status=ok proves this connection test succeeded; verify the requested table and read access separately.',
|
|
9
9
|
parameters: {
|
|
10
10
|
name: { type: 'string', required: true, description: 'Configured datasource name.' },
|
|
11
11
|
},
|
|
@@ -1,14 +1,11 @@
|
|
|
1
1
|
import { createUserMessage } from '@deepseek-ai/dsh-llm';
|
|
2
2
|
export const MARIVO_DATASOURCE_CREDENTIAL_PROMPT = [
|
|
3
|
-
'
|
|
3
|
+
'These are Host execution and credential rules; Marivo API and semantic contracts come from the bound Runtime Skill and live Help.',
|
|
4
4
|
'DSH Credentials owns Marivo datasource secrets. Never request values in chat, read credential files or ~/.marivo/secrets.toml, or write secrets to scripts, arguments, environment variables, reports or logs.',
|
|
5
|
-
'Use
|
|
6
|
-
'Execute analysis, metadata inspection and semantic data reads through marivo_python. Declare all exact Marivo datasource names this execution may access, including datasources without passwords
|
|
7
|
-
'marivo_python
|
|
8
|
-
'
|
|
9
|
-
"Each marivo_python call uses a separate process. Closing releases that process's Session resources; it does not end the analytical question or delete durable Artifacts. When continuing a persisted Marivo analysis, reuse its Session identity across calls.",
|
|
10
|
-
'Configured credentials do not imply a valid connection or query permissions. Preserve real failures; never automatically replay a script with possible side effects.',
|
|
11
|
-
'Session lifetime pattern inside one marivo_python call (create/resume using current Runtime Help):\nsession = ...\ntry:\n ... # analysis using this Session\nfinally:\n session.close()',
|
|
5
|
+
'Use marivo_datasource_configure for missing datasource setup or connection configuration repair; the user owns configuration in the Web form. Use marivo_datasource_test for connection checks under its tool contract. Configured credentials alone do not prove connection or read access.',
|
|
6
|
+
'Execute analysis, metadata inspection and semantic data reads through marivo_python in the bound Runtime and Workspace. Declare all exact Marivo datasource names this execution may access, including datasources without passwords; use datasources: [] for local pandas or native DuckDB without Marivo datasource access.',
|
|
7
|
+
'Each marivo_python call is a separate process. Create/resume Marivo Sessions inside the call, close them in finally, and retain the persisted Session identity when continuing the same analysis. Closing process resources does not delete durable Artifacts. Do not replace the credential resolver, read SecretValue contents, or bypass Host scope with environment/cache configuration.',
|
|
8
|
+
'Preserve real failures. After uncertain execution, inspect existing effects before retrying; never automatically replay a script with possible side effects.',
|
|
12
9
|
].join('\n');
|
|
13
10
|
export const MARIVO_ANALYSIS_CLOSEOUT_PROMPT = [
|
|
14
11
|
'Analysis semantics and execution contracts come from the activated Runtime Skill and current Help.',
|
package/lib/plugin-agents.js
CHANGED
|
@@ -12,7 +12,7 @@ import { registerMarivoExportHtmlTool } from "./presentation/export-html.js";
|
|
|
12
12
|
import { installMarivoPresentationCodeDelivery, registerMarivoPresentTool, } from "./presentation/index.js";
|
|
13
13
|
import { registerReportPublishTool } from "./report-publishing/adapters.js";
|
|
14
14
|
import { resolvePresentationWorkspace } from "./workspace-identity.js";
|
|
15
|
-
const PRESENTATION_PROMPT = '
|
|
15
|
+
const PRESENTATION_PROMPT = 'Match delivery to the user request. Ordinary answers and simple comparison tables can stay in chat. For analysis of attachments or Workspace data files, including short chat comparisons, first load dsh-data-analysis-files; requested CSV, JSON or PNG files use native present. For interactive charts or tables, saved reports, dashboards, report updates or visual source panels, load dsh-data-analysis-presentation and use marivo_present; that Skill also covers report export and publication when requested. Existing results can be presented directly. Use the Runtime skills and live Help for Marivo analysis or semantic authoring; local pandas or native DuckDB file analysis needs no Marivo semantic setup. When analysis reveals a reusable business definition or semantic gap, follow the relevant Skill to assess reuse or handoff to marivo-semantic, limited to what the current task needs or the user has authorized; stop when that scope is answered or its blockers are explicit.';
|
|
16
16
|
/**
|
|
17
17
|
* Install one already-bound environment into every live or subsequently published Agent scope.
|
|
18
18
|
* Installation is transactional for existing Agents and is disposed with the Cordis plugin.
|
|
@@ -87,7 +87,7 @@ export function createMarivoAgentInstallation(ctx, environmentOrResolver, option
|
|
|
87
87
|
controller.addDisposer(installMarivoExecutionGuidance(agent, controller));
|
|
88
88
|
controller.addDisposer(registerMarivoDatasourceTestTool(agent.ctx, datasourceSource, credentialService));
|
|
89
89
|
controller.addDisposer(registerMarivoDatasourceConfigureTool(agent.ctx, datasourceSource, credentialService));
|
|
90
|
-
controller.addDisposer(registerMarivoPythonTool(agent.ctx, datasourceSource, credentialService, pythonOptions));
|
|
90
|
+
controller.addDisposer(registerMarivoPythonTool(agent.ctx, datasourceSource, credentialService, options.pythonOptionsSource ?? pythonOptions));
|
|
91
91
|
controller.addDisposer(() => credentialService.disposeAgent(agent));
|
|
92
92
|
controller.addDisposer(registerMarivoPresentTool(agent.ctx, presentationSource, agent.session));
|
|
93
93
|
controller.addDisposer(registerMarivoExportHtmlTool(agent.ctx, () => resolvePresentationWorkspace(ctx, String(agent.session.id)), agent.session));
|
package/lib/plugin.js
CHANGED
|
@@ -5,6 +5,7 @@ import { createMarivoAgentInstallation } from "./plugin-agents.js";
|
|
|
5
5
|
import { registerPublishingCredentials } from "./report-publishing/adapters.js";
|
|
6
6
|
import { resolvePublishingConfig } from "./report-publishing/config.js";
|
|
7
7
|
import { ReportPublishingService } from "./report-publishing/service.js";
|
|
8
|
+
import { currentPythonOptions, installPythonSettings, } from "./settings.js";
|
|
8
9
|
import { resolvePresentationWorkspace } from "./workspace-identity.js";
|
|
9
10
|
export { installMarivoPlugin } from "./plugin-agents.js";
|
|
10
11
|
export { resolvePresentationWorkspace } from "./workspace-identity.js";
|
|
@@ -16,7 +17,7 @@ import { apply as installSkillFilesystem } from '@deepseek-ai/dsh-skill-filesyst
|
|
|
16
17
|
import { WorkspaceId } from '@deepseek-ai/dsh-workspace';
|
|
17
18
|
import z from '@deepseek-ai/schemastery';
|
|
18
19
|
import { MarivoDatasourceBridge } from "./datasource/bridge.js";
|
|
19
|
-
import {
|
|
20
|
+
import { DEFAULT_PYTHON_TIMEOUT_MS } from "./datasource/python-options.js";
|
|
20
21
|
import { registerCredentialRpc } from "./datasource/rpc.js";
|
|
21
22
|
import { MarivoCredentialService } from "./datasource/service.js";
|
|
22
23
|
import { registerMarivoRuntimeShellEnvironment } from "./datasource/shell-env.js";
|
|
@@ -46,8 +47,13 @@ export const Config = z.object({
|
|
|
46
47
|
// Defer validation to authoring so loader errors cannot echo configured values.
|
|
47
48
|
datasourceDefaults: z.any(),
|
|
48
49
|
reportPublishing: z.any(),
|
|
49
|
-
pythonTimeoutMs: z
|
|
50
|
-
|
|
50
|
+
pythonTimeoutMs: z
|
|
51
|
+
.number()
|
|
52
|
+
.min(1)
|
|
53
|
+
.max(2_147_483_647)
|
|
54
|
+
.step(1)
|
|
55
|
+
.default(DEFAULT_PYTHON_TIMEOUT_MS)
|
|
56
|
+
.volatile(),
|
|
51
57
|
credentialInteraction: z.union(['web', 'none']).default('web'),
|
|
52
58
|
projectRoot: z.string(),
|
|
53
59
|
pythonExecutable: z.string(),
|
|
@@ -65,7 +71,7 @@ function configuredProjectRoot(config, agent) {
|
|
|
65
71
|
/** Ensure the shared Runtime once, mount its skills, then bind each Workspace lazily. */
|
|
66
72
|
export async function apply(ctx, config = {}) {
|
|
67
73
|
const publishingConfig = resolvePublishingConfig(config.reportPublishing);
|
|
68
|
-
const pythonOptions =
|
|
74
|
+
const pythonOptions = currentPythonOptions(config);
|
|
69
75
|
const pythonExecutable = config.pythonExecutable ?? process.env.DSH_DATA_ANALYSIS_PYTHON;
|
|
70
76
|
const runtimeRoot = config.runtimeRoot ?? process.env.DSH_DATA_ANALYSIS_RUNTIME_ROOT;
|
|
71
77
|
const bootstrapPythonExecutable = config.bootstrapPythonExecutable ?? process.env.DSH_DATA_ANALYSIS_BOOTSTRAP_PYTHON;
|
|
@@ -100,6 +106,7 @@ export async function apply(ctx, config = {}) {
|
|
|
100
106
|
let disposePresentation;
|
|
101
107
|
let referenceService;
|
|
102
108
|
let agentInstallation;
|
|
109
|
+
let pythonSettings;
|
|
103
110
|
let closing;
|
|
104
111
|
const browserService = new SemanticBrowserService({
|
|
105
112
|
getWorkspace: (id) => ctx.workspaceRegistry.get(WorkspaceId(id)),
|
|
@@ -111,6 +118,7 @@ export async function apply(ctx, config = {}) {
|
|
|
111
118
|
return closing;
|
|
112
119
|
closing = finishCleanup([
|
|
113
120
|
() => agentInstallation?.close(),
|
|
121
|
+
() => pythonSettings?.dispose(),
|
|
114
122
|
() => disposeCredentials?.(),
|
|
115
123
|
disposeChanges,
|
|
116
124
|
() => disposePublishing?.(),
|
|
@@ -132,6 +140,7 @@ export async function apply(ctx, config = {}) {
|
|
|
132
140
|
return closing;
|
|
133
141
|
};
|
|
134
142
|
try {
|
|
143
|
+
pythonSettings = installPythonSettings(ctx, config);
|
|
135
144
|
unregisterChanges = ctx.typert.register(credentialChangesHost);
|
|
136
145
|
installSkillFilesystem(ctx, {
|
|
137
146
|
providerName: 'dsh-data-analysis-marivo',
|
|
@@ -160,6 +169,7 @@ export async function apply(ctx, config = {}) {
|
|
|
160
169
|
disposePublishing = registerPublishingCredentials(ctx.connection, reportPublishing, (id) => Boolean(ctx.workspaceRegistry.get(WorkspaceId(id))));
|
|
161
170
|
agentInstallation = createMarivoAgentInstallation(ctx, resolveEnvironment, {
|
|
162
171
|
...pythonOptions,
|
|
172
|
+
pythonOptionsSource: pythonSettings.get,
|
|
163
173
|
helpBridgeSource: helpBridge,
|
|
164
174
|
...(publishingConfig ? { reportPublishing } : {}),
|
|
165
175
|
credentialService,
|