rentabots-sdk 1.7.0 → 1.7.1

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/index.d.ts CHANGED
@@ -74,7 +74,7 @@ export interface AutopilotOptions {
74
74
  bidTemplate?: string;
75
75
  }
76
76
  /**
77
- * 🦀 RENTABOTS MASTER SDK (v1.5.7)
77
+ * 🦀 RENTABOTS MASTER SDK (v1.7.1)
78
78
  * Robust, production-grade autonomous agent runtime.
79
79
  * UPDATES:
80
80
  * - Agent Isolation Protocol (Private workspaces).
@@ -135,15 +135,54 @@ export declare class Agent extends EventEmitter {
135
135
  error: any;
136
136
  jobId?: undefined;
137
137
  }>;
138
+ private isBinaryFile;
138
139
  deliver(jobId: string, files: string[]): Promise<void>;
140
+ verifyDeliverables(jobId: string): Promise<{
141
+ success: boolean;
142
+ verified: boolean;
143
+ files?: any[];
144
+ issues?: string[];
145
+ error?: string;
146
+ }>;
147
+ preDeliveryCheck(jobId: string): Promise<{
148
+ canDeliver: boolean;
149
+ checks: any[];
150
+ }>;
139
151
  markComplete(jobId: string): Promise<any>;
152
+ initLLM(config?: Partial<LLMConfig>): Promise<void>;
153
+ generate(prompt: string, options?: {
154
+ system?: string;
155
+ }): Promise<{
156
+ success: boolean;
157
+ text?: string;
158
+ error?: string;
159
+ }>;
160
+ analyzeRequirements(job: Job): Promise<{
161
+ success: boolean;
162
+ requirements?: any;
163
+ error?: string;
164
+ }>;
165
+ codeGenerator(prompt: string, language?: string): Promise<{
166
+ success: boolean;
167
+ code?: string;
168
+ error?: string;
169
+ }>;
170
+ reviewCode(code: string, requirements: string): Promise<{
171
+ success: boolean;
172
+ review?: string;
173
+ passed: boolean;
174
+ error?: string;
175
+ }>;
140
176
  bid(jobId: string, amount: number, message: string): Promise<any>;
141
177
  sendMessage(jobId: string, content: string): Promise<import("axios").AxiosResponse<any, any, {}>>;
142
178
  setTyping(jobId: string, isTyping?: boolean): Promise<void>;
143
179
  /**
144
180
  * Update mission progress (0-100%)
145
181
  */
146
- setProgress(jobId: string, progress: number): Promise<import("axios").AxiosResponse<any, any, {}> | undefined>;
182
+ setProgress(jobId: string, progress: number): Promise<{
183
+ success: boolean;
184
+ error?: string;
185
+ }>;
147
186
  /**
148
187
  * Initialize isolated workspace for a mission, returns the path
149
188
  */
@@ -187,7 +226,11 @@ export declare class Agent extends EventEmitter {
187
226
  /**
188
227
  * Create a private repository for a mission
189
228
  */
190
- createRepo(jobId: string, name?: string): Promise<any>;
229
+ createRepo(jobId: string, name?: string): Promise<{
230
+ success: boolean;
231
+ repo?: any;
232
+ error?: string;
233
+ }>;
191
234
  /**
192
235
  * Upload files to a mission's repository
193
236
  */
@@ -203,10 +246,20 @@ export declare class Agent extends EventEmitter {
203
246
  success: boolean;
204
247
  error: any;
205
248
  })[]>;
249
+ uploadRepoFile(jobId: string, filePath: string, content: string | Buffer, isBlob?: boolean): Promise<{
250
+ success: boolean;
251
+ repoId?: string;
252
+ error?: string;
253
+ }>;
206
254
  /**
207
255
  * Check if a repository exists for a mission and get its info
208
256
  */
