| Age | Commit message (Collapse) | Author |
|
|
|
|
|
to k2.7; add pik6/kimi short aliases
|
|
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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>
|
|
|
|
glm-5.1:cloud, minimax-m2.7:cloud
|
|
|
|
|
|
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.
|
|
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.
|
|
|
|
|
|
|
|
DO_CLI_REF and resolveDoExecutable use ~/go/bin/ask; matchDoInvocation
still accepts legacy do prefixes. Update README and Nemotron hints.
Made-with: Cursor
|
|
|
|
Use DO_CLI_REF and resolveDoExecutable in agent-plan-mode; accept both
do and ~/go/bin/do in bash guards. Ask-mode shares matchDoInvocation.
Nemotron/Qwen tool discipline points to ~/go/bin/do done.
Made-with: Cursor
|
|
Rename task-wrapper invocations and prompts from ask to do in
agent-plan-mode (exec, bash guards, workflow strings), plan-mode README,
ask-mode readonly-command detection, and nemotron-tool-repair discipline
text. Internal helpers renamed for consistency (runDo, isSafeDoCommand).
Made-with: Cursor
|
|
VM1 (hyperstack-vm1-coder.toml, renamed from hyperstack-vm1-gptoss.toml):
- Default model switched from gpt-oss-120b to qwen3-coder-next
- Config file renamed to reflect actual default model
VM2 (hyperstack-vm2.toml):
- Default model switched from qwen3-coder-next to Gemma 4 31B AWQ
- Uses vLLM nightly image + transformers==5.5.0 workaround: Gemma 4
architecture is registered in transformers 5.x but vLLM stable pins <5
- max_model_len=131072 (128K context); KV cache fills ~95% of H100-80GB VRAM
- Added gemma4-31b preset
watcher.rb:
- Add loading_status field to VmSnapshot to show live model-load progress
(last relevant log line during startup instead of generic "loading" message)
- fetch_vm_stats now captures both Engine 0 stats and loading-phase log lines
in a single SSH call using a shell variable to avoid two docker log invocations
- clean_log_line() strips vLLM PID/timestamp prefix for readable display
cli.rb: update all hardcoded hyperstack-vm1-gptoss.toml references to
hyperstack-vm1-coder.toml
hypr.fish: replace pi-hyperstack-nemotron with pi-hyperstack-coder (VM1),
add pi-hyperstack-gemma4 (VM2)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
|
|
|
|
Qwen Coder models are trained on agent frameworks that include a "submit"
tool as a task-completion signal, causing "Tool submit not found" errors.
Adds QWEN_TOOL_DISCIPLINE injected unconditionally into the system prompt
for all Qwen Coder models, redirecting them to respond directly or use
`ask done uuid:<uuid>` for tracked tasks. Also adds the same submit hint
to NEMOTRON_TOOL_DISCIPLINE for consistency.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
- /loop pause: suspends all active loops by clearing their timers and
marking each job paused; jobs are kept so they can be resumed
- /loop cont: resumes all paused loops, resetting nextRunAt to a fresh
interval from now and rescheduling timers
- New jobs created while paused inherit the paused state so they don't
fire immediately on creation
- drainPendingJobs and handleJobDue guard against firing while paused
- UI: status bar shows "loop:N ⏸" when paused; widget header shows
"(paused)"; paused jobs show ⏸, pending jobs ⏳, active jobs ⟳
- Autocomplete: pause and cont added to top-level fixed completions
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
command
Root cause: pi's autocomplete.js returns null from getSuggestions() when
getArgumentCompletions() returns null or []. The TUI's outer fallback then
shows filesystem completions. Every branch in getArgumentCompletions now
always returns at least one item:
- cancel branch: falls back to "cancel all" when no jobs exist
- preset branch: falls back to "edit" hint when no presets are loaded
- top-level: falls back to full list instead of null on no match
Also removes /loop-preset (hyphen) command — /loop preset <name> is the
single intended interface.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
~/.pi symlinks to pi/ not pi/agent/, so the path was one level off and
loadPresets() always returned []. Fix the path to include the agent/ segment.
Also add /loop-preset <name> as a dedicated command — its getArgumentCompletions
receives just the preset name as the first argument, which is reliable, avoiding
the multi-word prefix matching issues with /loop's third-level autocomplete.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
Pi bundles extensions so import.meta.url resolves to the wrong location,
causing loadPresets() to always return [] and autocomplete to fall back
to the filesystem. Switch to homedir()/.pi/extensions/loop-scheduler/
which reliably resolves to the correct path.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
Previously typing "/loop preset" returned an exact-match stub which caused
the UI to fall back to filesystem completions. Now cancel/preset expand
directly to their full third-level items ("cancel all"/"cancel <id>",
"preset <name>") as soon as the prefix matches the verb.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
- /loop cancel <partial> now suggests "all" and active job IDs
- /loop preset <name> new explicit subcommand with third-level name autocomplete
- Second-level completions now also include "preset" as a discoverable subcommand
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
autocomplete
- New loop-presets.md file (alongside index.ts) with format: * name: INTERVAL prompt
- /loop edit opens the presets file in $VISUAL/$EDITOR, using TUI stop/restart pattern
- /loop presets lists all loaded presets with intervals and prompt previews
- /loop <name> activates a named preset (single-word args only, no collision with interval syntax)
- getArgumentCompletions provides tab-completion for subcommands and preset names
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
btw: replace blocking overlay with non-blocking widget
- Fire LLM call in background; return immediately so user can keep typing
- Show loading widget below editor while answering
- Display answer in same widget when ready; dismiss with /btw close
- Remove BtwOverlay and wrapText helpers (no longer needed)
loop-scheduler: update countdown every second
- Add startUiTick/stopUiTick (1s setInterval) so the "in Xs" countdown
in the scheduled-loops widget refreshes live instead of staying stale
- Tick starts automatically when jobs exist, stops when all are removed
or the session shuts down
prompt-history: persist editor input history across session restarts
- New extension saves every submitted prompt to ~/.pi/prompt-history.json
(up to 500 entries) via before_agent_start
- On session_start, reads the file, merges with in-memory editor history
(deduplicating), and re-seeds the editor so up-arrow history survives
process restarts and new sessions
- Requires addToHistory/getHistory on ctx.ui (patched into pi-coding-agent
dist/modes/interactive/interactive-mode.js and types.d.ts)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
- Add --reasoning-parser openai_gptoss to gpt-oss-120b vLLM config in
all three toml files; extracts <|channel|>analysis thinking blocks
into reasoning_content in API responses
- Mark gpt-oss-120b as reasoning: true in pi/agent/models.json for all
three providers (hyperstack, hyperstack1, hyperstack2)
- Update vm1 state file
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
The tool previously used pi.sendUserMessage("/reload-runtime", { deliverAs: "followUp" }),
which injected a user message that started a new AI turn and could cause the agent to
call reload_runtime again — resulting in a loop. Now the tool calls ctx.reload() directly
via a captured lastCtx, avoiding any follow-up message. Also tightened the tool description
to discourage repeated calls in the same turn.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
- Add hyperstack-vm1-gptoss.toml: A100x1 config for gpt-oss-120b (VM1)
and qwen3-coder-next (VM2) pair, replacing the H100x2 default
- Fix pi/agent/models.json: hyperstack provider URL was pointing at
hyperstack.wg1 (unresolvable); corrected to hyperstack1.wg1 (192.168.3.1)
- Update hyperstack.rb, hypr.fish: reference vm1-gptoss.toml for create-both
and pair commands; update fish abbrs for the new pair setup
- Update ask-mode/utils.ts: allow read-only 'ask' commands in ask-mode
- Update agent-plan-mode/utils.ts: tighten isAskCommand check
- Add state files for provisioned vm1/vm2 instances
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
Each plan mode session now tracks an activePlanFile. On first write
the target path is adopted as the active plan for that session. Any
subsequent write or edit to a different, already-existing plan file
in ~/.pi/plans is blocked with a clear message directing the agent to
create a new file instead.
Behaviour summary:
- New file → always allowed; becomes the active plan.
- Same file again → always allowed (updating the current plan).
- Different existing file → blocked unless explicitly the active plan.
- activePlanFile is persisted across session restores and reset to
undefined whenever plan mode is entered fresh via /plan.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
Plan mode previously allowed writing any .md file anywhere in the
project tree. Now write/edit tool calls are blocked unless the target
path is inside ~/.pi/plans (created on demand with mkdir -p).
The agent context prompt and task annotations are updated to match,
so the agent knows exactly where to put plan files and never touches
the project directory.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
The mode:deactivate event listeners in ask-mode and agent-plan-mode
correctly switched tool sets but had no access to ExtensionContext,
so the status bar indicator and notification were never updated when
one mode deactivated the other.
Fix: store lastCtx whenever a command handler or session_start fires,
then use it in the mode:deactivate listener to clear the status widget
and show a notification.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
- hyperstack.rb: add VllmWatcher class and `watch` subcommand — live
terminal dashboard polling all active VMs every 5 s via SSH; shows
GPU util/VRAM/temp/power bars and vLLM throughput/requests/KV-cache/
cache-hit bars aligned in a shared column layout
- draw(): render two or more VM panels side-by-side (horizontal) with a
│ separator, padded to equal visible width; single VM falls back to
vertical layout
- pi/agent/extensions/modal-editor: start in INSERT mode instead of NORMAL
- README: document watch command and update fish script rename
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
|
|
references
Rename extension from taskwarrior-plan-mode to agent-plan-mode.
Replace all Taskwarrior mentions with neutral task/ask terminology.
Update STATE_TYPE, custom types, error messages, and README.
Replace all task calls to use new ask subcommand syntax:
- ask list start.any: instead of ask start.any: export
- ask ready instead of ask +READY export
- ask info uuid: instead of ask uuid: _uuid
- ask annotate uuid: instead of ask uuid: annotate
- ask done uuid: instead of ask uuid: done
- ask modify uuid: instead of ask uuid: modify
- ask add with dep:add: instead of depends:
Remove _uuid lookups - UUID embedded at creation via ask info.
Remove taskwarrior-task-management and taskwarrior-plan-mode custom types.
All valid-example strings updated to new ask subcommand syntax.
Also updated: ask list +BLOCKED for blocked tasks visualization.
|
|
Switch VM1 from n3-H100x1 to n3-H100x2 to run Nemotron-3-Super with
1M token context window via tensor parallelism. The dual-GPU setup
(160 GB total VRAM) provides enough KV cache headroom to override the
model's config.json limit of 262144 tokens.
Key changes:
- flavor_name: n3-H100x1 → n3-H100x2
- tensor_parallel_size: 1 → 2
- max_model_len: 131072 → 1048576 (with VLLM_ALLOW_LONG_MAX_MODEL_LEN=1)
- gpu_memory_utilization: 0.92 → 0.85 (headroom for Mamba cache + sampler warmup)
- Remove --enforce-eager: no longer needed with dual-GPU VRAM budget
- Disable prefix caching: on NemotronH it forces Mamba "all" cache mode
which pre-allocates states for all max_num_seqs and OOMs before the
sampler warmup pass; per-request allocation is cheaper at startup
Add two new vllm config fields to hyperstack.rb:
- extra_docker_env: passes -e KEY=VALUE flags to Docker before the image
name (used for VLLM_ALLOW_LONG_MAX_MODEL_LEN=1 and
PYTORCH_ALLOC_CONF=expandable_segments:True)
- enable_prefix_caching: makes --enable-prefix-caching conditional
(default true for backward compat; false for NemotronH)
Both fields are supported in [vllm] defaults and [vllm.presets.*]
overrides with the same fallback semantics as existing fields.
Update pi/agent/models.json: Nemotron vm1 entry renamed to
"Nemotron 3 Super 120B 1M [vm1]" with contextWindow 1048576.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|