ShellPilot

0.4.0-preview0005

GitHub Copilot in your PowerShell terminal: device-flow auth, model listing, chat and agentic tool-calling with usage and cost.

Minimum PowerShell version

7.0

This is a prerelease version of ShellPilot.
There is a newer prerelease version of this module available.
See the version list below for details.

Installation Options

Copy and Paste the following command to install this package using PowerShellGet More Info

Install-Module -Name ShellPilot -RequiredVersion 0.4.0-preview0005 -AllowPrerelease

Copy and Paste the following command to install this package using Microsoft.PowerShell.PSResourceGet More Info

Install-PSResource -Name ShellPilot -Version 0.4.0-preview0005 -Prerelease

You can deploy this package directly to Azure Automation. Note that deploying packages with dependencies will deploy all the dependencies to Azure Automation. Learn More

Manually download the .nupkg file to your system's default download location. Note that the file won't be unpacked, and won't include any dependencies. Learn More

Owners

Copyright

(c) raandree. All rights reserved.

Package Details

Author(s)

  • raandree

Tags

GitHubCopilot Copilot AI LLM Chat Agent

Functions

Clear-ShpChat Clear-ShpContext Clear-ShpUsage ConvertTo-ShpTokenCount Get-ShpChat Get-ShpContext Get-ShpCosineSimilarity Get-ShpCostEstimate Get-ShpDefault Get-ShpModel Get-ShpModelName Get-ShpTool Get-ShpUsage Initialize-Shp Invoke-Shp Invoke-ShpBatch Register-ShpTool Request-ShpEmbedding Resolve-ShpError Select-ShpModel Set-ShpContext Start-ShpChat Unregister-ShpTool

PSEditions

Core

Dependencies

This module has no dependencies.

Release Notes

## [0.4.0-preview0005] - 2026-08-11

### Added

- `Get-ShpUsage` now records calls that **failed**, not only the ones that
 succeeded. A failed call carries `Success` `$false` and the failure message on
 `Error`, plus whatever spend its completed round-trips had already incurred.
 Both halves of that matter: a success rate computed from the old log was 100%
 by construction, because only successes were in it; and a turn is a loop of
 billable round-trips, so a turn refused on its third round-trip really was
 charged for the first two and reported nothing. Only a call that reached the
 API is recorded - a parameter combination rejected before any request was
 never a call. `Invoke-ShpBatch` inherits this, so a failed batch item now
 shows up in `Get-ShpUsage` too.
 See [specs/016-failed-call-usage-accounting.md](specs/016-failed-call-usage-accounting.md).
- `Get-ShpUsage -Summary` gained `Succeeded`, `Failed`, `TotalDurationMs`,
 `MeanDurationMs`, `FirstCall`, `LastCall` and `ElapsedMs`, and the `ByModel`
 breakdown gained `Succeeded`, `Failed` and `DurationMs`. `ElapsedMs` is
 wall-clock between the first and last call and is deliberately *not* the sum
 of `DurationMs`: under `Invoke-ShpBatch` the calls overlap, so the sum can far
 exceed the elapsed time and the ratio between them is the speed-up the batch
 bought.
- `Get-ShpUsage -Since` and `-Before` filter by time window, so one phase of a
 run can be summarised without clearing the log between phases. Both apply to
 the records and to `-Summary`. There is deliberately no `-GroupBy`:
 `Get-ShpUsage` returns the records, so `Group-Object` already groups by any
 field, and `ByModel` is pre-aggregated only because that split is the common
 case.

