mirror of
https://github.com/openclaw/openclaw.git
synced 2026-06-06 05:51:15 +08:00
docs: document codex plugin app config
This commit is contained in:
@@ -1,3 +1,7 @@
|
||||
/**
|
||||
* Activates configured Codex marketplace plugins and refreshes runtime state so
|
||||
* plugin-owned apps/tools are visible to native Codex turns.
|
||||
*/
|
||||
import fs from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
import type { CodexAppInventoryCache, CodexAppInventoryRequest } from "./app-inventory-cache.js";
|
||||
@@ -10,6 +14,7 @@ import {
|
||||
} from "./plugin-inventory.js";
|
||||
import type { v2 } from "./protocol.js";
|
||||
|
||||
/** Terminal reason reported after trying to activate one Codex plugin policy. */
|
||||
export type CodexPluginActivationReason =
|
||||
| "already_active"
|
||||
| "installed"
|
||||
@@ -19,10 +24,12 @@ export type CodexPluginActivationReason =
|
||||
| "auth_required"
|
||||
| "refresh_failed";
|
||||
|
||||
/** Human-readable diagnostic emitted during Codex plugin activation. */
|
||||
export type CodexPluginActivationDiagnostic = {
|
||||
message: string;
|
||||
};
|
||||
|
||||
/** Result of ensuring one configured Codex plugin is installed and enabled. */
|
||||
export type CodexPluginActivationResult = {
|
||||
identity: ResolvedCodexPluginPolicy;
|
||||
ok: boolean;
|
||||
@@ -33,6 +40,7 @@ export type CodexPluginActivationResult = {
|
||||
diagnostics: CodexPluginActivationDiagnostic[];
|
||||
};
|
||||
|
||||
/** Inputs for activating one resolved Codex plugin policy. */
|
||||
export type EnsureCodexPluginActivationParams = {
|
||||
identity: ResolvedCodexPluginPolicy;
|
||||
request: CodexPluginRuntimeRequest;
|
||||
@@ -41,10 +49,12 @@ export type EnsureCodexPluginActivationParams = {
|
||||
installEvenIfActive?: boolean;
|
||||
};
|
||||
|
||||
/** Diagnostics from refreshing Codex runtime surfaces after plugin activation. */
|
||||
export type CodexPluginRuntimeRefreshResult = {
|
||||
diagnostics: CodexPluginActivationDiagnostic[];
|
||||
};
|
||||
|
||||
/** Installs/enables a configured Codex plugin and refreshes plugin/app state. */
|
||||
export async function ensureCodexPluginActivation(
|
||||
params: EnsureCodexPluginActivationParams,
|
||||
): Promise<CodexPluginActivationResult> {
|
||||
@@ -130,6 +140,7 @@ export async function ensureCodexPluginActivation(
|
||||
};
|
||||
}
|
||||
|
||||
/** Forces Codex plugin, skill, hook, MCP, and app inventory refreshes after activation. */
|
||||
export async function refreshCodexPluginRuntimeState(params: {
|
||||
request: CodexPluginRuntimeRequest;
|
||||
appCache?: CodexAppInventoryCache;
|
||||
@@ -176,6 +187,7 @@ export async function refreshCodexPluginRuntimeState(params: {
|
||||
return { diagnostics };
|
||||
}
|
||||
|
||||
/** Ensures the Codex config enables app substrate support needed by plugin-owned apps. */
|
||||
export async function ensureCodexAppsSubstrateConfig(params: {
|
||||
codexHome: string;
|
||||
readFile?: (filePath: string, encoding: "utf8") => Promise<string>;
|
||||
@@ -211,6 +223,7 @@ export async function ensureCodexAppsSubstrateConfig(params: {
|
||||
return { changed: true, configPath };
|
||||
}
|
||||
|
||||
/** Upserts a boolean key in a TOML section while preserving the rest of the file. */
|
||||
export function upsertTomlBoolean(
|
||||
source: string,
|
||||
section: string,
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
/**
|
||||
* Reads Codex plugin marketplace state and app inventory to decide which
|
||||
* plugin-owned apps can be exposed to a native Codex thread.
|
||||
*/
|
||||
import { embeddedAgentLog } from "openclaw/plugin-sdk/agent-harness-runtime";
|
||||
import type {
|
||||
CodexAppInventoryCache,
|
||||
@@ -12,14 +16,17 @@ import {
|
||||
} from "./config.js";
|
||||
import type { v2 } from "./protocol.js";
|
||||
|
||||
/** Request callback used to call Codex app-server plugin/app methods. */
|
||||
export type CodexPluginRuntimeRequest = (method: string, params?: unknown) => Promise<unknown>;
|
||||
|
||||
/** Stable reference to the OpenAI curated Codex plugin marketplace. */
|
||||
export type CodexPluginMarketplaceRef = {
|
||||
name: typeof CODEX_PLUGINS_MARKETPLACE_NAME;
|
||||
path?: string;
|
||||
remoteMarketplaceName?: string;
|
||||
};
|
||||
|
||||
/** Machine-readable inventory diagnostic code used by thread config builders. */
|
||||
export type CodexPluginInventoryDiagnosticCode =
|
||||
| "disabled"
|
||||
| "marketplace_missing"
|
||||
@@ -30,12 +37,14 @@ export type CodexPluginInventoryDiagnosticCode =
|
||||
| "app_inventory_stale"
|
||||
| "app_ownership_ambiguous";
|
||||
|
||||
/** Diagnostic explaining why a configured plugin or app cannot be exposed. */
|
||||
export type CodexPluginInventoryDiagnostic = {
|
||||
code: CodexPluginInventoryDiagnosticCode;
|
||||
plugin?: ResolvedCodexPluginPolicy;
|
||||
message: string;
|
||||
};
|
||||
|
||||
/** App owned by a Codex plugin with current accessibility/auth state. */
|
||||
export type CodexPluginOwnedApp = {
|
||||
id: string;
|
||||
name: string;
|
||||
@@ -44,6 +53,7 @@ export type CodexPluginOwnedApp = {
|
||||
needsAuth: boolean;
|
||||
};
|
||||
|
||||
/** Inventory record for one configured Codex plugin policy. */
|
||||
export type CodexPluginInventoryRecord = {
|
||||
policy: ResolvedCodexPluginPolicy;
|
||||
summary: v2.PluginSummary;
|
||||
@@ -55,6 +65,7 @@ export type CodexPluginInventoryRecord = {
|
||||
apps: CodexPluginOwnedApp[];
|
||||
};
|
||||
|
||||
/** Complete inventory result for configured Codex plugins and owned apps. */
|
||||
export type CodexPluginInventory = {
|
||||
policy: ResolvedCodexPluginsPolicy;
|
||||
marketplace?: CodexPluginMarketplaceRef;
|
||||
@@ -63,6 +74,7 @@ export type CodexPluginInventory = {
|
||||
appInventory?: CodexAppInventoryCacheRead;
|
||||
};
|
||||
|
||||
/** Inputs for reading plugin marketplace/detail state and cached app inventory. */
|
||||
export type ReadCodexPluginInventoryParams = {
|
||||
pluginConfig?: unknown;
|
||||
policy?: ResolvedCodexPluginsPolicy;
|
||||
@@ -74,6 +86,7 @@ export type ReadCodexPluginInventoryParams = {
|
||||
suppressAppInventoryRefresh?: boolean;
|
||||
};
|
||||
|
||||
/** Reads configured Codex plugin state and maps owned apps to readiness diagnostics. */
|
||||
export async function readCodexPluginInventory(
|
||||
params: ReadCodexPluginInventoryParams,
|
||||
): Promise<CodexPluginInventory> {
|
||||
@@ -195,6 +208,7 @@ export async function readCodexPluginInventory(
|
||||
return inventory;
|
||||
}
|
||||
|
||||
/** Finds one plugin summary in the OpenAI curated marketplace response. */
|
||||
export function findOpenAiCuratedPluginSummary(
|
||||
listed: v2.PluginListResponse,
|
||||
pluginName: string,
|
||||
@@ -209,6 +223,7 @@ export function findOpenAiCuratedPluginSummary(
|
||||
return summary ? { marketplace: marketplaceRef(marketplaceEntry), summary } : undefined;
|
||||
}
|
||||
|
||||
/** Builds plugin/read or plugin/install params from a marketplace reference. */
|
||||
export function pluginReadParams(
|
||||
marketplace: CodexPluginMarketplaceRef,
|
||||
pluginName: string,
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
/**
|
||||
* Builds Codex thread config patches that expose only policy-approved
|
||||
* plugin-owned apps for native Codex turns.
|
||||
*/
|
||||
import crypto from "node:crypto";
|
||||
import { embeddedAgentLog } from "openclaw/plugin-sdk/agent-harness-runtime";
|
||||
import {
|
||||
@@ -26,6 +30,7 @@ import {
|
||||
} from "./plugin-inventory.js";
|
||||
import type { JsonObject, JsonValue } from "./protocol.js";
|
||||
|
||||
/** Policy context for one app id exposed by a configured Codex plugin. */
|
||||
export type PluginAppPolicyContextEntry = {
|
||||
configKey: string;
|
||||
marketplaceName: ResolvedCodexPluginPolicy["marketplaceName"];
|
||||
@@ -34,12 +39,14 @@ export type PluginAppPolicyContextEntry = {
|
||||
mcpServerNames: string[];
|
||||
};
|
||||
|
||||
/** Stable app-to-plugin ownership context persisted with Codex thread bindings. */
|
||||
export type PluginAppPolicyContext = {
|
||||
fingerprint: string;
|
||||
apps: Record<string, PluginAppPolicyContextEntry>;
|
||||
pluginAppIds: Record<string, string[]>;
|
||||
};
|
||||
|
||||
/** Diagnostic emitted while building app config for a native Codex thread. */
|
||||
export type CodexPluginThreadConfigDiagnostic =
|
||||
| CodexPluginInventoryDiagnostic
|
||||
| {
|
||||
@@ -48,6 +55,7 @@ export type CodexPluginThreadConfigDiagnostic =
|
||||
message: string;
|
||||
};
|
||||
|
||||
/** Complete Codex thread config patch plus inventory and policy fingerprints. */
|
||||
export type CodexPluginThreadConfig = {
|
||||
enabled: boolean;
|
||||
configPatch?: JsonObject;
|
||||
@@ -58,6 +66,7 @@ export type CodexPluginThreadConfig = {
|
||||
diagnostics: CodexPluginThreadConfigDiagnostic[];
|
||||
};
|
||||
|
||||
/** Inputs for building a Codex thread app/plugin config patch. */
|
||||
export type BuildCodexPluginThreadConfigParams = {
|
||||
pluginConfig?: unknown;
|
||||
request: CodexPluginRuntimeRequest;
|
||||
@@ -69,10 +78,12 @@ export type BuildCodexPluginThreadConfigParams = {
|
||||
const CODEX_PLUGIN_THREAD_CONFIG_INPUT_FINGERPRINT_VERSION = 1;
|
||||
const CODEX_PLUGIN_THREAD_CONFIG_FINGERPRINT_VERSION = 1;
|
||||
|
||||
/** Returns true when plugin config exists and thread config may need app patches. */
|
||||
export function shouldBuildCodexPluginThreadConfig(pluginConfig?: unknown): boolean {
|
||||
return resolveCodexPluginsPolicy(pluginConfig).configured;
|
||||
}
|
||||
|
||||
/** Fingerprints policy and app-cache identity before runtime inventory is read. */
|
||||
export function buildCodexPluginThreadConfigInputFingerprint(params: {
|
||||
pluginConfig?: unknown;
|
||||
appCacheKey?: string;
|
||||
@@ -85,6 +96,7 @@ export function buildCodexPluginThreadConfigInputFingerprint(params: {
|
||||
});
|
||||
}
|
||||
|
||||
/** Builds the Codex apps config patch and policy context for a native thread. */
|
||||
export async function buildCodexPluginThreadConfig(
|
||||
params: BuildCodexPluginThreadConfigParams,
|
||||
): Promise<CodexPluginThreadConfig> {
|
||||
@@ -257,6 +269,7 @@ export async function buildCodexPluginThreadConfig(
|
||||
};
|
||||
}
|
||||
|
||||
/** Deep-merges optional Codex thread config patches, returning undefined when empty. */
|
||||
export function mergeCodexThreadConfigs(
|
||||
...configs: Array<JsonObject | undefined>
|
||||
): JsonObject | undefined {
|
||||
@@ -270,6 +283,7 @@ export function mergeCodexThreadConfigs(
|
||||
return merged && Object.keys(merged).length > 0 ? merged : undefined;
|
||||
}
|
||||
|
||||
/** Detects when a stored thread binding no longer matches current plugin policy inputs. */
|
||||
export function isCodexPluginThreadBindingStale(params: {
|
||||
codexPluginsEnabled: boolean;
|
||||
bindingFingerprint?: string;
|
||||
@@ -442,6 +456,8 @@ function fingerprintJson(value: JsonValue): string {
|
||||
}
|
||||
|
||||
function stableStringify(value: JsonValue | undefined): string {
|
||||
// Fingerprints must be process-stable across object insertion order so prompt
|
||||
// cache and thread-binding comparisons do not churn between runs.
|
||||
if (Array.isArray(value)) {
|
||||
return `[${value.map((item) => stableStringify(item)).join(",")}]`;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user