mirror of
https://github.com/openclaw/openclaw.git
synced 2026-06-12 08:22:59 +00:00
docs: document agent catalog helpers
This commit is contained in:
@@ -12,6 +12,7 @@ import {
|
||||
type SessionEntry as AgentSessionEntry,
|
||||
} from "./sessions/session-manager.js";
|
||||
|
||||
/** Resolves the persisted transcript file for a BTW session handoff. */
|
||||
export function resolveBtwSessionTranscriptPath(params: {
|
||||
sessionId: string;
|
||||
sessionEntry?: StoredSessionEntry;
|
||||
@@ -33,6 +34,8 @@ export function resolveBtwSessionTranscriptPath(params: {
|
||||
}
|
||||
}
|
||||
|
||||
// Session entries can come from older transcript formats, so id fields are
|
||||
// narrowed at this boundary before branch reconstruction trusts them.
|
||||
function readSessionEntryId(entry: AgentSessionEntry): string | undefined {
|
||||
const id = (entry as { id?: unknown }).id;
|
||||
return typeof id === "string" && id.trim().length > 0 ? id : undefined;
|
||||
@@ -46,10 +49,14 @@ function readSessionEntryParentId(entry: AgentSessionEntry): string | null | und
|
||||
return typeof parentId === "string" && parentId.trim().length > 0 ? parentId : undefined;
|
||||
}
|
||||
|
||||
// Parent links mark fork-aware transcripts. Without them, the flat session
|
||||
// context builder preserves the legacy append-only transcript behavior.
|
||||
function hasParentLinkedEntries(entries: AgentSessionEntry[]): boolean {
|
||||
return entries.some((entry) => Boolean(readSessionEntryId(entry) && "parentId" in entry));
|
||||
}
|
||||
|
||||
// Reconstructs the selected branch from leaf to root. Missing links or cycles
|
||||
// mean the snapshot cannot be trusted, so callers fall back to a safe branch.
|
||||
function buildSessionBranchEntries(
|
||||
entries: AgentSessionEntry[],
|
||||
leafId: string | undefined,
|
||||
@@ -99,6 +106,13 @@ function isTrailingUserMessage(entry: AgentSessionEntry | undefined): boolean {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads prior messages for BTW continuation.
|
||||
*
|
||||
* When a transcript has fork links, this returns the selected snapshot branch
|
||||
* instead of the full file so a resumed agent does not inherit sibling-branch
|
||||
* messages.
|
||||
*/
|
||||
export async function readBtwTranscriptMessages(params: {
|
||||
sessionFile: string;
|
||||
sessionId: string;
|
||||
@@ -124,6 +138,8 @@ export async function readBtwTranscriptMessages(params: {
|
||||
}
|
||||
branchEntries ??= buildSessionBranchEntries(sessionEntries, readDefaultLeafId(sessionEntries));
|
||||
if (!params.snapshotLeafId && isTrailingUserMessage(branchEntries?.at(-1))) {
|
||||
// Auto-selecting the newest branch must not include the current user turn
|
||||
// that triggered BTW handoff; the subagent should continue from its parent.
|
||||
const parentId = readSessionEntryParentId(branchEntries!.at(-1)!);
|
||||
branchEntries = parentId ? (buildSessionBranchEntries(sessionEntries, parentId) ?? []) : [];
|
||||
}
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
import { normalizeStructuredPromptSection } from "./prompt-cache-stability.js";
|
||||
|
||||
// Labels plugin-provided system context so harness prompt compaction and user-facing
|
||||
// transcript views can distinguish it from real workspace files or chat content.
|
||||
const HOOK_SYSTEM_CONTEXT_HEADER =
|
||||
"OpenClaw plugin-injected system context. This block is not workspace file content.";
|
||||
|
||||
/** Normalizes and fences plugin-injected system context before it enters prompts. */
|
||||
export function wrapPluginSystemContextSection(value?: string): string | undefined {
|
||||
if (typeof value !== "string") {
|
||||
return undefined;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce";
|
||||
import type { OpenClawConfig } from "../config/types.openclaw.js";
|
||||
|
||||
/** Builds deterministic prompt lines for configured model aliases. */
|
||||
export function buildModelAliasLines(cfg?: OpenClawConfig) {
|
||||
const models = cfg?.agents?.defaults?.models ?? {};
|
||||
const entries: Array<{ alias: string; model: string }> = [];
|
||||
|
||||
@@ -3,6 +3,8 @@ import path from "node:path";
|
||||
import { normalizeProviderId } from "@openclaw/model-catalog-core/provider-id";
|
||||
import type { PluginMetadataSnapshot } from "../plugins/plugin-metadata-snapshot.types.js";
|
||||
|
||||
// Generated catalog files live under each agent profile so provider model
|
||||
// discovery can reuse plugin-owned catalogs without loading plugin runtimes.
|
||||
export const PLUGIN_MODEL_CATALOG_FILE = "catalog.json";
|
||||
export const PLUGIN_MODEL_CATALOG_GENERATED_BY = "openclaw-plugin-model-catalog-v1";
|
||||
|
||||
@@ -22,10 +24,12 @@ export type PluginModelCatalogFile = {
|
||||
relativePath: string;
|
||||
};
|
||||
|
||||
/** Encodes the profile-relative path for a plugin-owned generated model catalog. */
|
||||
export function encodePluginModelCatalogRelativePath(pluginId: string): string {
|
||||
return `plugins/${encodeURIComponent(pluginId)}/${PLUGIN_MODEL_CATALOG_FILE}`;
|
||||
}
|
||||
|
||||
/** Returns true only for canonical profile-relative generated catalog paths. */
|
||||
export function isPluginModelCatalogRelativePath(relativePath: string): boolean {
|
||||
const parts = relativePath.split(/[\\/]/);
|
||||
return (
|
||||
@@ -39,6 +43,7 @@ export function isPluginModelCatalogRelativePath(relativePath: string): boolean
|
||||
);
|
||||
}
|
||||
|
||||
/** Decodes the plugin id from a canonical generated catalog path. */
|
||||
export function decodePluginModelCatalogRelativePathPluginId(
|
||||
relativePath: string,
|
||||
): string | undefined {
|
||||
@@ -53,6 +58,7 @@ export function decodePluginModelCatalogRelativePathPluginId(
|
||||
}
|
||||
}
|
||||
|
||||
/** Lists deterministic generated catalog paths present in an agent profile. */
|
||||
export function listPluginModelCatalogRelativePaths(agentDir: string): string[] {
|
||||
const pluginsDir = path.join(agentDir, "plugins");
|
||||
let pluginDirs: Array<import("node:fs").Dirent>;
|
||||
@@ -68,6 +74,7 @@ export function listPluginModelCatalogRelativePaths(agentDir: string): string[]
|
||||
.toSorted((left, right) => left.localeCompare(right));
|
||||
}
|
||||
|
||||
/** Lists existing generated catalog files with decoded plugin ownership. */
|
||||
export function listPluginModelCatalogFiles(agentDir: string): PluginModelCatalogFile[] {
|
||||
return listPluginModelCatalogRelativePaths(agentDir)
|
||||
.map((relativePath) => {
|
||||
@@ -84,6 +91,7 @@ export function listPluginModelCatalogFiles(agentDir: string): PluginModelCatalo
|
||||
.filter((entry) => existsSync(entry.path));
|
||||
}
|
||||
|
||||
/** Detects model catalogs generated by OpenClaw rather than user-authored JSON. */
|
||||
export function isGeneratedPluginModelCatalog(value: unknown): boolean {
|
||||
return (
|
||||
typeof value === "object" &&
|
||||
@@ -93,6 +101,7 @@ export function isGeneratedPluginModelCatalog(value: unknown): boolean {
|
||||
);
|
||||
}
|
||||
|
||||
/** Resolves the sole enabled plugin that owns a provider's model catalog. */
|
||||
export function resolvePluginModelCatalogOwnerPluginId(params: {
|
||||
providerId: string;
|
||||
pluginMetadataSnapshot?: PluginModelCatalogMetadataSnapshot;
|
||||
@@ -123,6 +132,7 @@ export function resolvePluginModelCatalogOwnerPluginId(params: {
|
||||
: undefined;
|
||||
}
|
||||
|
||||
/** Keeps generated catalog providers only when the catalog plugin still owns them. */
|
||||
export function filterGeneratedPluginModelCatalogProviders<T>(params: {
|
||||
catalogPluginId?: string;
|
||||
parsedCatalog?: unknown;
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
// Shared spawn mode enums used by the session tool, registry, and announce
|
||||
// delivery code. Keep these narrow so tool schemas and persisted registry rows
|
||||
// agree on the same literals.
|
||||
export const SUBAGENT_SPAWN_MODES = ["run", "session"] as const;
|
||||
export type SpawnSubagentMode = (typeof SUBAGENT_SPAWN_MODES)[number];
|
||||
|
||||
/** Sandbox escalation policy requested for a spawned subagent. */
|
||||
export const SUBAGENT_SPAWN_SANDBOX_MODES = ["inherit", "require"] as const;
|
||||
export type SpawnSubagentSandboxMode = (typeof SUBAGENT_SPAWN_SANDBOX_MODES)[number];
|
||||
|
||||
/** Prompt context relationship between the parent session and spawned subagent. */
|
||||
export const SUBAGENT_SPAWN_CONTEXT_MODES = ["isolated", "fork"] as const;
|
||||
export type SpawnSubagentContextMode = (typeof SUBAGENT_SPAWN_CONTEXT_MODES)[number];
|
||||
|
||||
Reference in New Issue
Block a user