AIForce Connect
AIForce Connect is a VS Code extension for running an in-editor coding agent with a chat UI, workspace tools, published AIForce usecases, MCP integration, and optional A2A delegation.
What it does
- Sidebar agent experience inside VS Code
- Built-in workspace tools for search, file reads, file writes, and guarded terminal execution
- Published usecase discovery through AIForce AES endpoints
- Standard published usecase execution through AES, with A2A-enabled usecases routed through A2A
- Agent requests executed through AIForce Agent Execution
- VS Code LM tool support through
vscode.lm.tools, including MCP-backed tools
- Extension-managed MCP server registration through
registerMcpServerDefinitionProvider
- A2A-enabled published usecases and optional A2A agent tools
- In-sidebar settings editor with secret storage support
- Auth status validation before prompts/usecases are sent to AIForce
- Human-readable error messages in chat without raw stack traces
- Empty-state handling when no usecases are published
- State replay when the sidebar webview becomes visible again
- Optional auto-upload of relevant workspace files for usecase execution
- Approval-gated file writes that distinguish create vs update flows
Current UI flow
- Open the AIForce Connect activity bar view.
- Enter a prompt to talk to the coding agent.
- Type
# to pick a published usecase.
- Type
/ to invoke an available tool from the tool palette.
- Type
@ to attach files from the workspace.
- Use the settings button in the sidebar to edit extension configuration and manage secrets.
If the shared AIForce auth token is missing, the chat prompts the user to set it before executing standard usecases or agent requests. A2A-enabled usecases use the A2A bearer token stored in VS Code secret storage. The settings panel also shows whether the extension is authenticated.
When no usecase is selected, the extension can suggest matching published usecases based on the prompt. If a standard usecase is selected, the prompt is routed through AES. If an A2A-enabled usecase is selected, the prompt is routed through the A2A JSON-RPC message/send flow. Both paths render output directly in the same chat flow.
Configuration
All primary settings live under aiforceConnect.*.
Workspace rules
Create a Markdown file at .aiforce/aiforce-rules.md to define workspace-specific rules for AIForce Connect. The plugin reads this file automatically and injects it into every Chat and Agent request, so users can describe conventions such as:
- preferred project structure and file placement
- naming and coding conventions
- required validation commands
- framework or library constraints
- rules for generated tests and documentation
Example:
# Workspace rules
- Use the existing TypeScript patterns before introducing new abstractions.
- Prefer `npm run build` and `npm test` for validation.
- Do not create files under `AIForce_Outputs/` as workspace source files.
- Preserve existing public APIs unless the request explicitly asks for a breaking change.
The file is watched for changes and reloaded automatically. aiforce-rules.md is local plugin policy: it is applied by AIForce Connect's own Agent/Chat instruction layer and is not uploaded as usecase input. PROJECT.md is the only .aiforce context file uploaded for server-backed usecase/agent execution. Optional CONVENTIONS.md and ARCHITECTURE.md files remain local Agent/Chat guidance only. Files under .aiforce/skills/ and .aiforce/books/ use their dedicated loaders instead.
Setup
Please import the prompt stored in vscode_ext_prompt.json in the project where your usecases reside. Use the prompt_id created from that import when configuring aiforceConnect.agentExecution.promptId in the extension settings.
Safety
aiforceConnect.enableTerminalApprovals
aiforceConnect.enableWriteApprovals
Limits
aiforceConnect.maxSearchResults
aiforceConnect.maxDiagnosisCandidates
aiforceConnect.maxActivityItems
aiforceConnect.maxToolIterations
aiforceConnect.maxDynamicTools — caps how many discovered VS Code/MCP/A2A tools are sent to the model per turn (built-in tools are always included, uncapped). When the discovered set is larger, only the tools most relevant to the current prompt are kept, ranked by keyword overlap — never a blind first-N truncation. Defaults to 40 for Gemini/Claude models and 60 otherwise, since some models return errors (Gemini in particular can 500) or lose tool-selection accuracy well before any documented hard limit once handed a very large tool catalog.
Orchestrator
aiforceConnect.parallelToolCalls
aiforceConnect.openai.systemPrompt
AIForce services
aiforceConnect.aiforce.baseUrl
aiforceConnect.a2a.endpointUrl
aiforceConnect.agentExecution.promptId
aiforceConnect.agentExecution.lmConfigId
aiforceConnect.enableMcpTools
aiforceConnect.disabledMcpTools
aiforceConnect.enableA2ATools
aiforceConnect.mcpServers
aiforceConnect.a2aAgents
The extension still reads legacy aiforceCodex.* settings where migration compatibility is implemented, but new configuration should use aiforceConnect.*.
Secrets and commands
Secrets are stored in VS Code secret storage. The main commands are:
AIForce Connect: Open Sidebar
AIForce Connect: New Session
AIForce Connect: Set AIForce Auth Token
AIForce Connect: Clear AIForce Auth Token
AIForce Connect: Set A2A Auth Token
AIForce Connect: Clear A2A Auth Token
AIForce Connect: Set MCP Auth Token
AIForce Connect: Clear MCP Auth Token
AIForce Connect: List Visible LM Tools
AIForce Connect: Show MCP Diagnostics
AIForce Connect: List Configured MCP Servers
AIForce Connect: Refresh MCP Diagnostics Snapshot
AIForce Connect: Probe MCP Servers
Set Usecase Auth Token still exists as a legacy alias and writes the shared AIForce auth token.
The shared token is read from aiforceCodex.toolApiKey, with legacy/environment fallbacks handled by AuthTokenStore. HTTP 401/403 responses from standard usecase init/execution are treated as expired or invalid tokens and are surfaced as a re-authentication prompt.
The A2A token is read only from VS Code SecretStorage key aiforceCodex.a2aAuthToken. It is sent as Authorization: Bearer <token> for A2A-enabled usecase requests and configured A2A tool requests. Missing, rejected, or expired A2A tokens are shown as: A2A authentication failed. Please check your bearer token in Settings.
Published usecases
The extension loads published usecases from the AIForce AES API:
GET {AIForce base URL}/aes/usecases?publish_status=Published&page_size=1000&page=1
The list response is the source of truth for usecase metadata, including A2A flags such as a2aEnabled: true. The extension can:
- suggest matching usecases for a prompt
- load init messages for a selected usecase
- execute standard selected usecases through AES
- execute A2A-enabled selected usecases through A2A
- show an empty state with Refresh when no usecases are published
- preserve usecase conversation state across turns
- handle OAuth-backed usecases when required
- auto-upload likely relevant workspace files before execution
Standard usecases call:
GET {AIForce base URL}/aes/usecases/{usecaseId}/init-messages
POST {AIForce base URL}/aes/usecases/execute
A2A-enabled usecases skip AES init/OAuth and call a JSON-RPC message/send endpoint. Endpoint resolution order is:
aiforceConnect.a2a.endpointUrl
- A2A endpoint metadata from the published usecase response
{AIForce base URL}/a2a
If streamed or final usecase output contains generated code artifacts, the extension can save them back into the workspace through the built-in write flow.
Execution recovery (disconnection workaround)
The /usecases/execute stream can fail from the client's side while the execution keeps running on AI Force: a proxy returns a 5xx before the first byte, the connection drops mid-stream, or the stream carries an error frame. Instead of showing an error or re-sending the request (which would start a duplicate execution and trip the platform's 409 "already in progress" guard), the extension asks the platform what actually happened:
GET {AIForce base URL}/aes/executions?usecase_id={id}&jobs_scope=myJobs&order_by=desc(id) # find the execution when no execution_id was streamed yet
GET {AIForce base URL}/aes/executions/{execution_id} # exec_status + persisted output
What you see:
- Still running (
exec_status 0/1): status bar shows "Execution still running on AI Force — waiting for results (1m 42s)". Output already persisted by the platform appears per agent step (not token-by-token) as it lands. The extension keeps waiting until the platform reports Completed or Failed — exactly like a live stream — or until you press Stop; the execution keeps running on the platform.
- Completed (2): the result is shown and handled exactly like a normal stream (code extraction, changeset review, multi-turn). The next turn continues the same execution via
/execute with execution_id, so human-in-the-loop questions and additional files work unchanged.
- Failed (3): "Usecase execution failed on AI Force. Reason: … (Execution ID: N)". The session continues; a resend starts a fresh execution.
- Never started (no matching execution): the classic re-send retry runs with "Could not start usecase execution — retrying n/N" (
usecaseExecution.maxRetries).
Real errors (HTTP status, response bodies, stack traces) are always written to the AIForce Connect output channel. Every step of this flow is logged with a [recovery] prefix — why recovery started (or did not), the lookup request and its match, each status poll (full body only when it changes), every batch of replayed messages, and the final verdict — so [recovery] in the Output channel shows the whole story of a run.
Settings:
| Setting |
Default |
Meaning |
aiforceConnect.usecaseExecution.recoveryEnabled |
true |
Kill switch — false restores the previous behaviour. |
aiforceConnect.usecaseExecution.recoveryPollIntervalMs |
30000 |
Status poll interval while the execution is still running. |
aiforceConnect.usecaseExecution.recoveryMaxWaitMs |
0 |
Optional ceiling. 0 = keep waiting until Completed/Failed or Stop (same as a live stream); a positive value (≥ 30000 ms) gives up after that long. |
aiforceConnect.usecaseExecution.recoveryMaxRetries |
0 |
Optional quick retries before the normal network interval. Default 0 keeps recovery retries at one minute. |
aiforceConnect.usecaseExecution.maxRetries / retryDelayMs |
2 / 60000 |
Safe DNS and connection retry policy before any response. Ambiguous disconnects are recovered, not re-sent. |
A clean stream never calls the /aes/executions endpoints.
Gateway overload retry policy
HTTP 429, 502, 503, and 504 are handled separately from ordinary
connection failures. The extension first checks whether the original run
already started, waits with exponential backoff, checks once more, and only
then makes a bounded re-post when no execution exists. The defaults are two
re-post retries with a one-minute delay (maximum delay one minute), with 20%
random jitter and server Retry-After honoured. HTTP
500 is never automatically re-posted. This avoids adding retry traffic
while a gateway is under load.
The relevant settings are:
| Setting |
Default |
Meaning |
overloadMaxRetries |
2 |
Bounded re-post retry count for 429/502/503/504; 0 disables it. |
overloadInitialDelayMs / overloadMaxDelayMs |
60000 / 60000 |
Gateway-overload retry delay bounds. |
overloadJitterPercent |
20 |
Spreads client retries during an outage. |
recoveryNetworkJitterPercent |
20 |
Spreads one-minute recovery status checks; gateway overloads use the slow interval immediately. |
These setting names are under the aiforceConnect.usecaseExecution. prefix.
When aiforceConnect.enableMcpTools is enabled, the extension reads tools currently visible in vscode.lm.tools, converts them into OpenAI-compatible tool definitions, and routes tool calls through vscode.lm.invokeTool.
To keep MCP tools enabled but block specific visible tools, set aiforceConnect.disabledMcpTools. Each entry can be an exact tool name or a prefix. Example:
{
"aiforceConnect.disabledMcpTools": ["copilot_"]
}
This allows already configured MCP servers in VS Code to contribute tools to the agent without changing the agent loop.
Register MCP servers through this extension
You can also register MCP servers directly with aiforceConnect.mcpServers.
Example stdio server:
{
"aiforceConnect.mcpServers": [
{
"label": "Local Files MCP",
"transport": "stdio",
"command": "node",
"args": ["C:/tools/my-mcp-server/dist/index.js"],
"cwd": "C:/tools/my-mcp-server",
"env": {
"LOG_LEVEL": "info"
}
}
]
}
Example http server:
{
"aiforceConnect.mcpServers": [
{
"label": "Remote MCP",
"transport": "http",
"uri": "https://example.com/mcp",
"headers": {
"Authorization": "Bearer <token>"
}
}
]
}
Secret-backed auth example:
{
"aiforceConnect.mcpServers": [
{
"label": "Secure MCP",
"transport": "http",
"uri": "https://example.com/mcp",
"useSecretAuthToken": true,
"authHeaderName": "Authorization",
"authScheme": "Bearer"
}
]
}
Then run AIForce Connect: Set MCP Auth Token if the server uses a shared secret stored in VS Code.
This is separate from A2A-enabled published usecases. A2A-enabled usecases are discovered from the published usecase list and do not require entries in aiforceConnect.a2aAgents.
When aiforceConnect.enableA2ATools is enabled, configured A2A agents are exposed as delegate tools to the model.
Example:
{
"aiforceConnect.a2aAgents": [
{
"label": "My A2A Agent",
"agentCardUrl": "https://example/.well-known/agent.json",
"description": "Delegate specialized work to an external A2A agent.",
"useSecretAuthToken": true,
"authHeaderName": "Authorization",
"authScheme": "Bearer"
}
]
}
If the target agent requires secret-backed authentication, run AIForce Connect: Set A2A Auth Token.
Run locally
npm install
npm run build
- Open this folder in VS Code
- Press
F5 to start the Extension Development Host
Tests
Run:
npm test
This builds the extension and runs the included Node-based tests in dist/test.
Architecture
src/extension.ts: activation, commands, sidebar registration, secrets, MCP provider registration
src/view/AgentViewProvider.ts: webview UI, tool picker, usecase picker, settings panel
src/runtime/AgentController.ts: session state, orchestration, usecase flow, uploads, code save handling
src/runtime/OpenAIAgent.ts: model loop and tool execution coordination
src/runtime/OpenAIClient.ts: Agent Execution request shaping and response normalization
src/runtime/UsecaseClient.ts: published usecase list, init messages, execution, OAuth handling
src/runtime/A2AUsecaseClient.ts: A2A-enabled published usecase execution with bearer auth
src/runtime/AuthTokenStore.ts: shared AIForce/A2A token lookup and AIForce token validation
src/runtime/ErrorUtils.ts: user-facing error formatting, stack stripping, TLS/network hints
src/runtime/WorkspaceTools.ts: workspace search and file operations
src/runtime/WorkspaceUploadService.ts: workspace file upload support for usecases
src/runtime/TerminalTool.ts: guarded terminal execution
src/runtime/VscodeToolService.ts: bridge from vscode.lm.tools into agent tools
src/runtime/A2AToolService.ts: dynamic A2A tool discovery and invocation
src/runtime/McpServerProvider.ts: settings-backed MCP server registration and probing
Notes
- The extension display name is AIForce Connect.
- The shared AIForce auth token, A2A bearer token, and MCP auth token are stored in VS Code SecretStorage under their historical
aiforceCodex.* keys — unchanged so existing stored credentials aren't orphaned by the rename to aiforceConnect.* command/view ids and settings.
- The default
aiforceConnect.aiforce.baseUrl in source is a placeholder and should be set for real deployments.