@t0ken.ai/memoryx-openclaw-plugin 2.2.29 → 2.2.32
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/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +248 -2
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAkDH,UAAU,YAAY;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAkDH,UAAU,YAAY;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,mCAAmC;IACnC,aAAa,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,UAAU,YAAY;IAClB,QAAQ,EAAE,KAAK,CAAC;QACZ,EAAE,EAAE,MAAM,CAAC;QACX,OAAO,EAAE,MAAM,CAAC;QAChB,QAAQ,EAAE,MAAM,CAAC;QACjB,KAAK,EAAE,MAAM,CAAC;KACjB,CAAC,CAAC;IACH,eAAe,EAAE,KAAK,CAAC;QACnB,EAAE,EAAE,MAAM,CAAC;QACX,OAAO,EAAE,MAAM,CAAC;QAChB,QAAQ,EAAE,MAAM,CAAC;QACjB,KAAK,EAAE,MAAM,CAAC;KACjB,CAAC,CAAC;IACH,SAAS,EAAE,OAAO,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;CACxB;AAqDD,cAAM,aAAa;IACf,OAAO,CAAC,YAAY,CAA2B;IAC/C,OAAO,CAAC,WAAW,CAAkB;IACrC,OAAO,CAAC,aAAa,CAAkB;gBAE3B,YAAY,CAAC,EAAE,YAAY;IAIjC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAad,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC;IAUpC,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IA6B1D,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,GAAE,MAAU,GAAG,OAAO,CAAC,YAAY,CAAC;IAyC/D,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC;IAYhC,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAc1C,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAcvE,IAAI,CAAC,KAAK,GAAE,MAAW,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAiBxC,cAAc,IAAI,OAAO,CAAC;QACnC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;QACtB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;QACvB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;QACzB,WAAW,EAAE,OAAO,CAAC;QACrB,KAAK,CAAC,EAAE,GAAG,CAAC;KACf,CAAC;IAwBW,cAAc,IAAI,OAAO,CAAC;QACnC,OAAO,EAAE,OAAO,CAAC;QACjB,IAAI,CAAC,EAAE;YACH,QAAQ,EAAE,MAAM,CAAC;YACjB,IAAI,EAAE,MAAM,CAAC;YACb,UAAU,EAAE,MAAM,CAAC;YACnB,YAAY,EAAE,MAAM,CAAC;YACrB,iBAAiB,EAAE,MAAM,CAAC;YAC1B,gBAAgB,EAAE,MAAM,CAAC;YACzB,mBAAmB,EAAE,MAAM,CAAC;YAC5B,MAAM,EAAE,MAAM,CAAC;YACf,OAAO,EAAE,MAAM,CAAC;SACnB,CAAC;QACF,KAAK,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;CAcL;;;;;;kBAUiB,GAAG,iBAAiB,YAAY,GAAG,IAAI;;AANzD,wBAuwBE;AAEF,OAAO,EAAE,aAAa,EAAE,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -26,7 +26,7 @@ import * as fs from "fs";
|
|
|
26
26
|
import * as path from "path";
|
|
27
27
|
import * as os from "os";
|
|
28
28
|
// 插件版本号 - 由 prebuild 脚本自动从 package.json 同步
|
|
29
|
-
const PLUGIN_VERSION = "2.2.
|
|
29
|
+
const PLUGIN_VERSION = "2.2.32";
|
|
30
30
|
const DEFAULT_API_BASE = "https://t0ken.ai/api";
|
|
31
31
|
const PLUGIN_DIR = path.join(os.homedir(), ".openclaw", "extensions", "memoryx-openclaw-plugin");
|
|
32
32
|
let logStream = null;
|
|
@@ -679,7 +679,7 @@ export default {
|
|
|
679
679
|
if (result.memories.length === 0 && result.relatedMemories.length === 0)
|
|
680
680
|
return;
|
|
681
681
|
// Build a clean memory context with markdown formatting
|
|
682
|
-
const lines = ["## 🧠
|
|
682
|
+
const lines = ["## 🧠 MemoryX Context"];
|
|
683
683
|
lines.push("");
|
|
684
684
|
if (result.memories.length > 0) {
|
|
685
685
|
lines.push(`**Related memories** (${result.memories.length}):`);
|
|
@@ -716,6 +716,252 @@ export default {
|
|
|
716
716
|
await plugin.endConversation();
|
|
717
717
|
}
|
|
718
718
|
});
|
|
719
|
+
// =========================================================================
|
|
720
|
+
// MemoryX Proxy Provider - 注入记忆 + 转发请求 + 详细日志
|
|
721
|
+
// =========================================================================
|
|
722
|
+
// 从 OpenClaw config 提取 provider 凭证
|
|
723
|
+
const providerCredentials = new Map();
|
|
724
|
+
function extractProviderCredentials(config) {
|
|
725
|
+
if (config?.models?.providers) {
|
|
726
|
+
for (const [id, providerConfig] of Object.entries(config.models.providers)) {
|
|
727
|
+
const pc = providerConfig;
|
|
728
|
+
if (pc.baseUrl || pc.apiKey) {
|
|
729
|
+
providerCredentials.set(id, {
|
|
730
|
+
baseUrl: pc.baseUrl || '',
|
|
731
|
+
apiKey: pc.apiKey || process.env[`${id.toUpperCase()}_API_KEY`] || ''
|
|
732
|
+
});
|
|
733
|
+
log(`[Proxy] Extracted credentials for ${id}: baseUrl=${pc.baseUrl?.slice(0, 50)}...`);
|
|
734
|
+
}
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
// 提取凭证
|
|
739
|
+
try {
|
|
740
|
+
extractProviderCredentials(api.config);
|
|
741
|
+
log(`[Proxy] Found ${providerCredentials.size} providers in config`);
|
|
742
|
+
}
|
|
743
|
+
catch (e) {
|
|
744
|
+
log(`[Proxy] Failed to extract credentials: ${e}`);
|
|
745
|
+
}
|
|
746
|
+
// 从 OpenClaw config 动态提取模型列表
|
|
747
|
+
function extractModelsFromConfig(config) {
|
|
748
|
+
const models = [
|
|
749
|
+
// 默认模型
|
|
750
|
+
{
|
|
751
|
+
id: 'default',
|
|
752
|
+
name: 'MemoryX Auto Router',
|
|
753
|
+
reasoning: true,
|
|
754
|
+
input: ['text', 'image'],
|
|
755
|
+
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
|
756
|
+
contextWindow: 200000,
|
|
757
|
+
maxTokens: 8192,
|
|
758
|
+
},
|
|
759
|
+
];
|
|
760
|
+
// 从配置中提取所有模型
|
|
761
|
+
if (config?.models?.providers) {
|
|
762
|
+
for (const [providerId, providerConfig] of Object.entries(config.models.providers)) {
|
|
763
|
+
const pc = providerConfig;
|
|
764
|
+
if (pc.models && Array.isArray(pc.models)) {
|
|
765
|
+
pc.models.forEach((modelId) => {
|
|
766
|
+
models.push({
|
|
767
|
+
id: modelId,
|
|
768
|
+
name: `${modelId} (via MemoryX)`,
|
|
769
|
+
reasoning: true,
|
|
770
|
+
input: ['text'],
|
|
771
|
+
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
|
772
|
+
contextWindow: 128000,
|
|
773
|
+
maxTokens: 8192,
|
|
774
|
+
});
|
|
775
|
+
});
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
}
|
|
779
|
+
log(`[Proxy] Extracted ${models.length} models from config`);
|
|
780
|
+
return models;
|
|
781
|
+
}
|
|
782
|
+
// 注册 Proxy Provider
|
|
783
|
+
api.registerProvider({
|
|
784
|
+
id: 'memoryx-proxy',
|
|
785
|
+
name: 'MemoryX Proxy Provider',
|
|
786
|
+
// 声明支持的模型 - 从配置动态提取
|
|
787
|
+
models: {
|
|
788
|
+
baseUrl: 'http://memoryx-proxy.local',
|
|
789
|
+
api: 'anthropic-messages',
|
|
790
|
+
models: extractModelsFromConfig(api.config),
|
|
791
|
+
},
|
|
792
|
+
async sendMessage(params) {
|
|
793
|
+
const requestId = `req-${Date.now()}`;
|
|
794
|
+
// ========== 详细日志 ==========
|
|
795
|
+
log(`\n${'='.repeat(80)}`);
|
|
796
|
+
log(`[${requestId}] MemoryX Proxy - Request Start`);
|
|
797
|
+
log(`Timestamp: ${new Date().toISOString()}`);
|
|
798
|
+
log(`${'='.repeat(80)}`);
|
|
799
|
+
// 原始请求信息
|
|
800
|
+
log(`\n--- Original Request ---`);
|
|
801
|
+
log(`Model: ${params.model}`);
|
|
802
|
+
log(`Provider: ${params.provider}`);
|
|
803
|
+
log(`Stream: ${params.stream}`);
|
|
804
|
+
log(`Max Tokens: ${params.maxTokens}`);
|
|
805
|
+
log(`Temperature: ${params.temperature}`);
|
|
806
|
+
// System Prompt
|
|
807
|
+
log(`\n--- System Prompt (${(params.systemPrompt || '').length} chars) ---`);
|
|
808
|
+
log(params.systemPrompt || '(none)');
|
|
809
|
+
// 历史消息(完整)
|
|
810
|
+
log(`\n--- History Messages (${params.messages?.length || 0}) ---`);
|
|
811
|
+
if (params.messages) {
|
|
812
|
+
params.messages.forEach((msg, i) => {
|
|
813
|
+
const content = typeof msg.content === 'string'
|
|
814
|
+
? msg.content
|
|
815
|
+
: JSON.stringify(msg.content, null, 2);
|
|
816
|
+
log(`\n[${i}] ${msg.role.toUpperCase()}:`);
|
|
817
|
+
log(content); // 完整内容,不截断
|
|
818
|
+
});
|
|
819
|
+
}
|
|
820
|
+
// Tools
|
|
821
|
+
log(`\n--- Tools (${params.tools?.length || 0}) ---`);
|
|
822
|
+
if (params.tools && params.tools.length > 0) {
|
|
823
|
+
params.tools.forEach((tool, i) => {
|
|
824
|
+
log(`[${i}] ${tool.name}: ${tool.description?.slice(0, 100) || ''}`);
|
|
825
|
+
});
|
|
826
|
+
}
|
|
827
|
+
// 其他参数
|
|
828
|
+
log(`\n--- Other Parameters ---`);
|
|
829
|
+
if (params.toolChoice)
|
|
830
|
+
log(`toolChoice: ${JSON.stringify(params.toolChoice)}`);
|
|
831
|
+
if (params.stop)
|
|
832
|
+
log(`stop: ${JSON.stringify(params.stop)}`);
|
|
833
|
+
if (params.topP)
|
|
834
|
+
log(`topP: ${params.topP}`);
|
|
835
|
+
if (params.topK)
|
|
836
|
+
log(`topK: ${params.topK}`);
|
|
837
|
+
// ========== 注入记忆 ==========
|
|
838
|
+
let enhancedSystemPrompt = params.systemPrompt || '';
|
|
839
|
+
try {
|
|
840
|
+
const sdk = await getSDK(pluginConfig);
|
|
841
|
+
const lastUserMessage = params.messages?.filter((m) => m.role === 'user').pop();
|
|
842
|
+
const searchQuery = typeof lastUserMessage?.content === 'string'
|
|
843
|
+
? lastUserMessage.content
|
|
844
|
+
: '';
|
|
845
|
+
if (searchQuery) {
|
|
846
|
+
const memories = await sdk.search(searchQuery, 5);
|
|
847
|
+
if (memories.data && memories.data.length > 0) {
|
|
848
|
+
const memoryContext = `\n\n## 🧠 MemoryX Context (injected by proxy)\n\n` +
|
|
849
|
+
`**Related memories:**\n` +
|
|
850
|
+
memories.data.map((m, i) => `${i + 1}. ${m.content || m.memory}`).join('\n') + '\n';
|
|
851
|
+
enhancedSystemPrompt = enhancedSystemPrompt + memoryContext;
|
|
852
|
+
log(`\n--- Injected Memories (${memories.data.length}) ---`);
|
|
853
|
+
memories.data.forEach((m, i) => {
|
|
854
|
+
log(`[${i + 1}] ${m.content || m.memory}`);
|
|
855
|
+
});
|
|
856
|
+
}
|
|
857
|
+
}
|
|
858
|
+
}
|
|
859
|
+
catch (e) {
|
|
860
|
+
log(`[Proxy] Memory injection failed: ${e}`);
|
|
861
|
+
}
|
|
862
|
+
// ========== 转发请求 ==========
|
|
863
|
+
// 确定目标 provider
|
|
864
|
+
const targetProvider = params.provider || 'anthropic';
|
|
865
|
+
const credentials = providerCredentials.get(targetProvider);
|
|
866
|
+
if (!credentials) {
|
|
867
|
+
log(`[Proxy] ❌ No credentials for provider: ${targetProvider}`);
|
|
868
|
+
log(`[Proxy] Available providers: ${Array.from(providerCredentials.keys()).join(', ')}`);
|
|
869
|
+
throw new Error(`[MemoryX Proxy] No credentials found for provider: ${targetProvider}`);
|
|
870
|
+
}
|
|
871
|
+
log(`\n--- Forwarding Request ---`);
|
|
872
|
+
log(`Target Provider: ${targetProvider}`);
|
|
873
|
+
log(`Target URL: ${credentials.baseUrl}`);
|
|
874
|
+
log(`Model: ${params.model}`);
|
|
875
|
+
// 构建转发请求
|
|
876
|
+
const forwardBody = {
|
|
877
|
+
model: params.model,
|
|
878
|
+
messages: params.messages,
|
|
879
|
+
system: enhancedSystemPrompt, // 注入后的 system prompt
|
|
880
|
+
stream: params.stream,
|
|
881
|
+
};
|
|
882
|
+
if (params.maxTokens)
|
|
883
|
+
forwardBody.max_tokens = params.maxTokens;
|
|
884
|
+
if (params.temperature !== undefined)
|
|
885
|
+
forwardBody.temperature = params.temperature;
|
|
886
|
+
if (params.topP !== undefined)
|
|
887
|
+
forwardBody.top_p = params.topP;
|
|
888
|
+
if (params.topK !== undefined)
|
|
889
|
+
forwardBody.top_k = params.topK;
|
|
890
|
+
if (params.tools)
|
|
891
|
+
forwardBody.tools = params.tools;
|
|
892
|
+
if (params.toolChoice)
|
|
893
|
+
forwardBody.tool_choice = params.toolChoice;
|
|
894
|
+
if (params.stop)
|
|
895
|
+
forwardBody.stop = params.stop;
|
|
896
|
+
log(`\n--- Forward Request Body ---`);
|
|
897
|
+
log(JSON.stringify(forwardBody, null, 2).slice(0, 2000));
|
|
898
|
+
try {
|
|
899
|
+
// 确定目标 URL
|
|
900
|
+
let targetUrl = credentials.baseUrl;
|
|
901
|
+
if (targetProvider === 'anthropic') {
|
|
902
|
+
targetUrl = 'https://api.anthropic.com/v1/messages';
|
|
903
|
+
}
|
|
904
|
+
else if (targetProvider === 'openrouter') {
|
|
905
|
+
targetUrl = 'https://openrouter.ai/api/v1/chat/completions';
|
|
906
|
+
}
|
|
907
|
+
else if (targetProvider === 'openai') {
|
|
908
|
+
targetUrl = 'https://api.openai.com/v1/chat/completions';
|
|
909
|
+
}
|
|
910
|
+
else {
|
|
911
|
+
// 使用配置的 baseUrl
|
|
912
|
+
if (!targetUrl.endsWith('/chat/completions') && !targetUrl.endsWith('/messages')) {
|
|
913
|
+
targetUrl = targetUrl.replace(/\/$/, '') + '/v1/messages';
|
|
914
|
+
}
|
|
915
|
+
}
|
|
916
|
+
log(`Final URL: ${targetUrl}`);
|
|
917
|
+
const response = await fetch(targetUrl, {
|
|
918
|
+
method: 'POST',
|
|
919
|
+
headers: {
|
|
920
|
+
'Content-Type': 'application/json',
|
|
921
|
+
'Authorization': `Bearer ${credentials.apiKey}`,
|
|
922
|
+
'x-api-key': credentials.apiKey, // Anthropic needs this
|
|
923
|
+
'anthropic-version': '2023-06-01', // Anthropic needs this
|
|
924
|
+
},
|
|
925
|
+
body: JSON.stringify(forwardBody),
|
|
926
|
+
});
|
|
927
|
+
log(`\n--- Response Status ---`);
|
|
928
|
+
log(`Status: ${response.status} ${response.statusText}`);
|
|
929
|
+
if (!response.ok) {
|
|
930
|
+
const errorText = await response.text();
|
|
931
|
+
log(`Error Response: ${errorText}`);
|
|
932
|
+
throw new Error(`[MemoryX Proxy] API error: ${response.status} - ${errorText}`);
|
|
933
|
+
}
|
|
934
|
+
log(`[${requestId}] Request completed successfully`);
|
|
935
|
+
log(`${'='.repeat(80)}\n`);
|
|
936
|
+
// 返回流式响应
|
|
937
|
+
return response.body;
|
|
938
|
+
}
|
|
939
|
+
catch (e) {
|
|
940
|
+
log(`[Proxy] ❌ Request failed: ${e}`);
|
|
941
|
+
throw e;
|
|
942
|
+
}
|
|
943
|
+
}
|
|
944
|
+
});
|
|
945
|
+
api.logger.info('[MemoryX] 🔄 Proxy provider registered: memoryx-proxy');
|
|
946
|
+
// 保存原始请求信息,供 sendMessage 使用
|
|
947
|
+
let lastRequestInfo = {};
|
|
948
|
+
// 用 before_model_resolve 自动切换到 Proxy Provider
|
|
949
|
+
// 注意:event 只有 prompt 字段,provider 信息在 ctx.messageProvider
|
|
950
|
+
api.on('before_model_resolve', (event, ctx) => {
|
|
951
|
+
log(`\n[before_model_resolve] Intercepting request`);
|
|
952
|
+
log(` Prompt Preview: ${event.prompt?.slice(0, 200)}...`);
|
|
953
|
+
log(` Context Provider: ${ctx.messageProvider}`);
|
|
954
|
+
log(` Context AgentId: ${ctx.agentId}`);
|
|
955
|
+
// 保存原始信息(从 context 获取)
|
|
956
|
+
lastRequestInfo = {
|
|
957
|
+
provider: ctx.messageProvider
|
|
958
|
+
};
|
|
959
|
+
// 只覆盖 provider,让 OpenClaw 使用原始 model
|
|
960
|
+
return {
|
|
961
|
+
providerOverride: 'memoryx-proxy'
|
|
962
|
+
};
|
|
963
|
+
});
|
|
964
|
+
api.logger.info('[MemoryX] 🔄 Auto-routing enabled - all requests will go through MemoryX Proxy');
|
|
719
965
|
api.logger.info(`[MemoryX] ✅ Plugin v${PLUGIN_VERSION} ready! Your conversations will be remembered automatically.`);
|
|
720
966
|
// Async check and show portal link after SDK initializes
|
|
721
967
|
setImmediate(async () => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@t0ken.ai/memoryx-openclaw-plugin",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.32",
|
|
4
4
|
"description": "MemoryX real-time memory capture and recall plugin for OpenClaw (powered by @t0ken.ai/memoryx-sdk)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"author": "MemoryX Team",
|
|
@@ -36,6 +36,6 @@
|
|
|
36
36
|
"typescript": "^5.0.0"
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@t0ken.ai/memoryx-sdk": "^1.
|
|
39
|
+
"@t0ken.ai/memoryx-sdk": "^1.5.1"
|
|
40
40
|
}
|
|
41
41
|
}
|