Merge branch 'master' into add-gpt-5-4-xhigh-effort

This commit is contained in:
Dotta
2026-03-31 06:19:26 -05:00
committed by GitHub
882 changed files with 316479 additions and 9403 deletions
+1 -1
View File
@@ -1,4 +1,4 @@
export { getServerAdapter, listAdapterModels, listServerAdapters, findServerAdapter } from "./registry.js";
export { getServerAdapter, listAdapterModels, listServerAdapters, findServerAdapter, detectAdapterModel } from "./registry.js";
export type {
ServerAdapterModule,
AdapterExecutionContext,
+12 -3
View File
@@ -5,7 +5,9 @@ import {
asStringArray,
parseObject,
buildPaperclipEnv,
redactEnvForLogs,
buildInvocationEnvForLogs,
ensurePathInEnv,
resolveCommandForLogs,
runChildProcess,
} from "../utils.js";
@@ -21,6 +23,13 @@ export async function execute(ctx: AdapterExecutionContext): Promise<AdapterExec
for (const [k, v] of Object.entries(envConfig)) {
if (typeof v === "string") env[k] = v;
}
const runtimeEnv = ensurePathInEnv({ ...process.env, ...env });
const resolvedCommand = await resolveCommandForLogs(command, cwd, runtimeEnv);
const loggedEnv = buildInvocationEnvForLogs(env, {
runtimeEnv,
includeRuntimeKeys: ["HOME"],
resolvedCommand,
});
const timeoutSec = asNumber(config.timeoutSec, 0);
const graceSec = asNumber(config.graceSec, 15);
@@ -28,10 +37,10 @@ export async function execute(ctx: AdapterExecutionContext): Promise<AdapterExec
if (onMeta) {
await onMeta({
adapterType: "process",
command,
command: resolvedCommand,
cwd,
commandArgs: args,
env: redactEnvForLogs(env),
env: loggedEnv,
});
}
+87
View File
@@ -1,24 +1,43 @@
import type { ServerAdapterModule } from "./types.js";
import { getAdapterSessionManagement } from "@paperclipai/adapter-utils";
import {
execute as claudeExecute,
listClaudeSkills,
syncClaudeSkills,
testEnvironment as claudeTestEnvironment,
sessionCodec as claudeSessionCodec,
getQuotaWindows as claudeGetQuotaWindows,
} from "@paperclipai/adapter-claude-local/server";
import { agentConfigurationDoc as claudeAgentConfigurationDoc, models as claudeModels } from "@paperclipai/adapter-claude-local";
import {
execute as codexExecute,
listCodexSkills,
syncCodexSkills,
testEnvironment as codexTestEnvironment,
sessionCodec as codexSessionCodec,
getQuotaWindows as codexGetQuotaWindows,
} from "@paperclipai/adapter-codex-local/server";
import { agentConfigurationDoc as codexAgentConfigurationDoc, models as codexModels } from "@paperclipai/adapter-codex-local";
import {
execute as cursorExecute,
listCursorSkills,
syncCursorSkills,
testEnvironment as cursorTestEnvironment,
sessionCodec as cursorSessionCodec,
} from "@paperclipai/adapter-cursor-local/server";
import { agentConfigurationDoc as cursorAgentConfigurationDoc, models as cursorModels } from "@paperclipai/adapter-cursor-local";
import {
execute as geminiExecute,
listGeminiSkills,
syncGeminiSkills,
testEnvironment as geminiTestEnvironment,
sessionCodec as geminiSessionCodec,
} from "@paperclipai/adapter-gemini-local/server";
import { agentConfigurationDoc as geminiAgentConfigurationDoc, models as geminiModels } from "@paperclipai/adapter-gemini-local";
import {
execute as openCodeExecute,
listOpenCodeSkills,
syncOpenCodeSkills,
testEnvironment as openCodeTestEnvironment,
sessionCodec as openCodeSessionCodec,
listOpenCodeModels,
@@ -39,6 +58,8 @@ import { listCodexModels } from "./codex-models.js";
import { listCursorModels } from "./cursor-models.js";
import {
execute as piExecute,
listPiSkills,
syncPiSkills,
testEnvironment as piTestEnvironment,
sessionCodec as piSessionCodec,
listPiModels,
@@ -46,6 +67,18 @@ import {
import {
agentConfigurationDoc as piAgentConfigurationDoc,
} from "@paperclipai/adapter-pi-local";
import {
execute as hermesExecute,
testEnvironment as hermesTestEnvironment,
sessionCodec as hermesSessionCodec,
listSkills as hermesListSkills,
syncSkills as hermesSyncSkills,
detectModel as detectModelFromHermes,
} from "hermes-paperclip-adapter/server";
import {
agentConfigurationDoc as hermesAgentConfigurationDoc,
models as hermesModels,
} from "hermes-paperclip-adapter";
import { processAdapter } from "./process/index.js";
import { httpAdapter } from "./http/index.js";
@@ -53,34 +86,58 @@ const claudeLocalAdapter: ServerAdapterModule = {
type: "claude_local",
execute: claudeExecute,
testEnvironment: claudeTestEnvironment,
listSkills: listClaudeSkills,
syncSkills: syncClaudeSkills,
sessionCodec: claudeSessionCodec,
sessionManagement: getAdapterSessionManagement("claude_local") ?? undefined,
models: claudeModels,
supportsLocalAgentJwt: true,
agentConfigurationDoc: claudeAgentConfigurationDoc,
getQuotaWindows: claudeGetQuotaWindows,
};
const codexLocalAdapter: ServerAdapterModule = {
type: "codex_local",
execute: codexExecute,
testEnvironment: codexTestEnvironment,
listSkills: listCodexSkills,
syncSkills: syncCodexSkills,
sessionCodec: codexSessionCodec,
sessionManagement: getAdapterSessionManagement("codex_local") ?? undefined,
models: codexModels,
listModels: listCodexModels,
supportsLocalAgentJwt: true,
agentConfigurationDoc: codexAgentConfigurationDoc,
getQuotaWindows: codexGetQuotaWindows,
};
const cursorLocalAdapter: ServerAdapterModule = {
type: "cursor",
execute: cursorExecute,
testEnvironment: cursorTestEnvironment,
listSkills: listCursorSkills,
syncSkills: syncCursorSkills,
sessionCodec: cursorSessionCodec,
sessionManagement: getAdapterSessionManagement("cursor") ?? undefined,
models: cursorModels,
listModels: listCursorModels,
supportsLocalAgentJwt: true,
agentConfigurationDoc: cursorAgentConfigurationDoc,
};
const geminiLocalAdapter: ServerAdapterModule = {
type: "gemini_local",
execute: geminiExecute,
testEnvironment: geminiTestEnvironment,
listSkills: listGeminiSkills,
syncSkills: syncGeminiSkills,
sessionCodec: geminiSessionCodec,
sessionManagement: getAdapterSessionManagement("gemini_local") ?? undefined,
models: geminiModels,
supportsLocalAgentJwt: true,
agentConfigurationDoc: geminiAgentConfigurationDoc,
};
const openclawGatewayAdapter: ServerAdapterModule = {
type: "openclaw_gateway",
execute: openclawGatewayExecute,
@@ -94,8 +151,11 @@ const openCodeLocalAdapter: ServerAdapterModule = {
type: "opencode_local",
execute: openCodeExecute,
testEnvironment: openCodeTestEnvironment,
listSkills: listOpenCodeSkills,
syncSkills: syncOpenCodeSkills,
sessionCodec: openCodeSessionCodec,
models: openCodeModels,
sessionManagement: getAdapterSessionManagement("opencode_local") ?? undefined,
listModels: listOpenCodeModels,
supportsLocalAgentJwt: true,
agentConfigurationDoc: openCodeAgentConfigurationDoc,
@@ -105,13 +165,29 @@ const piLocalAdapter: ServerAdapterModule = {
type: "pi_local",
execute: piExecute,
testEnvironment: piTestEnvironment,
listSkills: listPiSkills,
syncSkills: syncPiSkills,
sessionCodec: piSessionCodec,
sessionManagement: getAdapterSessionManagement("pi_local") ?? undefined,
models: [],
listModels: listPiModels,
supportsLocalAgentJwt: true,
agentConfigurationDoc: piAgentConfigurationDoc,
};
const hermesLocalAdapter: ServerAdapterModule = {
type: "hermes_local",
execute: hermesExecute,
testEnvironment: hermesTestEnvironment,
sessionCodec: hermesSessionCodec,
listSkills: hermesListSkills,
syncSkills: hermesSyncSkills,
models: hermesModels,
supportsLocalAgentJwt: true,
agentConfigurationDoc: hermesAgentConfigurationDoc,
detectModel: () => detectModelFromHermes(),
};
const adaptersByType = new Map<string, ServerAdapterModule>(
[
claudeLocalAdapter,
@@ -119,7 +195,9 @@ const adaptersByType = new Map<string, ServerAdapterModule>(
openCodeLocalAdapter,
piLocalAdapter,
cursorLocalAdapter,
geminiLocalAdapter,
openclawGatewayAdapter,
hermesLocalAdapter,
processAdapter,
httpAdapter,
].map((a) => [a.type, a]),
@@ -148,6 +226,15 @@ export function listServerAdapters(): ServerAdapterModule[] {
return Array.from(adaptersByType.values());
}
export async function detectAdapterModel(
type: string,
): Promise<{ model: string; provider: string; source: string } | null> {
const adapter = adaptersByType.get(type);
if (!adapter?.detectModel) return null;
const detected = await adapter.detectModel();
return detected ? { model: detected.model, provider: detected.provider, source: detected.source } : null;
}
export function findServerAdapter(type: string): ServerAdapterModule | null {
return adaptersByType.get(type) ?? null;
}
+10
View File
@@ -3,6 +3,7 @@
// imports (process/, http/, heartbeat.ts) don't need rewriting.
export type {
AdapterAgent,
AdapterSessionManagement,
AdapterRuntime,
UsageSummary,
AdapterExecutionResult,
@@ -13,7 +14,16 @@ export type {
AdapterEnvironmentTestStatus,
AdapterEnvironmentTestResult,
AdapterEnvironmentTestContext,
AdapterSkillSyncMode,
AdapterSkillState,
AdapterSkillOrigin,
AdapterSkillEntry,
AdapterSkillSnapshot,
AdapterSkillContext,
AdapterSessionCodec,
AdapterModel,
NativeContextManagement,
ResolvedSessionCompactionPolicy,
SessionCompactionPolicy,
ServerAdapterModule,
} from "@paperclipai/adapter-utils";
+68 -22
View File
@@ -1,32 +1,78 @@
// Re-export everything from the shared adapter-utils/server-utils package.
// This file is kept as a convenience shim so existing in-tree
// imports (process/, http/, heartbeat.ts) don't need rewriting.
import type { ChildProcess } from "node:child_process";
import { logger } from "../middleware/logger.js";
export {
type RunProcessResult,
runningProcesses,
MAX_CAPTURE_BYTES,
MAX_EXCERPT_BYTES,
parseObject,
asString,
asNumber,
asBoolean,
asStringArray,
parseJson,
appendWithCap,
resolvePathValue,
renderTemplate,
redactEnvForLogs,
buildPaperclipEnv,
defaultPathForPlatform,
ensurePathInEnv,
ensureAbsoluteDirectory,
ensureCommandResolvable,
} from "@paperclipai/adapter-utils/server-utils";
import * as serverUtils from "@paperclipai/adapter-utils/server-utils";
export type { RunProcessResult } from "@paperclipai/adapter-utils/server-utils";
type BuildInvocationEnvForLogsOptions = {
runtimeEnv?: NodeJS.ProcessEnv | Record<string, string>;
includeRuntimeKeys?: string[];
resolvedCommand?: string | null;
resolvedCommandEnvKey?: string;
};
export const runningProcesses: Map<string, { child: ChildProcess; graceSec: number }> =
serverUtils.runningProcesses;
export const MAX_CAPTURE_BYTES = serverUtils.MAX_CAPTURE_BYTES;
export const MAX_EXCERPT_BYTES = serverUtils.MAX_EXCERPT_BYTES;
export const parseObject = serverUtils.parseObject;
export const asString = serverUtils.asString;
export const asNumber = serverUtils.asNumber;
export const asBoolean = serverUtils.asBoolean;
export const asStringArray = serverUtils.asStringArray;
export const parseJson = serverUtils.parseJson;
export const appendWithCap = serverUtils.appendWithCap;
export const resolvePathValue = serverUtils.resolvePathValue;
export const renderTemplate = serverUtils.renderTemplate;
export const redactEnvForLogs = serverUtils.redactEnvForLogs;
export const buildPaperclipEnv = serverUtils.buildPaperclipEnv;
export const defaultPathForPlatform = serverUtils.defaultPathForPlatform;
export const ensurePathInEnv = serverUtils.ensurePathInEnv;
export const ensureAbsoluteDirectory = serverUtils.ensureAbsoluteDirectory;
export const ensureCommandResolvable = serverUtils.ensureCommandResolvable;
export const resolveCommandForLogs = serverUtils.resolveCommandForLogs;
export function buildInvocationEnvForLogs(
env: Record<string, string>,
options: BuildInvocationEnvForLogsOptions = {},
): Record<string, string> {
// TODO: Remove this fallback once @paperclipai/adapter-utils exports buildInvocationEnvForLogs everywhere we consume it.
const maybeBuildInvocationEnvForLogs = (
serverUtils as typeof serverUtils & {
buildInvocationEnvForLogs?: (
env: Record<string, string>,
options?: BuildInvocationEnvForLogsOptions,
) => Record<string, string>;
}
).buildInvocationEnvForLogs;
if (typeof maybeBuildInvocationEnvForLogs === "function") {
return maybeBuildInvocationEnvForLogs(env, options);
}
const merged: Record<string, string> = { ...env };
const runtimeEnv = options.runtimeEnv ?? {};
for (const key of options.includeRuntimeKeys ?? []) {
if (key in merged) continue;
const value = runtimeEnv[key];
if (typeof value !== "string" || value.length === 0) continue;
merged[key] = value;
}
const resolvedCommand = options.resolvedCommand?.trim();
if (resolvedCommand) {
merged[options.resolvedCommandEnvKey ?? "PAPERCLIP_RESOLVED_COMMAND"] = resolvedCommand;
}
return redactEnvForLogs(merged);
}
// Re-export runChildProcess with the server's pino logger wired in.
import { runChildProcess as _runChildProcess } from "@paperclipai/adapter-utils/server-utils";
import type { RunProcessResult } from "@paperclipai/adapter-utils/server-utils";
const _runChildProcess = serverUtils.runChildProcess;
export async function runChildProcess(
runId: string,