209
- getRepo(jobId: string): Promise<any>;
257
+ getRepo(jobId: string): Promise<{
258
+ success: boolean;
259
+ exists: boolean;
260
+ repo?: any;
261
+ error?: string;
262
+ }>;
210
263
  /**
211
264
  * Ask the LLM brain a question. Works with OpenClaw or any custom API provider.
212
265
  * @param systemPrompt System-level instructions
package/dist/index.js CHANGED
@@ -38,6 +38,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
39
  exports.Agent = exports.MessageSchema = exports.JobSchema = exports.JobStatusSchema = void 0;
40
40
  const axios_1 = __importDefault(require("axios"));
41
+ // import { LLMClient } from "./llm"; // Removed missing module
41
42
  const socket_io_client_1 = require("socket.io-client");
42
43
  const zod_1 = require("zod");
43
44
  const events_1 = require("events");
@@ -86,14 +87,14 @@ exports.MessageSchema = zod_1.z.object({
86
87
  })
87
88
  });
88
89
  // --- CORE SDK ENGINE ---
89
- let SDK_VERSION = '1.5.7'; // BUMP to v1.5.7
90
+ let SDK_VERSION = '1.7.1'; // BUMP to v1.7.1
90
91
  try {
91
92
  const pkg = JSON.parse(fs.readFileSync(path.join(__dirname, '..', 'package.json'), 'utf8'));
92
93
  SDK_VERSION = pkg.version;
93
94
  }
94
95
  catch (e) { }
95
96
  /**
96
- * 🦀 RENTABOTS MASTER SDK (v1.5.7)
97
+ * 🦀 RENTABOTS MASTER SDK (v1.7.1)
97
98
  * Robust, production-grade autonomous agent runtime.
98
99
  * UPDATES:
99
100
  * - Agent Isolation Protocol (Private workspaces).
@@ -463,6 +464,10 @@ class Agent extends events_1.EventEmitter {
463
464
  return { success: false, error: e.response?.data?.error || e.message };
464
465
  }
465
466
  }
467
+ isBinaryFile(filePath) {
468
+ const textExts = ['.js', '.ts', '.json', '.md', '.txt', '.html', '.css', '.yml', '.yaml', '.toml'];
469
+ return !textExts.includes(path.extname(filePath).toLowerCase());
470
+ }
466
471
  async deliver(jobId, files) {
467
472
  const cwd = path.join(this.workspaceRoot, jobId);
468
473
  for (const file of files) {
@@ -473,6 +478,43 @@ class Agent extends events_1.EventEmitter {
473
478
  }
474
479
  }
475
480
  }
481
+ // --- ✅ VERIFICATION FLOW ---
482
+ async verifyDeliverables(jobId) {
483
+ try {
484
+ const cwd = path.join(this.workspaceRoot, jobId);
485
+ if (!fs.existsSync(cwd))
486
+ return { success: false, verified: false, error: 'No workspace' };
487
+ const issues = [];
488
+ const files = [];
489
+ const scanDir = (dir, rel = '') => {
490
+ fs.readdirSync(dir).forEach((item) => {
491
+ const full = path.join(dir, item);
492
+ const relPath = path.join(rel, item);
493
+ if (fs.statSync(full).isDirectory())
494
+ scanDir(full, relPath);
495
+ else
496
+ files.push({ path: relPath, size: fs.statSync(full).size });
497
+ });
498
+ };
499
+ scanDir(cwd);
500
+ if (files.length === 0)
501
+ issues.push('No deliverables');
502
+ if (!files.some(f => f.path.toLowerCase().includes('readme')))
503
+ issues.push('Missing README');
504
+ const verified = issues.length === 0;
505
+ return { success: true, verified, files, issues };
506
+ }
507
+ catch (e) {
508
+ return { success: false, verified: false, error: e.message };
509
+ }
510
+ }
511
+ async preDeliveryCheck(jobId) {
512
+ const verify = await this.verifyDeliverables(jobId);
513
+ const checks = [{ name: 'Deliverables', passed: verify.verified, details: verify.files?.length + ' files' }];
514
+ const job = this.activeMissions.get(jobId);
515
+ checks.push({ name: 'Progress', passed: (job?.progress || 0) >= 80, details: (job?.progress || 0) + '%' });
516
+ return { canDeliver: checks.every(c => c.passed), checks };
517
+ }
476
518
  async markComplete(jobId) {
477
519
  const res = await this.api.post(`jobs/${jobId}/complete`, { userId: this.agentId, role: 'agent' });
478
520
  if (res.data.success) {
@@ -484,6 +526,45 @@ class Agent extends events_1.EventEmitter {
484
526
  }
485
527
  return res.data;
486
528
  }
529
+ // --- 🧠 LLM INTEGRATION ---
530
+ async initLLM(config) {
531
+ if (config) {
532
+ this.llmConfig = { ...this.llmConfig, ...config };
533
+ }
534
+ }
535
+ async generate(prompt, options = {}) {
536
+ const res = await this.askLLM(options.system || 'You are a helpful assistant.', prompt);
537
+ if (res)
538
+ return { success: true, text: res };
539
+ return { success: false, error: 'LLM request failed' };
540
+ }
541
+ async analyzeRequirements(job) {
542
+ const prompt = 'Analyze job, return JSON with techStack, features, deliverables, timeline, risks. Title: ' + job.title + ' Desc: ' + job.description.slice(0, 500);
543
+ const res = await this.generate(prompt, { system: 'Extract requirements as JSON' });
544
+ if (!res.success)
545
+ return res;
546
+ try {
547
+ const json = res.text?.match(/\{[^]*\}/)?.[0];
548
+ return { success: true, requirements: JSON.parse(json || '{}') };
549
+ }
550
+ catch {
551
+ return { success: false, error: 'Parse failed' };
552
+ }
553
+ }
554
+ async codeGenerator(prompt, language = 'javascript') {
555
+ const res = await this.generate(prompt, { system: 'Output only ' + language + ' code' });
556
+ if (!res.success)
557
+ return res;
558
+ const code = res.text?.match(/```(?:\w+)?\n?([\s\S]*?)```/)?.[1] || res.text;
559
+ return { success: true, code: code?.trim() };
560
+ }
561
+ async reviewCode(code, requirements) {
562
+ const res = await this.generate('Review code. Reqs: ' + requirements + ' Code: ' + code.slice(0, 2000), { system: 'Code reviewer' });
563
+ if (!res.success)
564
+ return { success: false, passed: false, error: res.error };
565
+ const passed = !!(res.text?.toUpperCase().includes('PASS') && !res.text?.toUpperCase().includes('FAIL'));
566
+ return { success: true, review: res.text, passed };
567
+ }
487
568
  async bid(jobId, amount, message) {
488
569
  try {
489
570
  const res = await this.api.post('bids', { jobId, amount, message });
@@ -512,10 +593,18 @@ class Agent extends events_1.EventEmitter {
512
593
  */
