@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,492 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Allthough we can use store = true and previous_response_id: response.id,
|
|
3
|
+
Stil all tokens are billed.
|
|
4
|
+
*/
|
|
5
|
+
import { GLOBAL } from '../../fafs.js'
|
|
6
|
+
import { request as doRequest } from '@j-o-r/apiserver';
|
|
7
|
+
import { sleep } from '@j-o-r/sh';
|
|
8
|
+
/**
|
|
9
|
+
* @typedef {import('../../Prompt.js').default} Prompt
|
|
10
|
+
* @typedef {import('../../ToolSet.js').default} ToolSet
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* @typedef {'code_interpreter_call.outputs'|'computer_call_output.output.image_url'|'file_search_call.results'|'message.input_image.image_url'|'message.output_text.logprobs'|'reasoning.encrypted_conten'} Includes
|
|
14
|
+
*/
|
|
15
|
+
/**
|
|
16
|
+
* @typedef {Object} XAIOptions
|
|
17
|
+
* @property {?string} [include=null] - Optional include parameter.
|
|
18
|
+
* @property {XAIInput[]} [input=[]] - Array of input objects.
|
|
19
|
+
* @property {string} [instructions=''] - Instructions for the model.
|
|
20
|
+
* @property {number} [max_output_tokens=4000] - Maximum number of output tokens.
|
|
21
|
+
* @property {number} [max_tool_calls=10] - Maximum number of tool calls allowed.
|
|
22
|
+
* @property {?Object} [metadata=null] - Optional metadata object.
|
|
23
|
+
* @property {'grok-4-1-fast-reasoning'|'grok-4-1-fast-non-reasoning'|'grok-code-fast-1'|'grok-4-fast-reasoning'|'grok-4-fast-non-reasoning'} [model='grok-4-fast-non-reasoning'] - Model version to use.
|
|
24
|
+
* @property {?string} [prompt=null] - Reusable prompt string.
|
|
25
|
+
* @property {Object} [reasoning={effort: 'medium', summary: 'auto'}] - Reasoning configuration.
|
|
26
|
+
* @property {'low'|'medium'|'high'|null} reasoning.effort - Effort level for reasoning.
|
|
27
|
+
* @property {'auto'|'concise'|'detailed'} reasoning.summary - Summary type for reasoning.
|
|
28
|
+
* @property {'low'|'medium'|'high'} [search]
|
|
29
|
+
* @property {'auto'} [service_tier='auto'] - Service tier option, default is auto-selected.
|
|
30
|
+
* @property {boolean} [store=false] - Whether to store the response or not.
|
|
31
|
+
* @property {boolean} [stream=false] - Whether to stream the response or not.
|
|
32
|
+
* @property {number} [temperature=1] - Sampling temperature between 0 and 2.
|
|
33
|
+
* @property {Object} [text={format: {type: "text"}}] - text format
|
|
34
|
+
* @property {'text'|'json_schema'} text.format - Summary type for reasoning.
|
|
35
|
+
* @property {boolean} [parallel_tool_calls=true] - Allow parallel tool calls if true.
|
|
36
|
+
* @property {'auto'} [tool_choice='auto'] - Tool choice setting, default is auto-selected.
|
|
37
|
+
* @property {Array<XSearchTool|XAIFunctionTool|MCPTool|CodeInterpreterTool|FileSearchTool|XAIWebSearchTool>} [tools=[]] Array of tool call objects.
|
|
38
|
+
* @property {?number } [top_logprobs=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.
|
|
39
|
+
* @property {?number } [top_p] Top-p sampling value between 0 and 1.
|
|
40
|
+
* @property {?string} [previous_response_id] - Needed reponse_id to validate tool calls on the next request
|
|
41
|
+
*/
|
|
42
|
+
/// [start] ----- tools ----
|
|
43
|
+
/**
|
|
44
|
+
* @typedef {Object} XAIFunctionTool
|
|
45
|
+
* @property {'function'} type - The type of the tool call, e.g., "function".
|
|
46
|
+
* @property {string} name - The name of the function.
|
|
47
|
+
* @property {string} description - A brief description of what the function does.
|
|
48
|
+
* @property {Object} parameters - The parameters required by the function.
|
|
49
|
+
* @property {string} parameters.type - The type of parameters object, usually "object".
|
|
50
|
+
* @property {Object.<string, ParameterProperty>} parameters.properties - An object describing each parameter property.
|
|
51
|
+
* @property {string[]} [parameters.required] - An array of required parameter names.
|
|
52
|
+
*/
|
|
53
|
+
/**
|
|
54
|
+
* @typedef {Object} ParameterProperty
|
|
55
|
+
* @property {string} type - The data type of the parameter, e.g., "string".
|
|
56
|
+
* @property {string} description - A brief description of the parameter.
|
|
57
|
+
*/
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* @typedef {Object} WebSearchFilters
|
|
61
|
+
* @property {string[]|null} [allowed_domains] - Whitelist of domains (max 5); cannot use with excluded_domains.
|
|
62
|
+
* @property {string[]|null} [excluded_domains] - Blacklist of domains (max 5); cannot use with allowed_domains.
|
|
63
|
+
* @property {("low"|"medium"|"high")|null} [search_context_size] - Context size; for OpenAI compatibility (reject if set).
|
|
64
|
+
* @property {UserLocation|null} [user_location] - User location; for OpenAI compatibility (reject if set).
|
|
65
|
+
*/
|
|
66
|
+
/**
|
|
67
|
+
* @typedef {Object} UserLocation
|
|
68
|
+
* @property {string|null} [city] - City of the user's location.
|
|
69
|
+
* @property {string|null} [country] - ISO 3166-1 alpha-2 country code.
|
|
70
|
+
* @property {string|null} [region] - Region of the user's location.
|
|
71
|
+
* @property {string|null} [timezone] - IANA timezone.
|
|
72
|
+
* @property {"approximate"} type
|
|
73
|
+
*/
|
|
74
|
+
/**
|
|
75
|
+
* @typedef {Object} XAIWebSearchTool
|
|
76
|
+
* @property {string[]|null} [allowed_domains] - Whitelist of domains (max 5); cannot use with excluded_domains.
|
|
77
|
+
* @property {boolean|null} [enable_image_understanding] - Enable image understanding.
|
|
78
|
+
* @property {string[]|null} [excluded_domains] - Blacklist of domains (max 5); cannot use with allowed_domains.
|
|
79
|
+
* @property {boolean|null} [external_web_access] - For OpenAI compatibility (reject if set).
|
|
80
|
+
* @property {WebSearchFilters|null} [filters] - Filters; for OpenAI compatibility.
|
|
81
|
+
* @property {"web_search"} type
|
|
82
|
+
*/
|
|
83
|
+
/**
|
|
84
|
+
* @typedef {Object} XSearchTool
|
|
85
|
+
* @property {string[]|null} [allowed_x_handles] - Whitelist of X handles; cannot use with excluded_x_handles.
|
|
86
|
+
* @property {boolean|null} [enable_image_understanding] - Enable image understanding.
|
|
87
|
+
* @property {boolean|null} [enable_video_understanding] - Enable video understanding.
|
|
88
|
+
* @property {string[]|null} [excluded_x_handles] - Blacklist of X handles; cannot use with allowed_x_handles.
|
|
89
|
+
* @property {string|null} [from_date] - ISO-8601 date (YYYY-MM-DD).
|
|
90
|
+
* @property {string|null} [to_date] - ISO-8601 date (YYYY-MM-DD).
|
|
91
|
+
* @property {"x_search"} type
|
|
92
|
+
*/
|
|
93
|
+
/**
|
|
94
|
+
* @typedef {Object} FileSearchTool
|
|
95
|
+
* @property {Object} filters - For OpenAI compatibility (reject if set).
|
|
96
|
+
* @property {number|null} [max_num_results] - Max results (min 1).
|
|
97
|
+
* @property {Object} ranking_options - For OpenAI compatibility (reject if set).
|
|
98
|
+
* @property {string[]} vector_store_ids - List of vector store IDs.
|
|
99
|
+
* @property {"file_search"} type
|
|
100
|
+
*/
|
|
101
|
+
/**
|
|
102
|
+
* @typedef {Object} CodeInterpreterTool
|
|
103
|
+
* @property {string|Object} container - Container ID or uploaded files object; for OpenAI compatibility (reject if set).
|
|
104
|
+
* @property {"code_interpreter"} type
|
|
105
|
+
*/
|
|
106
|
+
/**
|
|
107
|
+
* @typedef {Object} MCPTool
|
|
108
|
+
* @property {string[]|null} [allowed_tools] - Allowed tools.
|
|
109
|
+
* @property {string|null} [authorization] - Authorization details.
|
|
110
|
+
* @property {string|null} [connector_id] - Connector ID.
|
|
111
|
+
* @property {Object|null} [headers] - Headers.
|
|
112
|
+
* @property {string|null} [require_approval] - Approval requirement.
|
|
113
|
+
* @property {string|null} [server_description] - Server description.
|
|
114
|
+
* @property {string} server_label - Server label.
|
|
115
|
+
* @property {string} server_url - Server URL.
|
|
116
|
+
* @property {"mcp"} type
|
|
117
|
+
*/
|
|
118
|
+
/// [end] ---- tools ----
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* @typedef {Object} XAIMessage
|
|
122
|
+
* @property {'assistant'|'user'} role - The role of the participant (e.g., "assistant", "user").
|
|
123
|
+
* @property {Array<XAIContent>} content - The content of the message.
|
|
124
|
+
*/
|
|
125
|
+
/**
|
|
126
|
+
* @typedef {Object} XAIInputMessage
|
|
127
|
+
* @property {'assistant'|'user'|'system'} role - The role of the participant (e.g., "assistant", "user").
|
|
128
|
+
* @property {string} content - The content of the message.
|
|
129
|
+
*/
|
|
130
|
+
/**
|
|
131
|
+
* @typedef {Object} XAIContent
|
|
132
|
+
* @property {'output_text'|'input_text'} type - The type of content (e.g., "output_text", "input_text").
|
|
133
|
+
* @property {string} text - The text content.
|
|
134
|
+
*/
|
|
135
|
+
/**
|
|
136
|
+
* @typedef {Object} XAIFunctionCall
|
|
137
|
+
* @property {string} id - Unique identifier for the function call.
|
|
138
|
+
* @property {'function_call'} type - Indicates this is a function call (e.g., "function_call").
|
|
139
|
+
* @property {string} call_id - Unique identifier for the specific function call instance.
|
|
140
|
+
* @property {string} name - The name of the function being called.
|
|
141
|
+
* @property {string} arguments - JSON string representing arguments passed to the function.
|
|
142
|
+
*/
|
|
143
|
+
/**
|
|
144
|
+
* @typedef {Object} XAIFunctionCallOutput
|
|
145
|
+
* @property {'function_call_output'} type - Indicates this is a function call output (e.g., "function_call_output").
|
|
146
|
+
* @property {string} call_id - Identifier linking to the related function call.
|
|
147
|
+
* @property {string} output - JSON string representing the output from the function call.
|
|
148
|
+
*/
|
|
149
|
+
/**
|
|
150
|
+
* Represents an OpenAI API response request INPUT structure.
|
|
151
|
+
*
|
|
152
|
+
* @typedef {(XAIInputMessage|XAIFunctionCall|XAIFunctionCallOutput)} XAIInput
|
|
153
|
+
*/
|
|
154
|
+
|
|
155
|
+
const API_URL = 'https://api.x.ai/v1/responses';
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Get the default headers
|
|
159
|
+
* @returns {object}
|
|
160
|
+
*/
|
|
161
|
+
const getHeaders = () => {
|
|
162
|
+
if (!process.env['XAIKEY']) {
|
|
163
|
+
throw new Error('Missing XAIKEY! export XAIKEY=[XAIKEY]')
|
|
164
|
+
}
|
|
165
|
+
const KEY = process.env['XAIKEY'];
|
|
166
|
+
return {
|
|
167
|
+
'Content-Type': 'application/json',
|
|
168
|
+
'Authorization': `Bearer ${KEY}`
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Convert a toolset to something openai understands
|
|
173
|
+
* @param {ToolSet} toolset
|
|
174
|
+
* @returns {XAIFunctionTool[]}
|
|
175
|
+
*/
|
|
176
|
+
const generateTools = (toolset) => {
|
|
177
|
+
const list = toolset.list();
|
|
178
|
+
/** @type {XAIFunctionTool[]} */
|
|
179
|
+
const result = [];
|
|
180
|
+
list.forEach((item) => {
|
|
181
|
+
result.push({
|
|
182
|
+
type: 'function',
|
|
183
|
+
name: item.name,
|
|
184
|
+
description: item.description,
|
|
185
|
+
parameters: item.parameters
|
|
186
|
+
})
|
|
187
|
+
});
|
|
188
|
+
return result;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Convert messages to OPENAI requirements
|
|
193
|
+
* @param {import("lib/Session").Message[]} messages
|
|
194
|
+
* @returns {XAIInput[]}
|
|
195
|
+
*/
|
|
196
|
+
const generateHistory = (messages) => {
|
|
197
|
+
return messages.reduce((result, msg) => {
|
|
198
|
+
delete msg.sticky;
|
|
199
|
+
delete msg.ts;
|
|
200
|
+
if (['assistant', 'user'].includes(msg.role)) {
|
|
201
|
+
/** @type {XAIFunctionCall[]} */
|
|
202
|
+
// @ts-ignore
|
|
203
|
+
const fr = msg.content.map(
|
|
204
|
+
/** @param {import('../../Prompt.js').FunctionRequest} item */
|
|
205
|
+
(item) => {
|
|
206
|
+
// Transform function requests
|
|
207
|
+
if (item.type === 'function_request') {
|
|
208
|
+
return {
|
|
209
|
+
// @ts-ignore
|
|
210
|
+
// id: item.function_request.id,
|
|
211
|
+
type: 'function_call',
|
|
212
|
+
call_id: item.function_request.call_id,
|
|
213
|
+
name: item.function_request.name,
|
|
214
|
+
arguments: item.function_request.parameters
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}).filter(item => item !== undefined);
|
|
218
|
+
if (fr.length > 0) {
|
|
219
|
+
result.push(...fr);
|
|
220
|
+
}
|
|
221
|
+
// transform normal text input
|
|
222
|
+
const content = msg.content.map((item) => {
|
|
223
|
+
if (item.type == 'text') {
|
|
224
|
+
item.type = msg.role === 'user' ? 'input_text' : 'output_text'
|
|
225
|
+
return item;
|
|
226
|
+
}
|
|
227
|
+
}).filter(item => item !== undefined);
|
|
228
|
+
if (content.length > 0) {
|
|
229
|
+
msg.content = content;
|
|
230
|
+
result.push(msg);
|
|
231
|
+
}
|
|
232
|
+
} else if (['tool'].includes(msg.role)) {
|
|
233
|
+
// transform function responses
|
|
234
|
+
const ar = msg.content.map(
|
|
235
|
+
/** @param {import('../../Prompt.js').FunctionResponse} item */
|
|
236
|
+
(item) => {
|
|
237
|
+
if (item.type === 'function_response') {
|
|
238
|
+
return {
|
|
239
|
+
type: 'function_call_output',
|
|
240
|
+
call_id: item.function_response.call_id,
|
|
241
|
+
output: item.function_response.response
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}).filter(item => item !== undefined);
|
|
245
|
+
if (ar.length > 0) {
|
|
246
|
+
result.push(...ar);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
return result;
|
|
250
|
+
}, []);
|
|
251
|
+
}
|
|
252
|
+
/** @type SearchSources */
|
|
253
|
+
const webSearch = [
|
|
254
|
+
{
|
|
255
|
+
type: 'x',
|
|
256
|
+
},
|
|
257
|
+
{
|
|
258
|
+
type: 'web',
|
|
259
|
+
safe_search: false
|
|
260
|
+
},
|
|
261
|
+
{
|
|
262
|
+
type: 'news',
|
|
263
|
+
safe_search: false
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
]
|
|
267
|
+
|
|
268
|
+
/** @type {XAIOptions} */
|
|
269
|
+
const defaultSettings = {
|
|
270
|
+
model: 'grok-4-fast-reasoning',
|
|
271
|
+
input: [
|
|
272
|
+
{
|
|
273
|
+
role: 'system',
|
|
274
|
+
content: 'Be precise and concise'
|
|
275
|
+
}
|
|
276
|
+
],
|
|
277
|
+
temperature: 0.2,
|
|
278
|
+
parallel_tool_calls: true,
|
|
279
|
+
tools: [],
|
|
280
|
+
// search_parameters: {
|
|
281
|
+
// from_date: null,
|
|
282
|
+
// max_search_results: 15,
|
|
283
|
+
// mode: 'off',
|
|
284
|
+
// return_citations: false,
|
|
285
|
+
// sources: webSearch,
|
|
286
|
+
// to_date: null
|
|
287
|
+
// },
|
|
288
|
+
store: false
|
|
289
|
+
};
|
|
290
|
+
|
|
291
|
+
|
|
292
|
+
// tools": [{"type": "web_search_preview"}],
|
|
293
|
+
|
|
294
|
+
/**
|
|
295
|
+
* Generate the POST body of a request
|
|
296
|
+
* @param {Prompt} prompt
|
|
297
|
+
* @param {ToolSet} [toolset]
|
|
298
|
+
* @param {XAIOptions} [options]
|
|
299
|
+
*/
|
|
300
|
+
function getBody(prompt, toolset, options) {
|
|
301
|
+
// From the messages I only want assistant and user
|
|
302
|
+
/** @type {XAIOptions} */
|
|
303
|
+
// @ts-ignore
|
|
304
|
+
const body = { ...defaultSettings, ...(options || {}) };
|
|
305
|
+
// const body = options ? mergeOptions(DEFAULT_OPTIONS, options) : DEFAULT_OPTIONS;
|
|
306
|
+
body.instructions = prompt.hasSystemprompt ? prompt.system_prompt : '';
|
|
307
|
+
// the last messages should be a role tool or user else the model cannot handle the request
|
|
308
|
+
const messages = prompt.messages;
|
|
309
|
+
if (!['user', 'tool'].includes(messages[messages.length - 1].role)) {
|
|
310
|
+
throw new Error('Missing last user question or tool');
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
body.input = generateHistory(messages);
|
|
314
|
+
if (toolset) {
|
|
315
|
+
// @ts-ignore
|
|
316
|
+
body.tool_choice = toolset.toolChoice;
|
|
317
|
+
body.tools = [...body.tools, ...generateTools(toolset)]
|
|
318
|
+
body.parallel_tool_calls = true;
|
|
319
|
+
// parallel_tool_calls
|
|
320
|
+
}
|
|
321
|
+
// Add OPENAI SEARCH
|
|
322
|
+
// in the toolset
|
|
323
|
+
// if (body.search) {
|
|
324
|
+
// if (!body.tools) {
|
|
325
|
+
// body.tools = [];
|
|
326
|
+
// }
|
|
327
|
+
// body.tools.push({
|
|
328
|
+
// type: 'web_search_preview',
|
|
329
|
+
// // @ts-ignore
|
|
330
|
+
// search_context_size: body.search
|
|
331
|
+
// })
|
|
332
|
+
// }
|
|
333
|
+
delete body.search;
|
|
334
|
+
return body;
|
|
335
|
+
}
|
|
336
|
+
/**
|
|
337
|
+
* @param {Prompt} prompt
|
|
338
|
+
* @param {ToolSet} [toolset]
|
|
339
|
+
* @param {XAIOptions} [options]
|
|
340
|
+
*/
|
|
341
|
+
function generateRequest(prompt, toolset, options) {
|
|
342
|
+
const headers = getHeaders();
|
|
343
|
+
const url = API_URL;
|
|
344
|
+
const body = getBody(prompt, toolset, options);
|
|
345
|
+
return { url, headers, body }
|
|
346
|
+
}
|
|
347
|
+
/**
|
|
348
|
+
* Parse response messages (output)
|
|
349
|
+
* @param {Array<*>} messages
|
|
350
|
+
* @param {Prompt} prompt
|
|
351
|
+
*/
|
|
352
|
+
function parseMessages(messages, prompt) {
|
|
353
|
+
/** @type {import('../../Prompt.js').FunctionRequest[]} */
|
|
354
|
+
const toolcall = [];
|
|
355
|
+
let i = 0;
|
|
356
|
+
const len = messages.length;
|
|
357
|
+
for (; i < len; i++) {
|
|
358
|
+
const msg = messages[i];
|
|
359
|
+
// types:
|
|
360
|
+
const type = msg.type;
|
|
361
|
+
if (type === 'reasoning') {
|
|
362
|
+
let messages = msg.summary.map((item) => {
|
|
363
|
+
if (item.type === 'summary_text') {
|
|
364
|
+
return { type: 'text', text: item.text }
|
|
365
|
+
}
|
|
366
|
+
});
|
|
367
|
+
messages = messages.filter(item => item !== undefined);
|
|
368
|
+
if (messages.length > 0) {
|
|
369
|
+
prompt.addMultiModal('reasoning', messages);
|
|
370
|
+
}
|
|
371
|
+
} else if (type === 'message') {
|
|
372
|
+
let annotations = '';
|
|
373
|
+
let messages = msg.content.map((item) => {
|
|
374
|
+
if (item.type === 'output_text') {
|
|
375
|
+
if (item['annotations'] && item.annotations.length > 0) {
|
|
376
|
+
const ann = item.annotations;
|
|
377
|
+
ann.forEach((a) => {
|
|
378
|
+
if (a.type === 'url_citation') {
|
|
379
|
+
annotations += `${a.url}\n`;
|
|
380
|
+
}
|
|
381
|
+
})
|
|
382
|
+
}
|
|
383
|
+
return { type: 'text', text: item.text }
|
|
384
|
+
}
|
|
385
|
+
});
|
|
386
|
+
if (annotations !== '') {
|
|
387
|
+
prompt.add('log', annotations)
|
|
388
|
+
}
|
|
389
|
+
messages = messages.filter(item => item !== undefined);
|
|
390
|
+
if (messages.length > 0) {
|
|
391
|
+
prompt.addMultiModal('assistant', messages);
|
|
392
|
+
}
|
|
393
|
+
} else if (type === 'image_generation_call') {
|
|
394
|
+
prompt.addMultiModal('assistant', [{ type: 'image_url', url: msg.result }]);
|
|
395
|
+
} else if (type === 'function_call' || msg.status === 'complete') {
|
|
396
|
+
toolcall.push({
|
|
397
|
+
type: 'function_request',
|
|
398
|
+
function_request: {
|
|
399
|
+
name: msg.name,
|
|
400
|
+
id: msg.id,
|
|
401
|
+
call_id: msg.call_id,
|
|
402
|
+
parameters: msg.arguments
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
});
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
if (toolcall.length > 0) {
|
|
409
|
+
prompt.addMultiModal('assistant', toolcall);
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
/**
|
|
414
|
+
* Parse a response
|
|
415
|
+
* @param {number} duration - Fetch time in MS
|
|
416
|
+
* @param {Prompt} prompt
|
|
417
|
+
* @param {import('@j-o-r/apiserver/types/request.js').FetchResponseObject} res
|
|
418
|
+
* @param {import('../../ToolSet.js').default} [toolset]
|
|
419
|
+
*/
|
|
420
|
+
async function parseResponse(duration, prompt, res, toolset) {
|
|
421
|
+
if (res.status !== 200) {
|
|
422
|
+
throw new Error(`${res.status}: ${JSON.stringify(res.response, null, ' ')}`)
|
|
423
|
+
}
|
|
424
|
+
// 1 = make a records
|
|
425
|
+
const record = prompt.templateRecord();
|
|
426
|
+
record.model = res.response.model;
|
|
427
|
+
record.id = res.response.id;
|
|
428
|
+
record.environment = API_URL;
|
|
429
|
+
record.isoDate = new Date(res.response.created_at * 1000).toISOString();
|
|
430
|
+
record.tokensIn = res.response.usage.input_tokens;
|
|
431
|
+
record.tokensOut = res.response.usage.output_tokens;
|
|
432
|
+
record.duration = duration;
|
|
433
|
+
// Parse the messages and and those to the prompt
|
|
434
|
+
parseMessages(res.response.output, prompt);
|
|
435
|
+
if (toolset) {
|
|
436
|
+
// Inspect for function_request and execute if so
|
|
437
|
+
await toolset.execute(prompt);
|
|
438
|
+
}
|
|
439
|
+
prompt.addRecord(record);
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
/**
|
|
443
|
+
* Do a request
|
|
444
|
+
* @param {Prompt} prompt
|
|
445
|
+
* @param {ToolSet|null} toolset
|
|
446
|
+
* @param {XAIOptions} [options]:
|
|
447
|
+
* @param {number} [counter] - leave empty this counts the number of requests when doing recursive request calls
|
|
448
|
+
* @return {Promise<import('../../Session.js').Message>}
|
|
449
|
+
*/
|
|
450
|
+
async function request(prompt, toolset = null, options = {}, counter = 0) {
|
|
451
|
+
// Max number of recurusive calls
|
|
452
|
+
const counterMax = GLOBAL.max_recursive_requests;
|
|
453
|
+
const start = new Date().getTime();
|
|
454
|
+
// if (counter === 0) {
|
|
455
|
+
// Fresh request
|
|
456
|
+
delete options.previous_response_id
|
|
457
|
+
// }
|
|
458
|
+
// Generate the request
|
|
459
|
+
const { url, headers, body } = generateRequest(prompt, toolset, options);
|
|
460
|
+
prompt.emit(prompt.EVENTS.http_request, {url, counter, body});
|
|
461
|
+
const res = await doRequest(url, 'POST', headers, body);
|
|
462
|
+
prompt.emit(prompt.EVENTS.http_response, res);
|
|
463
|
+
if (res.status !== 200) {
|
|
464
|
+
throw new Error(`${res.status}: ${JSON.stringify(res.response, null, ' ')}`)
|
|
465
|
+
}
|
|
466
|
+
/*
|
|
467
|
+
https://platform.openai.com/docs/assistants/deep-dive#runs-and-run-steps
|
|
468
|
+
status` can be: in_progress, completed, incomplete (plus searching / generating / failed for some tool-call items)
|
|
469
|
+
*/
|
|
470
|
+
const duration = new Date().getTime() - start;
|
|
471
|
+
await parseResponse(duration, prompt, res, toolset);
|
|
472
|
+
const previousId = res.response.id;
|
|
473
|
+
counter = 1 + counter;
|
|
474
|
+
if (counter >= counterMax) {
|
|
475
|
+
throw new Error('Max number of recursive calls reached');
|
|
476
|
+
}
|
|
477
|
+
const lastMessage = prompt.getLastMessage();
|
|
478
|
+
if (!lastMessage) throw new Error('No message found');
|
|
479
|
+
if (lastMessage.role === 'tool') {
|
|
480
|
+
// need to do another roundtrip to include the funtion_responses
|
|
481
|
+
// And add the previousId for toolsets to work
|
|
482
|
+
if (!options) {
|
|
483
|
+
options = {};
|
|
484
|
+
}
|
|
485
|
+
options.previous_response_id = previousId;
|
|
486
|
+
await sleep('2s');
|
|
487
|
+
return request(prompt, toolset, options, counter)
|
|
488
|
+
} else {
|
|
489
|
+
return lastMessage
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
export { generateRequest, parseResponse, request }
|
package/lib/API/x.ai/text.js
CHANGED
package/lib/AgentClient.js
CHANGED
|
@@ -21,6 +21,7 @@ import { WebSocketClient } from "@j-o-r/apiserver";
|
|
|
21
21
|
* @property {ToolSet} [toolset] - The toolset
|
|
22
22
|
* @property {string} description - Custom introduction message.
|
|
23
23
|
* @property {string} name - Logical name: e.g. search, code, os, support.
|
|
24
|
+
* @property {string} secret - Websocket server access secret.
|
|
24
25
|
* @property {string} [url='ws://127.0.0.1:8000/ws?params=1234']
|
|
25
26
|
* @property {number} [intervalMs=250] - How often to pull one message from the queue.
|
|
26
27
|
*/
|
|
@@ -33,6 +34,7 @@ class AgentClient {
|
|
|
33
34
|
#prompt;
|
|
34
35
|
#description = '';
|
|
35
36
|
#name;
|
|
37
|
+
#secret = '';
|
|
36
38
|
/** @type {WebSocketClient} */
|
|
37
39
|
#ws;
|
|
38
40
|
#url = 'ws://127.0.0.1:8000/ws';
|
|
@@ -57,6 +59,7 @@ class AgentClient {
|
|
|
57
59
|
this.#prompt = options.prompt;
|
|
58
60
|
this.#description = options.description;
|
|
59
61
|
this.#name = options.name;
|
|
62
|
+
this.#secret = options.secret;
|
|
60
63
|
if (typeof options.intervalMs === 'number') this.#intervalMs = Math.max(1, options.intervalMs);
|
|
61
64
|
this.#registerPromptEvents();
|
|
62
65
|
this._start();
|
|
@@ -69,15 +72,19 @@ class AgentClient {
|
|
|
69
72
|
const events = Object.keys(this.#prompt.EVENTS);
|
|
70
73
|
events.forEach((evt) => {
|
|
71
74
|
this.#prompt.on(evt, (_msg) => {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
75
|
+
console.log(`** ${this.#name} e:${evt}**`);
|
|
76
|
+
if (evt === 'tool_request') {
|
|
77
|
+
console.log(`tool execute: ${_msg.name} ${_msg.call_id}`);
|
|
78
|
+
} else if (evt === 'tool_error') {
|
|
79
|
+
console.log(`tool error:`);
|
|
80
|
+
console.log(JSON.stringify(_msg, null, ' '));
|
|
81
|
+
}
|
|
76
82
|
});
|
|
77
83
|
});
|
|
78
84
|
}
|
|
79
85
|
_start() {
|
|
80
|
-
this.#
|
|
86
|
+
const url = this.#url + '?wssrc_id=' + this.#secret;
|
|
87
|
+
this.#ws = new WebSocketClient(url); // Match server port/path
|
|
81
88
|
this.#ws.onopen = () => {
|
|
82
89
|
// Send my introduction to the server
|
|
83
90
|
this.#ws.send(JSON.stringify({
|
|
@@ -86,7 +93,7 @@ class AgentClient {
|
|
|
86
93
|
content: this.#description,
|
|
87
94
|
id: new Date().getTime()
|
|
88
95
|
}));
|
|
89
|
-
console.log('
|
|
96
|
+
console.log('introduction_send:>>')
|
|
90
97
|
console.log(this.#name);
|
|
91
98
|
console.log(this.#description);
|
|
92
99
|
};
|