@dsh-ft/dsh-fft-ftshare 0.0.0-stage → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +80 -2
  3. package/catalog.json +9762 -0
  4. package/catalog.meta.json +7 -0
  5. package/catalog.txt +250 -0
  6. package/cordis.patch.yml +27 -0
  7. package/lib/capabilities.d.ts +47 -0
  8. package/lib/capabilities.d.ts.map +1 -0
  9. package/lib/capabilities.js +145 -0
  10. package/lib/capabilities.js.map +1 -0
  11. package/lib/catalog-host.d.ts +19 -0
  12. package/lib/catalog-host.d.ts.map +1 -0
  13. package/lib/catalog-host.js +31 -0
  14. package/lib/catalog-host.js.map +1 -0
  15. package/lib/catalog.d.ts +51 -0
  16. package/lib/catalog.d.ts.map +1 -0
  17. package/lib/catalog.js +60 -0
  18. package/lib/catalog.js.map +1 -0
  19. package/lib/client.d.ts +52 -0
  20. package/lib/client.d.ts.map +1 -0
  21. package/lib/client.js +149 -0
  22. package/lib/client.js.map +1 -0
  23. package/lib/contract.d.ts +122 -0
  24. package/lib/contract.d.ts.map +1 -0
  25. package/lib/contract.js +24 -0
  26. package/lib/contract.js.map +1 -0
  27. package/lib/errors.d.ts +93 -0
  28. package/lib/errors.d.ts.map +1 -0
  29. package/lib/errors.js +261 -0
  30. package/lib/errors.js.map +1 -0
  31. package/lib/index.d.ts +64 -0
  32. package/lib/index.d.ts.map +1 -0
  33. package/lib/index.js +160 -0
  34. package/lib/index.js.map +1 -0
  35. package/lib/mask.d.ts +66 -0
  36. package/lib/mask.d.ts.map +1 -0
  37. package/lib/mask.js +106 -0
  38. package/lib/mask.js.map +1 -0
  39. package/lib/project.d.ts +98 -0
  40. package/lib/project.d.ts.map +1 -0
  41. package/lib/project.js +326 -0
  42. package/lib/project.js.map +1 -0
  43. package/lib/route.d.ts +48 -0
  44. package/lib/route.d.ts.map +1 -0
  45. package/lib/route.js +90 -0
  46. package/lib/route.js.map +1 -0
  47. package/lib/tools.d.ts +31 -0
  48. package/lib/tools.d.ts.map +1 -0
  49. package/lib/tools.js +132 -0
  50. package/lib/tools.js.map +1 -0
  51. package/lib/transport.d.ts +53 -0
  52. package/lib/transport.d.ts.map +1 -0
  53. package/lib/transport.js +147 -0
  54. package/lib/transport.js.map +1 -0
  55. package/package.json +91 -4