- `Invoke-ShpBatch` runs many independent prompts concurrently and returns one
 `ShellPilot.BatchResult` per input, carrying the answer, that item's usage and
 cost, and - when the call failed - the error. `-ThrottleLimit` bounds how many
 calls are in flight (default 4, deliberately conservative), and prompts can be
 piped in as plain strings or as objects with `Prompt` and an optional `Id`.
 Three guarantees are the point of it. Every item is stateless: a batch never
 reads or writes the session conversation, so it cannot reproduce the
 accumulation that makes a serial loop of `Invoke-Shp` calls grow until the
 model refuses it with `model_max_prompt_tokens_exceeded`. Failures are
 isolated: one failed call never aborts the batch and nothing is written to the
 error stream, because an error raised from a worker obeys the caller's
 `$ErrorActionPreference` and would destroy every result under `Stop`; check
 `Success` and `Error` on the results, and a single summary warning names how
 many did not complete. And identity is carried: results arrive in completion
 order, so every one has `Index`, `Id` and the original `InputObject`.
 `-MaxBatchBudgetUSD` caps the whole run as a gate on dispatch - calls already
 in flight are never cancelled. Streaming, `ask_user` and progress events are
 off for every item, for reasons the help gives. The model, sampling
 parameters, `-ResponseFormat` / `-JsonSchema`, `-SkillPath`,
 `-InstructionRoot`, the isolation switches and the connection options are all
 forwarded, and per-item usage is merged into `Get-ShpUsage`.
 See [specs/015-batch-execution.md](specs/015-batch-execution.md).

- `Invoke-Shp -MaxContextWindowTokens` and `Set-ShpContext
 -MaxContextWindowTokens` set the token budget above which a turn elides its
 oldest tool results, with the usual precedence of explicit parameter, then
 session context, then the built-in default. The built-in 900000 is a fallback
 rather than any model's real window - `claude-haiku-4.5` is 136000 - so the
 guard could never fire for a smaller model; set this from the model's own
 `MaxContextWindowTokens` (see `Get-ShpModel`) to make it fire when it should.
 `0` disables the guard. The default is unchanged, so existing calls behave
 exactly as before. Note this bounds tool results only: the session
 conversation is never elided, so a long loop of calls still needs
 `Clear-ShpChat` or `-History`.
- `Invoke-Shp` now explains a rejection it cannot recover from. A service reply
 of `model_max_prompt_tokens_exceeded` is emitted as a warning naming the real
 cause - every `-Prompt` call continues the session conversation, so a loop of
 calls grows until it no longer fits - and the two remedies. Left unexplained
 this reads as a bare 400 and gets mistaken for rate limiting.

- `Invoke-Shp -Temperature`, `-TopP` and `-Seed` control the model's sampling,
 so a call that has to be reproducible (grading or judging in an evaluation
 harness) can pin itself with `-Temperature 0` and a variance measurement can
 fix its operating point instead of inheriting the backend default. Each field
 is omitted from the request body entirely when the parameter is not passed, so
 existing calls are unchanged. `-Temperature` is validated against 0..2 and
 `-TopP` against 0..1 before the request is sent, and a model that rejects a
 field fails the call rather than having the field silently dropped.
 The values used are reported on the result as `Temperature`, `TopP` and
 `Seed`. See [specs/014-sampling-parameters.md](specs/014-sampling-parameters.md).
- `Invoke-Shp` and `Get-ShpCostEstimate` results carry `Priced` and
 `PriceTableKey`, so a call the price table cannot cost is no longer
 indistinguishable from a free one. `PriceTableKey` stays populated even when
 nothing matched, naming the key that was looked up and missed, and the first
 call for an unpriced model warns once per session rather than once per tool
 iteration. `CostUSD` and `Credits` are unchanged and still `null` - never `0` -
 when no rate is found. `Priced` is also recorded on each `Get-ShpUsage` entry.
- `Resolve-ShpError` explains the last error in the session and suggests a fix.
 It takes an error record (`$Error[0]` by default, or from the pipeline), sends
 the message, exception type, category, target, failing command line and script
 stack trace to the model, and returns the usual `Invoke-Shp` result. Every
 tool is disabled unless `-EnableTools` is passed, so diagnosing an error
 cannot touch the machine.
- `Invoke-Shp` supports `ShouldProcess`. `-WhatIf` dry-runs a whole agent turn -
 the model still plans and calls tools, but `write_file`, `create_directory`,
 `run_command` and user-registered tools are skipped and told they were not
 approved - and `-Confirm` prompts before each of those calls. Default
 behaviour is unchanged.
