decharge-scout 4.0.6 → 4.3.0

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.
Files changed (2) hide show
  1. package/index.js +133 -100
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -40,7 +40,7 @@ import { submitToOracle } from './src/oracle.js';
40
40
  import { initializePoints, awardPoints, getPoints, savePoints } from './src/points.js';
41
41
  import { getLocation } from './src/geolocation.js';
42
42
  import { purchasePremiumData } from './src/x402.js';
43
- import { hasBeenAskedForAlpha, markAskedForAlpha, parseAlphaContribution, saveAlphaContribution, calculateAlphaBonus, getAlphaInsights, verifyContribution, getInformationSources } from './src/local-alpha.js';
43
+ import { parseAlphaContribution, saveAlphaContribution, calculateAlphaBonus, getAlphaInsights, verifyContribution, getInformationSources } from './src/local-alpha.js';
44
44
 
45
45
  const __filename = fileURLToPath(import.meta.url);
46
46
  const __dirname = dirname(__filename);
@@ -354,17 +354,147 @@ async function runQueryCycle(wallet, agentName, location, options) {
354
354
  }
355
355
  }
356
356
 
357
- // Prepare submission data
357
+ // Ask for special notes before submission (with 10s timeout)
358
+ console.log(chalk.cyan('\n💬 Add special notes to this submission? (optional)'));
359
+ console.log(chalk.gray(' Examples: "High AC usage today", "Local festival", "Grid maintenance"\n'));
360
+ console.log(chalk.gray(' (Will auto-submit in 10 seconds if no input)\n'));
361
+
362
+ const specialNotes = await Promise.race([
363
+ question(chalk.blue('Special notes (or press Enter to skip): ')),
364
+ new Promise((resolve) => {
365
+ setTimeout(() => {
366
+ console.log(chalk.yellow('\n⏱️ Timeout - submitting without notes'));
367
+ resolve('');
368
+ }, 10000); // 10 second timeout
369
+ })
370
+ ]);
371
+
372
+ // Local Alpha Contribution - Ask BEFORE every submission for bonus points
373
+ console.log(chalk.cyan('\n💡 Bonus Points: Share Local Peak Time Knowledge!'));
374
+ console.log(chalk.gray(' Help improve global energy data by sharing when electricity is expensive/cheap in your area.\n'));
375
+
376
+ console.log(chalk.blue('💬 Examples:'));
377
+ console.log(chalk.gray(' • "7-9PM peak in Lagos" (evening peak)'));
378
+ console.log(chalk.gray(' • "1-5AM cheap in Berlin" (off-peak)'));
379
+ console.log(chalk.gray(' • "5-8PM peak in Mumbai" (dinner time surge)'));
380
+ console.log(chalk.gray(' • "2-6AM cheap in Texas" (wind energy overnight)'));
381
+ console.log(chalk.gray(' (Will auto-skip in 15 seconds if no input)\n'));
382
+
383
+ const alphaInput = await Promise.race([
384
+ question(chalk.blue('Share local peak times (or press Enter to skip): ')),
385
+ new Promise((resolve) => {
386
+ setTimeout(() => {
387
+ console.log(chalk.yellow('\n⏱️ Timeout - skipping bonus contribution'));
388
+ resolve('');
389
+ }, 15000); // 15 second timeout
390
+ })
391
+ ]);
392
+
393
+ // Process alpha contribution if provided
394
+ if (alphaInput.trim()) {
395
+ const parsed = parseAlphaContribution(alphaInput, location);
396
+ if (parsed) {
397
+ // Verify contribution against current pricing data
398
+ const verification = verifyContribution(parsed, energyData);
399
+
400
+ // Save contribution with verification status
401
+ const contribution = saveAlphaContribution(parsed, agentName, location, verification);
402
+
403
+ // Store for dashboard submission
404
+ pendingAlphaContribution = {
405
+ type: parsed.type,
406
+ startHour: parsed.startHour,
407
+ endHour: parsed.endHour,
408
+ location: parsed.location,
409
+ verified: verification.verified,
410
+ confidence: verification.confidence,
411
+ verificationReasons: verification.reasons
412
+ };
413
+
414
+ // Calculate bonus (higher for verified contributions)
415
+ const alphaBonus = calculateAlphaBonus(parsed, verification);
416
+
417
+ awardPoints(wallet, alphaBonus);
418
+
419
+ console.log(chalk.green(`\n✅ Thanks for contributing! Earned ${alphaBonus} bonus points!`));
420
+ console.log(chalk.gray(` Contribution: ${parsed.type} hours ${parsed.startHour}-${parsed.endHour} in ${parsed.location}`));
421
+
422
+ // Show verification results
423
+ if (verification.verified) {
424
+ console.log(chalk.green(` 🎯 Verified! Confidence: ${(verification.confidence * 100).toFixed(0)}%`));
425
+ verification.reasons.forEach(reason => {
426
+ console.log(chalk.gray(` ${reason}`));
427
+ });
428
+ console.log(chalk.green(` +${alphaBonus - 10} extra points for verified contribution!`));
429
+ } else {
430
+ console.log(chalk.yellow(` ⚠️ Low confidence: ${(verification.confidence * 100).toFixed(0)}%`));
431
+ verification.reasons.forEach(reason => {
432
+ console.log(chalk.gray(` ${reason}`));
433
+ });
434
+ console.log(chalk.gray(` Tip: Contributions that match actual price patterns earn more points!`));
435
+ }
436
+ } else {
437
+ console.log(chalk.yellow('⚠️ Could not parse contribution.'));
438
+ console.log(chalk.gray(' Accepted formats:'));
439
+ console.log(chalk.gray(' • "7-9PM peak in Lagos"'));
440
+ console.log(chalk.gray(' • "1-5AM cheap in Berlin"'));
441
+ console.log(chalk.gray(' • "19-21 peak Mumbai" (24-hour format also works)'));
442
+ }
443
+ }
444
+
445
+ // Prepare comprehensive submission data
358
446
  const submissionData = {
359
447
  agent_name: agentName,
360
448
  location: location,
361
449
  timestamp: Date.now(),
450
+
451
+ // Summary results (for quick display)
362
452
  results: {
363
453
  cheapest_window: cheapestWindow.timeWindow,
364
454
  price: cheapestWindow.price,
365
455
  savings: savings,
366
456
  data_points: energyData.length
367
- }
457
+ },
458
+
459
+ // Full weather data
460
+ weather: {
461
+ location: weatherData.location,
462
+ forecast_summary: {
463
+ hours: weatherData.forecast.length,
464
+ temp_range: {
465
+ min: Math.min(...weatherData.forecast.map(f => f.temperature)),
466
+ max: Math.max(...weatherData.forecast.map(f => f.temperature))
467
+ },
468
+ avg_wind: weatherData.forecast.reduce((sum, f) => sum + f.windSpeed, 0) / weatherData.forecast.length,
469
+ avg_solar: weatherData.forecast.reduce((sum, f) => sum + f.solarRadiation, 0) / weatherData.forecast.length
470
+ },
471
+ optimal_hour_conditions: cheapestHourData?.weather || null
472
+ },
473
+
474
+ // Pricing insights
475
+ pricing: {
476
+ region: insights.region,
477
+ base_price: insights.basePrice,
478
+ price_range: {
479
+ min: insights.minPrice,
480
+ max: insights.maxPrice,
481
+ variation_percent: insights.priceRange
482
+ },
483
+ savings_potential: insights.savingsPotential,
484
+ country_code: countryCode
485
+ },
486
+
487
+ // Optimization details
488
+ optimization: {
489
+ cheapest_hour: cheapestWindow.hour,
490
+ time_window: cheapestWindow.timeWindow,
491
+ price: cheapestWindow.price,
492
+ savings_percent: savings,
493
+ reasons: cheapestHourData?.reasons || []
494
+ },
495
+
496
+ // Special notes from user
497
+ notes: specialNotes.trim() || null
368
498
  };
