# How openwork-extensions-preview Steering Plugins Affect Agent Behavior

> Discover how openwork-extensions-preview steering plugins dynamically guide agent behavior. Learn how they control tool access, authentication, and fallback capabilities based on cloud status.

- Repository: [Different AI/openwork](https://github.com/different-ai/openwork)
- Tags: deep-dive
- Published: 2026-08-22

---

**The `openwork-extensions-preview` steering plugins dynamically inject runtime guidance into an agent's system prompt based on real-time OpenWork Cloud connection status, determining whether the agent can invoke cloud-based tools, must request user authentication, or should fall back to generic capabilities.**

The `different-ai/openwork` repository implements a sophisticated runtime steering mechanism through its `openwork-extensions-preview` OpenCode plugin. These steering plugins act as a **dynamic policy layer** that evaluates engine-side MCP registration and server health to shape agent behavior on every turn. By transforming the system prompt in real-time, they ensure the LLM receives accurate, context-aware instructions about OpenWork extension availability.

## Where Steering Is Applied in the System Prompt Pipeline

The steering injection occurs during the **system-prompt transformation** step via the `experimental.chat.system.transform` hook. In [`apps/server/src/opencode-plugins/openwork-extensions-preview.ts`](https://github.com/different-ai/openwork/blob/main/apps/server/src/opencode-plugins/openwork-extensions-preview.ts), the plugin calls `resolveOpenWorkExtensionDiscoveryInstruction` and inserts the returned string as a dedicated "routing" section:

```typescript
// apps/server/src/opencode-plugins/openwork-extensions-preview.ts
"experimental.chat.system.transform": async (input, output) => {
  const mergedInput = mergeTransformInputWithFactoryContext(input, factoryContext);
  const [extensionInstruction, skillInstruction, automationInstruction] = await Promise.all([
    resolveOpenWorkExtensionDiscoveryInstruction(mergedInput, fetch, {
      client: engineMcpStatusClient,
      directory: engineMcpStatusDirectory,
    }),
    resolveOpenWorkConnectSkillInstruction(mergedInput, fetch),
    resolveOpenWorkAutomationInstruction(mergedInput, fetch),
  ]);
  const sections = combineInstructionSections(
    createInstructionSection("routing", extensionInstruction),
    // …other sections omitted for brevity
  );
  output.system.push(...composeAgentInstructions(sections));
},

```

This architecture ensures the steering instruction appears **before** other capability sections, priming the model to check OpenWork-specific tools (`openwork_query`, `openwork_execute`) before defaulting to built-in alternatives.

## How Steering Messages Are Built

The resolution logic in [`apps/server/src/opencode-plugins/openwork-extensions-preview-steering.ts`](https://github.com/different-ai/openwork/blob/main/apps/server/src/opencode-plugins/openwork-extensions-preview-steering.ts) follows a cascading discovery pattern. The `resolveOpenWorkExtensionDiscoveryInstruction` function first attempts to read the **engine-side MCP status** via `fetchEngineMcpStatus`; if unavailable, it falls back to a **server-side health check** through `fetchOpenWorkConnectState`:

```typescript
// apps/server/src/opencode-plugins/openwork-extensions-preview-steering.ts
export async function resolveOpenWorkExtensionDiscoveryInstruction(
  input?: unknown,
  fetcher: OpenWorkFetch = fetch,
  engine: OpenWorkEngineMcpStatusSource = {},
): Promise<string> {
  if (engine.client) {
    const engineStatus = await fetchEngineMcpStatus(input, engine);
    if (engineStatus.found) return composeSteeringFromEngineMcpStatus(engineStatus.status);
  }
  return composeOpenWorkExtensionDiscoveryInstruction(
    await fetchOpenWorkConnectState(input, fetcher)
  );
}

```

This dual-source approach ensures robust behavior even when the OpenCode engine's MCP client is temporarily unreachable.

## The Four Steering Conditions and Their Impact

The steering system maps connection states to four distinct instruction constants defined in the steering module:

- **`OPENWORK_CLOUD_CONNECTION_INSTRUCTION`** – Returned when the engine MCP status is **connected** or when the server health reports **usable** with `usableByCurrentModel !== false`. Tells the agent that cloud-based tools are ready for invocation.

- **`OPENWORK_CONNECT_SIGN_IN_INSTRUCTION`** – Triggered when the engine reports **needs_auth** or **needs_client_registration**, or when the server detects authentication failures. Instructs the agent to direct users to Settings → Connect to sign in.

- **`OPENWORK_CONNECT_DISABLED_INSTRUCTION`** – Selected when the engine MCP status is **disabled** or the server reports **engine_disabled**. Advises the agent to inform the user that OpenWork Cloud agent access is explicitly disabled.

- **`OPENWORK_EXTENSION_DISCOVERY_INSTRUCTION`** – The fallback default used when no specific status can be determined. Guides the agent to inspect available extensions before claiming a capability is unavailable.

```typescript
// apps/server/src/opencode-plugins/openwork-extensions-preview-steering.ts
export const OPENWORK_EXTENSION_DISCOVERY_INSTRUCTION = "If the user asks for something you cannot do …";
export const OPENWORK_CLOUD_CONNECTION_INSTRUCTION = "The OpenWork Cloud connection is verified ready …";
export const OPENWORK_CONNECT_SIGN_IN_INSTRUCTION = `${OPENWORK_EXTENSION_DISCOVERY_INSTRUCTION} OpenWork Cloud is not signed in …`;
export const OPENWORK_CONNECT_DISABLED_INSTRUCTION = `${OPENWORK_EXTENSION_DISCOVERY_INSTRUCTION} OpenWork Cloud agent access is explicitly disabled …`;

```

## Runtime Behavioral Modifications

The `openwork-extensions-preview` steering plugins alter agent behavior through four distinct mechanisms:

**System Prompt Enrichment** – By injecting the steering string as the first "routing" section, the LLM receives explicit guidance on **when** to use OpenWork-specific affordances versus generic tooling.

**Tool Availability Priming** – The routing section precedes agent-surface and skill-authoring sections, causing the model to check `extension.actions` via `openwork_query` before attempting built-in file operations or terminal commands.

**Dynamic Adaptation** – Because the `experimental.chat.system.transform` hook runs on **every turn**, the agent automatically adjusts its strategy as conditions change. If a user signs in during a conversation, the next system prompt will contain `OPENWORK_CLOUD_CONNECTION_INSTRUCTION` instead of the sign-in directive, immediately enabling cloud tool usage without restarting the session.

**MCP Result Preservation** – The plugin's `tool.execute.after` hook ensures that MCP-generated UI results survive the LLM's output processing:

```typescript
// apps/server/src/opencode-plugins/openwork-extensions-preview.ts
"tool.execute.after": async (_input, output) => {
  preserveMcpResult(output);
},

```

This allows the OpenWork UI to render rich results even when the LLM discards the raw structured content from its final response.

## Practical Code Examples

When the steering indicates a healthy cloud connection, agents invoke OpenWork-specific tools:

```typescript
// Query available extensions when steering indicates cloud readiness
await openwork_query({ id: "extension.actions", args: {} });

```

If the steering returns a disabled or authentication-required state, the model generates user-facing guidance instead of attempting cloud calls:

```typescript
// When steering returns OPENWORK_CONNECT_SIGN_IN_INSTRUCTION
"OpenWork Cloud is not signed in; please go to Settings → Connect and sign in."

```

For session creation, the steering ensures the model selects the correct OpenWork tool rather than generic alternatives:

```typescript
// Steering guides selection of openwork_execute over generic file operations
await openwork_execute({ id: "session.create", args: { projectId: "123" } });

```

## Summary

- The `openwork-extensions-preview` plugin injects steering instructions via the `experimental.chat.system.transform` hook in [`openwork-extensions-preview.ts`](https://github.com/different-ai/openwork/blob/main/openwork-extensions-preview.ts).
- `resolveOpenWorkExtensionDiscoveryInstruction` determines the appropriate steering string by querying engine MCP status or server health endpoints.
- Four distinct constants (`OPENWORK_CLOUD_CONNECTION_INSTRUCTION`, `OPENWORK_CONNECT_SIGN_IN_INSTRUCTION`, `OPENWORK_CONNECT_DISABLED_INSTRUCTION`, `OPENWORK_EXTENSION_DISCOVERY_INSTRUCTION`) guide the agent's tool selection and user communication strategy.
- Steering recomputes on every turn, enabling real-time adaptation to authentication and configuration changes.
- The `preserveMcpResult` utility in the `tool.execute.after` hook ensures UI compatibility for MCP-generated content.

## Frequently Asked Questions

### How does the steering plugin detect the current OpenWork Cloud status?

The plugin queries the engine's MCP client via `fetchEngineMcpStatus` first; if that fails or returns no data, it falls back to `fetchOpenWorkConnectState` to check server-side health. Based on the returned status (connected, disabled, needs_auth), it selects the appropriate instruction constant.

### What happens when the engine MCP status is unavailable but the server is healthy?

If `engine.client` exists but `engineStatus.found` is false, the function proceeds to `composeOpenWorkExtensionDiscoveryInstruction` using the server health check results. This ensures the agent receives guidance even when the local engine's MCP registration is lagging.

### How does steering affect which tools the agent selects?

The steering string occupies the "routing" section of the system prompt, which appears before other capability descriptions. This positioning primes the LLM to consult the OpenWork extension catalog first—using `openwork_query` and `openwork_execute`—before falling back to generic file system or terminal tools.

### Is the steering instruction updated on every conversation turn?

Yes. Because the plugin implements `experimental.chat.system.transform`, it re-evaluates the OpenWork connection state and rebuilds the system prompt on each turn. If a user authenticates or disables Cloud access mid-conversation, the next message will reflect the new steering instruction immediately.