- `Invoke-Shp -MaxBudgetUSD` stops the tool-calling loop once the turn's
 estimated spend passes the cap, and the result carries a new `BudgetExceeded`
 flag.
- `Invoke-Shp -AppendSystemPrompt` adds inline system instructions in either
 parameter set, so a file-driven system prompt can still be topped up for a
 single call.
- `Invoke-Shp -AllowPrivateNetwork` opts the `fetch_url` tool back in to
 loopback, link-local and private addresses.
- `Start-ShpChat` gained the `/models`, `/history`, `/retry` and `/usage`
 commands. `/retry` drops the last exchange and resends the previous prompt.
- The price table supports a long-context tier. An entry may carry a
 `LongContext` block with a `Threshold` in input tokens plus its own rates, and
 the cost breakdown now reports `Tier` and `TiersUsed`.

### Changed

- **`Get-ShpUsage -Summary`'s `Calls` and `CostUSD` will report different
 numbers for a session in which something failed.** `Calls` now counts calls
 *attempted*; it previously counted records, and only successes were recorded,
 so it meant "calls that succeeded". Read `Succeeded` for the old number.
 `CostUSD` now includes the spend of turns that failed after one or more
 billable round-trips, which was previously dropped. Both are corrections
 rather than regressions - that money was really spent, and those calls were
 really made - but a caller reading `Calls` as a success count must move to
 `Succeeded`. Nothing changes for a session in which nothing failed.
- The HTTP retry backoff is now jittered: half the exponential delay plus a
 random amount up to the other half. A purely deterministic backoff
 synchronises under concurrency - several `Invoke-ShpBatch` workers refused by
 the same 429 would sleep identical durations and re-fire together, recreating
 the burst that caused the refusal. A `RetryDelaySec` of `0` still yields
 exactly `0`, so no existing call path changes.

### Fixed

- Streamed `Invoke-Shp` requests now use the same retry wrapper as buffered
 requests. HTTP 429/5xx responses are bounded by `MaxRetryCount`, and a true
 no-response transport failure uses `NetworkOutageToleranceSec`. The classifier
 reads the streaming sender's structured `StatusCode` before its bare
 `HttpRequestException` type, so a permanent 400 fails after one attempt instead
 of burning the network-outage budget. If reading an error body itself fails,
 the known status is preserved and both response and request are still disposed.
- `Invoke-Shp -History @()` now genuinely starts from nothing. `-History` is
 documented as stateless, but an empty array is falsy and the check tested
 truthiness, so an explicitly empty history silently fell through to seeding
 the call from the session conversation - the opposite of what was asked for.
 Binding is now the test, matching the module's rule for every other optional
 value whose type has a meaningful default.
- The streaming sender now carries the same structured error as the buffered
 one. Streaming is the `Invoke-Shp` default, so this was the common path on
 which a caller still had to match substrings in an exception message. A
 non-success status from `Invoke-ShpStreamRequest` now raises an ErrorRecord
 with the body on `ErrorDetails.Message` and a `ShellPilot.HttpErrorDetail` on
 `TargetObject`, which is also the only

FileList

Version History

Version Downloads Last updated
0.4.0-previe... 3 8/19/2026
0.4.0-previe... 5 8/12/2026
0.4.0-previe... 7 8/12/2026
0.4.0-previe... (current version) 5 8/11/2026
0.4.0-previe... 3 8/11/2026
0.4.0-previe... 10 8/6/2026
0.4.0-previe... 10 7/28/2026
0.4.0-previe... 3 7/28/2026
0.3.1 54 7/23/2026
0.3.1-previe... 3 7/23/2026
0.3.0-previe... 8 7/12/2026
0.3.0-previe... 7 7/9/2026
0.3.0-previe... 4 7/9/2026
0.3.0-previe... 7 7/9/2026
0.2.1-previe... 8 7/8/2026
0.2.0 37 7/8/2026
0.2.0-previe... 6 7/8/2026
0.2.0-previe... 4 7/8/2026
0.2.0-previe... 31 6/12/2026
Show more