@yejiming/dsh-data-agent 0.0.9 → 0.0.10

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.
@@ -16,7 +16,7 @@ export interface DataAgentWorkbenchInjected {
16
16
  };
17
17
  };
18
18
  }
19
- /** The workbench's full component props: the dock seat + the locale seat + the injected sessions hook. */
20
- export type DataAgentWorkbenchProps = PropsRuntime<'conversation.input.dock'> & PropsLocale<'data-agent'> & InjectFace<DataAgentWorkbenchInjected>;
19
+ /** The workbench's full component props: the composer-right seat + locale + sessions hook. */
20
+ export type DataAgentWorkbenchProps = PropsRuntime<'conversation.input.right'> & PropsLocale<'data-agent'> & InjectFace<DataAgentWorkbenchInjected>;
21
21
  /** The database workbench body. */
22
22
  export declare function DataAgentWorkbench({ sessionId, useSessions, t }: DataAgentWorkbenchProps): import("react").JSX.Element | null;
@@ -1,8 +1,7 @@
1
1
  /**
2
2
  * Data Agent browser half, plugin entry: registers the database workbench
3
- * into the composer input dock (the strip ABOVE the input bar) for
4
- * data-agent sessions, and the `data-agent` dictionaries. The old
5
- * conversation-view tab is gone — the workbench lives inside the session.
3
+ * as a compact context-row control for data-agent sessions, and the
4
+ * `data-agent` dictionaries. The workbench itself opens in one Modal.
6
5
  * Connection state lives in the server-side connection store, so layout and
7
6
  * session switches never lose it — the view only mirrors what
8
7
  * `/plugins/data-agent/status` reports.
@@ -20,7 +19,7 @@ declare module '@deepseek-ai/dsh-client-ui-slots' {
20
19
  export declare const inject: string[];
21
20
  /**
22
21
  * Client plugin body: register the data-agent dictionaries and the database
23
- * workbench into the composer input dock. The registration rides the slot
22
+ * workbench trigger into the composer card's right control region. The registration rides the slot
24
23
  * service's effect wrapper, so plugin unload removes it.
25
24
  * @param ctx - client root context.
26
25
  */
