@t0ken.ai/memoryx-openclaw-plugin 2.2.26 → 2.2.31
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 +211 -14
- 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,wBA+sBE;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.31";
|
|
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;
|
|
@@ -636,7 +636,6 @@ export default {
|
|
|
636
636
|
// User message capture via message_received hook
|
|
637
637
|
// Event structure: { from: string, content: string, timestamp?: number }
|
|
638
638
|
api.on("message_received", async (event, ctx) => {
|
|
639
|
-
log(`message_received hook triggered`, { console: true });
|
|
640
639
|
const { content } = event;
|
|
641
640
|
if (content && plugin) {
|
|
642
641
|
await plugin.onMessage("user", content);
|
|
@@ -645,18 +644,12 @@ export default {
|
|
|
645
644
|
// Assistant response capture via llm_output hook
|
|
646
645
|
// AI responses are saved to conversation history (for rounds/maxTokens counting)
|
|
647
646
|
// But they do NOT trigger memory search - only user messages do that
|
|
648
|
-
api.logger.info("[MemoryX] Registering llm_output hook...");
|
|
649
647
|
api.on("llm_output", async (event, ctx) => {
|
|
650
|
-
api.logger.info("[MemoryX] *** LLM_OUTPUT HOOK TRIGGERED ***");
|
|
651
648
|
const { assistantTexts } = event;
|
|
652
|
-
api.logger.info(`[MemoryX] assistantTexts: ${JSON.stringify(assistantTexts)}`);
|
|
653
649
|
if (assistantTexts && Array.isArray(assistantTexts) && plugin) {
|
|
654
|
-
// Join all assistant text segments
|
|
655
650
|
const fullContent = assistantTexts.join("\n");
|
|
656
|
-
api.logger.info(`[MemoryX] Full assistant content length: ${fullContent.length}`);
|
|
657
651
|
if (fullContent && fullContent.length >= 2) {
|
|
658
652
|
await plugin.onMessage("assistant", fullContent);
|
|
659
|
-
api.logger.info(`[MemoryX] Assistant message saved`);
|
|
660
653
|
}
|
|
661
654
|
}
|
|
662
655
|
});
|
|
@@ -685,17 +678,26 @@ export default {
|
|
|
685
678
|
}
|
|
686
679
|
if (result.memories.length === 0 && result.relatedMemories.length === 0)
|
|
687
680
|
return;
|
|
688
|
-
// Build a
|
|
689
|
-
|
|
690
|
-
|
|
681
|
+
// Build a clean memory context with markdown formatting
|
|
682
|
+
const lines = ["## 🧠 MemoryX Context"];
|
|
683
|
+
lines.push("");
|
|
691
684
|
if (result.memories.length > 0) {
|
|
692
|
-
lines.push(
|
|
685
|
+
lines.push(`**Related memories** (${result.memories.length}):`);
|
|
686
|
+
lines.push("```");
|
|
687
|
+
result.memories.forEach((m, i) => {
|
|
688
|
+
lines.push(`${i + 1}. ${m.content}`);
|
|
689
|
+
});
|
|
690
|
+
lines.push("```");
|
|
693
691
|
}
|
|
694
692
|
if (result.relatedMemories.length > 0) {
|
|
695
693
|
if (result.memories.length > 0)
|
|
696
694
|
lines.push("");
|
|
697
|
-
lines.push(
|
|
698
|
-
lines.push(
|
|
695
|
+
lines.push(`**Also relevant** (${result.relatedMemories.length}):`);
|
|
696
|
+
lines.push("```");
|
|
697
|
+
result.relatedMemories.forEach((m, i) => {
|
|
698
|
+
lines.push(`${i + 1}. ${m.content}`);
|
|
699
|
+
});
|
|
700
|
+
lines.push("```");
|
|
699
701
|
}
|
|
700
702
|
const context = lines.join("\n");
|
|
701
703
|
api.logger.info(`[MemoryX] Injected ${result.memories.length} direct + ${result.relatedMemories.length} related memories`);
|
|
@@ -714,6 +716,201 @@ export default {
|
|
|
714
716
|
await plugin.endConversation();
|
|
715
717
|
}
|
|
716
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
|
+
// 注册 Proxy Provider
|
|
747
|
+
api.registerProvider({
|
|
748
|
+
id: 'memoryx-proxy',
|
|
749
|
+
name: 'MemoryX Proxy Provider',
|
|
750
|
+
async sendMessage(params) {
|
|
751
|
+
const requestId = `req-${Date.now()}`;
|
|
752
|
+
// ========== 详细日志 ==========
|
|
753
|
+
log(`\n${'='.repeat(80)}`);
|
|
754
|
+
log(`[${requestId}] MemoryX Proxy - Request Start`);
|
|
755
|
+
log(`Timestamp: ${new Date().toISOString()}`);
|
|
756
|
+
log(`${'='.repeat(80)}`);
|
|
757
|
+
// 原始请求信息
|
|
758
|
+
log(`\n--- Original Request ---`);
|
|
759
|
+
log(`Model: ${params.model}`);
|
|
760
|
+
log(`Provider: ${params.provider}`);
|
|
761
|
+
log(`Stream: ${params.stream}`);
|
|
762
|
+
log(`Max Tokens: ${params.maxTokens}`);
|
|
763
|
+
log(`Temperature: ${params.temperature}`);
|
|
764
|
+
// System Prompt
|
|
765
|
+
log(`\n--- System Prompt (${(params.systemPrompt || '').length} chars) ---`);
|
|
766
|
+
log(params.systemPrompt || '(none)');
|
|
767
|
+
// 历史消息(完整)
|
|
768
|
+
log(`\n--- History Messages (${params.messages?.length || 0}) ---`);
|
|
769
|
+
if (params.messages) {
|
|
770
|
+
params.messages.forEach((msg, i) => {
|
|
771
|
+
const content = typeof msg.content === 'string'
|
|
772
|
+
? msg.content
|
|
773
|
+
: JSON.stringify(msg.content, null, 2);
|
|
774
|
+
log(`\n[${i}] ${msg.role.toUpperCase()}:`);
|
|
775
|
+
log(content); // 完整内容,不截断
|
|
776
|
+
});
|
|
777
|
+
}
|
|
778
|
+
// Tools
|
|
779
|
+
log(`\n--- Tools (${params.tools?.length || 0}) ---`);
|
|
780
|
+
if (params.tools && params.tools.length > 0) {
|
|
781
|
+
params.tools.forEach((tool, i) => {
|
|
782
|
+
log(`[${i}] ${tool.name}: ${tool.description?.slice(0, 100) || ''}`);
|
|
783
|
+
});
|
|
784
|
+
}
|
|
785
|
+
// 其他参数
|
|
786
|
+
log(`\n--- Other Parameters ---`);
|
|
787
|
+
if (params.toolChoice)
|
|
788
|
+
log(`toolChoice: ${JSON.stringify(params.toolChoice)}`);
|
|
789
|
+
if (params.stop)
|
|
790
|
+
log(`stop: ${JSON.stringify(params.stop)}`);
|
|
791
|
+
if (params.topP)
|
|
792
|
+
log(`topP: ${params.topP}`);
|
|
793
|
+
if (params.topK)
|
|
794
|
+
log(`topK: ${params.topK}`);
|
|
795
|
+
// ========== 注入记忆 ==========
|
|
796
|
+
let enhancedSystemPrompt = params.systemPrompt || '';
|
|
797
|
+
try {
|
|
798
|
+
const sdk = await getSDK(pluginConfig);
|
|
799
|
+
const lastUserMessage = params.messages?.filter((m) => m.role === 'user').pop();
|
|
800
|
+
const searchQuery = typeof lastUserMessage?.content === 'string'
|
|
801
|
+
? lastUserMessage.content
|
|
802
|
+
: '';
|
|
803
|
+
if (searchQuery) {
|
|
804
|
+
const memories = await sdk.search(searchQuery, 5);
|
|
805
|
+
if (memories.data && memories.data.length > 0) {
|
|
806
|
+
const memoryContext = `\n\n## 🧠 MemoryX Context (injected by proxy)\n\n` +
|
|
807
|
+
`**Related memories:**\n` +
|
|
808
|
+
memories.data.map((m, i) => `${i + 1}. ${m.content || m.memory}`).join('\n') + '\n';
|
|
809
|
+
enhancedSystemPrompt = enhancedSystemPrompt + memoryContext;
|
|
810
|
+
log(`\n--- Injected Memories (${memories.data.length}) ---`);
|
|
811
|
+
memories.data.forEach((m, i) => {
|
|
812
|
+
log(`[${i + 1}] ${m.content || m.memory}`);
|
|
813
|
+
});
|
|
814
|
+
}
|
|
815
|
+
}
|
|
816
|
+
}
|
|
817
|
+
catch (e) {
|
|
818
|
+
log(`[Proxy] Memory injection failed: ${e}`);
|
|
819
|
+
}
|
|
820
|
+
// ========== 转发请求 ==========
|
|
821
|
+
// 确定目标 provider
|
|
822
|
+
const targetProvider = params.provider || 'anthropic';
|
|
823
|
+
const credentials = providerCredentials.get(targetProvider);
|
|
824
|
+
if (!credentials) {
|
|
825
|
+
log(`[Proxy] ❌ No credentials for provider: ${targetProvider}`);
|
|
826
|
+
log(`[Proxy] Available providers: ${Array.from(providerCredentials.keys()).join(', ')}`);
|
|
827
|
+
throw new Error(`[MemoryX Proxy] No credentials found for provider: ${targetProvider}`);
|
|
828
|
+
}
|
|
829
|
+
log(`\n--- Forwarding Request ---`);
|
|
830
|
+
log(`Target Provider: ${targetProvider}`);
|
|
831
|
+
log(`Target URL: ${credentials.baseUrl}`);
|
|
832
|
+
log(`Model: ${params.model}`);
|
|
833
|
+
// 构建转发请求
|
|
834
|
+
const forwardBody = {
|
|
835
|
+
model: params.model,
|
|
836
|
+
messages: params.messages,
|
|
837
|
+
system: enhancedSystemPrompt, // 注入后的 system prompt
|
|
838
|
+
stream: params.stream,
|
|
839
|
+
};
|
|
840
|
+
if (params.maxTokens)
|
|
841
|
+
forwardBody.max_tokens = params.maxTokens;
|
|
842
|
+
if (params.temperature !== undefined)
|
|
843
|
+
forwardBody.temperature = params.temperature;
|
|
844
|
+
if (params.topP !== undefined)
|
|
845
|
+
forwardBody.top_p = params.topP;
|
|
846
|
+
if (params.topK !== undefined)
|
|
847
|
+
forwardBody.top_k = params.topK;
|
|
848
|
+
if (params.tools)
|
|
849
|
+
forwardBody.tools = params.tools;
|
|
850
|
+
if (params.toolChoice)
|
|
851
|
+
forwardBody.tool_choice = params.toolChoice;
|
|
852
|
+
if (params.stop)
|
|
853
|
+
forwardBody.stop = params.stop;
|
|
854
|
+
log(`\n--- Forward Request Body ---`);
|
|
855
|
+
log(JSON.stringify(forwardBody, null, 2).slice(0, 2000));
|
|
856
|
+
try {
|
|
857
|
+
// 确定目标 URL
|
|
858
|
+
let targetUrl = credentials.baseUrl;
|
|
859
|
+
if (targetProvider === 'anthropic') {
|
|
860
|
+
targetUrl = 'https://api.anthropic.com/v1/messages';
|
|
861
|
+
}
|
|
862
|
+
else if (targetProvider === 'openrouter') {
|
|
863
|
+
targetUrl = 'https://openrouter.ai/api/v1/chat/completions';
|
|
864
|
+
}
|
|
865
|
+
else if (targetProvider === 'openai') {
|
|
866
|
+
targetUrl = 'https://api.openai.com/v1/chat/completions';
|
|
867
|
+
}
|
|
868
|
+
else {
|
|
869
|
+
// 使用配置的 baseUrl
|
|
870
|
+
if (!targetUrl.endsWith('/chat/completions') && !targetUrl.endsWith('/messages')) {
|
|
871
|
+
targetUrl = targetUrl.replace(/\/$/, '') + '/v1/messages';
|
|
872
|
+
}
|
|
873
|
+
}
|
|
874
|
+
log(`Final URL: ${targetUrl}`);
|
|
875
|
+
const response = await fetch(targetUrl, {
|
|
876
|
+
method: 'POST',
|
|
877
|
+
headers: {
|
|
878
|
+
'Content-Type': 'application/json',
|
|
879
|
+
'Authorization': `Bearer ${credentials.apiKey}`,
|
|
880
|
+
'x-api-key': credentials.apiKey, // Anthropic needs this
|
|
881
|
+
'anthropic-version': '2023-06-01', // Anthropic needs this
|
|
882
|
+
},
|
|
883
|
+
body: JSON.stringify(forwardBody),
|
|
884
|
+
});
|
|
885
|
+
log(`\n--- Response Status ---`);
|
|
886
|
+
log(`Status: ${response.status} ${response.statusText}`);
|
|
887
|
+
if (!response.ok) {
|
|
888
|
+
const errorText = await response.text();
|
|
889
|
+
log(`Error Response: ${errorText}`);
|
|
890
|
+
throw new Error(`[MemoryX Proxy] API error: ${response.status} - ${errorText}`);
|
|
891
|
+
}
|
|
892
|
+
log(`[${requestId}] Request completed successfully`);
|
|
893
|
+
log(`${'='.repeat(80)}\n`);
|
|
894
|
+
// 返回流式响应
|
|
895
|
+
return response.body;
|
|
896
|
+
}
|
|
897
|
+
catch (e) {
|
|
898
|
+
log(`[Proxy] ❌ Request failed: ${e}`);
|
|
899
|
+
throw e;
|
|
900
|
+
}
|
|
901
|
+
}
|
|
902
|
+
});
|
|
903
|
+
api.logger.info('[MemoryX] 🔄 Proxy provider registered: memoryx-proxy');
|
|
904
|
+
// 用 before_model_resolve 自动切换到 Proxy Provider
|
|
905
|
+
api.on('before_model_resolve', (event, ctx) => {
|
|
906
|
+
log(`\n[before_model_resolve] Intercepting request`);
|
|
907
|
+
log(` Original Model: ${event.model}`);
|
|
908
|
+
log(` Prompt Preview: ${event.prompt?.slice(0, 200)}...`);
|
|
909
|
+
return {
|
|
910
|
+
providerOverride: 'memoryx-proxy'
|
|
911
|
+
};
|
|
912
|
+
});
|
|
913
|
+
api.logger.info('[MemoryX] 🔄 Auto-routing enabled - all requests will go through MemoryX Proxy');
|
|
717
914
|
api.logger.info(`[MemoryX] ✅ Plugin v${PLUGIN_VERSION} ready! Your conversations will be remembered automatically.`);
|
|
718
915
|
// Async check and show portal link after SDK initializes
|
|
719
916
|
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.31",
|
|
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
|
}
|