rentabots-sdk 1.7.15 → 1.7.17

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.js CHANGED
@@ -71,7 +71,7 @@ exports.MessageSchema = zod_1.z.object({
71
71
  })
72
72
  });
73
73
  // --- CORE SDK ENGINE ---
74
- let SDK_VERSION = '1.7.15'; // fallback when package.json is unavailable
74
+ let SDK_VERSION = '1.7.17'; // fallback when package.json is unavailable
75
75
  try {
76
76
  const pkg = JSON.parse(fs.readFileSync(path.join(__dirname, '..', 'package.json'), 'utf8'));
77
77
  SDK_VERSION = pkg.version;
@@ -658,13 +658,22 @@ class Agent extends events_1.EventEmitter {
658
658
  async syncFromCloud() {
659
659
  this.logInternal("Synchronizing missions and bids from cloud...");
660
660
  try {
661
- // 1. Sync Active Missions
661
+ // 1. Sync Active Missions (authoritative cloud state)
662
662
  const activeRes = await this.api.get('jobs?status=in_progress');
663
663
  const myActive = activeRes.data.data.filter((j) => j.agentId === this.agentId);
664
- for (const raw of myActive) {
665
- if (!this.activeMissions.has(raw.id)) {
666
- this.activeMissions.set(raw.id, this.enrichJob(raw));
664
+ const liveIds = new Set(myActive.map((j) => j.id));
665
+ // Prune stale local active missions so autopilot can resume after completion
666
+ for (const localId of Array.from(this.activeMissions.keys())) {
667
+ if (!liveIds.has(localId)) {
668
+ const stale = this.activeMissions.get(localId);
669
+ if (stale)
670
+ this.completedMissions.set(localId, { ...stale, status: 'completed' });
671
+ this.activeMissions.delete(localId);
672
+ this.logInternal(`Uplink: Pruned stale active mission ${localId}`);
667
673
  }
674
+ }
675
+ for (const raw of myActive) {
676
+ this.activeMissions.set(raw.id, this.enrichJob(raw));
668
677
  this.socket?.emit('join_mission', raw.id);
669
678
  this.logInternal(`Uplink: Monitoring active mission ${raw.id}`);
670
679
  }
package/init.js CHANGED
@@ -274,6 +274,7 @@ async function main() {
274
274
  };
275
275
  walk(workDir);
276
276
 
277
+ let fallbackGenerated = false;
277
278
  if (files.length === 0) {
278
279
  await agent.setProgress(job.id, 40);
279
280
  await agent.sendMessage(job.id, "⚠️ No deliverable files were produced yet. Entering forced-build fallback and generating starter deliverables now.");
@@ -287,6 +288,7 @@ async function main() {
287
288
  fs.writeFileSync(path.join(workDir, 'solution.py'), script);
288
289
 
289
290
  files.push('README.md', 'CLARIFICATIONS.md', 'solution.py');
291
+ fallbackGenerated = true;
290
292
  }
291
293
 
292
294
  const repoRes = await agent.getRepo(job.id);
@@ -312,6 +314,33 @@ async function main() {
312
314
  return;
313
315
  }
314
316
 
317
+ // Lightweight QA: ensure deliverables are relevant to mission intent
318
+ const missionText = (job.title + ' ' + job.description).toLowerCase();
319
+ const required = [];
320
+ if (missionText.includes('python')) required.push('python');
321
+ if (missionText.includes('csv')) required.push('csv');
322
+ if (missionText.includes('blank') || missionText.includes('whitespace')) required.push('strip');
323
+
324
+ let combinedText = '';
325
+ for (const rel of files) {
326
+ const ext = path.extname(rel).toLowerCase();
327
+ if (['.js','.ts','.tsx','.jsx','.json','.md','.txt','.py','.yml','.yaml','.html','.css','.csv'].includes(ext)) {
328
+ try { combinedText += '\n' + fs.readFileSync(path.join(workDir, rel), 'utf8').toLowerCase(); } catch (_) {}
329
+ }
330
+ }
331
+ const missing = required.filter(k => !combinedText.includes(k));
332
+ if (missing.length > 0) {
333
+ await agent.setProgress(job.id, 70);
334
+ await agent.sendMessage(job.id, '⚠️ QA check failed: output appears misaligned with mission (' + missing.join(', ') + ' not found). I will revise now.');
335
+ return;
336
+ }
337
+
338
+ if (fallbackGenerated) {
339
+ await agent.setProgress(job.id, 85);
340
+ await agent.sendMessage(job.id, '🛟 Draft fallback deliverables uploaded for review (not final). Repo: ' + (repo?.id ? ('https://rentabots.com/repos/' + repo.id) : 'mission repository') + '. I will continue refinement after your confirmation.');
341
+ return;
342
+ }
343
+
315
344
  await agent.setProgress(job.id, 100);
316
345
  if (repo?.id) {
317
346
  await agent.sendMessage(job.id, "✅ Execution complete. Deliverables uploaded: " + uploaded + " files. Repo: https://rentabots.com/repos/" + repo.id);
package/init_templates.js CHANGED
@@ -259,6 +259,7 @@ async function main() {
259
259
  };
260
260
  walk(workDir);
261
261
 
262
+ let fallbackGenerated = false;
262
263
  if (files.length === 0) {
263
264
  await agent.setProgress(job.id, 40);
264
265
  await agent.sendMessage(job.id, "⚠️ No deliverable files were produced yet. Entering forced-build fallback and generating starter deliverables now.");
@@ -272,6 +273,7 @@ async function main() {
272
273
  fs.writeFileSync(path.join(workDir, 'solution.py'), script);
273
274
 
274
275
  files.push('README.md', 'CLARIFICATIONS.md', 'solution.py');
276
+ fallbackGenerated = true;
275
277
  }
276
278
 
277
279
  const repoRes = await agent.getRepo(job.id);
@@ -297,6 +299,33 @@ async function main() {
297
299
  return;
298
300
  }
299
301
 
302
+ // Lightweight QA: ensure deliverables are relevant to mission intent
303
+ const missionText = (job.title + ' ' + job.description).toLowerCase();
304
+ const required = [];
305
+ if (missionText.includes('python')) required.push('python');
306
+ if (missionText.includes('csv')) required.push('csv');
307
+ if (missionText.includes('blank') || missionText.includes('whitespace')) required.push('strip');
308
+
309
+ let combinedText = '';
310
+ for (const rel of files) {
311
+ const ext = path.extname(rel).toLowerCase();
312
+ if (['.js','.ts','.tsx','.jsx','.json','.md','.txt','.py','.yml','.yaml','.html','.css','.csv'].includes(ext)) {
313
+ try { combinedText += '\n' + fs.readFileSync(path.join(workDir, rel), 'utf8').toLowerCase(); } catch (_) {}
314
+ }
315
+ }
316
+ const missing = required.filter(k => !combinedText.includes(k));
317
+ if (missing.length > 0) {
318
+ await agent.setProgress(job.id, 70);
319
+ await agent.sendMessage(job.id, '⚠️ QA check failed: output appears misaligned with mission (' + missing.join(', ') + ' not found). I will revise now.');
320
+ return;
321
+ }
322
+
323
+ if (fallbackGenerated) {
324
+ await agent.setProgress(job.id, 85);
325
+ await agent.sendMessage(job.id, '🛟 Draft fallback deliverables uploaded for review (not final). Repo: ' + (repo?.id ? ('https://rentabots.com/repos/' + repo.id) : 'mission repository') + '. I will continue refinement after your confirmation.');
326
+ return;
327
+ }
328
+
300
329
  await agent.setProgress(job.id, 100);
301
330
  if (repo?.id) {
302
331
  await agent.sendMessage(job.id, "✅ Execution complete. Deliverables uploaded: " + uploaded + " files. Repo: https://rentabots.com/repos/" + repo.id);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rentabots-sdk",
3
- "version": "1.7.15",
3
+ "version": "1.7.17",
4
4
  "description": "Official SDK for RentaBots AI Agent Marketplace",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",