@@ -40,6 +40,15 @@ export declare const zh: {
40
40
  'state.disconnected': string;
41
41
  'state.checking': string;
42
42
  'state.reconnecting': string;
43
+ 'workbench.open.connected': string;
44
+ 'workbench.open.disconnected': string;
45
+ 'workbench.open.checking': string;
46
+ 'workbench.open.error': string;
47
+ 'composer.placeholder.disconnected': string;
48
+ 'composer.placeholder.connected': string;
49
+ 'wb.workbench.title': string;
50
+ 'wb.workbench.description': string;
51
+ 'wb.workbench.tabs': string;
43
52
  'wb.schemas': string;
44
53
  'wb.tables': string;
45
54
  'wb.columns': string;
@@ -116,6 +125,15 @@ export declare const en: {
116
125
  'state.disconnected': string;
117
126
  'state.checking': string;
118
127
  'state.reconnecting': string;
128
+ 'workbench.open.connected': string;
129
+ 'workbench.open.disconnected': string;
130
+ 'workbench.open.checking': string;
131
+ 'workbench.open.error': string;
132
+ 'composer.placeholder.disconnected': string;
133
+ 'composer.placeholder.connected': string;
134
+ 'wb.workbench.title': string;
135
+ 'wb.workbench.description': string;
136
+ 'wb.workbench.tabs': string;
119
137
  'wb.schemas': string;
120
138
  'wb.tables': string;
121
139
  'wb.columns': string;
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Cross-platform database CLI discovery.
3
+ *
4
+ * The subprocess provider remains the authority for executable validation.
5
+ * This module only builds a bounded, platform-aware PATH fallback when the
6
+ * provider cannot resolve the configured/default bare command from its
7
+ * current execution environment. No shell, registry, or recursive scan is
8
+ * involved, and the exact discovery environment is returned for spawn.
9
+ * @module @yejiming/dsh-data-agent/client-discovery
10
+ */
11
+ import type { ClientConfig } from './clients.ts';
12
+ import type { DatabaseType } from './connections.ts';
13
+ /** Host facts are injectable so all supported platforms can be tested on one CI host. */
14
+ export interface ClientDiscoverySystem {
15
+ platform: NodeJS.Platform;
16
+ env: Readonly<Record<string, string | undefined>>;
17
+ homeDir: string;
18
+ cwd: string;
19
+ readDirectory(directory: string): Promise<readonly string[]>;
20
+ }
21
+ /** DSH subprocess executable resolver face. */
22
+ export type ExecutableResolver = (command: string, env?: Readonly<Record<string, string>>, signal?: AbortSignal) => Promise<string>;
23
+ /** A resolved executable plus the environment that must also be used for spawn. */
24
+ export interface ClientExecutableResolution {
25
+ executable: string;
26
+ env: Readonly<Record<string, string>>;
27
+ searchedDirectories: readonly string[];
28
+ }
29
+ /** Input for one database client resolution attempt. */
30
+ export interface ResolveClientExecutableOptions {
31
+ type: DatabaseType;
32
+ command: string;
33
+ config?: ClientConfig;
34
+ env: Readonly<Record<string, string>>;
35
+ signal: AbortSignal;
36
+ resolveExecutable: ExecutableResolver;
37
+ system?: ClientDiscoverySystem;
38
+ }
39
+ /** Build ordered fallback directories without recursively scanning the host. */
40
+ export declare function buildClientSearchDirectories(type: DatabaseType, config: ClientConfig | undefined, signal: AbortSignal, system?: ClientDiscoverySystem): Promise<string[]>;
41
+ /**
42
+ * Resolve one configured/default client. Current PATH (or an explicit path)
43
+ * always wins. Only a missing bare command activates bounded PATH discovery.
44
+ */
45
+ export declare function resolveClientExecutable(options: ResolveClientExecutableOptions): Promise<ClientExecutableResolution>;
@@ -45,25 +45,31 @@ export declare function sanitizeIdentifier(type: DatabaseType, identifier: strin
45
45
  /** One deployment override for a database type's CLI client. */
46
46
  export interface ClientConfig {
47
47
  /** Executable name (resolved through PATH) or absolute path. */
48
- command: string;
48
+ command?: string;
49
49
  /** Extra flag arguments prepended before the built-in flags. */
50
50
  args?: readonly string[];
51
+ /** Absolute directories searched after the current subprocess PATH. */
52
+ searchPaths?: readonly string[];
51
53
  }
52
54
  /** Loader schema for one client override (all fields optional at input). */
53
55
  export declare const clientConfigSchema: z<Schemastery.ObjectS<{
54
56
  command: z<string, string>;
55
57
  args: z<string[], string[]>;
58
+ searchPaths: z<string[], string[]>;
56
59
  }>, Schemastery.ObjectT<{
57
60
  command: z<string, string>;
58
61
  args: z<string[], string[]>;
62
+ searchPaths: z<string[], string[]>;
59
63
  }>>;
60
64
  /** Loader schema for the whole `clients` config object (any type key). */
61
65
  export declare const clientsSchema: z<import("cosmokit").Dict<{
62
66
  command?: string | null | undefined;
63
67
  args?: string[] | null | undefined;
68
+ searchPaths?: string[] | null | undefined;
64
69
  } & import("@deepseek-ai/cosmokit").Dict, string>, import("cosmokit").Dict<Schemastery.ObjectT<{
65
70
  command: z<string, string>;
66
71
  args: z<string[], string[]>;
72
+ searchPaths: z<string[], string[]>;
67
73
  }>, string>>;
68
74
  /**
69
75
  * A fully constructed client invocation: argv (command + flags, no SQL),
@@ -14,6 +14,8 @@ export declare const DEFAULT_INTROSPECT_MAX_TABLES = 500;
14
14
  export declare const DEFAULT_QUERY_TIMEOUT_MS = 30000;
15
15
  /** In-memory cap on database-tool captured output (stdout and stderr each). */
16
16
  export declare const DEFAULT_MAX_RESULT_CHARS = 20000;
17
+ /** Maximum structured rows returned by one database read tool call. */
18
+ export declare const DEFAULT_MAX_ROWS = 100;
17
19
  /** Cap on one /query SQL text length (abuse guard; the wire body stays small). */
18
20
  export declare const DEFAULT_MAX_QUERY_CHARS = 65536;
19
21
  /** Grace period for the subprocess terminate escalation. */
@@ -1,19 +1,22 @@
1
1
  /**
2
- * Data Agent server half for the dsh web GUI. The host row provides the
2
+ * Data Agent profile entry. The host row provides the
3
3
  * `dataAgentConnections` service (shared non-secret profile/binding storage;
4
4
  * temporary passwords stay process-local), seeds config connections (`connections`, `'*'` =
5
- * wildcard default), and installs the `data-agent` agent preset into
6
- * `$DSH_HOME/.agent-presets/` (idempotent, never overwrites a user-edited
7
- * directory).
5
+ * wildcard default), installs the `data-agent` agent preset into
6
+ * `$DSH_HOME/.agent-presets/`, and preloads the preset-scoped database tools
7
+ * and command through this profile bundle entry.
8
8
  *
9
9
  * The HTTP routes live in the separate `./routes` entry
10
10
  * (`@yejiming/dsh-data-agent/routes`, cordis row `data-agent-routes`) so
11
- * this row keeps working in headless profiles without a webserver; the
12
- * database tools themselves live in the `./tool` entry and are mounted only
13
- * by the data-agent preset.
11
+ * this row keeps working in headless profiles without a webserver. The
12
+ * database implementations still have public `./tool` and `./command`
13
+ * exports, but the shipped preset does not dynamically import those package
14
+ * subpaths. Loading them here keeps Desktop on the same profile-startup path
15
+ * as other UI bundles and avoids Electron ASAR package-resolution drift.
14
16
  * @module @yejiming/dsh-data-agent
15
17
  */
16
18
  import type { Context } from '@deepseek-ai/cordis';
19
+ import type { ScopeKey } from '@deepseek-ai/dsh-scope';
17
20
  /** The `dataAgentConnections` service face on the cordis context. */
18
21
  declare module '@deepseek-ai/cordis' {
19
22
  interface Context {
@@ -23,9 +26,10 @@ declare module '@deepseek-ai/cordis' {
23
26
  import z from 'schemastery';
24
27
  import { type DataAgentConnections, type DatabaseType } from './connections.ts';
25
28
  import { type ClientConfig } from './clients.ts';
29
+ import { type Config as ToolConfig } from './tool.ts';
26
30
  /** Cordis plugin name (diagnostics only). */
27
31
  export declare const name = "data-agent";
28
- /** Services required before the store can serve. */
32
+ /** Services required before the profile entry can mount its preset layer. */
29
33
  export declare const inject: string[];
30
34
  /** Deployment overrides for one database type's CLI client. */
31
35
  export type ClientsConfig = Partial<Record<DatabaseType, ClientConfig>>;
@@ -61,6 +65,8 @@ export interface Config {
61
65
  queryTimeoutMs: number;
62
66
  /** In-memory cap on database-tool captured output. */
63
67
  maxResultChars: number;
68
+ /** Maximum structured rows returned by one database read tool call. */
69
+ maxRows: number;
64
70
  /** Maximum SQL text accepted by the shared Web query adapter. */
65
71
  maxQueryChars: number;
66
72
  /** Default read-only guard: true rejects write statements in database tools and /query. */
@@ -80,15 +86,18 @@ export declare const Config: z<Schemastery.ObjectS<{
80
86
  introspectMaxTables: z<number, number>;
81
87
  queryTimeoutMs: z<number, number>;
82
88
  maxResultChars: z<number, number>;
89
+ maxRows: z<number, number>;
83
90
  maxQueryChars: z<number, number>;
84
91
  readonly: z<boolean, boolean>;
85
92
  persistConnections: z<boolean, boolean>;
86
93
  clients: z<import("cosmokit").Dict<{
87
94
  command?: string | null | undefined;
88
95
  args?: string[] | null | undefined;
96
+ searchPaths?: string[] | null | undefined;
89
97
  } & import("@deepseek-ai/cosmokit").Dict, string>, import("cosmokit").Dict<Schemastery.ObjectT<{
90
98
  command: z<string, string>;
91
99
  args: z<string[], string[]>;
100
+ searchPaths: z<string[], string[]>;
92
101
  }>, string>>;
93
102
  connections: z<import("cosmokit").Dict<{
94
103
  type?: "mysql" | "postgres" | "sqlite" | "oracle" | "hive" | "impala" | null | undefined;
@@ -116,15 +125,18 @@ export declare const Config: z<Schemastery.ObjectS<{
116
125
  introspectMaxTables: z<number, number>;
117
126
  queryTimeoutMs: z<number, number>;
118
127
  maxResultChars: z<number, number>;
128
+ maxRows: z<number, number>;
119
129
  maxQueryChars: z<number, number>;
120
130
  readonly: z<boolean, boolean>;
121
131
  persistConnections: z<boolean, boolean>;
122
132
  clients: z<import("cosmokit").Dict<{
123
133
  command?: string | null | undefined;
124
134
  args?: string[] | null | undefined;
135
+ searchPaths?: string[] | null | undefined;
125
136
  } & import("@deepseek-ai/cosmokit").Dict, string>, import("cosmokit").Dict<Schemastery.ObjectT<{
126
137
  command: z<string, string>;
127
138
  args: z<string[], string[]>;
139
+ searchPaths: z<string[], string[]>;
128
140
  }>, string>>;
129
141
  connections: z<import("cosmokit").Dict<{
130
142
  type?: "mysql" | "postgres" | "sqlite" | "oracle" | "hive" | "impala" | null | undefined;
@@ -153,21 +165,35 @@ export declare const Config: z<Schemastery.ObjectS<{
153
165
  export declare function resolveDshHome(env?: Record<string, string | undefined>): string;
154
166
  /**
155
167
  * Install the packaged `preset/data-agent/` directory into
156
- * `$DSH_HOME/.agent-presets/<presetId>/`. Idempotent: an existing target
157
- * directory is left untouched (user edits survive); `installPreset: false`
158
- * never calls this. Best-effort a failure logs a warning with manual
159
- * install instructions instead of failing the boot.
168
+ * `$DSH_HOME/.agent-presets/<presetId>/`. Idempotent: an existing target is
169
+ * normally left untouched. The exact package-owned 0.0.9 composition is
170
+ * migrated once because its two dynamic package rows are incompatible with
171
+ * DSH Desktop's unpacked-ASAR loader; user-edited compositions are never
172
+ * overwritten. `installPreset: false` never calls this. Best-effort — a
173
+ * failure logs a warning with manual install instructions instead of failing
174
+ * the boot.
160
175
  */
161
- export declare function installPreset(ctx: Context, presetId: string): Promise<void>;
176
+ export declare function installPreset(ctx: Context, presetId: string): Promise<boolean>;
177
+ /** Public for regression tests of the non-destructive preset migration gate. */
178
+ export declare function isLegacyManagedPreset(source: string): boolean;
162
179
  /** Exact profile-local package installation command used by diagnostics/docs. */
163
180
  export declare function profileInstallCommand(profile: string): string;
164
181
  /** Actionable diagnostic for a roster-visible preset whose profile lacks this package. */
165
182
  export declare function missingProfileDependencyMessage(profile: string): string;
183
+ /** Tool configuration inherited by the profile-preloaded preset capabilities. */
184
+ type PresetCapabilitiesConfig = Pick<ToolConfig, 'queryTimeoutMs' | 'maxResultChars' | 'maxRows' | 'maxQueryChars' | 'readonly' | 'clients'>;
166
185
  /**
167
- * Mount the data-agent host row: connection store, config-seeded
168
- * connections, and preset self-install. HTTP routes are the sibling
169
- * `data-agent-routes` row (`./routes`).
186
+ * Register the statically imported database tools and command under the exact
187
+ * standing key owned by the data-agent preset. Selecting the preset performs
188
+ * no package import and only links the agent scope to this key.
189
+ */
190
+ export declare function mountPresetCapabilities(ctx: Context, key: ScopeKey, scopeTag: symbol, config: PresetCapabilitiesConfig): Promise<void>;
191
+ /**
192
+ * Mount the data-agent profile row: connection store, config-seeded
193
+ * connections, preset installation, and profile-preloaded preset capabilities.
194
+ * HTTP routes are the sibling `data-agent-routes` row (`./routes`).
170
195
  * @param ctx - host cordis context.
171
196
  * @param config - validated loader configuration.
172
197
  */
173
198
  export declare function apply(ctx: Context, config: Config): Promise<void>;
199
+ export {};
@@ -6,22 +6,9 @@
6
6
  * in `DataAgentConnections`, which is also consumed by TUI commands/tools.
7
7
  * @module @yejiming/dsh-data-agent/routes
8
8
  */
9
- import type { IncomingMessage, ServerResponse } from 'node:http';
10
9
  import type { Context } from '@deepseek-ai/cordis';
11
10
  import z from 'schemastery';
12
11
  import type { DatabaseConnectionInput } from './connections.ts';
13
- interface WebServerLike {
14
- register(route: {
15
- kind: 'exact' | 'prefix';
16
- path: string;
17
- handler: (req: IncomingMessage, res: ServerResponse) => void | Promise<void>;
18
- }): () => void;
19
- }
20
- declare module '@deepseek-ai/cordis' {
21
- interface Context {
22
- webServer: WebServerLike;
23
- }
24
- }
25
12
  export declare const name = "data-agent-routes";
26
13
  /** Headless profiles activate this row without waiting forever for webServer. */
27
14
  export declare const inject: string[];
@@ -57,4 +44,3 @@ export interface ConnectRequestBody extends DatabaseConnectionInput {
57
44
  export declare function validateConnectBody(value: unknown, cwd?: string): ConnectRequestBody;
58
45
  /** Register Web routes only when both the webserver and shared service exist. */
59
46
  export declare function apply(ctx: Context, _config: Config): void;
60
- export {};
@@ -49,9 +49,11 @@ export declare const Config: z<Schemastery.ObjectS<{
49
49
  clients: z<import("cosmokit").Dict<{
50
50
  command?: string | null | undefined;
51
51
  args?: string[] | null | undefined;
52
+ searchPaths?: string[] | null | undefined;
52
53
  } & import("@deepseek-ai/cosmokit").Dict, string>, import("cosmokit").Dict<Schemastery.ObjectT<{
53
54
  command: z<string, string>;
54
55
  args: z<string[], string[]>;
56
+ searchPaths: z<string[], string[]>;
55
57
  }>, string>>;
56
58
  }>, Schemastery.ObjectT<{
57
59
  queryTimeoutMs: z<number, number>;
@@ -62,9 +64,11 @@ export declare const Config: z<Schemastery.ObjectS<{
62
64
  clients: z<import("cosmokit").Dict<{
63
65
  command?: string | null | undefined;
64
66
  args?: string[] | null | undefined;
67
+ searchPaths?: string[] | null | undefined;
65
68
  } & import("@deepseek-ai/cosmokit").Dict, string>, import("cosmokit").Dict<Schemastery.ObjectT<{
66
69
  command: z<string, string>;
67
70
  args: z<string[], string[]>;
71
+ searchPaths: z<string[], string[]>;
68
72
  }>, string>>;
69
73
  }>>;
70
74
  /**
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@yejiming/dsh-data-agent",
3
3
  "description": "Data Agent for DSH Web and TUI: shared database connections, a masked TUI form, secure credential references, SQL tools, and the data-agent preset",
4
- "version": "0.0.9",
4
+ "version": "0.0.10",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -79,6 +79,7 @@
79
79
  "peerDependencies": {
80
80
  "@deepseek-ai/cordis": "^4.0.1",
81
81
  "@deepseek-ai/dsh-agent": "^0.1.0-rc.6",
82
+ "@deepseek-ai/dsh-agent-presets": "^0.1.0-rc.6",
82
83
  "@deepseek-ai/dsh-client-locale": "^0.1.0-rc.6",
83
84
  "@deepseek-ai/dsh-client-runtime": "^0.1.0-rc.6",
84
85
  "@deepseek-ai/dsh-client-ui-conversation": "^0.1.0-rc.6",
@@ -89,6 +90,7 @@
89
90
  "@deepseek-ai/dsh-credentials": "^0.1.0-rc.6",
90
91
  "@deepseek-ai/dsh-host-webserver": "^0.1.0-rc.6",
91
92
  "@deepseek-ai/dsh-invariants": "^0.1.0-rc.6",
93
+ "@deepseek-ai/dsh-scope": "^0.1.0-rc.6",
92
94
  "@deepseek-ai/dsh-storage": "^0.1.0-rc.6",
93
95
  "@deepseek-ai/dsh-storage-domain": "^0.1.0-rc.6",
94
96
  "@deepseek-ai/dsh-storage-json": "^0.1.0-rc.6",
@@ -129,6 +131,7 @@
129
131
  "devDependencies": {
130
132
  "@deepseek-ai/cordis": "^4.0.1",
131
133
  "@deepseek-ai/dsh-agent": "^0.1.0-rc.6",
134
+ "@deepseek-ai/dsh-agent-presets": "^0.1.0-rc.6",
132
135
  "@deepseek-ai/dsh-client-locale": "^0.1.0-rc.6",
133
136
  "@deepseek-ai/dsh-client-runtime": "^0.1.0-rc.6",
134
137
  "@deepseek-ai/dsh-client-ui-conversation": "^0.1.0-rc.6",
@@ -139,6 +142,7 @@
139
142
  "@deepseek-ai/dsh-credentials": "^0.1.0-rc.6",
140
143
  "@deepseek-ai/dsh-host-webserver": "^0.1.0-rc.6",
141
144
  "@deepseek-ai/dsh-invariants": "^0.1.0-rc.6",
145
+ "@deepseek-ai/dsh-scope": "^0.1.0-rc.6",
142
146
  "@deepseek-ai/dsh-storage": "^0.1.0-rc.6",
143
147
  "@deepseek-ai/dsh-storage-domain": "^0.1.0-rc.6",
144
148
  "@deepseek-ai/dsh-storage-json": "^0.1.0-rc.6",
@@ -8,14 +8,13 @@
8
8
  # the registries themselves, the sandbox and approval stack, persistence, and
9
9
  # the model route.
10
10
  #
11
- # The database row below registers sql-query / sql-write / sql-cmd and the
12
- # editor row registers DSH's native str_replace_editor. The final row installs
13
- # a deny restriction for the host/community tools visible at preset mount, so
14
- # describe_image, ssh_*, bash, web, etc. stay unavailable while the four/five
15
- # tools owned by this standing scope remain visible to joined agents.
11
+ # The editor row registers DSH's native str_replace_editor. The database tools,
12
+ # /database command, and inherited-tool restriction are statically imported by
13
+ # the profile's `@yejiming/dsh-data-agent` bundle entry and registered under
14
+ # this preset's standing key. Selecting the preset therefore performs no
15
+ # dynamic import of this package (important for DSH Desktop's ASAR runtime).
16
16
  #
17
- # All four rows only CONSUME host services (the tools/commands registries,
18
- # filesystem, subprocess, and dataAgentConnections).
17
+ # Both rows only consume host services and remain safe for standing mounting.
19
18
 
20
19
  # ── identity ────────────────────────────────────────────────────────────────
21
20
 
@@ -45,21 +44,3 @@
45
44
  name: '@deepseek-ai/dsh-tool-str-replace-editor'
46
45
  config:
47
46
  maxOutputChars: 16000
48
-
49
- # ── database ────────────────────────────────────────────────────────────────
50
-
51
- # This package's database tool half; injects the host's subprocess service and
52
- # the dataAgentConnections connection store (see the data-agent host row).
53
- # Registers sql-query (structured read), sql-write (explicit write), and the
54
- # sql-cmd raw-terminal compatibility tool. When the host provides the webServer
55
- # service (Web profile), it additionally registers render-analysis directly
56
- # in this standing preset scope, so blank-session preset switches see it too.
57
- - id: tool-sql-cmd
58
- name: '@yejiming/dsh-data-agent/tool'
59
-
60
- # Human command surface consumed by dsh-tui and any other command adapter.
61
- # It is preset-scoped, recordInput=false, and adds no model-visible tools. It
62
- # also masks every host-global inherited model tool at the standing preset
63
- # scope. Sibling str_replace_editor/database registrations remain visible.
64
- - id: database-command
65
- name: '@yejiming/dsh-data-agent/command'
@@ -1,3 +1,3 @@
1
1
  name: 数据模式
2
- description: 数据工程师 Agent:连接 MySQL/PostgreSQL/SQLite 数据库,用 sql-query/sql-write/sql-cmd 与 DSH 原生 str_replace_editor 探查 schema、编写并执行 SQL;Web 界面还可由 Agent 自主调用 render-analysis 生成单图或多视图分析报告。
2
+ description: 连接数据库,用自然语言完成数据探索、SQL编写与业务分析。
3
3
  order: 4