@zhive/cli 0.6.3 → 0.6.5
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/CLAUDE.md +7 -0
- package/dist/backtest/CLAUDE.md +7 -0
- package/dist/cli.js +20 -0
- package/dist/commands/agent/commands/profile.js +3 -2
- package/dist/commands/agent/commands/profile.test.js +10 -12
- package/dist/commands/doctor/commands/index.js +93 -0
- package/dist/commands/megathread/commands/create-comment.js +4 -9
- package/dist/commands/megathread/commands/create-comment.test.js +15 -173
- package/dist/commands/megathread/commands/create-comments.js +83 -0
- package/dist/commands/megathread/commands/index.js +2 -0
- package/dist/commands/megathread/commands/list.js +5 -5
- package/dist/commands/megathread/commands/list.test.js +14 -14
- package/dist/commands/start/commands/prediction.js +3 -4
- package/dist/commands/start/hooks/useChat.js +40 -41
- package/dist/commands/start/services/command-registry.js +1 -1
- package/dist/index.js +2 -0
- package/dist/{agent → services/agent}/analysis.js +5 -5
- package/dist/{load-agent-env.js → services/agent/env.js} +1 -1
- package/dist/{agent → services/agent/helpers}/model.js +2 -2
- package/dist/{agent → services/agent/prompts}/memory-prompt.js +20 -22
- package/dist/{agent → services/agent/prompts}/prompt.js +80 -54
- package/dist/{agent → services/agent}/tools/market/client.js +1 -1
- package/dist/{agent → services/agent}/tools/mindshare/client.js +1 -1
- package/dist/{agents.js → services/config/agent.js} +2 -2
- package/dist/{config.js → services/config/config.js} +1 -7
- package/dist/services/config/constant.js +8 -0
- package/dist/shared/agent/config.js +75 -0
- package/dist/shared/agent/env.js +30 -0
- package/dist/shared/agent/helpers/model.js +92 -0
- package/dist/shared/ai-providers.js +66 -0
- package/dist/shared/config/agent.js +0 -11
- package/dist/shared/config/agent.test.js +4 -35
- package/package.json +2 -2
- package/dist/agent/app.js +0 -122
- package/dist/agent/commands/registry.js +0 -12
- package/dist/agent/components/AsciiTicker.js +0 -81
- package/dist/agent/components/CommandInput.js +0 -65
- package/dist/agent/components/HoneycombBoot.js +0 -291
- package/dist/agent/components/Spinner.js +0 -37
- package/dist/agent/hooks/useAgent.js +0 -480
- package/dist/agent/objects.js +0 -1
- package/dist/agent/process-lifecycle.js +0 -18
- package/dist/agent/run-headless.js +0 -189
- package/dist/agent/theme.js +0 -41
- package/dist/avatar.js +0 -34
- package/dist/backtest/default-backtest-data.js +0 -200
- package/dist/backtest/fetch.js +0 -41
- package/dist/backtest/import.js +0 -106
- package/dist/backtest/index.js +0 -10
- package/dist/backtest/results.js +0 -113
- package/dist/backtest/runner.js +0 -134
- package/dist/backtest/storage.js +0 -11
- package/dist/backtest/types.js +0 -1
- package/dist/commands/install.js +0 -50
- package/dist/commands/start/ui/PollText.js +0 -23
- package/dist/commands/start/ui/PredictionsPanel.js +0 -88
- package/dist/commands/start/ui/SpinnerContext.js +0 -20
- package/dist/components/InputGuard.js +0 -6
- package/dist/components/stdout-spinner.js +0 -48
- package/dist/create/CreateApp.js +0 -153
- package/dist/create/ai-generate.js +0 -147
- package/dist/create/generate.js +0 -73
- package/dist/create/steps/ApiKeyStep.js +0 -97
- package/dist/create/steps/AvatarStep.js +0 -16
- package/dist/create/steps/BioStep.js +0 -14
- package/dist/create/steps/DoneStep.js +0 -14
- package/dist/create/steps/IdentityStep.js +0 -163
- package/dist/create/steps/NameStep.js +0 -71
- package/dist/create/steps/ScaffoldStep.js +0 -58
- package/dist/create/steps/SoulStep.js +0 -58
- package/dist/create/steps/StrategyStep.js +0 -58
- package/dist/create/validate-api-key.js +0 -47
- package/dist/create/welcome.js +0 -304
- package/dist/list/ListApp.js +0 -79
- package/dist/migrate-templates/MigrateApp.js +0 -131
- package/dist/migrate-templates/migrate.js +0 -86
- package/dist/presets.js +0 -613
- package/dist/start/AgentProcessManager.js +0 -98
- package/dist/start/Dashboard.js +0 -92
- package/dist/start/SelectAgentApp.js +0 -81
- package/dist/start/StartApp.js +0 -189
- package/dist/start/patch-headless.js +0 -101
- package/dist/start/patch-managed-mode.js +0 -142
- package/dist/start/start-command.js +0 -24
- package/dist/theme.js +0 -54
- /package/dist/{agent → services/agent}/config.js +0 -0
- /package/dist/{agent → services/agent}/helpers.js +0 -0
- /package/dist/{agent → services/agent/prompts}/chat-prompt.js +0 -0
- /package/dist/{agent → services/agent}/skills/index.js +0 -0
- /package/dist/{agent → services/agent}/skills/skill-parser.js +0 -0
- /package/dist/{agent → services/agent}/skills/types.js +0 -0
- /package/dist/{agent → services/agent/tools}/edit-section.js +0 -0
- /package/dist/{agent → services/agent/tools}/fetch-rules.js +0 -0
- /package/dist/{agent → services/agent}/tools/index.js +0 -0
- /package/dist/{agent → services/agent}/tools/market/index.js +0 -0
- /package/dist/{agent → services/agent}/tools/market/tools.js +0 -0
- /package/dist/{agent → services/agent}/tools/mindshare/index.js +0 -0
- /package/dist/{agent → services/agent}/tools/mindshare/tools.js +0 -0
- /package/dist/{agent → services/agent}/tools/read-skill-tool.js +0 -0
- /package/dist/{agent → services/agent}/tools/ta/index.js +0 -0
- /package/dist/{agent → services/agent}/tools/ta/indicators.js +0 -0
- /package/dist/{agent → services/agent}/types.js +0 -0
- /package/dist/{ai-providers.js → services/ai-providers.js} +0 -0
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { HiveClient, loadConfig, } from '@zhive/sdk';
|
|
4
|
+
import { styled, symbols } from '../../shared/theme.js';
|
|
5
|
+
import { HIVE_API_URL } from '../../../shared/config/constant.js';
|
|
6
|
+
import { findAgentByName, scanAgents } from '../../../shared/config/agent.js';
|
|
7
|
+
import { printZodError } from '../../shared/ validation.js';
|
|
8
|
+
const convictionSchema = z
|
|
9
|
+
.object({
|
|
10
|
+
round: z.string().min(1),
|
|
11
|
+
conviction: z.coerce.number().min(-100).max(100),
|
|
12
|
+
text: z.string().min(1),
|
|
13
|
+
})
|
|
14
|
+
.array();
|
|
15
|
+
const CreateCommentsOptionsSchema = z.object({
|
|
16
|
+
agent: z.string().min(1),
|
|
17
|
+
json: z.string().transform((val, ctx) => {
|
|
18
|
+
try {
|
|
19
|
+
const parsed = convictionSchema.parse(JSON.parse(val));
|
|
20
|
+
return parsed;
|
|
21
|
+
}
|
|
22
|
+
catch (e) {
|
|
23
|
+
ctx.addIssue({
|
|
24
|
+
code: 'custom',
|
|
25
|
+
message: 'Invalid input',
|
|
26
|
+
});
|
|
27
|
+
return z.NEVER;
|
|
28
|
+
}
|
|
29
|
+
}),
|
|
30
|
+
});
|
|
31
|
+
export function createMegathreadCreateCommentsCommand() {
|
|
32
|
+
return new Command('create-comments')
|
|
33
|
+
.description('Batch create megathread comment')
|
|
34
|
+
.requiredOption('--agent <name>', 'Agent name')
|
|
35
|
+
.requiredOption('--json <object>', 'comment array')
|
|
36
|
+
.action(async (options) => {
|
|
37
|
+
const parseResult = CreateCommentsOptionsSchema.safeParse(options);
|
|
38
|
+
if (!parseResult.success) {
|
|
39
|
+
printZodError(parseResult);
|
|
40
|
+
process.exit(1);
|
|
41
|
+
}
|
|
42
|
+
const { agent: agentName, json } = parseResult.data;
|
|
43
|
+
const agentConfig = await findAgentByName(agentName);
|
|
44
|
+
if (!agentConfig) {
|
|
45
|
+
const agents = await scanAgents();
|
|
46
|
+
if (agents.length === 0) {
|
|
47
|
+
console.error(styled.red(`${symbols.cross} No agents found. Create one with: npx @zhive/cli@latest create`));
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
const availableNames = agents.map((a) => a.name).join(', ');
|
|
51
|
+
console.error(styled.red(`${symbols.cross} Agent "${agentName}" not found. Available agents: ${availableNames}`));
|
|
52
|
+
}
|
|
53
|
+
process.exit(1);
|
|
54
|
+
}
|
|
55
|
+
const credentials = await loadConfig(agentConfig.dir);
|
|
56
|
+
if (!credentials?.apiKey) {
|
|
57
|
+
console.error(styled.red(`${symbols.cross} No credentials found for agent "${agentName}". The agent may need to be registered first.`));
|
|
58
|
+
process.exit(1);
|
|
59
|
+
}
|
|
60
|
+
const client = new HiveClient(HIVE_API_URL, credentials.apiKey);
|
|
61
|
+
const payload = {
|
|
62
|
+
comments: [],
|
|
63
|
+
};
|
|
64
|
+
for (const item of json) {
|
|
65
|
+
payload.comments.push({
|
|
66
|
+
roundId: item.round,
|
|
67
|
+
conviction: item.conviction,
|
|
68
|
+
text: item.text,
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
try {
|
|
72
|
+
await client.postBatchMegathreadComments(payload);
|
|
73
|
+
console.log('');
|
|
74
|
+
console.log(styled.green(`${symbols.check} ${payload.comments.length} Comments posted successfully!`));
|
|
75
|
+
console.log('');
|
|
76
|
+
}
|
|
77
|
+
catch (error) {
|
|
78
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
79
|
+
console.error(styled.red(`${symbols.cross} Failed to post comment: ${message}`));
|
|
80
|
+
process.exit(1);
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
2
|
import { createMegathreadListCommand } from './list.js';
|
|
3
3
|
import { createMegathreadCreateCommentCommand } from './create-comment.js';
|
|
4
|
+
import { createMegathreadCreateCommentsCommand } from './create-comments.js';
|
|
4
5
|
export function createMegathreadCommand() {
|
|
5
6
|
const megathreadCommand = new Command('megathread').description('Megathread operations');
|
|
6
7
|
megathreadCommand.addCommand(createMegathreadListCommand());
|
|
7
8
|
megathreadCommand.addCommand(createMegathreadCreateCommentCommand());
|
|
9
|
+
megathreadCommand.addCommand(createMegathreadCreateCommentsCommand());
|
|
8
10
|
return megathreadCommand;
|
|
9
11
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
|
-
import { HiveClient, durationMsToTimeframe } from '@zhive/sdk';
|
|
2
|
+
import { HiveClient, durationMsToTimeframe, loadConfig } from '@zhive/sdk';
|
|
3
3
|
import { styled, symbols, border } from '../../shared/theme.js';
|
|
4
4
|
import { HIVE_API_URL } from '../../../shared/config/constant.js';
|
|
5
|
-
import { findAgentByName,
|
|
5
|
+
import { findAgentByName, scanAgents } from '../../../shared/config/agent.js';
|
|
6
6
|
import z from 'zod';
|
|
7
7
|
import { printZodError } from '../../shared/ validation.js';
|
|
8
8
|
const VALID_TIMEFRAMES = ['1h', '4h', '24h'];
|
|
@@ -50,12 +50,12 @@ export function createMegathreadListCommand() {
|
|
|
50
50
|
}
|
|
51
51
|
process.exit(1);
|
|
52
52
|
}
|
|
53
|
-
const
|
|
54
|
-
if (!
|
|
53
|
+
const config = await loadConfig(agentConfig.dir);
|
|
54
|
+
if (!config?.apiKey) {
|
|
55
55
|
console.error(styled.red(`${symbols.cross} No credentials found for agent "${agentName}". The agent may need to be registered first.`));
|
|
56
56
|
process.exit(1);
|
|
57
57
|
}
|
|
58
|
-
const client = new HiveClient(HIVE_API_URL,
|
|
58
|
+
const client = new HiveClient(HIVE_API_URL, config.apiKey);
|
|
59
59
|
try {
|
|
60
60
|
const rounds = await client.getUnpredictedRounds(timeframes);
|
|
61
61
|
console.log('');
|
|
@@ -17,7 +17,7 @@ vi.mock('@zhive/sdk', async () => {
|
|
|
17
17
|
HiveClient: vi.fn().mockImplementation(() => ({
|
|
18
18
|
getUnpredictedRounds: vi.fn(),
|
|
19
19
|
})),
|
|
20
|
-
|
|
20
|
+
loadConfig: vi.fn(),
|
|
21
21
|
TIMEFRAME_DURATION_MS: {
|
|
22
22
|
H1: 3600000,
|
|
23
23
|
H4: 14400000,
|
|
@@ -30,10 +30,10 @@ vi.mock('@zhive/sdk', async () => {
|
|
|
30
30
|
},
|
|
31
31
|
};
|
|
32
32
|
});
|
|
33
|
-
import { HiveClient,
|
|
33
|
+
import { HiveClient, loadConfig } from '@zhive/sdk';
|
|
34
34
|
import { createMegathreadListCommand } from './list.js';
|
|
35
35
|
const MockHiveClient = HiveClient;
|
|
36
|
-
const
|
|
36
|
+
const mockLoadConfig = loadConfig;
|
|
37
37
|
function createMockActiveRound(overrides = {}) {
|
|
38
38
|
return {
|
|
39
39
|
roundId: 'round-123',
|
|
@@ -88,21 +88,21 @@ describe('createMegathreadListCommand', () => {
|
|
|
88
88
|
expect(consoleErrorOutput.length).toBeGreaterThan(0);
|
|
89
89
|
});
|
|
90
90
|
it('accepts valid timeframe values', async () => {
|
|
91
|
-
|
|
91
|
+
mockLoadConfig.mockResolvedValue({ apiKey: 'test-api-key' });
|
|
92
92
|
mockGetUnpredictedRounds.mockResolvedValue([]);
|
|
93
93
|
const command = createMegathreadListCommand();
|
|
94
94
|
await command.parseAsync(['--agent', 'test-agent', '--timeframe', '1h,4h'], { from: 'user' });
|
|
95
95
|
expect(mockGetUnpredictedRounds).toHaveBeenCalledWith(['1h', '4h']);
|
|
96
96
|
});
|
|
97
97
|
it('accepts single valid timeframe', async () => {
|
|
98
|
-
|
|
98
|
+
mockLoadConfig.mockResolvedValue({ apiKey: 'test-api-key' });
|
|
99
99
|
mockGetUnpredictedRounds.mockResolvedValue([]);
|
|
100
100
|
const command = createMegathreadListCommand();
|
|
101
101
|
await command.parseAsync(['--agent', 'test-agent', '--timeframe', '24h'], { from: 'user' });
|
|
102
102
|
expect(mockGetUnpredictedRounds).toHaveBeenCalledWith(['24h']);
|
|
103
103
|
});
|
|
104
104
|
it('passes undefined when no timeframe filter specified', async () => {
|
|
105
|
-
|
|
105
|
+
mockLoadConfig.mockResolvedValue({ apiKey: 'test-api-key' });
|
|
106
106
|
mockGetUnpredictedRounds.mockResolvedValue([]);
|
|
107
107
|
const command = createMegathreadListCommand();
|
|
108
108
|
await command.parseAsync(['--agent', 'test-agent'], { from: 'user' });
|
|
@@ -122,13 +122,13 @@ describe('createMegathreadListCommand', () => {
|
|
|
122
122
|
});
|
|
123
123
|
describe('credentials validation', () => {
|
|
124
124
|
it('shows error when credentials are missing', async () => {
|
|
125
|
-
|
|
125
|
+
mockLoadConfig.mockResolvedValue(null);
|
|
126
126
|
const command = createMegathreadListCommand();
|
|
127
127
|
await expect(command.parseAsync(['--agent', 'test-agent'], { from: 'user' })).rejects.toThrow('process.exit(1)');
|
|
128
128
|
expect(consoleErrorOutput.join('\n')).toContain('No credentials found for agent "test-agent"');
|
|
129
129
|
});
|
|
130
130
|
it('shows error when credentials have no API key', async () => {
|
|
131
|
-
|
|
131
|
+
mockLoadConfig.mockResolvedValue({ apiKey: null });
|
|
132
132
|
const command = createMegathreadListCommand();
|
|
133
133
|
await expect(command.parseAsync(['--agent', 'test-agent'], { from: 'user' })).rejects.toThrow('process.exit(1)');
|
|
134
134
|
expect(consoleErrorOutput.join('\n')).toContain('No credentials found');
|
|
@@ -136,7 +136,7 @@ describe('createMegathreadListCommand', () => {
|
|
|
136
136
|
});
|
|
137
137
|
describe('rounds display', () => {
|
|
138
138
|
it('shows message when no unpredicted rounds available', async () => {
|
|
139
|
-
|
|
139
|
+
mockLoadConfig.mockResolvedValue({ apiKey: 'test-api-key' });
|
|
140
140
|
mockGetUnpredictedRounds.mockResolvedValue([]);
|
|
141
141
|
const command = createMegathreadListCommand();
|
|
142
142
|
await command.parseAsync(['--agent', 'test-agent'], { from: 'user' });
|
|
@@ -149,7 +149,7 @@ describe('createMegathreadListCommand', () => {
|
|
|
149
149
|
createMockActiveRound({ roundId: 'round-1', projectId: 'bitcoin', durationMs: 3600000 }),
|
|
150
150
|
createMockActiveRound({ roundId: 'round-2', projectId: 'ethereum', durationMs: 14400000 }),
|
|
151
151
|
];
|
|
152
|
-
|
|
152
|
+
mockLoadConfig.mockResolvedValue({ apiKey: 'test-api-key' });
|
|
153
153
|
mockGetUnpredictedRounds.mockResolvedValue(mockRounds);
|
|
154
154
|
const command = createMegathreadListCommand();
|
|
155
155
|
await command.parseAsync(['--agent', 'test-agent'], { from: 'user' });
|
|
@@ -168,7 +168,7 @@ describe('createMegathreadListCommand', () => {
|
|
|
168
168
|
const mockRounds = [
|
|
169
169
|
createMockActiveRound({ roundId: 'round-1', projectId: 'bitcoin', durationMs: 7200000 }),
|
|
170
170
|
];
|
|
171
|
-
|
|
171
|
+
mockLoadConfig.mockResolvedValue({ apiKey: 'test-api-key' });
|
|
172
172
|
mockGetUnpredictedRounds.mockResolvedValue(mockRounds);
|
|
173
173
|
const command = createMegathreadListCommand();
|
|
174
174
|
await command.parseAsync(['--agent', 'test-agent'], { from: 'user' });
|
|
@@ -178,7 +178,7 @@ describe('createMegathreadListCommand', () => {
|
|
|
178
178
|
});
|
|
179
179
|
describe('API error handling', () => {
|
|
180
180
|
it('shows error when API call fails', async () => {
|
|
181
|
-
|
|
181
|
+
mockLoadConfig.mockResolvedValue({ apiKey: 'test-api-key' });
|
|
182
182
|
mockGetUnpredictedRounds.mockRejectedValue(new Error('Network error'));
|
|
183
183
|
const command = createMegathreadListCommand();
|
|
184
184
|
await expect(command.parseAsync(['--agent', 'test-agent'], { from: 'user' })).rejects.toThrow('process.exit(1)');
|
|
@@ -186,7 +186,7 @@ describe('createMegathreadListCommand', () => {
|
|
|
186
186
|
expect(consoleErrorOutput.join('\n')).toContain('Network error');
|
|
187
187
|
});
|
|
188
188
|
it('handles non-Error exceptions', async () => {
|
|
189
|
-
|
|
189
|
+
mockLoadConfig.mockResolvedValue({ apiKey: 'test-api-key' });
|
|
190
190
|
mockGetUnpredictedRounds.mockRejectedValue('String error');
|
|
191
191
|
const command = createMegathreadListCommand();
|
|
192
192
|
await expect(command.parseAsync(['--agent', 'test-agent'], { from: 'user' })).rejects.toThrow('process.exit(1)');
|
|
@@ -196,7 +196,7 @@ describe('createMegathreadListCommand', () => {
|
|
|
196
196
|
});
|
|
197
197
|
describe('works with different fixture agents', () => {
|
|
198
198
|
it('works with empty-agent', async () => {
|
|
199
|
-
|
|
199
|
+
mockLoadConfig.mockResolvedValue({ apiKey: 'test-api-key' });
|
|
200
200
|
mockGetUnpredictedRounds.mockResolvedValue([]);
|
|
201
201
|
const command = createMegathreadListCommand();
|
|
202
202
|
await command.parseAsync(['--agent', 'empty-agent'], { from: 'user' });
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { loadConfig } from '@zhive/sdk';
|
|
2
2
|
import { HIVE_API_URL } from '../../../shared/config/constant.js';
|
|
3
3
|
import { extractErrorMessage } from '../../../shared/agent/utils.js';
|
|
4
4
|
import { styled } from '../../shared/theme.js';
|
|
@@ -50,13 +50,12 @@ function getOutcomeStr(pred) {
|
|
|
50
50
|
return `[WIN] +${pred.honey.toFixed(2)} Honey`;
|
|
51
51
|
}
|
|
52
52
|
if (pred.wax > 0) {
|
|
53
|
-
return `[
|
|
53
|
+
return `[LOSS] +${pred.wax.toFixed(2)} Wax`;
|
|
54
54
|
}
|
|
55
55
|
return '[LOSS]';
|
|
56
56
|
}
|
|
57
57
|
export async function predictionSlashCommand(agentName, callbacks) {
|
|
58
|
-
const
|
|
59
|
-
const credentials = await loadCredentials(filePath);
|
|
58
|
+
const credentials = await loadConfig();
|
|
60
59
|
if (!credentials?.apiKey) {
|
|
61
60
|
callbacks.onError?.('Agent not registered yet. Wait for agent to start.');
|
|
62
61
|
return;
|
|
@@ -7,7 +7,6 @@ import { fetchRulesTool } from '../../../shared/agent/tools/fetch-rules.js';
|
|
|
7
7
|
import { extractErrorMessage } from '../../../shared/agent/utils.js';
|
|
8
8
|
import { loadAgentConfig } from '../../../shared/config/agent.js';
|
|
9
9
|
import { getModel } from '../../../shared/config/ai-providers.js';
|
|
10
|
-
import { backtestSlashCommand } from '../commands/backtest.js';
|
|
11
10
|
import { predictionSlashCommand } from '../commands/prediction.js';
|
|
12
11
|
import { skillsSlashCommand } from '../commands/skills.js';
|
|
13
12
|
import { SLASH_COMMANDS } from '../services/command-registry.js';
|
|
@@ -73,46 +72,46 @@ export function useChat(agentName) {
|
|
|
73
72
|
const memoryOutput = memoryRef.current || 'No memory stored yet.';
|
|
74
73
|
addChatActivity({ type: 'chat-agent', text: memoryOutput });
|
|
75
74
|
},
|
|
76
|
-
'/backtest': async () => {
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
},
|
|
75
|
+
// '/backtest': async () => {
|
|
76
|
+
// const config: RunnerConfig = {
|
|
77
|
+
// agentPath: process.cwd(),
|
|
78
|
+
// soulContent: soulContentRef.current,
|
|
79
|
+
// strategyContent: strategyContentRef.current,
|
|
80
|
+
// agentName: agentName,
|
|
81
|
+
// };
|
|
82
|
+
// await backtestSlashCommand(parts.slice(1), config, {
|
|
83
|
+
// onFetchStart: (numThreads) => {
|
|
84
|
+
// addChatActivity({
|
|
85
|
+
// type: 'chat-agent',
|
|
86
|
+
// text: `Fetching ${numThreads} resolved threads...`,
|
|
87
|
+
// });
|
|
88
|
+
// },
|
|
89
|
+
// onFetchError: (error: string) => {
|
|
90
|
+
// addChatActivity({
|
|
91
|
+
// type: 'chat-agent',
|
|
92
|
+
// text: `API fetch failed (${error}), falling back to default dataset...`,
|
|
93
|
+
// });
|
|
94
|
+
// addChatActivity({
|
|
95
|
+
// type: 'chat-agent',
|
|
96
|
+
// text: 'Starting backtest against default dataset...',
|
|
97
|
+
// });
|
|
98
|
+
// },
|
|
99
|
+
// onThreadStart: (index, total, thread) => {
|
|
100
|
+
// addChatActivity({
|
|
101
|
+
// type: 'chat-agent',
|
|
102
|
+
// text: `Processing ${index + 1}/${total}: ${thread.project_name}...`,
|
|
103
|
+
// });
|
|
104
|
+
// },
|
|
105
|
+
// onBacktestSuccess: (report: string) => {
|
|
106
|
+
// addChatActivity({ type: 'chat-agent', text: report });
|
|
107
|
+
// sessionMessagesRef.current.push({ role: 'assistant', content: report });
|
|
108
|
+
// },
|
|
109
|
+
// onBacktestError: (err: unknown) => {
|
|
110
|
+
// const errMessage = extractErrorMessage(err);
|
|
111
|
+
// addChatActivity({ type: 'chat-error', text: `Backtest failed: ${errMessage}` });
|
|
112
|
+
// },
|
|
113
|
+
// });
|
|
114
|
+
// },
|
|
116
115
|
'/prediction': async () => {
|
|
117
116
|
await predictionSlashCommand(agentName, {
|
|
118
117
|
onFetchStart: () => {
|
|
@@ -3,7 +3,7 @@ export const SLASH_COMMANDS = [
|
|
|
3
3
|
{ name: '/help', description: 'Show available commands' },
|
|
4
4
|
{ name: '/clear', description: 'Clear chat history' },
|
|
5
5
|
{ name: '/memory', description: 'Show current memory state' },
|
|
6
|
-
{ name: '/backtest', description: 'Run agent against test set (/backtest <num> fetches from API)' },
|
|
6
|
+
// { name: '/backtest', description: 'Run agent against test set (/backtest <num> fetches from API)' },
|
|
7
7
|
{ name: '/prediction', description: 'Show your last 10 resolved predictions' },
|
|
8
8
|
];
|
|
9
9
|
export function filterCommands(prefix) {
|
package/dist/index.js
CHANGED
|
@@ -9,6 +9,7 @@ import { createStartCommand } from './commands/start/commands/index.js';
|
|
|
9
9
|
import { createStartAllCommand } from './commands/start-all/commands/index.js';
|
|
10
10
|
import { createRunCommand } from './commands/run/commands/index.js';
|
|
11
11
|
import { createMigrateTemplatesCommand } from './commands/migrate-templates/commands/index.js';
|
|
12
|
+
import { createDoctorCommand } from './commands/doctor/commands/index.js';
|
|
12
13
|
const require = createRequire(import.meta.url);
|
|
13
14
|
const packageJson = require('../package.json');
|
|
14
15
|
const program = new Command();
|
|
@@ -21,6 +22,7 @@ program.addCommand(createStartCommand());
|
|
|
21
22
|
program.addCommand(createStartAllCommand());
|
|
22
23
|
program.addCommand(createRunCommand());
|
|
23
24
|
program.addCommand(createMigrateTemplatesCommand());
|
|
25
|
+
program.addCommand(createDoctorCommand());
|
|
24
26
|
// Show help with exit code 0 when no arguments provided
|
|
25
27
|
const args = process.argv.slice(2);
|
|
26
28
|
if (args.length === 0) {
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { generateText, Output, ToolLoopAgent } from 'ai';
|
|
2
2
|
import { z } from 'zod';
|
|
3
|
-
import { buildAnalystPrompt, buildMegathreadPrompt } from './prompt.js';
|
|
4
|
-
import { loadMemory, saveMemory, getMemoryLineCount, MEMORY_SOFT_LIMIT } from '@hive-org/sdk';
|
|
5
|
-
import { buildMemoryExtractionPrompt } from './memory-prompt.js';
|
|
3
|
+
import { buildAnalystPrompt, buildMegathreadPrompt } from './prompts/prompt.js';
|
|
4
|
+
import { loadMemory, saveMemory, getMemoryLineCount, MEMORY_SOFT_LIMIT, } from '@hive-org/sdk';
|
|
5
|
+
import { buildMemoryExtractionPrompt } from './prompts/memory-prompt.js';
|
|
6
6
|
import { stripCodeFences } from './helpers.js';
|
|
7
|
-
import { getModel } from './model.js';
|
|
7
|
+
import { getModel } from './helpers/model.js';
|
|
8
8
|
// ─── Cache Helpers ─────────────────────────────────
|
|
9
9
|
function cacheableSystem(content) {
|
|
10
10
|
const message = {
|
|
@@ -146,7 +146,7 @@ export async function extractAndSaveMemory(sessionMessages) {
|
|
|
146
146
|
const model = await getModel();
|
|
147
147
|
const { text } = await generateText({
|
|
148
148
|
model,
|
|
149
|
-
|
|
149
|
+
prompt,
|
|
150
150
|
});
|
|
151
151
|
const cleaned = stripCodeFences(text);
|
|
152
152
|
await saveMemory(cleaned);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { AI_PROVIDERS } from '
|
|
2
|
-
import { getAgentProviderKeys } from '../
|
|
1
|
+
import { AI_PROVIDERS } from '../../ai-providers.js';
|
|
2
|
+
import { getAgentProviderKeys } from '../env.js';
|
|
3
3
|
const PROVIDERS = [
|
|
4
4
|
{
|
|
5
5
|
label: 'Anthropic',
|
|
@@ -1,9 +1,25 @@
|
|
|
1
1
|
export function buildMemoryExtractionPrompt(context) {
|
|
2
2
|
const { currentMemory, sessionMessages, lineCount } = context;
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
let sessionSection = '';
|
|
4
|
+
if (sessionMessages.length > 0) {
|
|
5
|
+
const listed = sessionMessages
|
|
6
|
+
.map((m) => `${m.role === 'user' ? 'Operator' : 'Agent'}: ${m.content}`)
|
|
7
|
+
.join('\n');
|
|
8
|
+
sessionSection = `\n## Session Chat Log\n\n${listed}\n`;
|
|
9
|
+
}
|
|
10
|
+
const currentMemorySection = currentMemory.trim().length > 0
|
|
11
|
+
? `\n## Current MEMORY.md\n\n\`\`\`markdown\n${currentMemory}\n\`\`\`\n`
|
|
12
|
+
: '\n## Current MEMORY.md\n\n(empty - this is a fresh agent)\n';
|
|
13
|
+
const consolidationNote = lineCount > 200
|
|
14
|
+
? `\n**IMPORTANT: The current memory is ${lineCount} lines, exceeding the 200-line soft limit. Aggressively consolidate: merge related items, remove outdated or low-value entries, and keep only the most important context.**\n`
|
|
15
|
+
: '';
|
|
16
|
+
const prompt = `You are an AI trading agent's memory system. Your job is to maintain conversational continuity between sessions with the agent's operator.
|
|
17
|
+
${currentMemorySection}${consolidationNote}
|
|
18
|
+
## Session Activity
|
|
19
|
+
${sessionSection}
|
|
20
|
+
## Instructions
|
|
5
21
|
|
|
6
|
-
Review the session
|
|
22
|
+
Review the session chat log above and update the agent's MEMORY.md file. This memory is about **conversational continuity** — making the agent feel like it remembers past sessions with its operator.
|
|
7
23
|
|
|
8
24
|
Focus on extracting:
|
|
9
25
|
1. **Topics discussed** — what subjects came up in conversation (e.g., "we talked about ETH gas fees", "operator asked about macro outlook")
|
|
@@ -25,23 +41,5 @@ Follow these rules:
|
|
|
25
41
|
6. **Keep it under ~200 lines** — This file is injected into every prompt, so brevity matters.
|
|
26
42
|
|
|
27
43
|
Output the complete updated MEMORY.md content. Start with \`# Memory\` as the top-level header. Output ONLY the markdown content, no code fences or explanation.`;
|
|
28
|
-
|
|
29
|
-
let sessionSection = '';
|
|
30
|
-
if (sessionMessages.length > 0) {
|
|
31
|
-
const listed = sessionMessages
|
|
32
|
-
.map((m) => `${m.role === 'user' ? 'Operator' : 'Agent'}: ${m.content}`)
|
|
33
|
-
.join('\n');
|
|
34
|
-
sessionSection = `\n## Session Chat Log\n\n${listed}\n`;
|
|
35
|
-
}
|
|
36
|
-
const currentMemorySection = currentMemory.trim().length > 0
|
|
37
|
-
? `\n## Current MEMORY.md\n\n\`\`\`markdown\n${currentMemory}\n\`\`\`\n`
|
|
38
|
-
: '\n## Current MEMORY.md\n\n(empty - this is a fresh agent)\n';
|
|
39
|
-
const consolidationNote = lineCount > 200
|
|
40
|
-
? `\n**IMPORTANT: The current memory is ${lineCount} lines, exceeding the 200-line soft limit. Aggressively consolidate: merge related items, remove outdated or low-value entries, and keep only the most important context.**\n`
|
|
41
|
-
: '';
|
|
42
|
-
const prompt = `${currentMemorySection}${consolidationNote}
|
|
43
|
-
## Session Activity
|
|
44
|
-
${sessionSection}
|
|
45
|
-
Update the MEMORY.md based on the session activity above.`;
|
|
46
|
-
return { system, prompt };
|
|
44
|
+
return prompt;
|
|
47
45
|
}
|