@t2000/mcp 0.17.29 → 0.18.3
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 +3 -1
- package/dist/bin.d.ts +0 -2
- package/dist/bin.js +1421 -1
- package/dist/bin.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.js +1419 -20
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/dist/bin.d.ts.map +0 -1
- package/dist/errors.d.ts +0 -16
- package/dist/errors.d.ts.map +0 -1
- package/dist/errors.js +0 -31
- package/dist/errors.js.map +0 -1
- package/dist/errors.test.d.ts +0 -2
- package/dist/errors.test.d.ts.map +0 -1
- package/dist/errors.test.js +0 -50
- package/dist/errors.test.js.map +0 -1
- package/dist/gate.test.d.ts +0 -2
- package/dist/gate.test.d.ts.map +0 -1
- package/dist/gate.test.js +0 -60
- package/dist/gate.test.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/integration.test.d.ts +0 -2
- package/dist/integration.test.d.ts.map +0 -1
- package/dist/integration.test.js +0 -216
- package/dist/integration.test.js.map +0 -1
- package/dist/mutex.d.ts +0 -5
- package/dist/mutex.d.ts.map +0 -1
- package/dist/mutex.js +0 -17
- package/dist/mutex.js.map +0 -1
- package/dist/mutex.test.d.ts +0 -2
- package/dist/mutex.test.d.ts.map +0 -1
- package/dist/mutex.test.js +0 -35
- package/dist/mutex.test.js.map +0 -1
- package/dist/prompts.d.ts +0 -3
- package/dist/prompts.d.ts.map +0 -1
- package/dist/prompts.js +0 -635
- package/dist/prompts.js.map +0 -1
- package/dist/prompts.test.d.ts +0 -2
- package/dist/prompts.test.d.ts.map +0 -1
- package/dist/prompts.test.js +0 -126
- package/dist/prompts.test.js.map +0 -1
- package/dist/tools/read.d.ts +0 -4
- package/dist/tools/read.d.ts.map +0 -1
- package/dist/tools/read.js +0 -93
- package/dist/tools/read.js.map +0 -1
- package/dist/tools/read.test.d.ts +0 -2
- package/dist/tools/read.test.d.ts.map +0 -1
- package/dist/tools/read.test.js +0 -198
- package/dist/tools/read.test.js.map +0 -1
- package/dist/tools/safety.d.ts +0 -4
- package/dist/tools/safety.d.ts.map +0 -1
- package/dist/tools/safety.js +0 -66
- package/dist/tools/safety.js.map +0 -1
- package/dist/tools/safety.test.d.ts +0 -2
- package/dist/tools/safety.test.d.ts.map +0 -1
- package/dist/tools/safety.test.js +0 -100
- package/dist/tools/safety.test.js.map +0 -1
- package/dist/tools/write.d.ts +0 -4
- package/dist/tools/write.d.ts.map +0 -1
- package/dist/tools/write.js +0 -394
- package/dist/tools/write.js.map +0 -1
- package/dist/tools/write.test.d.ts +0 -2
- package/dist/tools/write.test.d.ts.map +0 -1
- package/dist/tools/write.test.js +0 -332
- package/dist/tools/write.test.js.map +0 -1
- package/dist/unlock.d.ts +0 -3
- package/dist/unlock.d.ts.map +0 -1
- package/dist/unlock.js +0 -24
- package/dist/unlock.js.map +0 -1
- package/dist/unlock.test.d.ts +0 -2
- package/dist/unlock.test.d.ts.map +0 -1
- package/dist/unlock.test.js +0 -57
- package/dist/unlock.test.js.map +0 -1
package/dist/integration.test.js
DELETED
|
@@ -1,216 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, vi, beforeAll, afterAll } from 'vitest';
|
|
2
|
-
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
3
|
-
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
|
4
|
-
import { InMemoryTransport } from '@modelcontextprotocol/sdk/inMemory.js';
|
|
5
|
-
import { registerReadTools } from './tools/read.js';
|
|
6
|
-
import { registerWriteTools } from './tools/write.js';
|
|
7
|
-
import { registerSafetyTools } from './tools/safety.js';
|
|
8
|
-
import { registerPrompts } from './prompts.js';
|
|
9
|
-
function createMockAgent() {
|
|
10
|
-
return {
|
|
11
|
-
address: vi.fn().mockReturnValue('0xtest_integration'),
|
|
12
|
-
balance: vi.fn().mockResolvedValue({
|
|
13
|
-
available: 96.81,
|
|
14
|
-
savings: 5.10,
|
|
15
|
-
gasReserve: { sui: 0.86, usdEquiv: 0.84 },
|
|
16
|
-
total: 102.75,
|
|
17
|
-
assets: { USDC: 101.91 },
|
|
18
|
-
stables: { USDC: 96.81 },
|
|
19
|
-
}),
|
|
20
|
-
positions: vi.fn().mockResolvedValue({
|
|
21
|
-
positions: [
|
|
22
|
-
{ protocol: 'navi', asset: 'USDC', type: 'save', amount: 5.10, apy: 4.92 },
|
|
23
|
-
],
|
|
24
|
-
}),
|
|
25
|
-
rates: vi.fn().mockResolvedValue({
|
|
26
|
-
USDC: { saveApy: 4.92, borrowApy: 8.5 },
|
|
27
|
-
}),
|
|
28
|
-
healthFactor: vi.fn().mockResolvedValue({
|
|
29
|
-
healthFactor: 4.24, supplied: 5.10, borrowed: 0, maxBorrow: 3.50,
|
|
30
|
-
}),
|
|
31
|
-
history: vi.fn().mockResolvedValue([
|
|
32
|
-
{ digest: '0xabc', action: 'send', amount: 10, asset: 'USDC' },
|
|
33
|
-
]),
|
|
34
|
-
earnings: vi.fn().mockResolvedValue({
|
|
35
|
-
totalYieldEarned: 0.15, currentApy: 4.92, dailyEarning: 0.0007,
|
|
36
|
-
}),
|
|
37
|
-
send: vi.fn().mockResolvedValue({
|
|
38
|
-
digest: '0xsend123', amount: 10, to: '0xrecipient',
|
|
39
|
-
}),
|
|
40
|
-
save: vi.fn().mockResolvedValue({ digest: '0xsave123', amount: 50 }),
|
|
41
|
-
withdraw: vi.fn().mockResolvedValue({ digest: '0xwithdraw123', amount: 25 }),
|
|
42
|
-
borrow: vi.fn().mockResolvedValue({ digest: '0xborrow123', amount: 5 }),
|
|
43
|
-
repay: vi.fn().mockResolvedValue({ digest: '0xrepay123', amount: 5 }),
|
|
44
|
-
exchange: vi.fn().mockResolvedValue({ digest: '0xswap123' }),
|
|
45
|
-
exchangeQuote: vi.fn().mockResolvedValue({
|
|
46
|
-
expectedOutput: 10.25, priceImpact: 0.01, fee: { amount: 0.03 },
|
|
47
|
-
}),
|
|
48
|
-
rebalance: vi.fn().mockResolvedValue({ moved: false, reason: 'no improvement' }),
|
|
49
|
-
maxBorrow: vi.fn().mockResolvedValue({ maxAmount: 3.50, healthFactorAfter: 2.1 }),
|
|
50
|
-
enforcer: {
|
|
51
|
-
assertNotLocked: vi.fn(),
|
|
52
|
-
check: vi.fn(),
|
|
53
|
-
getConfig: vi.fn().mockReturnValue({
|
|
54
|
-
locked: false, maxPerTx: 100, maxDailySend: 1000, dailyUsed: 0,
|
|
55
|
-
}),
|
|
56
|
-
isConfigured: vi.fn().mockReturnValue(true),
|
|
57
|
-
lock: vi.fn(),
|
|
58
|
-
set: vi.fn(),
|
|
59
|
-
},
|
|
60
|
-
contacts: {
|
|
61
|
-
list: vi.fn().mockReturnValue([]),
|
|
62
|
-
resolve: vi.fn().mockImplementation((nameOrAddress) => {
|
|
63
|
-
if (nameOrAddress.startsWith('0x'))
|
|
64
|
-
return { address: nameOrAddress };
|
|
65
|
-
throw new Error(`"${nameOrAddress}" is not a valid Sui address or saved contact.`);
|
|
66
|
-
}),
|
|
67
|
-
},
|
|
68
|
-
portfolio: {
|
|
69
|
-
getPositions: vi.fn().mockReturnValue([]),
|
|
70
|
-
getRealizedPnL: vi.fn().mockReturnValue(0),
|
|
71
|
-
},
|
|
72
|
-
getPortfolio: vi.fn().mockResolvedValue({
|
|
73
|
-
positions: [],
|
|
74
|
-
totalInvested: 0,
|
|
75
|
-
totalValue: 0,
|
|
76
|
-
unrealizedPnL: 0,
|
|
77
|
-
unrealizedPnLPct: 0,
|
|
78
|
-
realizedPnL: 0,
|
|
79
|
-
}),
|
|
80
|
-
investBuy: vi.fn().mockResolvedValue({
|
|
81
|
-
success: true, tx: '0xinvest123', type: 'buy', asset: 'SUI',
|
|
82
|
-
amount: 100, price: 0.95, usdValue: 95, fee: 0, gasCost: 0.001,
|
|
83
|
-
}),
|
|
84
|
-
investSell: vi.fn().mockResolvedValue({
|
|
85
|
-
success: true, tx: '0xinvest456', type: 'sell', asset: 'SUI',
|
|
86
|
-
amount: 50, price: 0.97, usdValue: 48.5, fee: 0, gasCost: 0.001,
|
|
87
|
-
}),
|
|
88
|
-
};
|
|
89
|
-
}
|
|
90
|
-
describe('integration: MCP client ↔ server', () => {
|
|
91
|
-
let client;
|
|
92
|
-
let server;
|
|
93
|
-
let clientTransport;
|
|
94
|
-
let serverTransport;
|
|
95
|
-
beforeAll(async () => {
|
|
96
|
-
const agent = createMockAgent();
|
|
97
|
-
server = new McpServer({ name: 't2000-test', version: '0.0.1' });
|
|
98
|
-
registerReadTools(server, agent);
|
|
99
|
-
registerWriteTools(server, agent);
|
|
100
|
-
registerSafetyTools(server, agent);
|
|
101
|
-
registerPrompts(server);
|
|
102
|
-
[clientTransport, serverTransport] = InMemoryTransport.createLinkedPair();
|
|
103
|
-
client = new Client({ name: 'test-client', version: '0.0.1' });
|
|
104
|
-
await server.connect(serverTransport);
|
|
105
|
-
await client.connect(clientTransport);
|
|
106
|
-
});
|
|
107
|
-
afterAll(async () => {
|
|
108
|
-
await client.close();
|
|
109
|
-
await server.close();
|
|
110
|
-
});
|
|
111
|
-
it('lists all 23 tools', async () => {
|
|
112
|
-
const { tools } = await client.listTools();
|
|
113
|
-
expect(tools).toHaveLength(23);
|
|
114
|
-
const names = tools.map(t => t.name).sort();
|
|
115
|
-
expect(names).toEqual([
|
|
116
|
-
't2000_address',
|
|
117
|
-
't2000_auto_invest',
|
|
118
|
-
't2000_balance',
|
|
119
|
-
't2000_borrow',
|
|
120
|
-
't2000_claim_rewards',
|
|
121
|
-
't2000_config',
|
|
122
|
-
't2000_contacts',
|
|
123
|
-
't2000_earnings',
|
|
124
|
-
't2000_exchange',
|
|
125
|
-
't2000_health',
|
|
126
|
-
't2000_history',
|
|
127
|
-
't2000_invest',
|
|
128
|
-
't2000_invest_rebalance',
|
|
129
|
-
't2000_lock',
|
|
130
|
-
't2000_portfolio',
|
|
131
|
-
't2000_positions',
|
|
132
|
-
't2000_rates',
|
|
133
|
-
't2000_rebalance',
|
|
134
|
-
't2000_repay',
|
|
135
|
-
't2000_save',
|
|
136
|
-
't2000_send',
|
|
137
|
-
't2000_strategy',
|
|
138
|
-
't2000_withdraw',
|
|
139
|
-
]);
|
|
140
|
-
});
|
|
141
|
-
it('lists all 15 prompts', async () => {
|
|
142
|
-
const { prompts } = await client.listPrompts();
|
|
143
|
-
expect(prompts).toHaveLength(15);
|
|
144
|
-
const names = prompts.map(p => p.name).sort();
|
|
145
|
-
expect(names).toEqual(['budget-check', 'claim-rewards', 'dca-advisor', 'financial-report', 'investment-strategy', 'morning-briefing', 'optimize-yield', 'quick-exchange', 'risk-check', 'safeguards', 'savings-strategy', 'send-money', 'sweep', 'weekly-recap', 'what-if']);
|
|
146
|
-
});
|
|
147
|
-
it('calls t2000_balance and returns structured JSON', async () => {
|
|
148
|
-
const result = await client.callTool({ name: 't2000_balance', arguments: {} });
|
|
149
|
-
expect(result.isError).toBeFalsy();
|
|
150
|
-
const content = result.content;
|
|
151
|
-
const data = JSON.parse(content[0].text);
|
|
152
|
-
expect(data.available).toBe(96.81);
|
|
153
|
-
expect(data.savings).toBe(5.10);
|
|
154
|
-
expect(data.total).toBe(102.75);
|
|
155
|
-
});
|
|
156
|
-
it('calls t2000_address and returns address', async () => {
|
|
157
|
-
const result = await client.callTool({ name: 't2000_address', arguments: {} });
|
|
158
|
-
const content = result.content;
|
|
159
|
-
const data = JSON.parse(content[0].text);
|
|
160
|
-
expect(data.address).toBe('0xtest_integration');
|
|
161
|
-
});
|
|
162
|
-
it('calls t2000_send with dryRun and returns preview', async () => {
|
|
163
|
-
const result = await client.callTool({
|
|
164
|
-
name: 't2000_send',
|
|
165
|
-
arguments: {
|
|
166
|
-
to: '0x0000000000000000000000000000000000000000000000000000000000000001',
|
|
167
|
-
amount: 10,
|
|
168
|
-
dryRun: true,
|
|
169
|
-
},
|
|
170
|
-
});
|
|
171
|
-
expect(result.isError).toBeFalsy();
|
|
172
|
-
const content = result.content;
|
|
173
|
-
const data = JSON.parse(content[0].text);
|
|
174
|
-
expect(data.preview).toBe(true);
|
|
175
|
-
expect(data.canSend).toBe(true);
|
|
176
|
-
expect(data.amount).toBe(10);
|
|
177
|
-
});
|
|
178
|
-
it('calls t2000_config show and returns limits', async () => {
|
|
179
|
-
const result = await client.callTool({
|
|
180
|
-
name: 't2000_config',
|
|
181
|
-
arguments: { action: 'show' },
|
|
182
|
-
});
|
|
183
|
-
const content = result.content;
|
|
184
|
-
const data = JSON.parse(content[0].text);
|
|
185
|
-
expect(data.locked).toBe(false);
|
|
186
|
-
expect(data.maxPerTx).toBe(100);
|
|
187
|
-
expect(data.maxDailySend).toBe(1000);
|
|
188
|
-
});
|
|
189
|
-
it('calls t2000_lock and returns locked state', async () => {
|
|
190
|
-
const result = await client.callTool({ name: 't2000_lock', arguments: {} });
|
|
191
|
-
const content = result.content;
|
|
192
|
-
const data = JSON.parse(content[0].text);
|
|
193
|
-
expect(data.locked).toBe(true);
|
|
194
|
-
expect(data.message).toContain('t2000 unlock');
|
|
195
|
-
});
|
|
196
|
-
it('returns error for invalid tool arguments', async () => {
|
|
197
|
-
const result = await client.callTool({
|
|
198
|
-
name: 't2000_send',
|
|
199
|
-
arguments: { to: 'not-a-valid-address', amount: 10 },
|
|
200
|
-
});
|
|
201
|
-
expect(result.isError).toBe(true);
|
|
202
|
-
const content = result.content;
|
|
203
|
-
const data = JSON.parse(content[0].text);
|
|
204
|
-
expect(data.code).toBeDefined();
|
|
205
|
-
});
|
|
206
|
-
it('gets a prompt with messages', async () => {
|
|
207
|
-
const result = await client.getPrompt({ name: 'financial-report' });
|
|
208
|
-
expect(result.messages).toHaveLength(1);
|
|
209
|
-
expect(result.messages[0].role).toBe('user');
|
|
210
|
-
expect(result.messages[0].content).toMatchObject({
|
|
211
|
-
type: 'text',
|
|
212
|
-
text: expect.stringContaining('t2000_balance'),
|
|
213
|
-
});
|
|
214
|
-
});
|
|
215
|
-
});
|
|
216
|
-
//# sourceMappingURL=integration.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"integration.test.js","sourceRoot":"","sources":["../src/integration.test.ts"],"names":[],"mappings":"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"}
|
package/dist/mutex.d.ts
DELETED
package/dist/mutex.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"mutex.d.ts","sourceRoot":"","sources":["../src/mutex.ts"],"names":[],"mappings":"AAAA,qBAAa,OAAO;IAClB,OAAO,CAAC,KAAK,CAAoC;IAE3C,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;CAY/C"}
|
package/dist/mutex.js
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
export class TxMutex {
|
|
2
|
-
queue = Promise.resolve();
|
|
3
|
-
async run(fn) {
|
|
4
|
-
let release;
|
|
5
|
-
const next = new Promise(r => { release = r; });
|
|
6
|
-
const prev = this.queue;
|
|
7
|
-
this.queue = next;
|
|
8
|
-
await prev;
|
|
9
|
-
try {
|
|
10
|
-
return await fn();
|
|
11
|
-
}
|
|
12
|
-
finally {
|
|
13
|
-
release();
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
//# sourceMappingURL=mutex.js.map
|
package/dist/mutex.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"mutex.js","sourceRoot":"","sources":["../src/mutex.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,OAAO;IACV,KAAK,GAAkB,OAAO,CAAC,OAAO,EAAE,CAAC;IAEjD,KAAK,CAAC,GAAG,CAAI,EAAoB;QAC/B,IAAI,OAAmB,CAAC;QACxB,MAAM,IAAI,GAAG,IAAI,OAAO,CAAO,CAAC,CAAC,EAAE,GAAG,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACtD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC;QACxB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;QAClB,MAAM,IAAI,CAAC;QACX,IAAI,CAAC;YACH,OAAO,MAAM,EAAE,EAAE,CAAC;QACpB,CAAC;gBAAS,CAAC;YACT,OAAQ,EAAE,CAAC;QACb,CAAC;IACH,CAAC;CACF"}
|
package/dist/mutex.test.d.ts
DELETED
package/dist/mutex.test.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"mutex.test.d.ts","sourceRoot":"","sources":["../src/mutex.test.ts"],"names":[],"mappings":""}
|
package/dist/mutex.test.js
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from 'vitest';
|
|
2
|
-
import { TxMutex } from './mutex.js';
|
|
3
|
-
describe('TxMutex', () => {
|
|
4
|
-
it('should serialize concurrent operations', async () => {
|
|
5
|
-
const mutex = new TxMutex();
|
|
6
|
-
const order = [];
|
|
7
|
-
const p1 = mutex.run(async () => {
|
|
8
|
-
await new Promise(r => setTimeout(r, 50));
|
|
9
|
-
order.push(1);
|
|
10
|
-
return 'first';
|
|
11
|
-
});
|
|
12
|
-
const p2 = mutex.run(async () => {
|
|
13
|
-
order.push(2);
|
|
14
|
-
return 'second';
|
|
15
|
-
});
|
|
16
|
-
const [r1, r2] = await Promise.all([p1, p2]);
|
|
17
|
-
expect(r1).toBe('first');
|
|
18
|
-
expect(r2).toBe('second');
|
|
19
|
-
expect(order).toEqual([1, 2]);
|
|
20
|
-
});
|
|
21
|
-
it('should release lock even if operation throws', async () => {
|
|
22
|
-
const mutex = new TxMutex();
|
|
23
|
-
await expect(mutex.run(async () => { throw new Error('fail'); })).rejects.toThrow('fail');
|
|
24
|
-
const result = await mutex.run(async () => 'recovered');
|
|
25
|
-
expect(result).toBe('recovered');
|
|
26
|
-
});
|
|
27
|
-
it('should handle sequential operations', async () => {
|
|
28
|
-
const mutex = new TxMutex();
|
|
29
|
-
const r1 = await mutex.run(async () => 1);
|
|
30
|
-
const r2 = await mutex.run(async () => 2);
|
|
31
|
-
expect(r1).toBe(1);
|
|
32
|
-
expect(r2).toBe(2);
|
|
33
|
-
});
|
|
34
|
-
});
|
|
35
|
-
//# sourceMappingURL=mutex.test.js.map
|
package/dist/mutex.test.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"mutex.test.js","sourceRoot":"","sources":["../src/mutex.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAErC,QAAQ,CAAC,SAAS,EAAE,GAAG,EAAE;IACvB,EAAE,CAAC,wCAAwC,EAAE,KAAK,IAAI,EAAE;QACtD,MAAM,KAAK,GAAG,IAAI,OAAO,EAAE,CAAC;QAC5B,MAAM,KAAK,GAAa,EAAE,CAAC;QAE3B,MAAM,EAAE,GAAG,KAAK,CAAC,GAAG,CAAC,KAAK,IAAI,EAAE;YAC9B,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;YAC1C,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACd,OAAO,OAAO,CAAC;QACjB,CAAC,CAAC,CAAC;QAEH,MAAM,EAAE,GAAG,KAAK,CAAC,GAAG,CAAC,KAAK,IAAI,EAAE;YAC9B,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACd,OAAO,QAAQ,CAAC;QAClB,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;QAC7C,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACzB,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC1B,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAChC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8CAA8C,EAAE,KAAK,IAAI,EAAE;QAC5D,MAAM,KAAK,GAAG,IAAI,OAAO,EAAE,CAAC;QAE5B,MAAM,MAAM,CACV,KAAK,CAAC,GAAG,CAAC,KAAK,IAAI,EAAE,GAAG,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CACpD,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAE1B,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC,WAAW,CAAC,CAAC;QACxD,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IACnC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qCAAqC,EAAE,KAAK,IAAI,EAAE;QACnD,MAAM,KAAK,GAAG,IAAI,OAAO,EAAE,CAAC;QAC5B,MAAM,EAAE,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAC1C,MAAM,EAAE,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAC1C,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACnB,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACrB,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
package/dist/prompts.d.ts
DELETED
package/dist/prompts.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../src/prompts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAGzE,wBAAgB,eAAe,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA4sBvD"}
|