How openwork-extensions-preview Steering Plugins Affect Agent Behavior

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, the plugin calls resolveOpenWorkExtensionDiscoveryInstruction and inserts the returned string as a dedicated "routing" section:

// 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 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:

// 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.

// 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:

// 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:

// 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:

// 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:

// 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.
  • 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.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →