@kernel.chat/kbot 3.83.0 → 3.86.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.
@@ -13,7 +13,7 @@ import { createCanvas } from 'canvas';
13
13
  import { drawRobot, drawMoodParticles, drawHat, drawPet, drawBuddyCompanion } from './sprite-engine.js';
14
14
  import { initIntelligence, tickIntelligence, handleIntelligenceCommand, drawBrainPanel, getBrainAction, tickMiniGame, drawMiniGameOverlay, tickProgression, updateQuestProgress, drawQuestPanel, tickRandomEvent, drawRandomEvent, shippedEffects, extraJokeResponses, multiLanguageGreetings } from './stream-intelligence.js';
15
15
  import { initStreamBrain, analyzeChatForDomains, tickStreamBrain, handleBrainCommand, drawBrainActivity } from './stream-brain.js';
16
- import { renderLighting, renderBloom, renderPostProcessing, renderSky, renderParticles, tickParticles as tickRenderParticles, createParticleEmitter, drawCharacterEffects, checkMoodTransition, renderDamageFlash, buildCharacterLights, buildCharacterBloom, getAmbientForTime, renderAnimatedWater, renderLavaFlow, buildParallaxLayers, renderParallaxLayers, tickGrowingPlants, renderGrowingPlants } from './render-engine.js';
16
+ import { renderLighting, renderBloom, renderPostProcessing, renderSky, renderParticles, tickParticlesPBD, createParticleEmitter, drawCharacterEffects, checkMoodTransition, renderDamageFlash, buildCharacterLights, buildCharacterBloom, getAmbientForTime, renderAnimatedWater, renderLavaFlow, buildParallaxLayers, renderParallaxLayers, tickGrowingPlants, renderGrowingPlants, createRadianceGrid, updateRadianceGrid, renderRadianceOverlay, renderSubsurfaceGlow, buildSubsurfacePanels, createFrameCache, renderVolumetricFog, getFogParams, computeAnimationParams } from './render-engine.js';
17
17
  const KBOT_DIR = join(homedir(), '.kbot');
18
18
  const CHAT_BRIDGE_FILE = join(KBOT_DIR, 'stream-chat-live.json');
19
19
  const MEMORY_FILE = join(KBOT_DIR, 'stream-memory.json');
@@ -1447,6 +1447,11 @@ let charState = {
1447
1447
  growingPlants: [],
1448
1448
  parallaxLayers: [],
1449
1449
  isExecutingTool: false,
1450
+ radianceGrid: createRadianceGrid(),
1451
+ frameCache: createFrameCache(),
1452
+ animParams: { blinkRate: 0.2, wobbleFreq: 0.04, wobbleAmp: 2, glowPulseSpeed: 0.1, breathSpeed: 0.05, energyLevel: 0.5 },
1453
+ lastMoodForCache: 'wave',
1454
+ lastGroundForCache: 'grass',
1450
1455
  };
1451
1456
  // ─── Phase 1: Buddy Speech Pools ─────────────────────────────