513
594
  async setProgress(jobId, progress) {
514
595
  try {
515
- return await this.api.post(`jobs/${jobId}/progress`, { progress, agentId: this.agentId });
596
+ const res = await this.api.post(`jobs/${jobId}/progress`, { progress, agentId: this.agentId });
597
+ const job = this.activeMissions.get(jobId);
598
+ if (job) {
599
+ job.progress = progress;
600
+ this.activeMissions.set(jobId, job);
601
+ this.saveState();
602
+ }
603
+ return { success: true };
516
604
  }
517
605
  catch (e) {
518
606
  this.logInternal(`Failed to update progress for ${jobId}: ${e.message}`);
607
+ return { success: false, error: e.message };
519
608
  }
520
609
  }
521
610
  /**
@@ -616,7 +705,7 @@ class Agent extends events_1.EventEmitter {
616
705
  try {
617
706
  const res = await this.api.post(`jobs/${jobId}/repo`, { name });
618
707
  this.logInternal(`Repository created for job ${jobId}`);
619
- return res.data;
708
+ return { success: true, repo: res.data.repo };
620
709
  }
621
710
  catch (e) {
622
711
  this.logInternal(`createRepo failed: ${e.message}`);
@@ -639,16 +728,35 @@ class Agent extends events_1.EventEmitter {
639
728
  }
640
729
  return results;
641
730
  }
731
+ async uploadRepoFile(jobId, filePath, content, isBlob = false) {
732
+ try {
733
+ let finalContent;
734
+ if (Buffer.isBuffer(content)) {
735
+ finalContent = content.toString('base64');
736
+ isBlob = true;
737
+ }
738
+ else {
739
+ finalContent = String(content);
740
+ }
741
+ const res = await this.api.post(`jobs/${jobId}/repo/files`, { path: filePath, content: finalContent, isBlob });
742
+ return { success: true, repoId: res.data.repoId };
743
+ }
744
+ catch (e) {
745
+ return { success: false, error: e.response?.data?.error || e.message };
746
+ }
747
+ }
642
748
  /**
643
749
  * Check if a repository exists for a mission and get its info
644
750
  */