package/lib/route.js ADDED
@@ -0,0 +1,90 @@
1
+ /**
2
+ * 宿主助手:把 `ctx.ftshareData` 挂到跨平面路由上(**消费方自己挂**)。
3
+ *
4
+ * 底座不声明 `dsh.client` —— 它不是客户端面,只发布两段实现。需要浏览器取数的消费方
5
+ * 自己挂这一行:
6
+ *
7
+ * ```ts
8
+ * ctx.inject(['connection', 'ftshareData'], scope =>
9
+ * scope.effect(() => registerFtshareRoute(scope.ctx, scope.ftshareData), 'ftshare: /api route'))
10
+ * ```
11
+ *
12
+ * 路由是 `connection.fetch` 的**精确**路由,复用 `/api` 载体的 Host/Origin 围栏与
13
+ * 浏览器鉴权。契约(设计 §5.1):
14
+ *
15
+ * - **原样过桥**:成功就是一份 `FtshareCallResult`,`notice` 与 `upgradeUrl` 一起带,
16
+ * 面板才能把「没权限」渲染成「去升级」而不是「没有数据」;
17
+ * - **接口名校验**:只接受目录里的接口名,否则 400 —— 底座不能变成任意上游的穿透代理;
18
+ * - **取消与超时**:`request.signal` 原样转给 `call({ signal })`,面板的连点与切标的
19
+ * 因此能真的取消掉在途请求。
20
+ * @module @dsh-ft/dsh-fft-ftshare/route
21
+ */
22
+ import { catalogEntryOf, missingRequiredArgs } from './catalog.js';
23
+ import { loadCatalog } from './catalog-host.js';
24
+ import { FTSHARE_DATA_ROUTE } from './contract.js';
25
+ import { isRecord } from './errors.js';
26
+ /**
27
+ * 造一条只回答 `/api/ftshare-data` 的路由定义(纯函数,便于测试)。
28
+ * @param data - 宿主侧的 `ctx.ftshareData`。
29
+ * @returns 路由定义。
30
+ */
31
+ export function createFtshareRoute(data) {
32
+ return {
33
+ path: FTSHARE_DATA_ROUTE,
34
+ methods: ['POST'],
35
+ requestBody: 'buffered',
36
+ async fetch(request) {
37
+ const body = await readJsonBody(request);
38
+ if (body === undefined)
39
+ return errorResponse(400, 'bad_request', '请求体不是合法的 JSON 对象');
40
+ const name = typeof body.interface === 'string' ? body.interface.trim() : '';
41
+ const args = isRecord(body.args) ? body.args : undefined;
42
+ if (name === '')
43
+ return errorResponse(400, 'bad_request', '缺少 interface');
44
+ const entry = catalogEntryOf(loadCatalog(), name);
45
+ if (entry === undefined)
46
+ return errorResponse(400, 'unknown_interface', `接口 ${name} 不在目录里,不能直调`);
47
+ const missing = missingRequiredArgs(entry, args);
48
+ if (missing.length > 0)
49
+ return errorResponse(400, 'missing_arguments', `缺必填入参:${missing.join('、')}`);
50
+ const result = await data.call(name, args ?? {}, { signal: request.signal });
51
+ // 四态**原样**过桥:这里不翻译、不裁字段,面板与宿主看到同一份东西。
52
+ return json(200, result);
53
+ },
54
+ };
55
+ }
56
+ /**
57
+ * 注册路由;调用方自己决定挂在哪一层(返回值就是载体的 disposer)。
58
+ * @param ctx - 已经 inject 到 `connection` 的上下文。
59
+ * @param data - 宿主侧的 `ctx.ftshareData`。
60
+ * @returns 载体的注销函数,交给 `ctx.effect` 管。
61
+ */
62
+ export function registerFtshareRoute(ctx, data) {
63
+ const connection = ctx.get('connection');
64
+ const fetch = connection?.fetch;
65
+ if (fetch === undefined)
66
+ throw new Error('registerFtshareRoute 需要 connection.fetch:先把 connection inject 进来');
67
+ return fetch.register(createFtshareRoute(data));
68
+ }
69
+ /** 读一个 JSON 对象请求体;非法或非对象时 undefined。 */
70
+ async function readJsonBody(request) {
71
+ try {
72
+ const parsed = await request.json();
73
+ return isRecord(parsed) ? parsed : undefined;
74
+ }
75
+ catch {
76
+ return undefined;
77
+ }
78
+ }
79
+ /** 错误信封:客户端按 `error.code` / `error.message` 渲染成 `failed`。 */
80
+ function errorResponse(status, code, message) {
81
+ return json(status, { error: { code, message } });
82
+ }
83
+ /** JSON 应答。 */
84
+ function json(status, payload) {
85
+ return new Response(JSON.stringify(payload), {
86
+ status,
87
+ headers: { 'content-type': 'application/json' },
88
+ });
89
+ }
90
+ //# sourceMappingURL=route.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route.js","sourceRoot":"","sources":["../src/route.ts"],"names":[],"mappings":"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"}
package/lib/tools.d.ts ADDED
@@ -0,0 +1,31 @@
1
+ /**
2
+ * preset 平面:把接口表里带 `expose` 的条目注册成 `ctx.tools` 里的 `ftshare_*` 工具,
3
+ * 外加一个长尾入口 `ftshare_call`。
4
+ *
5
+ * 由 preset 行以子路径名 `@dsh-ft/dsh-fft-ftshare/tools` 挂载,因此这些工具只存在于
6
+ * 所选 preset 的 agent 作用域内(标准模式下不存在)。取数走全局平面提供的
7
+ * `ctx.ftshareData`,本平面不开连接、不碰凭据。
8
+ *
9
+ * 每个工具都把 {@link FtshareCallResult} 的四态结局原样印进正文:`denied` 说
10
+ * 「当前套餐无权访问」,`empty` 才说「没有记录」。这是 P8 的教训——两种结局不能
11
+ * 长得一样。
12
+ * @module @dsh-ft/dsh-fft-ftshare/tools
13
+ */
14
+ import type { Context } from '@deepseek-ai/cordis';
15
+ import { type Capability } from './capabilities.js';
16
+ export * from './capabilities.js';
17
+ export * from './catalog.js';
18
+ /** Cordis 插件名。 */
19
+ export declare const name = "@dsh-ft/dsh-fft-ftshare/tools";
20
+ /** 注册工具要 `tools`,取数要全局 plane 的 `ftshareData`。 */
21
+ export declare const inject: string[];
22
+ /** 接口表里要下发给模型的那部分(其余条目只供本仓程序调用)。 */
23
+ export declare const FTSHARE_EXPOSED_CAPABILITIES: readonly Capability[];
24
+ /** 长尾接口的通用直调工具名。 */
25
+ export declare const FTSHARE_CALL_TOOL = "ftshare_call";
26
+ /**
27
+ * 注册接口表里每一个暴露条目,外加一个通用直调。
28
+ * @param ctx - preset 子树的上下文。
29
+ */
30
+ export declare function apply(ctx: Context): void;
31
+ //# sourceMappingURL=tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAU,MAAM,qBAAqB,CAAA;AAI1D,OAAO,EAAwB,KAAK,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAMzE,cAAc,mBAAmB,CAAA;AACjC,cAAc,cAAc,CAAA;AAE5B,kBAAkB;AAClB,eAAO,MAAM,IAAI,kCAAkC,CAAA;AAEnD,iDAAiD;AACjD,eAAO,MAAM,MAAM,UAA2B,CAAA;AAwB9C,oCAAoC;AACpC,eAAO,MAAM,4BAA4B,EAAE,SAAS,UAAU,EACI,CAAA;AAElE,oBAAoB;AACpB,eAAO,MAAM,iBAAiB,iBAAiB,CAAA;AAE/C;;;GAGG;AACH,wBAAgB,KAAK,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI,CAIxC"}
package/lib/tools.js ADDED
@@ -0,0 +1,132 @@
1
+ /**
2
+ * preset 平面:把接口表里带 `expose` 的条目注册成 `ctx.tools` 里的 `ftshare_*` 工具,
3
+ * 外加一个长尾入口 `ftshare_call`。
4
+ *
5
+ * 由 preset 行以子路径名 `@dsh-ft/dsh-fft-ftshare/tools` 挂载,因此这些工具只存在于
6
+ * 所选 preset 的 agent 作用域内(标准模式下不存在)。取数走全局平面提供的
7
+ * `ctx.ftshareData`,本平面不开连接、不碰凭据。
8
+ *
9
+ * 每个工具都把 {@link FtshareCallResult} 的四态结局原样印进正文:`denied` 说
10
+ * 「当前套餐无权访问」,`empty` 才说「没有记录」。这是 P8 的教训——两种结局不能
11
+ * 长得一样。
12
+ * @module @dsh-ft/dsh-fft-ftshare/tools
13
+ */
14
+ import { defineTool } from '@deepseek-ai/dsh-tools';
15
+ import { FTSHARE_CAPABILITIES } from './capabilities.js';
16
+ import { catalogEntryOf, missingRequiredArgs } from './catalog.js';
17
+ import { FTSHARE_CATALOG_INDEX_PATH, loadCatalog } from './catalog-host.js';
18
+ import { isRecord } from './errors.js';
19
+ import { renderCallResult } from './project.js';
20
+ export * from './capabilities.js';
21
+ export * from './catalog.js';
22
+ /** Cordis 插件名。 */
23
+ export const name = '@dsh-ft/dsh-fft-ftshare/tools';
24
+ /** 注册工具要 `tools`,取数要全局 plane 的 `ftshareData`。 */
25
+ export const inject = ['tools', 'ftshareData'];
26
+ /**
27
+ * 工具的规范化输出:渲染好的正文加四态结局。
28
+ *
29
+ * 结局单独留一个字段,是为了让 `presentResult` 之类的消费者将来能按状态取样式,
30
+ * 而不必再解析正文。
31
+ */
32
+ const outputSchema = {
33
+ type: 'object',
34
+ additionalProperties: false,
35
+ properties: {
36
+ tool: { type: 'string' },
37
+ state: { type: 'string' },
38
+ text: { type: 'string' },
39
+ },
40
+ };
41
+ /** 所有 `ftshare_*` 工具共用的输出:正文加四态结局。 */
42
+ const toolOutput = {
43
+ schema: outputSchema,
44
+ render: (_args, value) => [{ type: 'text', text: value.text ?? '' }],
45
+ };
46
+ /** 接口表里要下发给模型的那部分(其余条目只供本仓程序调用)。 */
47
+ export const FTSHARE_EXPOSED_CAPABILITIES = FTSHARE_CAPABILITIES.filter(entry => entry.expose !== undefined);
48
+ /** 长尾接口的通用直调工具名。 */
49
+ export const FTSHARE_CALL_TOOL = 'ftshare_call';
50
+ /**
51
+ * 注册接口表里每一个暴露条目,外加一个通用直调。
52
+ * @param ctx - preset 子树的上下文。
53
+ */
54
+ export function apply(ctx) {
55
+ const logger = ctx.logger('dsh-fft-ftshare-tools');
56
+ for (const entry of FTSHARE_EXPOSED_CAPABILITIES)
57
+ register(ctx, logger, entry);
58
+ registerCatalogTool(ctx, logger);
59
+ }
60
+ /**
61
+ * 注册单个接口表条目。
62
+ * @param ctx - preset 子树的上下文。
63
+ * @param logger - 具名 logger。
64
+ * @param entry - 带 `expose` 的接口表条目。
65
+ */
66
+ function register(ctx, logger, entry) {
67
+ const exposed = entry.expose;
68
+ if (exposed === undefined)
69
+ return;
70
+ ctx.tools.register(defineTool({
71
+ name: exposed.name,
72
+ description: `${entry.title}。${exposed.description}`,
73
+ parameters: entry.args,
74
+ output: toolOutput,
75
+ async execute(args, exec) {
76
+ const result = await ctx.ftshareData.call(entry.interface, (args ?? {}), { signal: exec.signal });
77
+ if (result.state === 'denied' || result.state === 'failed') {
78
+ logger.warn('ftshare.tool_result', { tool: entry.interface, state: result.state, code: result.notice?.code });
79
+ }
80
+ return { tool: entry.interface, state: result.state, text: renderCallResult(entry.title, entry.interface, result) };
81
+ },
82
+ }));
83
+ }
84
+ /**
85
+ * 注册通用直调:`ftshare_call(interface, args)`。
86
+ *
87
+ * 它是长尾接口的唯一入口——一个工具定义换掉 250 份 schema。三种结局各有各的话:
88
+ * 名字不在目录(给出索引文件路径,让模型去 `grep`,而不是猜第二个名字)、套餐无权
89
+ * (由 {@link renderCallResult} 带上升级入口)、配额用尽(由 errors 层附文案)。
90
+ * @param ctx - preset 子树的上下文。
91
+ * @param logger - 具名 logger。
92
+ */
93
+ function registerCatalogTool(ctx, logger) {
94
+ ctx.tools.register(defineTool({
95
+ name: FTSHARE_CALL_TOOL,
96
+ description: `直调 FTShare 目录里的任意接口。不要猜接口名:先在 ${FTSHARE_CATALOG_INDEX_PATH} 里 grep `
97
+ + '(一行一个接口,格式 `接口名 | 标题 | 入参名`,带 * 的是必填),目录之外的名字会被拒绝。',
98
+ parameters: {
99
+ interface: { type: 'string', description: '上游接口名,必须来自目录索引', required: true },
100
+ args: { type: 'object', additionalProperties: true, description: '接口入参;必填项见目录索引里带 * 的名字' },
101
+ },
102
+ output: toolOutput,
103
+ async execute(args, exec) {
104
+ const call = isRecord(args) ? args : {};
105
+ const interfaceName = typeof call.interface === 'string' ? call.interface.trim() : '';
106
+ const callArgs = isRecord(call.args) ? call.args : {};
107
+ const entry = catalogEntryOf(loadCatalog(), interfaceName);
108
+ if (entry === undefined) {
109
+ return {
110
+ tool: interfaceName,
111
+ state: 'failed',
112
+ text: `目录里没有接口 ${interfaceName === '' ? '(未给名字)' : interfaceName},不能直调。`
113
+ + `先在 ${FTSHARE_CATALOG_INDEX_PATH} 里 grep 一下:一行一个接口,格式「接口名 | 标题 | 入参名」。`,
114
+ };
115
+ }
116
+ const missing = missingRequiredArgs(entry, callArgs);
117
+ if (missing.length > 0) {
118
+ return {
119
+ tool: entry.name,
120
+ state: 'failed',
121
+ text: `缺必填入参:${missing.join('、')}。${entry.name} 的必填项见目录索引里带 * 的名字。`,
122
+ };
123
+ }
124
+ const result = await ctx.ftshareData.call(entry.name, callArgs, { signal: exec.signal });
125
+ if (result.state === 'denied' || result.state === 'failed') {
126
+ logger.warn('ftshare.tool_result', { tool: entry.name, state: result.state, code: result.notice?.code });
127
+ }
128
+ return { tool: entry.name, state: result.state, text: renderCallResult(entry.title, entry.name, result) };
129
+ },
130
+ }));
131
+ }
132
+ //# sourceMappingURL=tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.js","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * 出站传输:到 FTShare 网关的 StreamableHTTP MCP 会话。
3
+ *
4
+ * 两件事值得记下来:
5
+ *
6
+ * 1. **凭据只从 `ctx.ftshareSettings.apiKey.resolve()` 取**,绝不自己读
7
+ * `~/.dsh/.credentials.yaml`。设置服务是凭据的唯一入口,它还要负责把「用户
8
+ * 在设置页填的 Key」和「环境变量回退」按同一优先级合起来;绕过它就会出现
9
+ * 「设置页显示已配置、实际取数用的是另一个 Key」这类无法排查的分歧。
10
+ * 2. **每次调用开一个新会话**(`initialize` → `callTool` → `close`)。会话里带
11
+ * 着凭据,缓存会话就等于缓存秘密,而设置契约要求「每次操作重新 resolve」;
12
+ * 连接成本换正确性是划算的,这条与投研舱的既有做法一致。
13
+ * @module @dsh-ft/dsh-fft-ftshare/transport
14
+ */
15
+ import type { Logger } from '@deepseek-ai/cordis';
16
+ import type { FtshareToolInfo } from './contract.js';
17
+ /** 默认网关地址:FTShare 的 MCP StreamableHTTP 入口。 */
18
+ export declare const FTSHARE_GATEWAY_ENDPOINT = "https://market.ft.tech/gateway/mcp";
19
+ /** 承载 API Key 的请求头名。 */
20
+ export declare const FTSHARE_API_KEY_HEADER = "FTSHARE_API_KEY";
21
+ /** 一次上游调用的原始结果。`value` 是上游自己的结构化载荷,未做任何解释。 */
22
+ export interface FtshareTransportResult {
23
+ value: unknown;
24
+ }
25
+ /** 传输层:与传输实现无关的最小面,便于测试注入假实现。 */
26
+ export interface FtshareTransport {
27
+ /** 调一个上游工具;上游报错时抛异常(由调用方归一)。 */
28
+ call(tool: string, args: Record<string, unknown>, options?: {
29
+ signal?: AbortSignal;
30
+ }): Promise<FtshareTransportResult>;
31
+ /** 上游工具清单;上游不可达时抛异常。 */
32
+ listTools(): Promise<readonly FtshareToolInfo[]>;
33
+ }
34
+ /** 建传输层所需的依赖。 */
35
+ export interface FtshareTransportOptions {
36
+ /** 网关地址,默认 {@link FTSHARE_GATEWAY_ENDPOINT}。 */
37
+ endpoint?: string;
38
+ /** 每次操作重新取凭据;返回空串/undefined 表示未配置。 */
39
+ resolveApiKey: () => Promise<string | undefined>;
40
+ /** 具名 logger;不传则不记录。 */
41
+ logger?: Logger;
42
+ /** MCP 客户端自称的名字,只影响上游日志。 */
43
+ clientName?: string;
44
+ /** MCP 客户端版本。 */
45
+ clientVersion?: string;
46
+ }
47
+ /**
48
+ * 建一个到 FTShare 网关的传输层。
49
+ * @param options - 见 {@link FtshareTransportOptions}。
50
+ * @returns 传输层实现。
51
+ */
52
+ export declare function createFtshareTransport(options: FtshareTransportOptions): FtshareTransport;
53
+ //# sourceMappingURL=transport.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAKjD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAGpD,8CAA8C;AAC9C,eAAO,MAAM,wBAAwB,uCAAuC,CAAA;AAE5E,wBAAwB;AACxB,eAAO,MAAM,sBAAsB,oBAAoB,CAAA;AAEvD,8CAA8C;AAC9C,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,OAAO,CAAA;CACf;AAED,iCAAiC;AACjC,MAAM,WAAW,gBAAgB;IAC/B,gCAAgC;IAChC,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,WAAW,CAAA;KAAE,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAAA;IACtH,wBAAwB;IACxB,SAAS,IAAI,OAAO,CAAC,SAAS,eAAe,EAAE,CAAC,CAAA;CACjD;AAED,iBAAiB;AACjB,MAAM,WAAW,uBAAuB;IACtC,gDAAgD;IAChD,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,sCAAsC;IACtC,aAAa,EAAE,MAAM,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAA;IAChD,wBAAwB;IACxB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,4BAA4B;IAC5B,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,iBAAiB;IACjB,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAyCD;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,uBAAuB,GAAG,gBAAgB,CA6EzF"}
@@ -0,0 +1,147 @@
1
+ /**
2
+ * 出站传输:到 FTShare 网关的 StreamableHTTP MCP 会话。
3
+ *
4
+ * 两件事值得记下来:
5
+ *
6
+ * 1. **凭据只从 `ctx.ftshareSettings.apiKey.resolve()` 取**,绝不自己读
7
+ * `~/.dsh/.credentials.yaml`。设置服务是凭据的唯一入口,它还要负责把「用户
8
+ * 在设置页填的 Key」和「环境变量回退」按同一优先级合起来;绕过它就会出现
9
+ * 「设置页显示已配置、实际取数用的是另一个 Key」这类无法排查的分歧。
10
+ * 2. **每次调用开一个新会话**(`initialize` → `callTool` → `close`)。会话里带
11
+ * 着凭据,缓存会话就等于缓存秘密,而设置契约要求「每次操作重新 resolve」;
12
+ * 连接成本换正确性是划算的,这条与投研舱的既有做法一致。
13
+ * @module @dsh-ft/dsh-fft-ftshare/transport
14
+ */
15
+ import { Client } from '@modelcontextprotocol/sdk/client/index.js';
16
+ import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
17
+ import { asText, isRecord } from './errors.js';
18
+ /** 默认网关地址:FTShare 的 MCP StreamableHTTP 入口。 */
19
+ export const FTSHARE_GATEWAY_ENDPOINT = 'https://market.ft.tech/gateway/mcp';
20
+ /** 承载 API Key 的请求头名。 */
21
+ export const FTSHARE_API_KEY_HEADER = 'FTSHARE_API_KEY';
22
+ /**
23
+ * 从 MCP 调用的错误结果里取出可读文本。
24
+ * @param content - `callTool` 返回的 content 数组。
25
+ * @param fallback - 取不到文本时的说明。
26
+ * @returns 多块文本以换行拼接。
27
+ */
28
+ function errorTextFromContent(content, fallback) {
29
+ if (!Array.isArray(content))
30
+ return fallback;
31
+ const text = content
32
+ .filter((block) => isRecord(block) && block.type === 'text' && typeof block.text === 'string')
33
+ .map(block => block.text)
34
+ .join('\n')
35
+ .trim();
36
+ return text === '' ? fallback : text;
37
+ }
38
+ /**
39
+ * 选一次调用的结构化载荷:优先 `structuredContent`,缺失时退回把文本当 JSON 解析。
40
+ *
41
+ * `dsh-kline` 两个都给;只给文本的上游也不该被判成空结果。
42
+ * @param result - `callTool` 的返回。
43
+ * @param tool - 工具名,仅用于日志。
44
+ * @param logger - 具名 logger。
45
+ * @returns 结构化载荷;两者都没有时为 undefined。
46
+ */
47
+ function payloadOf(result, tool, logger) {
48
+ const record = isRecord(result) ? result : {};
49
+ if (isRecord(record.structuredContent))
50
+ return record.structuredContent;
51
+ const text = errorTextFromContent(record.content, '');
52
+ if (text !== '' && /^[[{]/u.test(text)) {
53
+ try {
54
+ return JSON.parse(text);
55
+ }
56
+ catch {
57
+ logger?.warn('ftshare.invalid_json_payload', { tool });
58
+ }
59
+ }
60
+ return record.structuredContent ?? undefined;
61
+ }
62
+ /**
63
+ * 建一个到 FTShare 网关的传输层。
64
+ * @param options - 见 {@link FtshareTransportOptions}。
65
+ * @returns 传输层实现。
66
+ */
67
+ export function createFtshareTransport(options) {
68
+ const endpoint = options.endpoint?.trim() || FTSHARE_GATEWAY_ENDPOINT;
69
+ const clientName = options.clientName ?? 'dsh-fft-ftshare';
70
+ const clientVersion = options.clientVersion ?? '0.1.0';
71
+ /**
72
+ * 开一个已握手的会话;调用方负责关闭。
73
+ * @returns 已连接的 MCP 客户端。
74
+ */
75
+ async function connect() {
76
+ const headers = {};
77
+ const apiKey = asText(await options.resolveApiKey());
78
+ // 未配置时不带该头:网关会以「未携带 API Key」拒绝,比伪造一个空 Key 更可诊断。
79
+ if (apiKey !== undefined)
80
+ headers[FTSHARE_API_KEY_HEADER] = apiKey;
81
+ const client = new Client({ name: clientName, version: clientVersion });
82
+ const transport = new StreamableHTTPClientTransport(new URL(endpoint), { requestInit: { headers } });
83
+ await client.connect(transport);
84
+ return client;
85
+ }
86
+ return {
87
+ async call(tool, args, callOptions) {
88
+ const signal = callOptions?.signal;
89
+ if (signal?.aborted === true)
90
+ throw new Error(`FTShare ${tool} 调用前已被取消`);
91
+ const startedAt = Date.now();
92
+ const client = await connect();
93
+ try {
94
+ const result = await client.callTool({ name: tool, arguments: args }, undefined, {
95
+ ...signal !== undefined ? { signal } : {},
96
+ });
97
+ if (result.isError === true) {
98
+ // 抛出一段文本:归一器既能读其中的 JSON 码,也能读纯文案。
99
+ throw new Error(errorTextFromContent(result.content, `${tool} 返回 MCP 错误`));
100
+ }
101
+ const value = payloadOf(result, tool, options.logger);
102
+ if (value === undefined)
103
+ throw new Error(`${tool} 未返回 structuredContent,也没有可解析的文本载荷`);
104
+ return { value };
105
+ }
106
+ catch (error) {
107
+ options.logger?.warn('ftshare.call_failed', {
108
+ tool,
109
+ durationMs: Date.now() - startedAt,
110
+ message: error instanceof Error ? error.message : String(error),
111
+ });
112
+ throw error;
113
+ }
114
+ finally {
115
+ await client.close().catch(() => undefined);
116
+ }
117
+ },
118
+ async listTools() {
119
+ const client = await connect();
120
+ try {
121
+ const listed = await client.listTools();
122
+ const tools = [];
123
+ for (const entry of Array.isArray(listed.tools) ? listed.tools : []) {
124
+ if (!isRecord(entry))
125
+ continue;
126
+ const tool = asText(entry.name);
127
+ if (tool === undefined)
128
+ continue;
129
+ const description = asText(entry.description);
130
+ tools.push({
131
+ tool,
132
+ title: asText(entry.title) ?? tool,
133
+ // 目录产物(`catalog.json` / `catalog.txt`)就是这两项生成的:少了它们
134
+ // 目录只能给名字,模型没法判断该调哪个接口、要传什么。
135
+ ...description !== undefined ? { description } : {},
136
+ ...entry.inputSchema !== undefined ? { inputSchema: entry.inputSchema } : {},
137
+ });
138
+ }
139
+ return tools;
140
+ }
141
+ finally {
142
+ await client.close().catch(() => undefined);
143
+ }
144
+ },
145
+ };
146
+ }
147
+ //# sourceMappingURL=transport.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transport.js","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAA;AAClE,OAAO,EAAE,6BAA6B,EAAE,MAAM,oDAAoD,CAAA;AAIlG,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAE9C,8CAA8C;AAC9C,MAAM,CAAC,MAAM,wBAAwB,GAAG,oCAAoC,CAAA;AAE5E,wBAAwB;AACxB,MAAM,CAAC,MAAM,sBAAsB,GAAG,iBAAiB,CAAA;AA6BvD;;;;;GAKG;AACH,SAAS,oBAAoB,CAAC,OAAgB,EAAE,QAAgB;IAC9D,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC;QAAE,OAAO,QAAQ,CAAA;IAC5C,MAAM,IAAI,GAAG,OAAO;SACjB,MAAM,CAAC,CAAC,KAAK,EAA2C,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,IAAI,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,CAAC;SACtI,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC;SACxB,IAAI,CAAC,IAAI,CAAC;SACV,IAAI,EAAE,CAAA;IACT,OAAO,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAA;AACtC,CAAC;AAED;;;;;;;;GAQG;AACH,SAAS,SAAS,CAAC,MAAe,EAAE,IAAY,EAAE,MAAe;IAC/D,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAA;IAC7C,IAAI,QAAQ,CAAC,MAAM,CAAC,iBAAiB,CAAC;QAAE,OAAO,MAAM,CAAC,iBAAiB,CAAA;IACvE,MAAM,IAAI,GAAG,oBAAoB,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,CAAC,CAAA;IACrD,IAAI,IAAI,KAAK,EAAE,IAAI,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QACvC,IAAI,CAAC;YACH,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;QACzB,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,EAAE,IAAI,CAAC,8BAA8B,EAAE,EAAE,IAAI,EAAE,CAAC,CAAA;QACxD,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC,iBAAiB,IAAI,SAAS,CAAA;AAC9C,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,sBAAsB,CAAC,OAAgC;IACrE,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,EAAE,IAAI,EAAE,IAAI,wBAAwB,CAAA;IACrE,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,iBAAiB,CAAA;IAC1D,MAAM,aAAa,GAAG,OAAO,CAAC,aAAa,IAAI,OAAO,CAAA;IAEtD;;;OAGG;IACH,KAAK,UAAU,OAAO;QACpB,MAAM,OAAO,GAA2B,EAAE,CAAA;QAC1C,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,OAAO,CAAC,aAAa,EAAE,CAAC,CAAA;QACpD,gDAAgD;QAChD,IAAI,MAAM,KAAK,SAAS;YAAE,OAAO,CAAC,sBAAsB,CAAC,GAAG,MAAM,CAAA;QAClE,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,aAAa,EAAE,CAAC,CAAA;QACvE,MAAM,SAAS,GAAG,IAAI,6BAA6B,CACjD,IAAI,GAAG,CAAC,QAAQ,CAAC,EACjB,EAAE,WAAW,EAAE,EAAE,OAAO,EAAE,EAAE,CACL,CAAA;QACzB,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;QAC/B,OAAO,MAAM,CAAA;IACf,CAAC;IAED,OAAO;QACL,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,WAAW;YAChC,MAAM,MAAM,GAAG,WAAW,EAAE,MAAM,CAAA;YAClC,IAAI,MAAM,EAAE,OAAO,KAAK,IAAI;gBAAE,MAAM,IAAI,KAAK,CAAC,WAAW,IAAI,UAAU,CAAC,CAAA;YACxE,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;YAC5B,MAAM,MAAM,GAAG,MAAM,OAAO,EAAE,CAAA;YAC9B,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE;oBAC/E,GAAG,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE;iBAC1C,CAAC,CAAA;gBACF,IAAI,MAAM,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC;oBAC5B,kCAAkC;oBAClC,MAAM,IAAI,KAAK,CAAC,oBAAoB,CAAC,MAAM,CAAC,OAAO,EAAE,GAAG,IAAI,YAAY,CAAC,CAAC,CAAA;gBAC5E,CAAC;gBACD,MAAM,KAAK,GAAG,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,CAAA;gBACrD,IAAI,KAAK,KAAK,SAAS;oBAAE,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,oCAAoC,CAAC,CAAA;gBACrF,OAAO,EAAE,KAAK,EAAE,CAAA;YAClB,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,qBAAqB,EAAE;oBAC1C,IAAI;oBACJ,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS;oBAClC,OAAO,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;iBAChE,CAAC,CAAA;gBACF,MAAM,KAAK,CAAA;YACb,CAAC;oBAAS,CAAC;gBACT,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAA;YAC7C,CAAC;QACH,CAAC;QAED,KAAK,CAAC,SAAS;YACb,MAAM,MAAM,GAAG,MAAM,OAAO,EAAE,CAAA;YAC9B,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,SAAS,EAAE,CAAA;gBACvC,MAAM,KAAK,GAAsB,EAAE,CAAA;gBACnC,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;oBACpE,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;wBAAE,SAAQ;oBAC9B,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;oBAC/B,IAAI,IAAI,KAAK,SAAS;wBAAE,SAAQ;oBAChC,MAAM,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,CAAA;oBAC7C,KAAK,CAAC,IAAI,CAAC;wBACT,IAAI;wBACJ,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,IAAI;wBAClC,oDAAoD;wBACpD,6BAA6B;wBAC7B,GAAG,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE;wBACnD,GAAG,KAAK,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE;qBAC7E,CAAC,CAAA;gBACJ,CAAC;gBACD,OAAO,KAAK,CAAA;YACd,CAAC;oBAAS,CAAC;gBACT,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAA;YAC7C,CAAC;QACH,CAAC;KACF,CAAA;AACH,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,93 @@
1
1
  {
2
2
  "name": "@dsh-ft/dsh-fft-ftshare",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.3.0",
4
+ "description": "FTShare 数据底座:全 bundle 唯一出站、一处四态归一、一处模型可见面,并随包发布上游接口目录。",
5
+ "type": "module",
6
+ "main": "lib/index.js",
7
+ "types": "lib/index.d.ts",
8
+ "license": "MIT",
9
+ "homepage": "https://github.com/gigaflw/dsh-fft-bundle/tree/dev/packages/dsh-fft-ftshare#readme",
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "git+https://github.com/gigaflw/dsh-fft-bundle.git",
13
+ "directory": "packages/dsh-fft-ftshare"
14
+ },
15
+ "bugs": {
16
+ "url": "https://github.com/gigaflw/dsh-fft-bundle/issues"
17
+ },
18
+ "keywords": [
19
+ "dsh-plugin",
20
+ "deepseek-harness",
21
+ "ftshare",
22
+ "mcp"
23
+ ],
24
+ "exports": {
25
+ ".": {
26
+ "types": "./lib/index.d.ts",
27
+ "default": "./lib/index.js"
28
+ },
29
+ "./contract": {
30
+ "types": "./lib/contract.d.ts",
31
+ "default": "./lib/contract.js"
32
+ },
33
+ "./catalog": {
34
+ "types": "./lib/catalog.d.ts",
35
+ "default": "./lib/catalog.js"
36
+ },
37
+ "./tools": {
38
+ "types": "./lib/tools.d.ts",
39
+ "default": "./lib/tools.js"
40
+ },
41
+ "./mask": {
42
+ "types": "./lib/mask.d.ts",
43
+ "default": "./lib/mask.js"
44
+ },
45
+ "./project": {
46
+ "types": "./lib/project.d.ts",
47
+ "default": "./lib/project.js"
48
+ },
49
+ "./route": {
50
+ "types": "./lib/route.d.ts",
51
+ "default": "./lib/route.js"
52
+ },
53
+ "./client": {
54
+ "types": "./lib/client.d.ts",
55
+ "default": "./lib/client.js"
56
+ },
57
+ "./catalog.json": "./catalog.json",
58
+ "./cordis.patch.yml": "./cordis.patch.yml",
59
+ "./package.json": "./package.json"
60
+ },
61
+ "files": [
62
+ "lib",
63
+ "catalog.json",
64
+ "catalog.txt",
65
+ "catalog.meta.json",
66
+ "README.md",
67
+ "LICENSE",
68
+ "cordis.patch.yml",
69
+ "package.json"
70
+ ],
71
+ "publishConfig": {
72
+ "access": "public"
73
+ },
74
+ "dependencies": {
75
+ "@modelcontextprotocol/sdk": "^1.30.0"
76
+ },
77
+ "peerDependencies": {
78
+ "@deepseek-ai/cordis": "^4.0.2",
79
+ "@deepseek-ai/dsh-llm": ">=0.2.0-rc.2",
80
+ "@deepseek-ai/dsh-tools": ">=0.2.0-rc.2"
81
+ },
82
+ "engines": {
83
+ "node": ">=22.19.0"
84
+ },
85
+ "dsh": {
86
+ "bundle": {
87
+ "patch": "./cordis.patch.yml"
88
+ },
89
+ "engines": {
90
+ "dsh": ">=0.2.0-rc.2"
91
+ }
92
+ }
93
+ }