@ducci/jarvis 1.0.60 → 1.0.62

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ducci/jarvis",
3
- "version": "1.0.60",
3
+ "version": "1.0.62",
4
4
  "description": "A fully automated agent system that lives on a server.",
5
5
  "main": "./src/index.js",
6
6
  "type": "module",
@@ -90,10 +90,10 @@ function anthropicResponseToOpenAI(response) {
90
90
  const text = textParts.map(t => t.text).join('') || null;
91
91
  const toolCalls = toolParts.length > 0
92
92
  ? toolParts.map(t => ({
93
- id: t.id,
94
- type: 'function',
95
- function: { name: t.name, arguments: JSON.stringify(t.input) },
96
- }))
93
+ id: t.id,
94
+ type: 'function',
95
+ function: { name: t.name, arguments: JSON.stringify(t.input) },
96
+ }))
97
97
  : undefined;
98
98
 
99
99
  return {
@@ -151,7 +151,7 @@ export function createClient(config) {
151
151
  }
152
152
  if (config.provider === 'z-ai') {
153
153
  return new OpenAI({
154
- baseURL: 'https://api.z.ai/api/paas/v4/',
154
+ baseURL: 'https://api.z.ai/api/coding/paas/v4/',
155
155
  apiKey: config.apiKey,
156
156
  });
157
157
  }
@@ -161,6 +161,7 @@ const SEED_TOOLS = {
161
161
  `,
162
162
  },
163
163
  perplexity_search: {
164
+ requires: 'PERPLEXITY_API_KEY',
164
165
  definition: {
165
166
  type: 'function',
166
167
  function: {
@@ -205,6 +206,62 @@ const SEED_TOOLS = {
205
206
  return { answer, citations };
206
207
  `,
207
208
  },
209
+ zai_web_search: {
210
+ requires: 'ZAI_API_KEY',
211
+ definition: {
212
+ type: 'function',
213
+ function: {
214
+ name: 'zai_web_search',
215
+ description: 'Search the web using Z.AI web search. Returns real-time search results with titles, URLs, and summaries. Use this for current events, factual lookups, or research questions. Use sparingly — at most 3 searches per topic. Do not repeat the same query with minor variations; if an initial search does not yield what you need, switch to a different approach.',
216
+ parameters: {
217
+ type: 'object',
218
+ properties: {
219
+ query: {
220
+ type: 'string',
221
+ description: 'The search query or question.',
222
+ },
223
+ },
224
+ required: ['query'],
225
+ },
226
+ },
227
+ },
228
+ code: `
229
+ const https = require('https');
230
+ const body = JSON.stringify({
231
+ jsonrpc: '2.0',
232
+ id: 1,
233
+ method: 'tools/call',
234
+ params: { name: 'webSearchPrime', arguments: { query: args.query } },
235
+ });
236
+ const result = await new Promise((resolve, reject) => {
237
+ const req = https.request({
238
+ hostname: 'api.z.ai',
239
+ path: '/api/mcp/web_search_prime/mcp',
240
+ method: 'POST',
241
+ headers: {
242
+ 'Authorization': 'Bearer ' + process.env.ZAI_API_KEY,
243
+ 'Content-Type': 'application/json',
244
+ 'Content-Length': Buffer.byteLength(body),
245
+ },
246
+ }, (res) => {
247
+ let data = '';
248
+ res.on('data', chunk => data += chunk);
249
+ res.on('end', () => {
250
+ try { resolve(JSON.parse(data)); }
251
+ catch (e) { reject(new Error('Invalid JSON response: ' + data.slice(0, 200))); }
252
+ });
253
+ });
254
+ req.on('error', reject);
255
+ req.write(body);
256
+ req.end();
257
+ });
258
+ if (result.error) return { status: 'error', error: result.error.message };
259
+ const content = result.result?.content;
260
+ if (!content) return { status: 'error', error: 'Empty response from Z.AI' };
261
+ const text = Array.isArray(content) ? content.map(c => c.text || '').join('\\n') : String(content);
262
+ return { status: 'ok', results: text };
263
+ `,
264
+ },
208
265
  system_install: {
209
266
  timeout: 300_000, // 5 minutes — package downloads and installs routinely exceed 60s
210
267
  definition: {
@@ -695,6 +752,9 @@ export async function loadTools() {
695
752
  export function getToolDefinitions(tools) {
696
753
  const defs = [];
697
754
  for (const [name, t] of Object.entries(tools)) {
755
+ if (t.requires && !process.env[t.requires]) {
756
+ continue;
757
+ }
698
758
  const params = t.definition?.function?.parameters;
699
759
  if (typeof params !== 'object' || params === null || Array.isArray(params)) {
700
760
  console.warn(`[tools] Skipping tool '${name}': parameters is not a valid object (got ${typeof params})`);