1452
1457
  const BUDDY_SPEECH_POOL = {
@@ -2106,6 +2111,24 @@ function renderFrame() {
2106
2111
  // Update world
2107
2112
  updateParticles();
2108
2113
  tickPhysics();
2114
+ // NVIDIA: Compute animation params from stream context
2115
+ {
2116
+ const elapsed = Math.floor((Date.now() - charState.startTime) / 1000);
2117
+ const streamMinutes = elapsed / 60;
2118
+ const recentMessages = charState.chatMessages.slice(-30);
2119
+ const chatTimespanMs = recentMessages.length > 1
2120
+ ? (Date.now() - recentMessages[0]?.timestamp || Date.now()) : 60000;
2121
+ const chatRate = recentMessages.length / Math.max(1, chatTimespanMs / 60000);
2122
+ const viewerEstimate = Math.max(1, Math.floor(memory.totalMessages / 3) + Object.keys(memory.users).length);
2123
+ charState.animParams = computeAnimationParams(chatRate, viewerEstimate, charState.mood, world.timeOfDay, streamMinutes);
2124
+ }
2125
+ // NVIDIA: Detect cache invalidation triggers
2126
+ const moodChanged = charState.mood !== charState.lastMoodForCache;
2127
+ const worldChanged = world.ground !== charState.lastGroundForCache;
2128
+ if (moodChanged)
2129
+ charState.lastMoodForCache = charState.mood;
2130
+ if (worldChanged)
2131
+ charState.lastGroundForCache = world.ground;
2109
2132
  // AAA: Continuous particle effects for biomes
2110
2133
  if (world.ground === 'lava' && animFrame % 4 === 0) {
2111
2134
  charState.renderParticles.push(...createParticleEmitter('fire', 50 + Math.random() * 480, 485, 1));
@@ -2117,7 +2140,7 @@ function renderFrame() {
2117
2140
  if (charState.renderParticles.length > 150) {
2118
2141
  charState.renderParticles = charState.renderParticles.slice(-150);
2119
2142
  }
2120
- charState.renderParticles = tickRenderParticles(charState.renderParticles);
2143
+ charState.renderParticles = tickParticlesPBD(charState.renderParticles, 480, charState.robotX + 160, 280);
2121
2144
  // AAA: Tick growing plants
2122
2145
  tickGrowingPlants(charState.growingPlants);
2123
2146
  // PRIORITY 2: Screen shake offset
@@ -2129,6 +2152,8 @@ function renderFrame() {
2129
2152
  }
2130
2153
  ctx.save();
2131
2154
  ctx.translate(shakeOffX, shakeOffY);
2155
+ // NVIDIA: Early moodColor resolution (needed by fog and all rendering)
2156
+ const moodColorHex = MOOD_COLORS[charState.mood] ?? COLORS.green;
2132
2157
  // Background — AAA: base fill + procedural sky
2133
2158
  ctx.fillStyle = world.events.includes('lightning') ? '#ffffff' : getWorldBg();
2134
2159
  ctx.fillRect(0, 0, WIDTH, HEIGHT);
@@ -2173,6 +2198,12 @@ function renderFrame() {
2173
2198
  ctx.fillRect(p.x, p.y, 2, 6);
2174
2199
  }
2175
2200
  }
2201
+ // NVIDIA: Volumetric fog (between background and character layers)
2202
+ {
2203
+ const fogParams = getFogParams(world.ground, world.timeOfDay);
2204
+ const fogLights = buildCharacterLights(charState.robotX, 90, 10, moodColorHex, animFrame, world.events.includes('lightning'), world.items.map(i => ({ x: i.x, y: i.y, emoji: i.emoji, name: i.name })));
2205
+ renderVolumetricFog(ctx, WIDTH, HEIGHT, animFrame, fogParams.density, fogParams.color, fogLights);
2206
+ }
2176
2207
  // World items (physics-enabled)
2177
2208
  ctx.fillStyle = COLORS.text;
2178
2209
  ctx.font = '18px "Courier New", monospace';
@@ -2322,7 +2353,6 @@ function renderFrame() {
2322
2353
  const glowCenterX = robotX + 16 * robotScale;
2323
2354
  const glowCenterY = robotY + 26 * robotScale;
2324
2355
  const glowRadius = 10 * robotScale;
2325
- const moodColorHex = MOOD_COLORS[charState.mood] ?? COLORS.green;
2326
2356
  const grad = ctx.createRadialGradient(glowCenterX, glowCenterY, 0, glowCenterX, glowCenterY, glowRadius);
2327
2357
  grad.addColorStop(0, hexToRgba(moodColorHex, 0.2));
2328
2358
  grad.addColorStop(1, hexToRgba(moodColorHex, 0));
@@ -2353,6 +2383,11 @@ function renderFrame() {
2353
2383
  drawMoodParticles(ctx, robotX, robotY, robotScale, charState.mood, animFrame);
2354
2384
  // AAA: Render advanced particles
2355
2385
  renderParticles(ctx, charState.renderParticles);
2386
+ // NVIDIA: Subsurface scattering on translucent panels
2387
+ {
2388
+ const sssPanels = buildSubsurfacePanels(charState.robotX, 90, robotScale, moodColorHex);
2389
+ renderSubsurfaceGlow(ctx, sssPanels);
2390
+ }
2356
2391
  // PRIORITY 6: Draw hat AFTER robot so it layers on top
2357
2392
  if (charState.hat !== 'none') {
2358
2393
  drawHat(ctx, robotX, robotY, robotScale, charState.hat, animFrame);
@@ -2725,6 +2760,13 @@ function renderFrame() {
2725
2760
  const lights = buildCharacterLights(charState.robotX, 90, robotScale, moodColorHex, animFrame, hasLightning, world.items.map(i => ({ x: i.x, y: i.y, emoji: i.emoji, name: i.name })));
2726
2761
  renderLighting(ctx, lights, WIDTH, HEIGHT, ambientLevel);
2727
2762
  }
2763
+ // ── NVIDIA: Radiance Grid — ambient light propagation ──
2764
+ {
2765
+ const hasLightning = world.events.includes('lightning');
2766
+ const lights = buildCharacterLights(charState.robotX, 90, 10, moodColorHex, animFrame, hasLightning, world.items.map(i => ({ x: i.x, y: i.y, emoji: i.emoji, name: i.name })));
2767
+ updateRadianceGrid(charState.radianceGrid, lights);
2768
+ renderRadianceOverlay(ctx, charState.radianceGrid, WIDTH, HEIGHT);
2769
+ }
2728
2770
  // ── AAA: Bloom Effect ──
2729
2771
  {
2730
2772
  const robotScale = 10;
@@ -3345,6 +3387,9 @@ export function registerStreamRendererTools() {
3345
3387
  buddy: initBuddyForStream(),
3346
3388
  dreamInsights: [], dreamInsightIndex: 0, dreamInsightTime: 0, isDreamingWithOllama: false,
3347
3389
  renderParticles: [], growingPlants: initGrowingPlants(), parallaxLayers: buildParallaxLayers(world.ground, 580), isExecutingTool: false,
3390
+ radianceGrid: createRadianceGrid(), frameCache: createFrameCache(),
3391
+ animParams: { blinkRate: 0.2, wobbleFreq: 0.04, wobbleAmp: 2, glowPulseSpeed: 0.1, breathSpeed: 0.05, energyLevel: 0.5 },
3392
+ lastMoodForCache: 'wave', lastGroundForCache: 'grass',
3348
3393
  };
3349
3394
  animFrame = 0;
3350
3395
  lastChatCount = 0;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kernel.chat/kbot",
3
- "version": "3.83.0",
3
+ "version": "3.86.0",
4
4
  "description": "Open-source terminal AI agent. 764+ tools, 35 agents, 20 providers. Dreams, learns, watches your system. Controls your phone. Fully local, fully sovereign. MIT.",
5
5
  "type": "module",
6
6
  "repository": {