645
751
  async getRepo(jobId) {
646
752
  try {
647
753
  const res = await this.api.get(`jobs/${jobId}/repo`);
648
- return res.data;
754
+ return { success: true, exists: res.data.exists, repo: res.data.repo };
649
755
  }
650
756
  catch (e) {
651
- return { exists: false };
757
+ if (e.response?.status === 404)
758
+ return { success: true, exists: false };
759
+ return { success: false, exists: false, error: e.response?.data?.error || e.message };
652
760
  }
653
761
  }
654
762
  // --- 🧠 LLM ABSTRACTION LAYER ---
package/dist/llm.d.ts ADDED
@@ -0,0 +1,34 @@
1
+ /**
2
+ * LLM Provider Configuration
3
+ * Agents use their own API keys - no server proxy needed
4
+ */
5
+ export interface LLMConfig {
6
+ provider: 'groq' | 'openai' | 'anthropic' | 'google' | 'nvidia';
7
+ apiKey: string;
8
+ baseUrl?: string;
9
+ model?: string;
10
+ }
11
+ export interface LLMResponse {
12
+ success: boolean;
13
+ text?: string;
14
+ error?: string;
15
+ usage?: {
16
+ promptTokens: number;
17
+ completionTokens: number;
18
+ };
19
+ }
20
+ export declare class LLMClient {
21
+ private config;
22
+ private client;
23
+ constructor(config?: Partial<LLMConfig>);
24
+ private detectProvider;
25
+ private getApiKey;
26
+ generate(prompt: string, options?: {
27
+ system?: string;
28
+ temperature?: number;
29
+ maxTokens?: number;
30
+ model?: string;
31
+ }): Promise<LLMResponse>;
32
+ private callAnthropic;
33
+ }
34
+ export default LLMClient;
package/dist/llm.js ADDED
@@ -0,0 +1,129 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.LLMClient = void 0;
7
+ const axios_1 = __importDefault(require("axios"));
8
+ const PROVIDER_CONFIGS = {
9
+ groq: {
10
+ baseUrl: 'https://api.groq.com/openai/v1',
11
+ defaultModel: 'llama-3.3-70b-versatile',
12
+ apiFormat: 'openai'
13
+ },
14
+ openai: {
15
+ baseUrl: 'https://api.openai.com/v1',
16
+ defaultModel: 'gpt-4o-mini',
17
+ apiFormat: 'openai'
18
+ },
19
+ anthropic: {
20
+ baseUrl: 'https://api.anthropic.com',
21
+ defaultModel: 'claude-3-sonnet-20240229',
22
+ apiFormat: 'anthropic'
23
+ },
24
+ google: {
25
+ baseUrl: 'https://generativelanguage.googleapis.com/v1beta',
26
+ defaultModel: 'gemini-1.5-flash',
27
+ apiFormat: 'openai'
28
+ },
29
+ nvidia: {
30
+ baseUrl: 'https://integrate.api.nvidia.com/v1',
31
+ defaultModel: 'meta/llama-3.1-405b-instruct',
32
+ apiFormat: 'openai'
33
+ }
34
+ };
35
+ class LLMClient {
36
+ constructor(config) {
37
+ // Auto-detect from environment
38
+ const provider = config?.provider || this.detectProvider();
39
+ const apiKey = config?.apiKey || this.getApiKey(provider);
40
+ if (!apiKey) {
41
+ throw new Error(`No API key found for LLM provider '${provider}'. Set ${provider.toUpperCase()}_API_KEY or GROQ_API_KEY`);
42
+ }
43
+ const preset = PROVIDER_CONFIGS[provider];
44
+ this.config = {
45
+ provider,
46
+ apiKey,
47
+ baseUrl: config?.baseUrl || preset?.baseUrl,
48
+ model: config?.model || preset?.defaultModel
49
+ };
50
+ this.client = axios_1.default.create({
51
+ baseURL: this.config.baseUrl,
52
+ headers: provider === 'anthropic'
53
+ ? { 'x-api-key': apiKey, 'anthropic-version': '2023-06-01' }
54
+ : { 'Authorization': `Bearer ${apiKey}` }
55
+ });
56
+ }
57
+ detectProvider() {
58
+ if (process.env.ANTHROPIC_API_KEY)
59
+ return 'anthropic';
60
+ if (process.env.OPENAI_API_KEY)
61
+ return 'openai';
62
+ if (process.env.GOOGLE_API_KEY)
63
+ return 'google';
64
+ if (process.env.NVIDIA_API_KEY)
65
+ return 'nvidia';
66
+ return 'groq'; // Default
67
+ }
68
+ getApiKey(provider) {
69
+ const envMap = {
70
+ groq: 'GROQ_API_KEY',
71
+ openai: 'OPENAI_API_KEY',
72
+ anthropic: 'ANTHROPIC_API_KEY',
73
+ google: 'GOOGLE_API_KEY',
74
+ nvidia: 'NVIDIA_API_KEY'
75
+ };
76
+ return process.env[envMap[provider]] || process.env.GROQ_API_KEY || process.env.RENTABOTS_LLM_KEY;
77
+ }
78
+ async generate(prompt, options = {}) {
79
+ const model = options.model || this.config.model;
80
+ try {
81
+ if (this.config.provider === 'anthropic') {
82
+ return await this.callAnthropic(prompt, options, model);
83
+ }
84
+ // OpenAI-compatible format
85
+ const res = await this.client.post('/chat/completions', {
86
+ model,
87
+ messages: [
88
+ ...(options.system ? [{ role: 'system', content: options.system }] : []),
89
+ { role: 'user', content: prompt }
90
+ ],
91
+ temperature: options.temperature ?? 0.7,
92
+ max_tokens: options.maxTokens ?? 2048
93
+ });
94
+ return {
95
+ success: true,
96
+ text: res.data.choices[0]?.message?.content,
97
+ usage: res.data.usage ? {
98
+ promptTokens: res.data.usage.prompt_tokens,
99
+ completionTokens: res.data.usage.completion_tokens
100
+ } : undefined
101
+ };
102
+ }
103
+ catch (error) {
104
+ return {
105
+ success: false,
106
+ error: error.response?.data?.error?.message || error.message
107
+ };
108
+ }
109
+ }
110
+ async callAnthropic(prompt, options, model) {
111
+ const res = await this.client.post('/v1/messages', {
112
+ model,
113
+ messages: [{ role: 'user', content: prompt }],
114
+ system: options.system,
115
+ temperature: options.temperature ?? 0.7,
116
+ max_tokens: options.maxTokens ?? 2048
117
+ });
118
+ return {
119
+ success: true,
120
+ text: res.data.content[0]?.text,
121
+ usage: {
122
+ promptTokens: res.data.usage?.input_tokens || 0,
123
+ completionTokens: res.data.usage?.output_tokens || 0
124
+ }
125
+ };
126
+ }
127
+ }
128
+ exports.LLMClient = LLMClient;
129
+ exports.default = LLMClient;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rentabots-sdk",
3
- "version": "1.7.0",
3
+ "version": "1.7.1",
4
4
  "description": "Official SDK for RentaBots AI Agent Marketplace",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",