mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-24 18:19:05 +02:00
Merge origin/master into provider routing connections
This commit is contained in:
commit
b6bc28667e
627 files changed
+97335
-5708
No files matched your search
@@ -1130,6 +1130,10 @@ const specialMethodsFor = (entry) => {
|
||||
apiKeyMethodFor(entry, "mcp-api-key", entry.serverUrl, {
|
||||
guidanceMd: `Open the ${entry.name} dashboard, create an API key for the account agents should use, and paste it below.`,
|
||||
consoleLinks: { keys: entry.slug === "mem0" ? "https://app.mem0.ai/dashboard/api-keys" : "https://app.honcho.dev", docs: entry.docsUrl },
|
||||
...(entry.slug === "honcho" ? { tenantFields: [{
|
||||
key: "workspaceId", label: "Honcho workspace", type: "text", required: true,
|
||||
placeholder: "Workspace ID", validation: { maxLength: 512 },
|
||||
}] } : {}),
|
||||
}),
|
||||
];
|
||||
if (entry.slug === "zep") return [oauthMethodFor(entry, "mcp-oauth", entry.serverUrl, {
|
||||
@@ -1778,6 +1782,21 @@ for (const app of apps) {
|
||||
}
|
||||
}
|
||||
|
||||
// Reviewed instruction templates are authored in each app's definition. Keep
|
||||
// that optional capability intact when regenerating its transport/auth fields.
|
||||
for (const app of apps) {
|
||||
const definitionPath = path.join(out, `${app.slug}.json`);
|
||||
if (!fs.existsSync(definitionPath)) continue;
|
||||
const { agentInstructions: template } = JSON.parse(fs.readFileSync(definitionPath, "utf8"));
|
||||
if (template === undefined) continue;
|
||||
if (!template || typeof template.id !== "string" || !template.id.trim() || template.id.length > 160
|
||||
|| !Number.isInteger(template.version) || template.version < 1
|
||||
|| typeof template.text !== "string" || !template.text.trim() || template.text.length > 2000) {
|
||||
throw new Error(`${app.slug}: invalid agent instruction template`);
|
||||
}
|
||||
app.agentInstructions = template;
|
||||
}
|
||||
|
||||
const validateApp = (app) => {
|
||||
if (
|
||||
app.schemaVersion !== 1 ||
|
||||
|
||||
@@ -100,7 +100,7 @@ try {
|
||||
if (!request.reservationId || request.maxCostUsd !== 0.5 || !["gpt-5.6-luna", "claude-sonnet-5", ...OPENROUTER_MODELS].includes(request.model)) throw new Error("Paid attempt requires ledger reservation and qualified model");
|
||||
if (isOpenRouter) {
|
||||
providerVersion = execFileSync(resolve("packages/paperclip-runner/node_modules/opencode-ai/bin/opencode.exe"), ["--version"], { encoding: "utf8" }).trim();
|
||||
if (providerVersion !== "1.18.32") throw new Error("OpenCode profile requires version 1.18.32");
|
||||
if (providerVersion !== "1.18.34") throw new Error("OpenCode profile requires version 1.18.34");
|
||||
}
|
||||
const providerEnvironment = isOpenRouter ? openRouterEnvironment() : request.model === "claude-sonnet-5" ? (() => {
|
||||
const token = process.env.CLAUDE_CODE_OAUTH_TOKEN;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Opt-in real Codex qualification; no model turn or live account data.
|
||||
// Run from the repository root:
|
||||
// node --import ./server/node_modules/tsx/dist/loader.mjs scripts/tests/native-cleanup-paginated-codex.mjs
|
||||
// PAPERCLIP_TEST_CODEX_BINARY may select the exact installed Codex 0.156.0 binary.
|
||||
// PAPERCLIP_TEST_CODEX_BINARY may select the exact installed Codex 0.160.0 binary.
|
||||
// Fresh synthetic fixture directories are retained for inspection; never reuse live homes.
|
||||
import { spawn, execFileSync } from "node:child_process";
|
||||
import {
|
||||
@@ -26,10 +26,10 @@ if (
|
||||
execFileSync(codexBinary, ["--version"], {
|
||||
encoding: "utf8",
|
||||
timeout: 10000,
|
||||
}).trim() !== "codex-cli 0.156.0"
|
||||
}).trim() !== "codex-cli 0.160.0"
|
||||
) {
|
||||
throw new Error(
|
||||
"This opt-in qualification requires Codex CLI 0.156.0. Requalify deliberately before changing the pin.",
|
||||
"This opt-in qualification requires Codex CLI 0.160.0. Requalify deliberately before changing the pin.",
|
||||
);
|
||||
}
|
||||
const home = await mkdtemp(join(tmpdir(), "paperclip-paginated-probe-"));
|
||||
@@ -132,7 +132,7 @@ const lines =
|
||||
timestamp,
|
||||
cwd: home,
|
||||
originator: "codex",
|
||||
cli_version: "0.156.0",
|
||||
cli_version: "0.160.0",
|
||||
source: "cli",
|
||||
model_provider: "openai",
|
||||
selected_capability_roots: [],
|
||||
|
||||
@@ -88,7 +88,7 @@ if (args.length === 0 || (args.length === 1 && args[0] === "--help")) {
|
||||
}).trim();
|
||||
assert.equal(
|
||||
version,
|
||||
"codex-cli 0.156.0",
|
||||
"codex-cli 0.160.0",
|
||||
"qualified_codex_version_required",
|
||||
);
|
||||
const ledger = join(fixture, "provider-process-starts.txt");
|
||||
@@ -309,7 +309,7 @@ if (args.length === 0 || (args.length === 1 && args[0] === "--help")) {
|
||||
kind: "codex",
|
||||
provider: "codex",
|
||||
driver: "codex_app_server",
|
||||
providerVersion: "0.156.0",
|
||||
providerVersion: "0.160.0",
|
||||
command: shim,
|
||||
args: [
|
||||
"--cd",
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
#!/usr/bin/env node
|
||||
// Refresh only Arcade's public support claim; never update Composio verification dates.
|
||||
import { readFile, writeFile } from "node:fs/promises";
|
||||
const source = "https://docs.arcade.dev/en/resources/integrations";
|
||||
const args = process.argv.slice(2);
|
||||
const verifiedAt = args[args.indexOf("--verified-at") + 1];
|
||||
if (!args.includes("--verified-at") || !/^\d{4}-\d{2}-\d{2}$/.test(verifiedAt)) {
|
||||
throw new Error("Supply --verified-at YYYY-MM-DD after reviewing the official public Arcade catalog.");
|
||||
}
|
||||
const input = args.includes("--input") ? args[args.indexOf("--input") + 1] : null;
|
||||
let html;
|
||||
if (input) html = await readFile(input, "utf8");
|
||||
else {
|
||||
const response = await fetch(source);
|
||||
if (!response.ok) throw new Error(`Arcade catalog request failed (${response.status})`);
|
||||
html = await response.text();
|
||||
}
|
||||
const records = [...html.matchAll(/self\.__next_f\.push\(\[1,("(?:\\.|[^"\\])*?")\]\)/g)]
|
||||
.map((match) => JSON.parse(match[1])).join("");
|
||||
const start = records.indexOf('"toolkits":[');
|
||||
if (start < 0) throw new Error("Arcade catalog payload was not found; preserve the previous snapshot.");
|
||||
const rest = records.slice(start + '"toolkits":'.length);
|
||||
let end = 0, depth = 0, quoted = false, escaped = false;
|
||||
for (; end < rest.length; end++) {
|
||||
const char = rest[end];
|
||||
if (escaped) { escaped = false; continue; }
|
||||
if (quoted && char === "\\") { escaped = true; continue; }
|
||||
if (char === '"') { quoted = !quoted; continue; }
|
||||
if (!quoted && char === "[") depth++;
|
||||
if (!quoted && char === "]" && --depth === 0) { end++; break; }
|
||||
}
|
||||
const toolkits = JSON.parse(rest.slice(0, end));
|
||||
const apps = toolkits.filter((app) => app.isComingSoon === false && app.isHidden === false).map((app) => {
|
||||
const toolkit = app.relativeDocsLink.split("/").at(-1);
|
||||
const slug = toolkit.replaceAll("_", "-");
|
||||
const logoUrl = new URL(app.publicIconUrl, source);
|
||||
const docsUrl = new URL(app.hasPage ? app.docsLink : source);
|
||||
if (!/^[a-z0-9-]+$/.test(slug) || !app.label || typeof app.id !== "string"
|
||||
|| logoUrl.protocol !== "https:" || !["docs.arcade.dev", "design-system.arcade.dev"].includes(logoUrl.hostname)
|
||||
|| docsUrl.origin !== "https://docs.arcade.dev") throw new Error(`Invalid public Arcade entry: ${app.id}`);
|
||||
return { slug, toolkit, name: app.label, logoUrl: logoUrl.href, docsUrl: docsUrl.href, aliases: [app.id, toolkit], category: app.category };
|
||||
}).sort((a, b) => a.slug.localeCompare(b.slug, "en"));
|
||||
if (apps.length < 100 || new Set(apps.map((app) => app.slug)).size !== apps.length) {
|
||||
throw new Error("Arcade catalog is incomplete or contains duplicate slugs; preserve the previous snapshot.");
|
||||
}
|
||||
const target = new URL("../packages/shared/src/arcade-app-catalog.json", import.meta.url);
|
||||
await writeFile(target, `${JSON.stringify({ source, verifiedAt, apps }, null, 2)}\n`);
|
||||
console.log(`Indexed ${apps.length} public Arcade apps (${verifiedAt}).`);
|
||||
Reference in new issue
Block a user