@j-o-r/hello-dave 0.0.2 → 0.0.4
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/CHANGELOG.md +21 -0
- package/README.md +445 -160
- package/README.md.backup +269 -0
- package/README.md.bak +481 -0
- package/README.md.bak.1774780058 +338 -0
- package/README.md.bak2 +455 -0
- package/bin/dave.js +165 -0
- package/docs.bak.1774780058/agent-manager.md +167 -0
- package/docs.bak.1774780058/agent-manager.md.bak +137 -0
- package/docs.bak.1774780058/agent-manager.md.bak2 +157 -0
- package/docs.bak.1774780058/codeserver-pattern.md +191 -0
- package/docs.bak.1774780058/path-resolution-best-practices.md +104 -0
- package/docs.bak.1774780058/project-overview.md +67 -0
- package/docs.bak.1774780058/project-overview.md.bak +67 -0
- package/docs.bak.1774780058/prompt-class.md +141 -0
- package/docs.bak.1774780058/prompt-class.md.bak +142 -0
- package/docs.bak.1774780058/tools-syntax-validation.md +121 -0
- package/docs.bak.1774780058/tools-syntax-validation.md.bak2 +125 -0
- package/docs.bak.1774780058/tools-syntax-validation.md.bak3 +125 -0
- package/docs.bak.1774780058/tools-syntax-validation.md.bak4 +106 -0
- package/docs.bak.1774780058/tools-syntax-validation.md.bak_path +106 -0
- package/docs.bak.1774780058/toolset.md +164 -0
- package/docs.bak.1774780058/toolset.md.bak +94 -0
- package/docs.bak.1774780058/toolset.md.bak3 +161 -0
- package/docs.bak.1774780058/toolset.md.bak4 +161 -0
- package/docs.bak.1774780058/toolset.md.bak5 +161 -0
- package/docs.bak.1774780058/toolset.md.bak6 +163 -0
- package/docs.bak.1774780058/toolset.md.bak_path +163 -0
- package/docs.bak.1774780058/toolset.md.bak_syntax +161 -0
- package/docs.bak.1774780058/xai-responses.md +111 -0
- package/docs.bak.1774780058/xai-responses.md.bak +107 -0
- package/docs.bak.1774780058/xai-responses.md.bak2 +107 -0
- package/docs.bak.1774780058/xai_collections.md +106 -0
- package/examples/ask_agent.js +137 -0
- package/examples/code_agent.js +149 -0
- package/examples/coderev_agent.js +136 -0
- package/examples/codeserver.sh +47 -0
- package/examples/daisy_agent.js +170 -0
- package/examples/docs_agent.js +148 -0
- package/examples/gpt_agent.js +125 -0
- package/examples/grok_agent.js +132 -0
- package/examples/grok_agent.js.bak +98 -0
- package/examples/grok_agent.js.bak.2 +99 -0
- package/examples/grok_agent.js.bak.3 +1 -0
- package/examples/grok_agent.js.bak.4 +124 -0
- package/examples/grok_agent.js.bak.5 +1 -0
- package/examples/grok_agent.js.bak.6 +1 -0
- package/examples/memory_agent.js +152 -0
- package/examples/npm_agent.js +202 -0
- package/examples/npm_agent.js.bak.3 +2 -0
- package/examples/npm_agent.js.bak.4 +205 -0
- package/examples/npm_agent.js.bak.5 +1 -0
- package/examples/npm_agent.js.bak.6 +1 -0
- package/examples/prompt_agent.js +133 -0
- package/examples/readme_agent.js +148 -0
- package/examples/spawn_agent.js +293 -0
- package/examples/test_agent.js +187 -0
- package/examples/todo_agent.js +175 -0
- package/examples.bak.1774780058/ask_agent.js +114 -0
- package/examples.bak.1774780058/code_agent.js +149 -0
- package/examples.bak.1774780058/coderev_agent.js +72 -0
- package/examples.bak.1774780058/codeserver.sh +47 -0
- package/examples.bak.1774780058/daisy_agent.js +177 -0
- package/examples.bak.1774780058/docs_agent.js +119 -0
- package/{bin/hdAsk.js → examples.bak.1774780058/gpt_agent.js} +46 -40
- package/examples.bak.1774780058/grok_agent.js +98 -0
- package/examples.bak.1774780058/memory_agent.js +112 -0
- package/examples.bak.1774780058/npm_agent.js +175 -0
- package/examples.bak.1774780058/prompt_agent.js +112 -0
- package/examples.bak.1774780058/readme_agent.js +144 -0
- package/examples.bak.1774780058/spawn_agent.js +263 -0
- package/examples.bak.1774780058/test_agent.js +162 -0
- package/examples.bak.1774780058/todo_agent.js +138 -0
- package/lib/API/openai.com/reponses/text.js +12 -18
- package/lib/API/x.ai/collections.js +354 -0
- package/lib/API/x.ai/files.js +218 -0
- package/lib/API/x.ai/responses.js +492 -0
- package/lib/API/x.ai/text.js +1 -1
- package/lib/AgentClient.js +13 -6
- package/lib/AgentManager.js +80 -10
- package/lib/AgentServer.js +50 -22
- package/lib/Cli.js +7 -1
- package/lib/Prompt.js +4 -2
- package/lib/ToolSet.js +2 -1
- package/lib/genericToolset.js +258 -88
- package/lib/genericToolset.js.bak_syntax +402 -0
- package/lib/index.js +4 -2
- package/lib/wsCli.js +256 -0
- package/lib/wsIO.js +96 -0
- package/package.json +26 -21
- package/scenarios.bak.1774780058/data/eval_node_message.json +9 -0
- package/scenarios.bak.1774780058/data/hist_oa.json +66 -0
- package/scenarios.bak.1774780058/data/o3_response1.json +96 -0
- package/scenarios.bak.1774780058/data/oa_reasoning_parse.json +112 -0
- package/scenarios.bak.1774780058/data/tool_oa.json +96 -0
- package/scenarios.bak.1774780058/data/tool_xai.json +59 -0
- package/scenarios.bak.1774780058/data/tool_xai2.json +40 -0
- package/scenarios.bak.1774780058/data/xai-response-1.json +59 -0
- package/scenarios.bak.1774780058/data/xai-response-2.json +10 -0
- package/scenarios.bak.1774780058/data/xai_reasoning_tools_resp.json +59 -0
- package/scenarios.bak.1774780058/data/xai_search_response.json +58 -0
- package/scenarios.bak.1774780058/environment.js +10 -0
- package/scenarios.bak.1774780058/example.js +17 -0
- package/scenarios.bak.1774780058/genericToolset.test.js +182 -0
- package/scenarios.bak.1774780058/grok.js +113 -0
- package/scenarios.bak.1774780058/memory-tools.js +51 -0
- package/scenarios.bak.1774780058/openai-o3.js +137 -0
- package/scenarios.bak.1774780058/openai-prompt.js +155 -0
- package/scenarios.bak.1774780058/openai-session.js +148 -0
- package/scenarios.bak.1774780058/openai.js +102 -0
- package/scenarios.bak.1774780058/prompt.js +118 -0
- package/scenarios.bak.1774780058/promptFishbowl.js +76 -0
- package/scenarios.bak.1774780058/search.brave.com.js +25 -0
- package/scenarios.bak.1774780058/sh.js +15 -0
- package/scenarios.bak.1774780058/test-wsio.js +26 -0
- package/scenarios.bak.1774780058/testToolset.js +42 -0
- package/scenarios.bak.1774780058/toolset.js +16 -0
- package/scenarios.bak.1774780058/toolset.test.js +141 -0
- package/scenarios.bak.1774780058/write_file_syntax.test.js +145 -0
- package/scenarios.bak.1774780058/write_file_validation/README.md +30 -0
- package/scenarios.bak.1774780058/write_file_validation/bad.js +3 -0
- package/scenarios.bak.1774780058/write_file_validation/good.js +4 -0
- package/scenarios.bak.1774780058/write_file_validation/test.sh +43 -0
- package/scenarios.bak.1774780058/wsClient.js +69 -0
- package/scenarios.bak.1774780058/xai_responses.integration.test.js +57 -0
- package/scenarios.bak.1774780058/xai_responses.test.js +154 -0
- package/scenarios.bak.1774780058/xaicoll.js +50 -0
- package/scenarios.bak.1774780058/xaifiles.js +48 -0
- package/types/API/openai.com/reponses/text.d.ts +17 -3
- package/types/API/x.ai/collections.d.ts +167 -0
- package/types/API/x.ai/files.d.ts +84 -0
- package/types/API/x.ai/responses.d.ts +379 -0
- package/types/AgentClient.d.ts +5 -0
- package/types/AgentManager.d.ts +25 -31
- package/types/AgentServer.d.ts +5 -1
- package/types/Prompt.d.ts +4 -2
- package/types/ToolSet.d.ts +1 -0
- package/types/index.d.ts +4 -3
- package/types/wsCli.d.ts +3 -0
- package/types/wsIO.d.ts +26 -0
- package/utils/bars.js +40 -0
- package/utils/clear_sessions.sh +54 -0
- package/{bin/hdInspect.js → utils/format_log.js} +5 -0
- package/utils/list_sessions.sh +46 -0
- package/utils/search_sessions.sh +73 -0
- package/utils/syntax_check.sh +61 -0
- package/utils/test.sh +46 -0
- package/bin/hdClear.js +0 -13
- package/bin/hdCode.js +0 -115
- package/bin/hdConnect.js +0 -230
- package/bin/hdNpm.js +0 -114
- package/bin/hdPrompt.js +0 -108
- package/examples/claude-test.js +0 -89
- package/examples/claude.js +0 -143
- package/examples/gpt.js +0 -127
- package/examples/gpt_code.js +0 -125
- package/examples/gpt_note_keeping.js +0 -117
- package/examples/grok.js +0 -119
- package/examples/grok_code.js +0 -114
- package/examples/grok_note_keeping.js +0 -111
- package/module.md +0 -189
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Test, assert } from '@j-o-r/sh';
|
|
3
|
+
import { request } from '../lib/API/x.ai/responses.js';
|
|
4
|
+
import Prompt from '../lib/Prompt.js';
|
|
5
|
+
import tools from './testToolset.js'; // Reuse weather mock for recursion
|
|
6
|
+
|
|
7
|
+
const t = new Test();
|
|
8
|
+
|
|
9
|
+
// Real API: tools + recursion (default model)
|
|
10
|
+
t.add('request: real with tools (recursion)', async () => {
|
|
11
|
+
const p = new Prompt();
|
|
12
|
+
p.add('system', 'You are helpful. Use tools for weather.', true);
|
|
13
|
+
p.add('user', 'Weather in Amsterdam?');
|
|
14
|
+
const msg = await request(p, tools);
|
|
15
|
+
assert.strictEqual(msg.role, 'assistant');
|
|
16
|
+
assert.ok(msg.content.some(c => c.type === 'text'), 'Final text response');
|
|
17
|
+
const toolMsg = p.messages.find(m => m.role === 'tool');
|
|
18
|
+
assert.ok(toolMsg, 'Tool executed');
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
// Real API: custom options (non-reasoning model)
|
|
22
|
+
t.add('request: real options (model/temp/store)', async () => {
|
|
23
|
+
const p = new Prompt();
|
|
24
|
+
p.add('system', 'Answer in JSON.', true);
|
|
25
|
+
p.add('user', '2+2 as JSON.');
|
|
26
|
+
const msg = await request(p, null, {
|
|
27
|
+
model: 'grok-4-fast-non-reasoning',
|
|
28
|
+
temperature: 0.1,
|
|
29
|
+
store: true,
|
|
30
|
+
max_output_tokens: 100
|
|
31
|
+
});
|
|
32
|
+
assert.strictEqual(msg.role, 'assistant');
|
|
33
|
+
assert.ok(msg.content[0].text.includes('4'), 'JSON with 4');
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
// Real API: reasoning rejected (unsupported on default model)
|
|
37
|
+
t.add('request: reasoning rejected on incompatible model', async () => {
|
|
38
|
+
const p = new Prompt();
|
|
39
|
+
p.add('user', 'Why is sky blue?');
|
|
40
|
+
await assert.rejects(
|
|
41
|
+
() => request(p, null, { reasoning: { effort: 'high', summary: 'concise' } }),
|
|
42
|
+
/invalid argument|reasoningEffort/
|
|
43
|
+
);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
// Real API: invalid model rejects (4xx)
|
|
47
|
+
t.add('request: invalid model rejects', async () => {
|
|
48
|
+
const p = new Prompt();
|
|
49
|
+
p.add('user', 'Hi');
|
|
50
|
+
await assert.rejects(
|
|
51
|
+
() => request(p, null, { model: 'invalid-xyz' }),
|
|
52
|
+
/Error.*4\\d{2}|Model not found|400/
|
|
53
|
+
);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
const report = await t.run();
|
|
57
|
+
process.exit(report.errors > 0 ? 1 : 0);
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Test, assert } from '@j-o-r/sh';
|
|
3
|
+
import { generateRequest, parseResponse, request } from '../lib/API/x.ai/responses.js';
|
|
4
|
+
import Prompt from '../lib/Prompt.js';
|
|
5
|
+
import ToolSet from '../lib/ToolSet.js';
|
|
6
|
+
import tools from './testToolset.js';
|
|
7
|
+
|
|
8
|
+
const t = new Test();
|
|
9
|
+
|
|
10
|
+
// Fake response helpers
|
|
11
|
+
const fakeTextRes = () => ({
|
|
12
|
+
status: 200,
|
|
13
|
+
response: {
|
|
14
|
+
id: 'fake-text',
|
|
15
|
+
model: 'grok-beta',
|
|
16
|
+
created_at: Math.floor(Date.now() / 1000),
|
|
17
|
+
usage: { input_tokens: 10, output_tokens: 5 },
|
|
18
|
+
output: [{ type: 'message', content: [{ type: 'output_text', text: 'Hello!' }] }]
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
const fakeReasoningRes = () => ({
|
|
23
|
+
status: 200,
|
|
24
|
+
response: {
|
|
25
|
+
id: 'fake-reason',
|
|
26
|
+
model: 'grok-beta',
|
|
27
|
+
created_at: Math.floor(Date.now() / 1000),
|
|
28
|
+
usage: { input_tokens: 10, output_tokens: 5 },
|
|
29
|
+
output: [{ type: 'reasoning', summary: [{ type: 'summary_text', text: 'Thought.' }] }]
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
const fakeCitationRes = () => ({
|
|
34
|
+
status: 200,
|
|
35
|
+
response: {
|
|
36
|
+
id: 'fake-cit',
|
|
37
|
+
model: 'grok-beta',
|
|
38
|
+
created_at: Math.floor(Date.now() / 1000),
|
|
39
|
+
usage: { input_tokens: 10, output_tokens: 5 },
|
|
40
|
+
output: [{ type: 'message', content: [{ type: 'output_text', text: 'Text', annotations: [{ type: 'url_citation', url: 'https://ex.com' }] }] }]
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
const fakeToolRes = (name = 'get_current_weather', args = '{"location":"Amsterdam"}') => ({
|
|
45
|
+
status: 200,
|
|
46
|
+
response: {
|
|
47
|
+
id: 'fake-tool',
|
|
48
|
+
model: 'grok-beta',
|
|
49
|
+
created_at: Math.floor(Date.now() / 1000),
|
|
50
|
+
usage: { input_tokens: 20, output_tokens: 10 },
|
|
51
|
+
output: [{ type: 'function_call', name, id: 'fid', call_id: 'fcid', arguments: args, status: 'complete' }]
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
t.add('generateRequest: basic', () => {
|
|
56
|
+
const p = new Prompt();
|
|
57
|
+
p.add('system', 'Helpful', true);
|
|
58
|
+
p.add('user', 'Hi');
|
|
59
|
+
const { url, headers, body } = generateRequest(p);
|
|
60
|
+
assert.strictEqual(url, 'https://api.x.ai/v1/responses');
|
|
61
|
+
assert.strictEqual(headers['Content-Type'], 'application/json');
|
|
62
|
+
assert.ok(headers.Authorization.startsWith('Bearer'));
|
|
63
|
+
assert.strictEqual(body.model, 'grok-4-fast-reasoning');
|
|
64
|
+
assert.strictEqual(body.instructions, 'Helpful');
|
|
65
|
+
assert.strictEqual(body.input.length, 1);
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
t.add('generateRequest: tools', () => {
|
|
69
|
+
const p = new Prompt();
|
|
70
|
+
p.add('user', 'Weather');
|
|
71
|
+
const { body } = generateRequest(p, tools);
|
|
72
|
+
assert.ok(body.tools.some(tl => tl.name === 'get_current_weather'));
|
|
73
|
+
assert.strictEqual(body.parallel_tool_calls, true);
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
t.add('generateRequest: options', () => {
|
|
77
|
+
const p = new Prompt();
|
|
78
|
+
p.add('user', 'Hi');
|
|
79
|
+
const { body } = generateRequest(p, null, { model: 'grok-4-1-fast-reasoning' });
|
|
80
|
+
assert.strictEqual(body.model, 'grok-4-1-fast-reasoning');
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
t.add('generateRequest: throws bad last role', () => {
|
|
84
|
+
const p = new Prompt();
|
|
85
|
+
p.add('system', '', true);
|
|
86
|
+
p.add('assistant', 'bad');
|
|
87
|
+
assert.throws(() => generateRequest(p));
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
t.add('parseResponse: text', async () => {
|
|
91
|
+
const p = new Prompt();
|
|
92
|
+
p.add('user', 'Hi');
|
|
93
|
+
await parseResponse(100, p, fakeTextRes());
|
|
94
|
+
const msg = p.getLastMessage();
|
|
95
|
+
assert.strictEqual(msg.role, 'assistant');
|
|
96
|
+
assert.strictEqual(msg.content[0].text, 'Hello!');
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
t.add('parseResponse: reasoning', async () => {
|
|
100
|
+
const p = new Prompt();
|
|
101
|
+
await parseResponse(100, p, fakeReasoningRes());
|
|
102
|
+
const msg = p.getLastMessage();
|
|
103
|
+
assert.strictEqual(msg.role, 'reasoning');
|
|
104
|
+
assert.strictEqual(msg.content[0].text, 'Thought.');
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
t.add('parseResponse: citations', async () => {
|
|
108
|
+
const p = new Prompt();
|
|
109
|
+
await parseResponse(100, p, fakeCitationRes());
|
|
110
|
+
const log = p.messages.find(m => m.role === 'log');
|
|
111
|
+
assert.ok(log);
|
|
112
|
+
assert.ok(log.content[0].text.includes('https://ex.com'));
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
t.add('parseResponse: function_call', async () => {
|
|
116
|
+
const p = new Prompt();
|
|
117
|
+
p.add('user', 'Weather');
|
|
118
|
+
await parseResponse(100, p, fakeToolRes());
|
|
119
|
+
const msg = p.getLastMessage();
|
|
120
|
+
assert.strictEqual(msg.role, 'assistant');
|
|
121
|
+
assert.strictEqual(msg.content[0].type, 'function_request');
|
|
122
|
+
assert.strictEqual(msg.content[0].function_request.name, 'get_current_weather');
|
|
123
|
+
assert.strictEqual(msg.content[0].function_request.parameters, '{"location":"Amsterdam"}');
|
|
124
|
+
assert.strictEqual(msg.content[0].function_request.call_id, 'fcid');
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
t.add('parseResponse: toolset exec', async () => {
|
|
128
|
+
const p = new Prompt();
|
|
129
|
+
p.add('user', 'Weather Amsterdam');
|
|
130
|
+
await parseResponse(100, p, fakeToolRes('get_current_weather', '{"location":"Amsterdam"}'), tools);
|
|
131
|
+
const toolMsg = p.getLastMessage();
|
|
132
|
+
assert.strictEqual(toolMsg.role, 'tool');
|
|
133
|
+
assert.strictEqual(toolMsg.content[0].type, 'function_response');
|
|
134
|
+
assert.strictEqual(toolMsg.content[0].function_response.name, 'get_current_weather');
|
|
135
|
+
assert.ok(toolMsg.content[0].function_response.response.includes('24 C'));
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
t.add('parseResponse: non-200 rejects', async () => {
|
|
139
|
+
const p = new Prompt();
|
|
140
|
+
const bad = { status: 400, response: { error: 'bad' } };
|
|
141
|
+
await assert.rejects(async () => parseResponse(100, p, bad), /400: /);
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
t.add('request: real simple', async () => {
|
|
145
|
+
const p = new Prompt();
|
|
146
|
+
p.add('system', 'You are a helpful assistant. Answer briefly.', true);
|
|
147
|
+
p.add('user', 'What is 2+2?');
|
|
148
|
+
const msg = await request(p);
|
|
149
|
+
assert.strictEqual(msg.role, 'assistant');
|
|
150
|
+
assert.ok(msg.content.some(c => c.type === 'text' && c.text.includes('4')), 'Expected 4');
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
const report = await t.run();
|
|
154
|
+
process.exit(report.errors > 0 ? 1 : 0);
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Test, assert, SH } from '@j-o-r/sh'
|
|
3
|
+
import collections from '../lib/API/x.ai/collections.js';
|
|
4
|
+
import path from 'node:path'
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
import Prompt from '../lib/Prompt.js';
|
|
8
|
+
import tools from './testToolset.js';
|
|
9
|
+
|
|
10
|
+
function LOG(me) {
|
|
11
|
+
console.log(JSON.stringify(me, null, ' '));
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const test = new Test();
|
|
15
|
+
|
|
16
|
+
test.add('List collections, start in a clean state', async () => {
|
|
17
|
+
const list = await collections.list();
|
|
18
|
+
let i = 0;
|
|
19
|
+
const len = list.length;
|
|
20
|
+
for (; i < len; i++) {
|
|
21
|
+
const col = list[i];
|
|
22
|
+
if (col.collection_name === 'test_col' || col.collection_name === 'test_col2') {
|
|
23
|
+
const check = await collections.get(col.collection_id);
|
|
24
|
+
assert.equal(check.collection_id, col.collection_id);
|
|
25
|
+
// Delete all test collections
|
|
26
|
+
await collections.del(check.collection_id);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
test.add('Add, update, delete a collection', async () => {
|
|
32
|
+
const coll_id = await collections.create('test_col');
|
|
33
|
+
let coll = await collections.get(coll_id);
|
|
34
|
+
assert.strictEqual(coll_id, coll.collection_id);
|
|
35
|
+
await collections.update(coll_id, 'test_col2');
|
|
36
|
+
coll = await collections.get(coll_id);
|
|
37
|
+
assert.strictEqual(coll.collection_name, 'test_col2');
|
|
38
|
+
await collections.del(coll_id);
|
|
39
|
+
// DELETED
|
|
40
|
+
await assert.rejects(
|
|
41
|
+
async () => await collections.get(coll_id),
|
|
42
|
+
(err) => {
|
|
43
|
+
return err.toString().includes('doesn\'t exist or your team');
|
|
44
|
+
}
|
|
45
|
+
)
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
await test.run();
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Test, assert, SH } from '@j-o-r/sh'
|
|
3
|
+
import { files } from '../lib/API/x.ai/files.js';
|
|
4
|
+
import path from 'node:path'
|
|
5
|
+
|
|
6
|
+
import Prompt from '../lib/Prompt.js';
|
|
7
|
+
import tools from './testToolset.js';
|
|
8
|
+
|
|
9
|
+
function LOG(me) {
|
|
10
|
+
console.log(JSON.stringify(me, null, ' '));
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const test = new Test();
|
|
14
|
+
|
|
15
|
+
test.add('List files', async () => {
|
|
16
|
+
const fp = path.resolve('docs', 'toolset.md');
|
|
17
|
+
const list = (await files.list()).data;
|
|
18
|
+
let i = 0;
|
|
19
|
+
const len = list.length;
|
|
20
|
+
for(;i < len; i++) {
|
|
21
|
+
const f = list[i];
|
|
22
|
+
if (f.filename === 'test.md' || f.filename === fp) {
|
|
23
|
+
await files.rm(f.id);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
test.add('create, add and remove files', async () => {
|
|
29
|
+
const fp = path.resolve('docs', 'toolset.md');
|
|
30
|
+
const res = await files.upload(fp);
|
|
31
|
+
const content = await files.get(res.id);
|
|
32
|
+
assert.equal(content.length, res.bytes);
|
|
33
|
+
const meta = await files.getMeta(res.id);
|
|
34
|
+
assert.equal(content.length, meta.bytes);
|
|
35
|
+
await files.rm(res.id);
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
test.add('create, add and remove files with custom content', async () => {
|
|
39
|
+
const fp = 'test.md';
|
|
40
|
+
// Add custom content to a file instead of reading the file itself
|
|
41
|
+
const res = await files.upload(fp, 'Hello World');
|
|
42
|
+
const content = await files.get(res.id);
|
|
43
|
+
assert.equal(content, 'Hello World');
|
|
44
|
+
const meta = await files.getMeta(res.id);
|
|
45
|
+
assert.equal(content.length, meta.bytes);
|
|
46
|
+
await files.rm(res.id);
|
|
47
|
+
})
|
|
48
|
+
await test.run();
|
|
@@ -33,7 +33,7 @@ export type OAOptions = {
|
|
|
33
33
|
/**
|
|
34
34
|
* - Model version to use.
|
|
35
35
|
*/
|
|
36
|
-
model?: "gpt-4
|
|
36
|
+
model?: "gpt-5.4" | "gpt-5-mini" | "gpt-5-nano" | "gpt-5-pro" | undefined;
|
|
37
37
|
/**
|
|
38
38
|
* - Reusable prompt string.
|
|
39
39
|
*/
|
|
@@ -51,6 +51,9 @@ export type OAOptions = {
|
|
|
51
51
|
*/
|
|
52
52
|
summary: "auto" | "concise" | "detailed";
|
|
53
53
|
} | undefined;
|
|
54
|
+
/**
|
|
55
|
+
* - Convenience: Adds `{type: "web_search_preview", search_context_size: search}` tool.
|
|
56
|
+
*/
|
|
54
57
|
search?: "low" | "high" | "medium" | undefined;
|
|
55
58
|
/**
|
|
56
59
|
* - Service tier option, default is auto-selected.
|
|
@@ -86,9 +89,9 @@ export type OAOptions = {
|
|
|
86
89
|
*/
|
|
87
90
|
tool_choice?: "auto" | undefined;
|
|
88
91
|
/**
|
|
89
|
-
*
|
|
92
|
+
* - Array of tool objects: custom function tools (`OAToolCall`) or built-in OpenAI tools (e.g., `{type: "web_search_preview"}`).
|
|
90
93
|
*/
|
|
91
|
-
tools
|
|
94
|
+
tools?: OpenAITool[] | undefined;
|
|
92
95
|
/**
|
|
93
96
|
* =null An integer between 0 and 20 specifying the number of most likely tokens to return at each token position, each with an associated log probability.
|
|
94
97
|
*/
|
|
@@ -126,6 +129,17 @@ export type OAToolCall = {
|
|
|
126
129
|
required?: string[] | undefined;
|
|
127
130
|
};
|
|
128
131
|
};
|
|
132
|
+
export type OABuiltinTool = {
|
|
133
|
+
/**
|
|
134
|
+
* - Type of built-in OpenAI tool (Responses API).
|
|
135
|
+
*/
|
|
136
|
+
type: "code_interpreter" | "file_search" | "computer" | "web_search";
|
|
137
|
+
/**
|
|
138
|
+
* - Context size for `web_search_preview` only.
|
|
139
|
+
*/
|
|
140
|
+
search_context_size?: "low" | "high" | "medium" | undefined;
|
|
141
|
+
};
|
|
142
|
+
export type OpenAITool = OAToolCall | OABuiltinTool;
|
|
129
143
|
export type OAParameterProperty = {
|
|
130
144
|
/**
|
|
131
145
|
* - The data type of the parameter, e.g., "string".
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
declare namespace _default {
|
|
2
|
+
export { create };
|
|
3
|
+
export { list };
|
|
4
|
+
export { get };
|
|
5
|
+
export { status };
|
|
6
|
+
export { details };
|
|
7
|
+
export { update };
|
|
8
|
+
export { del };
|
|
9
|
+
export { addFileToCollection };
|
|
10
|
+
export { deleteFileFromCollection };
|
|
11
|
+
export { searchInCollections };
|
|
12
|
+
export { getStorage as storage };
|
|
13
|
+
}
|
|
14
|
+
export default _default;
|
|
15
|
+
export type Collection = {
|
|
16
|
+
/**
|
|
17
|
+
* - Unique identifier for the collection.
|
|
18
|
+
*/
|
|
19
|
+
collection_id: string;
|
|
20
|
+
/**
|
|
21
|
+
* - Name of the collection.
|
|
22
|
+
*/
|
|
23
|
+
collection_name: string;
|
|
24
|
+
/**
|
|
25
|
+
* - ISO datetime string when the collection was created.
|
|
26
|
+
*/
|
|
27
|
+
created_at: string;
|
|
28
|
+
updated_at: string;
|
|
29
|
+
/**
|
|
30
|
+
* - Configuration for the indexing model.
|
|
31
|
+
*/
|
|
32
|
+
index_configuration: {
|
|
33
|
+
model_name: string;
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* - Configuration for chunking documents.
|
|
37
|
+
*/
|
|
38
|
+
chunk_configuration: {
|
|
39
|
+
tokens_configuration: {
|
|
40
|
+
max_chunk_size_tokens: number;
|
|
41
|
+
chunk_overlap_tokens: number;
|
|
42
|
+
encoding_name: string;
|
|
43
|
+
};
|
|
44
|
+
strip_whitespace: boolean;
|
|
45
|
+
inject_name_into_chunks: boolean;
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* - Number of documents in the collection.
|
|
49
|
+
*/
|
|
50
|
+
documents_count: number;
|
|
51
|
+
/**
|
|
52
|
+
* - Array of field definitions.
|
|
53
|
+
*/
|
|
54
|
+
field_definitions: any[];
|
|
55
|
+
};
|
|
56
|
+
export type fileList = {
|
|
57
|
+
data: File[];
|
|
58
|
+
pagination_token: string | null;
|
|
59
|
+
};
|
|
60
|
+
export type File = {
|
|
61
|
+
/**
|
|
62
|
+
* - File size in bytes.
|
|
63
|
+
*/
|
|
64
|
+
bytes: number;
|
|
65
|
+
/**
|
|
66
|
+
* - Unix timestamp of creation.
|
|
67
|
+
*/
|
|
68
|
+
created_at: number;
|
|
69
|
+
/**
|
|
70
|
+
* - Unix timestamp of expiration, or null.
|
|
71
|
+
*/
|
|
72
|
+
expires_at: number | null;
|
|
73
|
+
/**
|
|
74
|
+
* - Path to the file.
|
|
75
|
+
*/
|
|
76
|
+
filename: string;
|
|
77
|
+
/**
|
|
78
|
+
* - Unique file identifier.
|
|
79
|
+
*/
|
|
80
|
+
id: string;
|
|
81
|
+
/**
|
|
82
|
+
* - Type of object, e.g., 'file'.
|
|
83
|
+
*/
|
|
84
|
+
object: string;
|
|
85
|
+
/**
|
|
86
|
+
* - Purpose of the file.
|
|
87
|
+
*/
|
|
88
|
+
purpose: string;
|
|
89
|
+
};
|
|
90
|
+
export type SearchResult = {
|
|
91
|
+
document_id: string;
|
|
92
|
+
content: string;
|
|
93
|
+
metadata: Object;
|
|
94
|
+
score: number;
|
|
95
|
+
};
|
|
96
|
+
/**
|
|
97
|
+
* Create a collection
|
|
98
|
+
* @param {string} name
|
|
99
|
+
* @returns {Promise<string>} collection_id
|
|
100
|
+
*/
|
|
101
|
+
declare function create(name: string): Promise<string>;
|
|
102
|
+
/**
|
|
103
|
+
* List collections
|
|
104
|
+
* @returns {Promise<Array<Collection>>}
|
|
105
|
+
*/
|
|
106
|
+
declare function list(): Promise<Array<Collection>>;
|
|
107
|
+
/**
|
|
108
|
+
* Get collection details
|
|
109
|
+
* @param {string} id
|
|
110
|
+
* @returns {Promise<Collection>}
|
|
111
|
+
*/
|
|
112
|
+
declare function get(id: string): Promise<Collection>;
|
|
113
|
+
/**
|
|
114
|
+
* The status of files in a collection
|
|
115
|
+
* @param {string} collectionId
|
|
116
|
+
* @returns {Promise<void>}
|
|
117
|
+
*/
|
|
118
|
+
declare function status(collectionId: string): Promise<void>;
|
|
119
|
+
/**
|
|
120
|
+
* The status of files in a collection
|
|
121
|
+
* @param {string} collectionId
|
|
122
|
+
* @param {string} fileId
|
|
123
|
+
* @returns {Promise<void>}
|
|
124
|
+
*/
|
|
125
|
+
declare function details(collectionId: string, fileId: string): Promise<void>;
|
|
126
|
+
/**
|
|
127
|
+
* Update collection collection name
|
|
128
|
+
* @param {string} id
|
|
129
|
+
* @param {string} name
|
|
130
|
+
* @returns {Promise<void>}
|
|
131
|
+
*/
|
|
132
|
+
declare function update(id: string, name: string): Promise<void>;
|
|
133
|
+
/**
|
|
134
|
+
* Delete collection
|
|
135
|
+
* @param {string} id
|
|
136
|
+
* @returns {Promise<void>}
|
|
137
|
+
*/
|
|
138
|
+
declare function del(id: string): Promise<void>;
|
|
139
|
+
/**
|
|
140
|
+
* Add file to collection
|
|
141
|
+
* @param {string} collectionId
|
|
142
|
+
* @param {string} fileId
|
|
143
|
+
* @returns {Promise<void>}
|
|
144
|
+
*/
|
|
145
|
+
declare function addFileToCollection(collectionId: string, fileId: string): Promise<void>;
|
|
146
|
+
/**
|
|
147
|
+
* Delete file from collection
|
|
148
|
+
* @param {string} collectionId
|
|
149
|
+
* @param {string} fileId
|
|
150
|
+
* @returns {Promise<void>}
|
|
151
|
+
*/
|
|
152
|
+
declare function deleteFileFromCollection(collectionId: string, fileId: string): Promise<void>;
|
|
153
|
+
/**
|
|
154
|
+
* Search in collections
|
|
155
|
+
* @param {string} query
|
|
156
|
+
* @param {string[]} collectionIds
|
|
157
|
+
* @param {Object} [options]
|
|
158
|
+
* @param {string} [options.retrieval_mode] - e.g., 'hybrid'
|
|
159
|
+
* @returns {Promise<SearchResult[]>}
|
|
160
|
+
*/
|
|
161
|
+
declare function searchInCollections(query: string, collectionIds: string[], options?: {
|
|
162
|
+
retrieval_mode?: string | undefined;
|
|
163
|
+
}): Promise<SearchResult[]>;
|
|
164
|
+
/**
|
|
165
|
+
* @returns {Promise<Map<string, Collection>>}
|
|
166
|
+
*/
|
|
167
|
+
declare function getStorage(): Promise<Map<string, Collection>>;
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
declare namespace _default {
|
|
2
|
+
export { list };
|
|
3
|
+
export { upload };
|
|
4
|
+
export { get };
|
|
5
|
+
export { getMeta };
|
|
6
|
+
export { rm };
|
|
7
|
+
export { getStorage as storage };
|
|
8
|
+
}
|
|
9
|
+
export default _default;
|
|
10
|
+
export type fileList = {
|
|
11
|
+
data: File[];
|
|
12
|
+
pagination_token: string | null;
|
|
13
|
+
};
|
|
14
|
+
export type File = {
|
|
15
|
+
/**
|
|
16
|
+
* - File size in bytes.
|
|
17
|
+
*/
|
|
18
|
+
bytes: number;
|
|
19
|
+
/**
|
|
20
|
+
* - Unix timestamp of creation.
|
|
21
|
+
*/
|
|
22
|
+
created_at: number;
|
|
23
|
+
/**
|
|
24
|
+
* - Unix timestamp of expiration, or null.
|
|
25
|
+
*/
|
|
26
|
+
expires_at: number | null;
|
|
27
|
+
/**
|
|
28
|
+
* - Path to the file.
|
|
29
|
+
*/
|
|
30
|
+
filename: string;
|
|
31
|
+
/**
|
|
32
|
+
* - Unique file identifier.
|
|
33
|
+
*/
|
|
34
|
+
id: string;
|
|
35
|
+
/**
|
|
36
|
+
* - Type of object, e.g., 'file'.
|
|
37
|
+
*/
|
|
38
|
+
object: string;
|
|
39
|
+
/**
|
|
40
|
+
* - Purpose of the file.
|
|
41
|
+
*/
|
|
42
|
+
purpose: string;
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* List Files
|
|
46
|
+
* @param {number} limit
|
|
47
|
+
* @param {'asc'|'desc'} order
|
|
48
|
+
* @param {'created_at'|'filename'| 'size'} sort_by
|
|
49
|
+
* @param {string} page (pagination_token)
|
|
50
|
+
* @retuns {Promise<fileList>}
|
|
51
|
+
*/
|
|
52
|
+
declare function list(limit?: number, order?: "asc" | "desc", sort_by?: "created_at" | "filename" | "size", page?: string): Promise<any>;
|
|
53
|
+
/**
|
|
54
|
+
* Upload a file
|
|
55
|
+
* When content is filled this will be used as file content
|
|
56
|
+
* @param {string} filePath
|
|
57
|
+
* @param {string} [content] - optional content for a non existing file
|
|
58
|
+
* @returns {Promise<File>} file_id
|
|
59
|
+
*/
|
|
60
|
+
declare function upload(filePath: string, content?: string): Promise<File>;
|
|
61
|
+
/**
|
|
62
|
+
* Get file content
|
|
63
|
+
* @param {string} fileId
|
|
64
|
+
* @returns {Promise<*>}
|
|
65
|
+
*/
|
|
66
|
+
declare function get(fileId: string): Promise<any>;
|
|
67
|
+
/**
|
|
68
|
+
* Get file meta data
|
|
69
|
+
* @param {string} fileId
|
|
70
|
+
* @returns {Promise<File>}
|
|
71
|
+
*/
|
|
72
|
+
declare function getMeta(fileId: string): Promise<File>;
|
|
73
|
+
/**
|
|
74
|
+
* Remove a file
|
|
75
|
+
* @param {string} fileId
|
|
76
|
+
* @returns {Promise<void>}
|
|
77
|
+
*/
|
|
78
|
+
declare function rm(fileId: string): Promise<void>;
|
|
79
|
+
/**
|
|
80
|
+
* Get all on-line files
|
|
81
|
+
* @returns {Promise<Map<string, File>>}
|
|
82
|
+
*
|
|
83
|
+
*/
|
|
84
|
+
declare function getStorage(page?: string): Promise<Map<string, File>>;
|