@skillfm/local 2.0.9 → 2.1.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.
- package/README.md +44 -10
- package/dist/agent-hints.js +8 -8
- package/dist/agent-hints.js.map +1 -1
- package/dist/doctor.js +3 -3
- package/dist/index.js +1 -1
- package/dist/mcp-stdio/api-client.d.ts +28 -0
- package/dist/mcp-stdio/api-client.d.ts.map +1 -0
- package/dist/mcp-stdio/api-client.js +123 -0
- package/dist/mcp-stdio/api-client.js.map +1 -0
- package/dist/mcp-stdio/bin.d.ts +3 -0
- package/dist/mcp-stdio/bin.d.ts.map +1 -0
- package/dist/mcp-stdio/bin.js +18 -0
- package/dist/mcp-stdio/bin.js.map +1 -0
- package/dist/mcp-stdio/config.d.ts +6 -0
- package/dist/mcp-stdio/config.d.ts.map +1 -0
- package/dist/mcp-stdio/config.js +26 -0
- package/dist/mcp-stdio/config.js.map +1 -0
- package/dist/mcp-stdio/render-flow.d.ts +53 -0
- package/dist/mcp-stdio/render-flow.d.ts.map +1 -0
- package/dist/mcp-stdio/render-flow.js +70 -0
- package/dist/mcp-stdio/render-flow.js.map +1 -0
- package/dist/mcp-stdio/request-context.d.ts +30 -0
- package/dist/mcp-stdio/request-context.d.ts.map +1 -0
- package/dist/mcp-stdio/request-context.js +78 -0
- package/dist/mcp-stdio/request-context.js.map +1 -0
- package/dist/mcp-stdio/server.d.ts +19 -0
- package/dist/mcp-stdio/server.d.ts.map +1 -0
- package/dist/mcp-stdio/server.js +651 -0
- package/dist/mcp-stdio/server.js.map +1 -0
- package/dist/skill-md/template.js +4 -4
- package/package.json +8 -4
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
// RequestContext — 每请求独立的客户端上下文,HTTP Streamable 模式下使用。
|
|
2
|
+
//
|
|
3
|
+
// 为什么需要这个?
|
|
4
|
+
// stdio 模式是单租户进程,全局 config + 全局 conv-state 没问题。
|
|
5
|
+
// HTTP 模式是多租户(多个 agent 带各自的 Bearer 打到同一个 process),
|
|
6
|
+
// 必须按 brainKey 隔离出站状态,避免 conv-state bleed across agents。
|
|
7
|
+
//
|
|
8
|
+
// 设计:
|
|
9
|
+
// - RequestContext 不可变 (per-request frozen)
|
|
10
|
+
// - ConvStateStore 是 brainKey → {state, feedback} 的 Map
|
|
11
|
+
// - LRU-ish cap(512 条)防止内存无界增长;真出问题再换 Redis
|
|
12
|
+
//
|
|
13
|
+
// BYOK 红线 (Principle 24): 这里永不读/存任何 LLM key, 只存平台自己的 brainKey + JWT。
|
|
14
|
+
const MAX_ENTRIES = 512;
|
|
15
|
+
export class ConvStateStore {
|
|
16
|
+
map = new Map();
|
|
17
|
+
getHandle(brainKey) {
|
|
18
|
+
const store = this;
|
|
19
|
+
return {
|
|
20
|
+
get: () => store.getEntry(brainKey).state,
|
|
21
|
+
set: (v) => {
|
|
22
|
+
const e = store.getEntry(brainKey);
|
|
23
|
+
e.state = v;
|
|
24
|
+
store.touch(brainKey, e);
|
|
25
|
+
},
|
|
26
|
+
getFeedback: () => store.getEntry(brainKey).feedback,
|
|
27
|
+
consumeFeedback: () => {
|
|
28
|
+
const e = store.getEntry(brainKey);
|
|
29
|
+
const f = e.feedback;
|
|
30
|
+
e.feedback = null;
|
|
31
|
+
return f;
|
|
32
|
+
},
|
|
33
|
+
pushFeedback: (v) => {
|
|
34
|
+
const e = store.getEntry(brainKey);
|
|
35
|
+
e.feedback = v === null ? null : JSON.stringify(v);
|
|
36
|
+
store.touch(brainKey, e);
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
getEntry(brainKey) {
|
|
41
|
+
let e = this.map.get(brainKey);
|
|
42
|
+
if (!e) {
|
|
43
|
+
e = { state: null, feedback: null };
|
|
44
|
+
this.map.set(brainKey, e);
|
|
45
|
+
this.evictIfNeeded();
|
|
46
|
+
}
|
|
47
|
+
return e;
|
|
48
|
+
}
|
|
49
|
+
touch(brainKey, e) {
|
|
50
|
+
// LRU: delete + re-set 让它移到 Map 末尾
|
|
51
|
+
this.map.delete(brainKey);
|
|
52
|
+
this.map.set(brainKey, e);
|
|
53
|
+
}
|
|
54
|
+
evictIfNeeded() {
|
|
55
|
+
while (this.map.size > MAX_ENTRIES) {
|
|
56
|
+
const oldest = this.map.keys().next().value;
|
|
57
|
+
if (oldest !== undefined) {
|
|
58
|
+
this.map.delete(oldest);
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
break;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
/** 测试辅助 */
|
|
66
|
+
_clear() {
|
|
67
|
+
this.map.clear();
|
|
68
|
+
}
|
|
69
|
+
_size() {
|
|
70
|
+
return this.map.size;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* 全局单例 store — stdio 模式/tests 也会用到,HTTP 模式的 app 实例也直接用它。
|
|
75
|
+
* 不同 brainKey 天然隔离。
|
|
76
|
+
*/
|
|
77
|
+
export const globalConvStore = new ConvStateStore();
|
|
78
|
+
//# sourceMappingURL=request-context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request-context.js","sourceRoot":"","sources":["../../src/mcp-stdio/request-context.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
3
|
+
import { type RequestContext } from './request-context.js';
|
|
4
|
+
type ToolContextProvider = (extra: {
|
|
5
|
+
authInfo?: {
|
|
6
|
+
token?: string;
|
|
7
|
+
};
|
|
8
|
+
} | undefined) => RequestContext;
|
|
9
|
+
/**
|
|
10
|
+
* 构造一个注册了所有工具的 McpServer。
|
|
11
|
+
* 工具回调在运行时调用 getCtx(extra) 拿到 per-request RequestContext。
|
|
12
|
+
*/
|
|
13
|
+
declare function buildMcpServer(getCtx: ToolContextProvider): McpServer;
|
|
14
|
+
export { buildMcpServer };
|
|
15
|
+
export { globalConvStore } from './request-context.js';
|
|
16
|
+
export type { RequestContext } from './request-context.js';
|
|
17
|
+
export type { ToolContextProvider };
|
|
18
|
+
export declare function main(): Promise<void>;
|
|
19
|
+
//# sourceMappingURL=server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/mcp-stdio/server.ts"],"names":[],"mappings":";AAoBA,OAAO,EAAE,SAAS,EAAoB,MAAM,yCAAyC,CAAC;AAOtF,OAAO,EAAmB,KAAK,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAQ5E,KAAK,mBAAmB,GAAG,CAAC,KAAK,EAAE;IAAE,QAAQ,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,GAAG,SAAS,KAAK,cAAc,CAAC;AAEpG;;;GAGG;AACH,iBAAS,cAAc,CAAC,MAAM,EAAE,mBAAmB,GAAG,SAAS,CAqkB9D;AA4BD,OAAO,EAAE,cAAc,EAAE,CAAC;AAC1B,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,YAAY,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,YAAY,EAAE,mBAAmB,EAAE,CAAC;AAEpC,wBAAsB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAU1C"}
|