summaryrefslogtreecommitdiff
AgeCommit message (Collapse)Author
2026-06-17Add GLM 5.2 and minimax-m3 to ollama-cloud models + glm fish aliasmainPaul Buetow
2026-06-14Commit remaining workspace changesPaul Buetow
2026-06-14hypr.fish: keep pik and kimi aliases on K2.6, add pik-code for K2.7 CodePaul Buetow
2026-06-14Add kimi-k2.7-code:cloud via ollama-cloud; update pik/pi-ollama-kimi aliases ↵Paul Buetow
to k2.7; add pik6/kimi short aliases
2026-06-08pi models: add local ollama gemma4:26b-a4b-it-qat-32k-ctx modelPaul Buetow
2026-06-03Remove glm-4.6 cloud modelPaul Buetow
2026-06-02Add minimax-m3:cloud to pi agent models and hypr.fish aliasesPaul Buetow
2026-05-31no plansPaul Buetow
2026-05-31cleanupPaul Buetow
2026-05-31fixPaul Buetow
2026-05-30fix(reload-runtime): remove broken lastCtx.reload() call from toolPaul Buetow
Tools receive ExtensionContext, which does not have a reload() method. Only ExtensionCommandContext (command handlers) has reload(). The tool now always queues /reload-runtime as a follow-up command, matching the upstream example pattern. This fixes: lastCtx.reload is not a function
2026-05-30pik aliasPaul Buetow
2026-05-25updatePaul Buetow
2026-05-25Remove justfile; expand README Quickstart with VM1/VM2 create, test, and ↵Paul Buetow
connect instructions
2026-05-25Fix Gemma 4 vLLM startup and improve partial-provisioning UXPaul Buetow
- provisioning.rb: auto-install pytest before pre_start_cmd to fix missing dependency in nightly vLLM images that crashes EngineCore on cupy import - cli.rb: relax active_config_loaders/vm1_alive? to match by vm_id+public_ip instead of requiring status==ACTIVE, so watch/status/test work on VMs that were interrupted mid-provisioning - vm_lifecycle.rb: persist API status/vm_state back to state file during status calls; add 'Provisioning: incomplete' notice when provisioned_at is missing - provisioning_orchestrator.rb: add wait_for_ssh polling before ensure_trusted_host to fix race between SSH daemon readiness and keyscan
2026-05-25chore(provisioning): remove dead LiteLLM decommission codePaul Buetow
LiteLLM was a legacy inference proxy that was removed from the stack months ago. The SSH-based decommission helper and its script generator were kept as cleanup guardrails, but they add unnecessary round-trips and YAGNI surface. Remove: - ProvisioningScripts#litellm_decommission_script - RemoteProvisioner#decommission_litellm - Call sites in ProvisioningOrchestrator#run and ModelSwitcher#switch No remaining references in the codebase. Legacy Hyperstack cloud firewall rule cleanup (port 4000) intentionally remains in ProvisioningOrchestrator#legacy_litellm_rules.
2026-05-25fix(client): use nil-safe fetch fallback in list_flavors/list_imagesPaul Buetow
Replace || fallback with Hash#fetch block in list_flavors and list_images. The old code incorrectly swapped falsy-but-present values (empty string, false, 0) via ||. fetch only falls through when the key is absent, preserving legitimate falsy values from the API.
2026-05-25fix(prefixed_output): add flush to prevent losing final unterminated linePaul Buetow
PrefixedOutput#print buffers partial lines until a newline is received. When the last chunk from a stream does not end with \n (common with Open3 popen2e EOF), that chunk was discarded. Add #flush to emit the remaining buffer with the prefix, and call it at the end of all streaming loops in SshRunner and WireGuardSetup.
2026-05-25fix(client): explicitly rescue Net::ReadTimeout alongside Net::OpenTimeoutPaul Buetow
Net::ReadTimeout inherits from Timeout::Error and was already caught indirectly, but listing it explicitly matches the pattern used in Config and InferenceTester and guards against future Ruby changes. Also makes the retry intent obvious for anyone auditing the rescue clause.
2026-05-25fix(inference_tester): add bounded-retry guard around vLLM chat inferencePaul Buetow
Retry up to 3 times with 15/30/45s backoff on Net::ReadTimeout, Net::OpenTimeout, connection errors, non-200 HTTP, and JSON parse failures. Prevents a single transient timeout from failing the whole test run. Task referenced Manager#vllm_chat which no longer exists after refactor; applied guard to InferenceTester#chat where the call actually lives.
2026-05-25refactor(config): extract shared ConfigDataHelpers modulePaul Buetow
Both ConfigLoader and Config duplicated fetch/dig/blank?/truthy? helpers. Extract them into HyperstackVM::ConfigDataHelpers and include it in both classes. No behaviour change; DRY surface reduced.
2026-05-25fix(wireguard): remove memoization from config_contents and hosts_contentsPaul Buetow
Stale external changes to wg1.conf or /etc/hosts were invisible because LocalWireGuard cached the first read forever. Remove the cache entirely so every operation sees the current file state. Also removed the now-unnecessary ivar updates after write_config/write_hosts.
2026-05-25refactor(manager): move dry-run/resume logic into VmLifecycle; thin Manager ↵Paul Buetow
facade - Manager is now a thin facade (~160 lines) that delegates VM lifecycle, provisioning, testing, and cleanup to focused collaborators. - Moved replace/resume/dry-run handling and presentation helpers from Manager into VmLifecycle where they belong. - Fixed operator-precedence bug: instance && instance['id']. - Fixed status fallback to return public_ip from state on API error. - Fixed LocalWireGuard delegation bug (removed @local_wireguard.show_local_wireguard call which did not exist; now routes through Manager#show_local_wireguard). - Removed dead code: unused ensure_security_rules and legacy_litellm from VmLifecycle. - ProvisioningOrchestrator: removed spurious show_local_wireguard call and added legacy_litellm_rules cleanup with proper warn_out helper. - Added missing require statements (json, fileutils, provisioning). - Removed dead attr_reader :config from InferenceTester. - Renamed shadowed variable in cleanup_local_access.
2026-05-25refactor(manager): extract focused collaborators from Manager God ClassPaul Buetow
Extract VM lifecycle, SSH execution, WireGuard setup, model switching, end-to-end inference tests, and provisioning orchestration into separate collaborator classes. Manager becomes a thin facade (~80 lines). Also fixes CLI edge-cases: status/model-list when no VMs are active, and threads --vllm/--ollama flags through the provisioning pipeline.
2026-05-25Add OpenRouter Qwen3.6 models to pi configPaul Buetow
Add two models to the OpenRouter provider in pi/agent/models.json: - qwen/qwen3.6-27b (dense, 27B params) - qwen/qwen3.6-35b-a3b (MoE, 35B total / 3B active) Both use the openrouter thinking format and route to AkashML to avoid broken tool calling on other providers. Text and image inputs supported. Context window: 262k tokens.
2026-05-25fix(loop-scheduler): defer agent_busy reset after agent_end instead of ↵Paul Buetow
isIdle polling The agent_end handler receives ExtensionContext, not the command variant, so ctx.waitForIdle() was never available (TypeError). The previous fix replaced it with an isIdle() polling loop, but isIdle() remains false while any agent_end listener is still executing (finishRun() completes only after listeners settle). This caused a 30-second busy-wait on every turn, leaving the UI stuck on 'Working...'. Defer resetting agentBusy and draining pending jobs via setTimeout(..., 0) so the work happens in a macrotask after finishRun() has completed and the agent is genuinely idle.
2026-05-25fix(loop-scheduler): replace ctx.waitForIdle() with isIdle() polling in ↵Paul Buetow
agent_end handler The agent_end event handler receives ExtensionContext, not ExtensionCommandContext, so ctx.waitForIdle() is not available. Replace with a polling loop using ctx.isIdle() to wait for the run to finish before draining pending jobs, preventing stuck follow-up messages.
2026-05-25fix(loop-scheduler): await waitForIdle in agent_end before drainingPaul Buetow
Inside an agent_end listener, agent.state.isStreaming is still true — finishRun() only clears it in the finally block of runWithLifecycle, after all agent_end listeners settle. So when we dispatched a pending job from agent_end and called pi.sendUserMessage(..., { deliverAs: 'followUp' }), the message was routed into agent.followUpQueue. The agent loop had already passed its getFollowUpMessages() check, so it exited without draining the queue. The message sat there as a stuck 'Follow-up: ...' in pi's UI, agentBusy stayed true forever, and every subsequent pending loop was blocked because no further agent_end fired. Await ctx.waitForIdle() in the agent_end handler before resetting agentBusy and calling drainPendingJobs. By then finishRun() has cleared isStreaming, so sendUserMessage starts a fresh run instead of enqueueing into a dead followUp queue, and pending loops drain serially as designed. Amp-Thread-ID: https://ampcode.com/threads/T-019e5de9-a0c3-7559-9cf0-f81ce751e763 Co-authored-by: Amp <amp@ampcode.com>
2026-05-25fix(watch): auto-recover when default VM is dead or replacedPaul Buetow
- Add per-VM 10s fetch timeout so one dead VM cannot stall the dashboard - Make fallback logic check VM state (public_ip + ACTIVE status) instead of just file existence, so a stale/deleted VM1 state does not block watch - Auto-replace cached SSH host keys when a VM is recreated instead of failing - Suppress Ruby thread exception noise on killed SSH threads Fixes 'just watch' showing blank screen when VM1 is deleted but has a stale state file, and SSH host-key mismatch on VM recreation.
2026-05-25update hyperstack2 VM state and config after recreationPaul Buetow
2026-05-24fix(provisioning): recover from vLLM readiness timeout and increase poll windowPaul Buetow
When create timed out during vLLM readiness polling (common for large models like Qwen3.6-27B-FP8), rerunning create would stop and restart the already-running container, restarting the whole startup sequence. Now the vLLM install script checks if the container is already running and serving the correct model before touching it. If it detects a healthy container, it skips the stop/pull/start cycle entirely. Also increases the readiness timeout from 20 min (240x5s) to 30 min (360x5s) to accommodate cold starts with model download and CUDA graph capture on large models.
2026-05-24feat(tooling): add ollama fish abbreviations for kimi, qwen, glm, minimaxPaul Buetow
2026-05-24feat(pi): add ollama provider with kimi-k2.6:cloud, qwen3.5:cloud, ↵Paul Buetow
glm-5.1:cloud, minimax-m2.7:cloud
2026-05-24chore(config): revert vm2 default to n3-A100x1; simplify justfilePaul Buetow
2026-05-24chore(tooling): add justfile for common VM lifecycle, observability, and ↵Paul Buetow
debugging commands
2026-05-24chore(vm2): H100 provisioning, L40 plan, and H100-specific vLLM tuningPaul Buetow
2026-05-24fix(cli): watch/status/test auto-detect active VMs when default VM1 is not ↵Paul Buetow
provisioned
2026-05-24chore(config): remove gpt-oss-120b references since qwen3.6 is betterPaul Buetow
2026-05-24fix(watcher): show actionable error when VM not provisioned or SSH failsPaul Buetow
2026-05-24replace qwen3-coder-next with qwen3.6-27b across configs, docs, and toolingPaul Buetow
2026-05-24feat(watch): retry SSH connection failures with exponential backoffPaul Buetow
Remove the vm_api_reachable? filter from run_watch so VMs that are currently booting are not silently dropped from the dashboard. Add exponential-backoff retry logic (up to 4 attempts, sleeping 2s, 4s, 8s, 16s) inside VllmWatcher#fetch_vm_stats for transient SSH/WireGuard errors such as connection refused, host unreachable, and exit 255. This lets watch automatically recover while a VM is still starting up instead of failing immediately.
2026-05-24chore: add pi/prompt-history.json to .gitignorePaul Buetow
2026-05-24fix(loop-scheduler): always pass deliverAs followUp for scheduled messagesPaul Buetow
The runtime now requires a streamingBehavior (steer/followUp) to queue a message when the agent is already processing. Previously only Gemma 4 models passed { deliverAs: 'followUp' }, causing all other models to throw 'Agent is already processing' and leaving the job stuck in pending. Scheduled and watch messages are independent prompts, so followUp is the correct behavior for all models.
2026-05-24chore(gitignore): ignore hyperstack state temp filesPaul Buetow
Add patterns for .hyperstack-*-state.json and .hyperstack-*-state.json.known_hosts to keep ephemeral VM state and WireGuard artifacts out of version control.
2026-05-24docs: refresh README, hypr.fish, AGENTS.md for consolidated --vm CLIPaul Buetow
2026-05-24feat(cli): replace --config with --vm 1|2|both, remove create-both/delete-bothPaul Buetow
- Drop single-VM default hyperstack-vm.toml and @config_path/@config_explicit machinery - Add global --vm flag (default: 1) mapping to hyperstack-vm1.toml and/or hyperstack-vm2.toml - Fold create-both and delete-both into create/delete --vm both - Teach status, watch, test, model to accept --vm (default: 1) - Update help text and README/AGENTS/fish abbreviations accordingly
2026-05-24docs: remove single-VM and ComfyUI/photo referencesPaul Buetow
2026-05-24cleanup: remove ComfyUI and photo-related code from lib/hyperstackPaul Buetow
2026-05-24chore: remove photo/ComfyUI top-level filesPaul Buetow
Delete hyperstack-vm-photo.toml, photo-enhance.rb, photo-enhance-review.md, smart_photo_node.py, workflows/photo-enhance.json (and empty workflows/ dir), and __pycache__/smart_photo_node.cpython-314.pyc (and empty __pycache__/ dir). No .hyperstack-vm-photo-state.json* state files were present. ComfyUI references in lib/hyperstack/*.rb intentionally left for task T2.
2026-05-24fix(loop-scheduler): reset agentBusy when drainPending detects idle contextPaul Buetow
The agentBusy flag could get stuck if an agent_start event fired but no matching agent_end followed (e.g. crash or forced shutdown). The scheduler would then show 'pending' forever even though the agent was completely idle. Now drainPendingJobs() and drainPendingWatchJobs() ask the ExtensionContext's isIdle() as a ground-truth fallback whenever agentBusy is true. If the context reports idle, we reset agentBusy = false and proceed to dispatch pending jobs instead of bailing out.