mirror of
https://github.com/alkimake/paperclip.git
synced 2026-06-14 18:10:39 +09:00
Merge branch 'master' into add-gpt-5-4-xhigh-effort
This commit is contained in:
commit
19aaa54ae4
882 changed files with 316479 additions and 9403 deletions
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue