Files
paseo/packages/plugin/src/client/runtime-context-bridge.tsx
T
Mohamed Boudra 0aeb1ae1f9 feat(plugins): reach a running agent's composer by reference
useComposers(selector) in any plugin component and composers(selector) on every command context return the composer of a running agent, named by id or by focus, whether or not its tab is open.

A running agent now has one store-backed composer model apart from any mounted tab. The mounted composer plugs its cursor-aware insert in while mounted; otherwise insertText and setPrompt write the agent's saved prompt. model and thinking resolve through the provider catalog with the picker's own function, so a read equals what the picker shows.

The host reads one ComposerModel from context and no longer knows whether it is in an agent, a draft or New workspace. The daemon rejects an unlisted model or thinking option for a running agent, replacing the app-side guard.
2026-11-04 08:10:28 +01:00

56 lines
2.0 KiB
TypeScript

import { PluginTranslationProvider, usePluginTranslationRuntime } from "./translations.js";
import { useCallback, type ReactNode } from "react";
import {
PluginComposerProvider,
PluginComposersProvider,
usePluginComposerValue,
usePluginComposersSource,
} from "./composer.js";
import { PluginClientStateProvider, usePluginClientStateSource } from "./client-state.js";
import { PaseoApiProvider, usePaseoContextValue } from "./paseo-context.js";
import { PluginRpcProvider, usePluginRpcContextValue } from "./rpc-context.js";
export type PluginRuntimeContextBridge = (children: ReactNode) => ReactNode;
/** Rebuilds plugin runtime contexts inside React Native portal hosts. */
export function usePluginRuntimeContextBridge(): PluginRuntimeContextBridge {
const translations = usePluginTranslationRuntime();
const paseo = usePaseoContextValue();
const rpc = usePluginRpcContextValue();
const state = usePluginClientStateSource();
const composer = usePluginComposerValue();
const composers = usePluginComposersSource();
if (!paseo || !rpc) {
throw new Error("Plugin UI must run inside a contributed plugin surface");
}
return useCallback(
(children: ReactNode) => {
const withState = state ? (
<PluginClientStateProvider source={state}>{children}</PluginClientStateProvider>
) : (
children
);
const withComposers = composers ? (
<PluginComposersProvider source={composers}>{withState}</PluginComposersProvider>
) : (
withState
);
const content = composer ? (
<PluginComposerProvider composer={composer}>{withComposers}</PluginComposerProvider>
) : (
withComposers
);
return (
<PaseoApiProvider paseo={paseo}>
<PluginRpcProvider invoke={rpc.invoke} subscribe={rpc.subscribe}>
<PluginTranslationProvider runtime={translations}>{content}</PluginTranslationProvider>
</PluginRpcProvider>
</PaseoApiProvider>
);
},
[composer, composers, paseo, rpc, state, translations],
);
}