369
499
 
370
500
  // Submit to oracle
@@ -435,103 +565,6 @@ async function runQueryCycle(wallet, agentName, location, options) {
435
565
  console.log(chalk.magenta(`\n⭐ Earned ${totalPointsEarned} points! (${basePoints} base${bonusPoints > 0 ? ` + ${bonusPoints} bonus` : ''})`));
436
566
  console.log(chalk.magenta(`⭐ Total Points: ${currentPoints}`));
437
567
 
438
- // Local Alpha Contribution (ask once after first run)
439
- if (totalRuns === 1 && !hasBeenAskedForAlpha()) {
440
- console.log(chalk.cyan('\n💡 Local Alpha Contribution - Help Improve Global Energy Data!'));
441
- console.log(chalk.gray(' Share your local electricity peak time knowledge for bonus points.\n'));
442
-
443
- // Show where to find this information
444
- console.log(chalk.blue('📚 Where to find peak time information:'));
445
- const sources = getInformationSources(location);
446
-
447
- // General sources
448
- sources.general.forEach(source => {
449
- console.log(chalk.gray(` ${source}`));
450
- });
451
-
452
- // Region-specific sources
453
- const regionKeys = Object.keys(sources.byRegion);
454
- if (regionKeys.length > 0) {
455
- console.log(chalk.blue('\n📍 For your region:'));
456
- regionKeys.forEach(region => {
457
- sources.byRegion[region].forEach(source => {
458
- console.log(chalk.gray(` ${source}`));
459
- });
460
- });
461
- }
462
-
463
- console.log(chalk.blue('\n💬 Examples of good contributions:'));
464
- console.log(chalk.gray(' • "7-9PM peak in Lagos" (evening peak)'));
465
- console.log(chalk.gray(' • "1-5AM cheap in Berlin" (off-peak)'));
466
- console.log(chalk.gray(' • "5-8PM peak in Mumbai" (dinner time surge)'));
467
- console.log(chalk.gray(' • "2-6AM cheap in Texas" (wind energy overnight)'));
468
- console.log(chalk.gray(' (Will auto-skip in 15 seconds if no input)\n'));
469
-
470
- // Add timeout to prevent hanging
471
- const alphaInput = await Promise.race([
472
- question(chalk.blue('Share local peak times (or press Enter to skip): ')),
473
- new Promise((resolve) => {
474
- setTimeout(() => {
475
- console.log(chalk.yellow('\n⏱️ Timeout - skipping alpha contribution'));
476
- resolve('');
477
- }, 15000); // 15 second timeout
478
- })
479
- ]);
480
-
481
- if (alphaInput.trim()) {
482
- const parsed = parseAlphaContribution(alphaInput, location);
483
- if (parsed) {
484
- // Verify contribution against current pricing data
485
- const verification = verifyContribution(parsed, energyData);
486
-
487
- // Save contribution with verification status
488
- const contribution = saveAlphaContribution(parsed, agentName, location, verification);
489
-
490
- // Store for dashboard submission
491
- pendingAlphaContribution = {
492
- type: parsed.type,
493
- startHour: parsed.startHour,
494
- endHour: parsed.endHour,
495
- location: parsed.location,
496
- verified: verification.verified,
497
- confidence: verification.confidence,
498
- verificationReasons: verification.reasons
499
- };
500
-
501
- // Calculate bonus (higher for verified contributions)
502
- const alphaBonus = calculateAlphaBonus(parsed, verification);
503
-
504
- awardPoints(wallet, alphaBonus);
505
-
506
- console.log(chalk.green(`\n✅ Thanks for contributing! Earned ${alphaBonus} bonus points!`));
507
- console.log(chalk.gray(` Contribution: ${parsed.type} hours ${parsed.startHour}-${parsed.endHour} in ${parsed.location}`));
508
-
509
- // Show verification results
510
- if (verification.verified) {
511
- console.log(chalk.green(` 🎯 Verified! Confidence: ${(verification.confidence * 100).toFixed(0)}%`));
512
- verification.reasons.forEach(reason => {
513
- console.log(chalk.gray(` ${reason}`));
514
- });
515
- console.log(chalk.green(` +${alphaBonus - 10} extra points for verified contribution!`));
516
- } else {
517
- console.log(chalk.yellow(` ⚠️ Low confidence: ${(verification.confidence * 100).toFixed(0)}%`));
518
- verification.reasons.forEach(reason => {
519
- console.log(chalk.gray(` ${reason}`));
520
- });
521
- console.log(chalk.gray(` Tip: Contributions that match actual price patterns earn more points!`));
522
- }
523
- } else {
524
- console.log(chalk.yellow('⚠️ Could not parse contribution.'));
525
- console.log(chalk.gray(' Accepted formats:'));
526
- console.log(chalk.gray(' • "7-9PM peak in Lagos"'));
527
- console.log(chalk.gray(' • "1-5AM cheap in Berlin"'));
528
- console.log(chalk.gray(' • "19-21 peak Mumbai" (24-hour format also works)'));
529
- }
530
- }
531
-
532
- markAskedForAlpha();
533
- }
534
-
535
568
  // Show alpha insights if available
536
569
  if (totalRuns === 1) {
537
570
  const alphaInsights = getAlphaInsights(location);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "decharge-scout",
3
- "version": "4.0.6",
3
+ "version": "4.3.0",
4
4
  "description": "Global Energy Scout - Weather-powered intelligent energy price forecasting with Solana integration",
5
5
  "main": "index.js",
6
6
  "type": "module",