@xache/langchain 0.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/src/index.ts ADDED
@@ -0,0 +1,59 @@
1
+ /**
2
+ * @xache/langchain
3
+ * LangChain.js integration for Xache Protocol
4
+ *
5
+ * Drop-in memory, retrieval, and collective intelligence with verifiable receipts.
6
+ *
7
+ * @example
8
+ * ```typescript
9
+ * // One-line memory replacement
10
+ * import { XacheMemory } from '@xache/langchain';
11
+ *
12
+ * const memory = new XacheMemory({
13
+ * walletAddress: '0x...',
14
+ * privateKey: '0x...',
15
+ * });
16
+ *
17
+ * // Use with any LangChain chain
18
+ * const chain = new ConversationChain({ llm, memory });
19
+ * ```
20
+ *
21
+ * @packageDocumentation
22
+ */
23
+
24
+ // Memory
25
+ export { XacheMemory, XacheConversationBufferMemory } from './memory';
26
+ export type { XacheMemoryConfig } from './memory';
27
+
28
+ // Chat History
29
+ export { XacheChatMessageHistory } from './chat_history';
30
+ export type { XacheChatMessageHistoryConfig } from './chat_history';
31
+
32
+ // Retrieval
33
+ export { XacheRetriever } from './retriever';
34
+ export type { XacheRetrieverConfig } from './retriever';
35
+
36
+ // Extraction
37
+ export { XacheExtractor } from './extraction';
38
+ export type {
39
+ XacheExtractorConfig,
40
+ ExtractedMemory,
41
+ ExtractionResult,
42
+ } from './extraction';
43
+
44
+ // Collective Intelligence
45
+ export {
46
+ createCollectiveContributeTool,
47
+ createCollectiveQueryTool,
48
+ XacheCollectiveContributeTool,
49
+ XacheCollectiveQueryTool,
50
+ } from './collective';
51
+ export type { CollectiveToolConfig } from './collective';
52
+
53
+ // Reputation
54
+ export {
55
+ createReputationTool,
56
+ XacheReputationTool,
57
+ XacheReputationChecker,
58
+ } from './reputation';
59
+ export type { ReputationToolConfig, ReputationResult } from './reputation';
package/src/memory.ts ADDED
@@ -0,0 +1,121 @@
1
+ /**
2
+ * Xache Memory for LangChain.js
3
+ * Drop-in replacement for ConversationBufferMemory with verifiable receipts
4
+ */
5
+
6
+ import { BaseMemory, InputValues, OutputValues, MemoryVariables } from '@langchain/core/memory';
7
+ import { XacheChatMessageHistory, XacheChatMessageHistoryConfig } from './chat_history';
8
+
9
+ export interface XacheMemoryConfig extends XacheChatMessageHistoryConfig {
10
+ /** Memory key for input (default: 'input') */
11
+ inputKey?: string;
12
+ /** Memory key for output (default: 'output') */
13
+ outputKey?: string;
14
+ /** Key for returning memory (default: 'history') */
15
+ memoryKey?: string;
16
+ /** Return messages as list vs string */
17
+ returnMessages?: boolean;
18
+ }
19
+
20
+ /**
21
+ * Drop-in replacement for LangChain memory with Xache storage.
22
+ *
23
+ * Provides persistent, verifiable memory that survives across sessions.
24
+ *
25
+ * @example
26
+ * ```typescript
27
+ * import { XacheMemory } from '@xache/langchain';
28
+ * import { ChatOpenAI } from '@langchain/openai';
29
+ * import { ConversationChain } from 'langchain/chains';
30
+ *
31
+ * const memory = new XacheMemory({
32
+ * walletAddress: '0x...',
33
+ * privateKey: '0x...',
34
+ * });
35
+ *
36
+ * const chain = new ConversationChain({
37
+ * llm: new ChatOpenAI(),
38
+ * memory,
39
+ * });
40
+ *
41
+ * await chain.call({ input: 'Hello!' });
42
+ * ```
43
+ */
44
+ export class XacheMemory extends BaseMemory {
45
+ lc_namespace = ['xache', 'memory'];
46
+
47
+ private chatHistory: XacheChatMessageHistory;
48
+ private inputKey: string;
49
+ private outputKey: string;
50
+ private memoryKey: string;
51
+ private returnMessages: boolean;
52
+
53
+ constructor(config: XacheMemoryConfig) {
54
+ super();
55
+ this.chatHistory = new XacheChatMessageHistory(config);
56
+ this.inputKey = config.inputKey || 'input';
57
+ this.outputKey = config.outputKey || 'output';
58
+ this.memoryKey = config.memoryKey || 'history';
59
+ this.returnMessages = config.returnMessages ?? false;
60
+ }
61
+
62
+ get memoryKeys(): string[] {
63
+ return [this.memoryKey];
64
+ }
65
+
66
+ /**
67
+ * Load memory variables
68
+ */
69
+ async loadMemoryVariables(_values: InputValues): Promise<MemoryVariables> {
70
+ const messages = await this.chatHistory.getMessages();
71
+
72
+ if (this.returnMessages) {
73
+ return { [this.memoryKey]: messages };
74
+ }
75
+
76
+ // Convert to string format
77
+ const history = messages
78
+ .map((m) => {
79
+ const role = m._getType() === 'human' ? 'Human' : 'AI';
80
+ const content =
81
+ typeof m.content === 'string' ? m.content : JSON.stringify(m.content);
82
+ return `${role}: ${content}`;
83
+ })
84
+ .join('\n');
85
+
86
+ return { [this.memoryKey]: history };
87
+ }
88
+
89
+ /**
90
+ * Save context from this conversation to buffer
91
+ */
92
+ async saveContext(
93
+ inputValues: InputValues,
94
+ outputValues: OutputValues
95
+ ): Promise<void> {
96
+ const input = inputValues[this.inputKey];
97
+ const output = outputValues[this.outputKey];
98
+
99
+ if (input) {
100
+ await this.chatHistory.addUserMessage(String(input));
101
+ }
102
+
103
+ if (output) {
104
+ await this.chatHistory.addAIMessage(String(output));
105
+ }
106
+ }
107
+
108
+ /**
109
+ * Clear memory contents
110
+ */
111
+ async clear(): Promise<void> {
112
+ await this.chatHistory.clear();
113
+ }
114
+ }
115
+
116
+ /**
117
+ * Extended memory with conversation buffer capabilities
118
+ */
119
+ export class XacheConversationBufferMemory extends XacheMemory {
120
+ lc_namespace = ['xache', 'memory', 'buffer'];
121
+ }
@@ -0,0 +1,195 @@
1
+ /**
2
+ * Xache Reputation for LangChain.js
3
+ * Portable, verifiable agent reputation with ERC-8004 support
4
+ */
5
+
6
+ import { DynamicStructuredTool } from '@langchain/core/tools';
7
+ import { z } from 'zod';
8
+ import { XacheClient, DID } from '@xache/sdk';
9
+
10
+ export interface ReputationToolConfig {
11
+ /** Wallet address for authentication */
12
+ walletAddress: string;
13
+ /** Private key for signing */
14
+ privateKey: string;
15
+ /** API URL (defaults to https://api.xache.xyz) */
16
+ apiUrl?: string;
17
+ /** Chain: 'base' or 'solana' */
18
+ chain?: 'base' | 'solana';
19
+ }
20
+
21
+ export interface ReputationResult {
22
+ /** Reputation score (0-1) */
23
+ score: number;
24
+ /** Reputation level */
25
+ level: string;
26
+ /** Total contributions made */
27
+ totalContributions: number;
28
+ /** Total payments made */
29
+ totalPayments: number;
30
+ /** Whether ERC-8004 is enabled */
31
+ erc8004Enabled: boolean;
32
+ /** ERC-8004 agent ID if enabled */
33
+ erc8004AgentId?: string;
34
+ }
35
+
36
+ /**
37
+ * Get reputation level from score
38
+ */
39
+ function getLevel(score: number): string {
40
+ if (score >= 0.9) return 'Elite';
41
+ if (score >= 0.7) return 'Trusted';
42
+ if (score >= 0.5) return 'Established';
43
+ if (score >= 0.3) return 'Developing';
44
+ return 'New';
45
+ }
46
+
47
+ /**
48
+ * Create an Xache client for reputation tools
49
+ */
50
+ function createClient(config: ReputationToolConfig): XacheClient {
51
+ const chainPrefix = config.chain === 'solana' ? 'sol' : 'evm';
52
+ const did = `did:agent:${chainPrefix}:${config.walletAddress.toLowerCase()}` as DID;
53
+
54
+ return new XacheClient({
55
+ apiUrl: config.apiUrl || 'https://api.xache.xyz',
56
+ did,
57
+ privateKey: config.privateKey,
58
+ });
59
+ }
60
+
61
+ /**
62
+ * Create a tool for checking your own reputation.
63
+ *
64
+ * @example
65
+ * ```typescript
66
+ * import { createReputationTool } from '@xache/langchain';
67
+ *
68
+ * const repTool = createReputationTool({
69
+ * walletAddress: '0x...',
70
+ * privateKey: '0x...',
71
+ * });
72
+ *
73
+ * const tools = [repTool, ...];
74
+ * ```
75
+ */
76
+ export function createReputationTool(
77
+ config: ReputationToolConfig
78
+ ): DynamicStructuredTool {
79
+ const client = createClient(config);
80
+
81
+ return new DynamicStructuredTool({
82
+ name: 'xache_check_reputation',
83
+ description:
84
+ 'Check your current reputation score and status. ' +
85
+ 'Returns your score (0-1), level, and ERC-8004 on-chain status. ' +
86
+ 'Higher reputation means lower costs and more trust from other agents.',
87
+ schema: z.object({}),
88
+ func: async () => {
89
+ const result = await client.reputation.getReputation();
90
+
91
+ // Overall score is 0-100, normalize to 0-1
92
+ const score = (result.overall || 0) / 100;
93
+ const level = getLevel(score);
94
+
95
+ let output = `Reputation Score: ${score.toFixed(2)}/1.00 (${level})\n`;
96
+ output += `Memory Quality: ${result.memoryQuality || 0}/100\n`;
97
+ output += `Contribution Success: ${result.contribSuccess || 0}/100\n`;
98
+ output += `Economic Value: ${result.economicValue || 0}/100\n`;
99
+
100
+ // Check ERC-8004 status separately
101
+ try {
102
+ const erc8004Status = await client.reputation.getERC8004Status();
103
+ if (erc8004Status.enabled) {
104
+ output += `ERC-8004 Status: Enabled\n`;
105
+ output += 'Your reputation is verifiable on-chain!';
106
+ } else {
107
+ output += 'ERC-8004 Status: Not enabled\n';
108
+ output += 'Enable ERC-8004 to make your reputation portable and verifiable.';
109
+ }
110
+ } catch {
111
+ output += 'ERC-8004 Status: Unknown';
112
+ }
113
+
114
+ return output;
115
+ },
116
+ });
117
+ }
118
+
119
+ /**
120
+ * Class-based reputation tool (alternative API)
121
+ */
122
+ export class XacheReputationTool {
123
+ private tool: DynamicStructuredTool;
124
+
125
+ constructor(config: ReputationToolConfig) {
126
+ this.tool = createReputationTool(config);
127
+ }
128
+
129
+ asTool(): DynamicStructuredTool {
130
+ return this.tool;
131
+ }
132
+ }
133
+
134
+ /**
135
+ * Utility class for checking reputation of any agent.
136
+ *
137
+ * @example
138
+ * ```typescript
139
+ * import { XacheReputationChecker } from '@xache/langchain';
140
+ *
141
+ * const checker = new XacheReputationChecker({
142
+ * walletAddress: '0x...',
143
+ * privateKey: '0x...',
144
+ * });
145
+ *
146
+ * const rep = await checker.check('did:agent:evm:0xOtherAgent...');
147
+ * if (rep.score >= 0.5) {
148
+ * console.log('Agent is trustworthy');
149
+ * }
150
+ * ```
151
+ */
152
+ export class XacheReputationChecker {
153
+ private client: XacheClient;
154
+
155
+ constructor(config: ReputationToolConfig) {
156
+ this.client = createClient(config);
157
+ }
158
+
159
+ /**
160
+ * Check an agent's reputation
161
+ */
162
+ async check(agentDid: string): Promise<ReputationResult> {
163
+ const result = await this.client.reputation.getReputation(agentDid as DID);
164
+
165
+ // Overall score is 0-100, normalize to 0-1
166
+ const score = (result.overall || 0) / 100;
167
+
168
+ // Try to get ERC-8004 status
169
+ let erc8004Enabled = false;
170
+ let erc8004AgentId: string | undefined;
171
+ try {
172
+ const erc8004Status = await this.client.reputation.getERC8004Status();
173
+ erc8004Enabled = erc8004Status.enabled;
174
+ } catch {
175
+ // ERC-8004 status not available
176
+ }
177
+
178
+ return {
179
+ score,
180
+ level: getLevel(score),
181
+ totalContributions: 0, // Not available in current API
182
+ totalPayments: 0, // Not available in current API
183
+ erc8004Enabled,
184
+ erc8004AgentId,
185
+ };
186
+ }
187
+
188
+ /**
189
+ * Check if an agent meets minimum reputation threshold
190
+ */
191
+ async meetsThreshold(agentDid: string, minScore: number): Promise<boolean> {
192
+ const result = await this.check(agentDid);
193
+ return result.score >= minScore;
194
+ }
195
+ }
@@ -0,0 +1,100 @@
1
+ /**
2
+ * Xache Retriever for LangChain.js
3
+ * Memory retrieval for RAG pipelines with verifiable receipts
4
+ */
5
+
6
+ import { BaseRetriever, BaseRetrieverInput } from '@langchain/core/retrievers';
7
+ import { Document } from '@langchain/core/documents';
8
+ import { CallbackManagerForRetrieverRun } from '@langchain/core/callbacks/manager';
9
+ import { XacheClient, DID } from '@xache/sdk';
10
+
11
+ export interface XacheRetrieverConfig extends BaseRetrieverInput {
12
+ /** Wallet address for authentication */
13
+ walletAddress: string;
14
+ /** Private key for signing */
15
+ privateKey: string;
16
+ /** Number of documents to retrieve */
17
+ k?: number;
18
+ /** Filter by context */
19
+ context?: string;
20
+ /** API URL (defaults to https://api.xache.xyz) */
21
+ apiUrl?: string;
22
+ /** Chain: 'base' or 'solana' */
23
+ chain?: 'base' | 'solana';
24
+ }
25
+
26
+ /**
27
+ * Retriever that fetches documents from Xache memory storage.
28
+ *
29
+ * Use this for RAG pipelines with persistent, verifiable document storage.
30
+ *
31
+ * @example
32
+ * ```typescript
33
+ * import { XacheRetriever } from '@xache/langchain';
34
+ * import { ChatOpenAI } from '@langchain/openai';
35
+ * import { RetrievalQAChain } from 'langchain/chains';
36
+ *
37
+ * const retriever = new XacheRetriever({
38
+ * walletAddress: '0x...',
39
+ * privateKey: '0x...',
40
+ * k: 5,
41
+ * });
42
+ *
43
+ * const qa = RetrievalQAChain.fromLLM(new ChatOpenAI(), retriever);
44
+ * const result = await qa.call({ query: 'What do you know about X?' });
45
+ * ```
46
+ */
47
+ export class XacheRetriever extends BaseRetriever {
48
+ lc_namespace = ['xache', 'retriever'];
49
+
50
+ static lc_name() {
51
+ return 'XacheRetriever';
52
+ }
53
+
54
+ private client: XacheClient;
55
+ private k: number;
56
+ private filterContext?: string;
57
+
58
+ constructor(config: XacheRetrieverConfig) {
59
+ super(config);
60
+
61
+ const chainPrefix = config.chain === 'solana' ? 'sol' : 'evm';
62
+ const did = `did:agent:${chainPrefix}:${config.walletAddress.toLowerCase()}` as DID;
63
+
64
+ this.client = new XacheClient({
65
+ apiUrl: config.apiUrl || 'https://api.xache.xyz',
66
+ did,
67
+ privateKey: config.privateKey,
68
+ });
69
+
70
+ this.k = config.k ?? 5;
71
+ this.filterContext = config.context;
72
+ }
73
+
74
+ async _getRelevantDocuments(
75
+ _query: string,
76
+ _runManager?: CallbackManagerForRetrieverRun
77
+ ): Promise<Document[]> {
78
+ // Use list method to get memories filtered by context
79
+ const result = await this.client.memory.list({
80
+ context: this.filterContext,
81
+ limit: this.k,
82
+ });
83
+
84
+ const memories = result.memories || [];
85
+
86
+ return memories.map(
87
+ (m) =>
88
+ new Document({
89
+ pageContent: m.context || '',
90
+ metadata: {
91
+ storageKey: m.storage_key,
92
+ context: m.context,
93
+ tier: m.storage_tier,
94
+ createdAt: m.created_at,
95
+ size: m.size_bytes,
96
+ },
97
+ })
98
+ );
99
+ }
100
+ }