PSAISuite is a high-performance, unified interface designed for systems architects and developers to integrate multiple LLMs through a standardized engineering layer.
By providing a consistent abstraction—similar to OpenAI’s SDK—it allows teams to swap, test, and benchmark responses across 15+ providers without modifying core application logic. This "Interface-First" approach brings multi-decade software architecture principles to the rapidly evolving AI landscape.
Wondering which model is fastest? Most instruction-compliant? Best at reasoning?
PSAISuiteBenchmarks is a built-in benchmark suite that runs standardized tests across all your providers in parallel and prints a leaderboard.
Import-Module .\PSAISuiteBenchmarks\PSAISuiteBenchmarks.psm1 -Force
Invoke-Benchmark -Models 'anthropic:claude-sonnet-4-6', 'xAI:grok-4-1-fast-non-reasoning', 'openai:gpt-4o' -Category 'InstructionFollowing'Real results. Real latency. Across all 15 providers.
Currently supported providers are:
- Anthropic
- Azure AI Foundry
- DeepSeek
- GitHub
- Groq
- Inception
- Mistral
- Nebius
- Novita
- Ollama
- OpenAI
- OpenRouter
- Poe
- Perplexity
- Vercel AI Gateway
- xAI
You can install the module from the PowerShell Gallery.
Install-Module PSAISuite🏗️ Architectural Core Provider Agnostic: Designed to prevent vendor lock-in through a decoupled interface.
Parallel Execution: Built-in benchmarking for real-time latency and instruction-compliance testing.
Context-Aware Piping: Engineered to handle massive data streams as context directly from the PowerShell pipeline.
To get started, you will need API Keys for the providers you intend to use.
The API Keys need to be be set as environment variables.
Set the API keys.
$env:OpenAIKey="your-openai-api-key"
$env:AnthropicKey="your-anthropic-api-key"
$env:NebiusKey="your-nebius-api-key"
$env:GITHUB_TOKEN="your-github-token" # Add GitHub token
# ... and so on for other providers
$env:INCEPTION_API_KEY="your-inception-api-key"
$env:AI_GATEWAY_API_KEY="your-vercel-ai-gateway-key"You will need to set the AzureAIKey and AzureAIEndpoint environment variables.
$env:AzureAIKey = "your-azure-ai-key"
$env:AzureAIEndpoint = "your-azure-ai-endpoint"You can pipe data directly into Invoke-ChatCompletion (or its alias icc) to use it as context for your prompt. This is useful for summarizing files, analyzing command output, or providing additional information to the model.
For example:
Get-Content .\README.md | icc -Messages "Summarize this document." -Model "openai:gpt-4o-mini"You can also use the output of any command:
Get-Process | Out-String | icc -Messages "What processes are running?" -Model "openai:gpt-4o-mini"Tip:
- The
-Modelparameter supports tab completion for available providers and models. Start typing a provider (likeopenai:orgithub:) and pressTabto see suggestions.- You can use the
iccorgenerateTextalias instead ofInvoke-ChatCompletionin all examples above.
See PIPE-EXAMPLES.md for more details and examples.
🛠️ Tool Calling (Function Orchestration) PSAISuite implements native tool-calling patterns, allowing LLMs to interact with your local environment securely. This bridges the gap between static chat and high-agency autonomous actions.
- Native PowerShell Integration: Register any cmdlet or function as a tool instantly.
- Standardized Schemas: Pass custom JSON/Hashtable definitions for complex API interactions.
- Cross-Provider Support: Consistent implementation across OpenAI, Vercel, DeepSeek, xAI, Anthropic, and Google.
You can pass tools to Invoke-ChatCompletion using the -Tools parameter. Tools can be specified as:
- Cmdlet objects: Pass the cmdlet directly (e.g., Get-ChildItem), and it will be registered as a tool
- Pre-defined tool schemas (hashtables): Custom tool definitions
Example using a built-in command:
Invoke-ChatCompletion -Messages "List the files in the current directory" -Tools Get-ChildItem -Model "openai:gpt-4.1"This will allow the AI model to call the Get-ChildItem cmdlet to list directory contents. The model may respond with something like:
The files in the current directory are:
- README.md
- LICENSE
- PSAISuite.psd1
- ...
Example with custom tool definition:
$customTool = @{
Name = "Get-Weather"
Description = "Get current weather for a location"
Parameters = @{
type = "object"
properties = @{
location = @{
type = "string"
description = "City name"
}
}
required = @("location")
}
}
Invoke-ChatCompletion -Messages "What's the weather in New York?" -Tools $customTool -Model "openai:gpt-4o"Currently, tool calling is supported for the OpenAI, Vercel, DeepSeek, xAI, Anthropic, and Google providers. Support for other providers will be added in future updates.
New in v0.10.0: DeepSeek uses its Responses API for local PowerShell tools. See the
DeepSeek guide for setup, thinking controls, and full
conversation continuation with reasoning and tool results.
Its built-in file tools stay inside the starting folder by default. Set
-ToolRoot to select another scope, and -ToolPolicy to configure budgets or
your own local permission callback; those decisions are separate from the model.
PSAISuite's shared PowerShell tool executor normalizes optional arguments
generated by the model. Empty values, disabled switches, and values outside a
command's declared validation range are omitted so commands such as Get-Date
can run reliably even when a model supplies placeholder arguments.
Introduced in v0.9.0 with prompt execution and an interactive mode; updated
in v0.9.1 with shared provider progress and Anthropic token handling.
v0.10.0 adds DeepSeek Responses tools, full conversation replay, and
configurable local tool policies.
Migration: calls that previously returned a harness object must now add
-PassThru; omitting -Prompt starts an interactive conversation.
For the original object-based walkthrough, see
Build a Custom Agent Harness with PowerShell and PSAISuite.
New-AgentHarness -Prompt runs a request through PSAISuite's existing agent
loop, executes tool calls, and returns the final response:
New-AgentHarness -Prompt 'List the files in the current directory.' -Tools Get-ChildItemPrompt is the first positional parameter, so you can also write:
New-AgentHarness 'What time is it?' -Tools Get-DateOmit -Prompt to start an interactive conversation using Read-Host. Each
turn runs the same model/tool loop. User messages and final assistant replies
are retained for follow-up questions during the session; tool exchanges are
handled within each turn. DeepSeek also retains its full reasoning and tool
history across turns. Enter exit, quit, or an empty line to finish.
New-AgentHarness -Model 'openai:gpt-5.6-luna' -Tools Get-Date -SystemPrompt 'Use tools when needed.' -MaxIterations 3-Model supports the same provider and model tab completion as
Invoke-ChatCompletion.
OpenAI, Anthropic, DeepSeek, and Vercel show the same progress display during a request:
the model, current round, waiting status, tool starts and completions, elapsed
time, and failures. Add -Verbose to retain these updates as an activity log:
New-AgentHarness 'What time is it?' -Model anthropic:claude-sonnet-5-5 -Tools Get-Date -VerboseThis also works in interactive mode and with Invoke-ChatCompletion. Progress
and verbose messages are separate from the response, so assigning or piping
the answer keeps it clean. Set $ProgressPreference = 'SilentlyContinue' to
hide the progress display. Updates occur at request and tool boundaries;
the waiting status is not a live thinking feed or a completion percentage.
To create an editable object without starting a request or reading input, use
-PassThru. Existing object-construction calls should add this switch:
$harness = New-AgentHarness -PassThru -Model 'openai:gpt-5.6-luna' -Tools Get-ChildItem -SystemPrompt 'Use the tool to answer questions about files.' -MaxIterations 3
$harness.GetResponse('What files are here?')
$harness | Format-List Model, Tools, SystemPrompt, MaxIterations
$harness.MaxIterations = 5Tools can be command names or the tool schemas accepted by
Invoke-ChatCompletion. The default is no tools, model openai:gpt-5.6-luna,
and five tool-calling rounds. Provider credentials, model overrides such as
PSAISUITE_DEFAULT_MODEL, and provider support follow Invoke-ChatCompletion.
Starting in v0.9.1, Anthropic requests allow up to 4,096 output tokens per response, including
thinking. If that limit is reached, the provider reports truncation and does
not execute tool calls from the incomplete response. This is separate from
MaxIterations, which limits the number of model/tool rounds.
-PassThru cannot be combined with -Prompt. Creating the object with
-PassThru makes no model request. Each GetResponse call uses the
current properties and starts a fresh conversation; it does not retain earlier
messages. Custom functions run with your session's permissions. DeepSeek's
built-in file tools additionally enforce ToolRoot and ToolPolicy; this is
not an operating-system sandbox. MaxIterations limits model requests,
including the final answer, rather than tokens or spending.
To verify prompt execution, real tool calls, interactive history, and live model completion using your configured credentials, run the explicit live test:
pwsh -NoProfile -File ./__tests__/Test-AgentHarnessLive.ps1For the Anthropic file-reading and script-generation regression, run:
pwsh -NoProfile -File ./__tests__/Test-AnthropicAgentHarnessLive.ps1To verify progress during real OpenAI, Anthropic, DeepSeek, and Vercel requests, including tool failures, iteration limits, and API failures:
pwsh -NoProfile -File ./__tests__/Test-AgentProgressLive.ps1OpenAI system and developer messages are sent as Responses API instructions and remain available across tool-calling rounds. Structured text content is supported as well:
$messages = @(
@{ role = 'system'; content = @(@{ type = 'input_text'; text = 'Use standard Markdown links.' }) }
@{ role = 'developer'; content = 'Keep the response concise.' }
@{ role = 'user'; content = 'Create an index of the project.' }
)
Invoke-ChatCompletion -Messages $messages -Model 'openai:gpt-5.6'For OpenAI, Anthropic, DeepSeek, and Vercel tool workflows, -MaxIterations controls the maximum
number of model requests, including tool rounds and the final answer, and defaults to 5:
Invoke-ChatCompletion `
-Messages 'Find the files and summarize their contents.' `
-Model 'openai:gpt-5.6' `
-Tools 'Get-ChildItem' `
-MaxIterations 10The same limit can be used with Anthropic models:
Invoke-ChatCompletion `
-Messages 'Find the files and summarize their contents.' `
-Model 'anthropic:claude-3-5-sonnet-20241022' `
-Tools 'Get-ChildItem' `
-MaxIterations 10OpenAI effort values are model-dependent. The accepted values are none,
minimal, low, medium, high, xhigh, and max. When an AGENTS.md
file is present in the current project path or one of its project ancestors,
it is loaded as project guidance and refreshed between tool rounds.
Anthropic models support adaptive thinking with -EffortLevel values of low,
medium, high, xhigh, and max. Use -SpeedLevel fast or
-SpeedLevel priority for the provider's priority-capable tier, or
-SpeedLevel flex to request standard-only capacity.
Using PSAISuite to generate chat completion responses from different providers.
You can list all available AI providers using the Get-ChatProviders function:
# Get a list of all available providers
Get-ChatProvidersYou can list OpenRouter models by name using the Get-OpenRouterModel function. Use the -Raw switch to return all properties for matching models:
# List all OpenRouter models with 'gpt' in their name
Get-OpenRouterModel -Name '*gpt*'
# List all OpenRouter models and return all properties
Get-OpenRouterModel -Raw
# List models by name and return all properties
Get-OpenRouterModel -Name '*gpt*' -RawThe -Raw switch returns the full model object from the OpenRouter API, including all available properties.
# Import the module
Import-Module PSAISuite
$models = @("openai:gpt-4o", "anthropic:claude-3-5-sonnet-20240620", "azureai:gpt-4o", "nebius:meta-llama/Llama-3.3-70B-Instruct")
$message = New-ChatMessage -Prompt "What is the capital of France?"
foreach($model in $models) {
Invoke-ChatCompletion -Messages $message -Model $model
}# Import the module
Import-Module PSAISuite
$message = New-ChatMessage -Prompt "What is the capital of France?"
Invoke-ChatCompletion -Messages $message -Raw
# You can also use the alias:
generateText -Messages $message -Raw# Import the module
Import-Module PSAISuite
$model = "openai:gpt-4o"
$message = New-ChatMessage -Prompt "What is the capital of France?"
Invoke-ChatCompletion -Model $model -Messages $message
# or by setting the environment variable
$env:PSAISUITE_DEFAULT_MODEL = "openai:gpt-4o"
$message = New-ChatMessage -Prompt "What is the capital of France?"
Invoke-ChatCompletion -Messages $message Note that the model name in the Invoke-ChatCompletion call uses the format - <provider>:<model-name>.
documentation coming soon
