@rynfar/meridian 1.69.0 → 1.70.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -108,6 +108,7 @@ The Claude Agent SDK provides programmatic access to Claude. But your favorite c
108
108
  | [Prime Agent](https://www.npmjs.com/package/prime-agent) | ⚠️ Single-agent verified | Extension config (see [Agent Setup](docs/agents.md)) — reliable with one active agent. Concurrent RLM subagents receive distinct session keys, but are not yet production-safe; see [Prime Agent subagents](#prime-agent-subagents). The extension's `metadata.user_id` stamp is **required**, not optional. |
109
109
  | [Claude Code](https://docs.anthropic.com/en/docs/claude-code) | ✅ Verified | `ANTHROPIC_BASE_URL` — remote clients share a Max subscription over the network; client CWD preserved in system prompt |
110
110
  | [Cherry Studio](https://github.com/CherryHQ/cherry-studio) | ✅ Verified | `cherry` adapter (see [Agent Setup](docs/agents.md)) — chat client with Claude's built-in web search via internal mode |
111
+ | [Polytoken](https://polytoken.dev/) | ✅ Verified | Provider config (see [Agent Setup](docs/agents.md#Polytoken)) — `X-Polytoken-Session` identity, mandatory client-owned tools (passthrough cannot be disabled), signed-thinking passthrough |
111
112
  | Jcode | ✅ Verified | `/v1/chat/completions` + `x-jcode-session` header — dedicated `jcode` adapter keeps append-only history intact, so retained sessions resume on one SDK session (90.9% cache hit on turn 2 of a two-turn Opus session) |
112
113
  | [Codex CLI](https://github.com/openai/codex) | ✅ Verified | `/v1/responses` (see [Agent Setup](docs/agents.md)) — Responses-API provider, passthrough tool execution; verified on 0.144 (plain + tool-driving turns) |
113
114
  | [Continue](https://github.com/continuedev/continue) | 🔲 Untested | OpenAI-compatible endpoints should work — set `apiBase` to `http://127.0.0.1:3456` |
@@ -3338,6 +3338,93 @@ var init_cherry = __esm(() => {
3338
3338
  };
3339
3339
  });
3340
3340
 
3341
+ // src/proxy/transforms/polytoken.ts
3342
+ var polytokenTransforms;
3343
+ var init_polytoken = __esm(() => {
3344
+ polytokenTransforms = [
3345
+ {
3346
+ name: "polytoken-core",
3347
+ adapters: ["polytoken"],
3348
+ onRequest(ctx) {
3349
+ return {
3350
+ ...ctx,
3351
+ blockedTools: [],
3352
+ incompatibleTools: [],
3353
+ allowedMcpTools: [],
3354
+ coreToolNames: [],
3355
+ passthrough: true,
3356
+ sdkAgents: {},
3357
+ sdkHooks: undefined,
3358
+ systemContext: ctx.systemContext,
3359
+ supportsThinking: true,
3360
+ shouldTrackFileChanges: false,
3361
+ extractFileChangesFromToolUse: undefined
3362
+ };
3363
+ }
3364
+ }
3365
+ ];
3366
+ });
3367
+
3368
+ // src/proxy/adapters/polytoken.ts
3369
+ function normalizePolytokenSessionId(value) {
3370
+ const trimmed = value?.trim();
3371
+ return trimmed ? trimmed : undefined;
3372
+ }
3373
+ var POLYTOKEN_SESSION_HEADER = "x-polytoken-session", polytokenAdapter;
3374
+ var init_polytoken2 = __esm(() => {
3375
+ init_messages();
3376
+ init_polytoken();
3377
+ polytokenAdapter = {
3378
+ name: "polytoken",
3379
+ clientEnvironmentMayDifferFromProxy: true,
3380
+ getSessionId(c) {
3381
+ return normalizePolytokenSessionId(c.req.header(POLYTOKEN_SESSION_HEADER));
3382
+ },
3383
+ extractWorkingDirectory(_body) {
3384
+ return;
3385
+ },
3386
+ extractClientWorkingDirectory(_body) {
3387
+ return;
3388
+ },
3389
+ normalizeContent(content) {
3390
+ return normalizeContent(content);
3391
+ },
3392
+ getBlockedBuiltinTools() {
3393
+ return [];
3394
+ },
3395
+ getAgentIncompatibleTools() {
3396
+ return [];
3397
+ },
3398
+ getMcpServerName() {
3399
+ return "polytoken";
3400
+ },
3401
+ getAllowedMcpTools() {
3402
+ return [];
3403
+ },
3404
+ getCoreToolNames() {
3405
+ return [];
3406
+ },
3407
+ usesPassthrough() {
3408
+ return true;
3409
+ },
3410
+ supportsThinking() {
3411
+ return true;
3412
+ },
3413
+ shouldTrackFileChanges() {
3414
+ return false;
3415
+ },
3416
+ buildSdkAgents(_body, _mcpToolNames) {
3417
+ return {};
3418
+ },
3419
+ buildSdkHooks(_body, _sdkAgents) {
3420
+ return;
3421
+ },
3422
+ buildSystemContextAddendum(_body, _sdkAgents) {
3423
+ return "";
3424
+ }
3425
+ };
3426
+ });
3427
+
3341
3428
  // src/proxy/adapterInstances.ts
3342
3429
  import { existsSync as existsSync4, readFileSync as readFileSync4 } from "node:fs";
3343
3430
  import { join as join5 } from "node:path";
@@ -3429,6 +3516,10 @@ __export(exports_detect, {
3429
3516
  function listAdapterNames() {
3430
3517
  return [...new Set(Object.values(ADAPTER_MAP).map((a) => a.name))];
3431
3518
  }
3519
+ function resolveDefaultAdapter() {
3520
+ const current = (process.env.MERIDIAN_DEFAULT_AGENT || "").toLowerCase();
3521
+ return ADAPTER_MAP[current] ?? openCodeAdapter;
3522
+ }
3432
3523
  function isLiteLLMRequest(c) {
3433
3524
  if ((c.req.header("user-agent") || "").startsWith("litellm/"))
3434
3525
  return true;
@@ -3456,19 +3547,20 @@ function detectAdapter(c) {
3456
3547
  }
3457
3548
  const instances = loadAdapterInstances();
3458
3549
  const instanceNames = Object.keys(instances);
3459
- if (instanceNames.length > 0) {
3460
- if (agentOverride && instances[agentOverride]) {
3461
- const inst = makeInstanceAdapter(agentOverride, instances[agentOverride]);
3550
+ if (instanceNames.length > 0 && agentOverride && instances[agentOverride]) {
3551
+ const inst = makeInstanceAdapter(agentOverride, instances[agentOverride]);
3552
+ if (inst)
3553
+ return inst;
3554
+ }
3555
+ if (normalizePolytokenSessionId(c.req.header("x-polytoken-session"))) {
3556
+ return polytokenAdapter;
3557
+ }
3558
+ for (const name of instanceNames) {
3559
+ if (matchesInstance(instances[name], (h) => c.req.header(h))) {
3560
+ const inst = makeInstanceAdapter(name, instances[name]);
3462
3561
  if (inst)
3463
3562
  return inst;
3464
3563
  }
3465
- for (const name of instanceNames) {
3466
- if (matchesInstance(instances[name], (h) => c.req.header(h))) {
3467
- const inst = makeInstanceAdapter(name, instances[name]);
3468
- if (inst)
3469
- return inst;
3470
- }
3471
- }
3472
3564
  }
3473
3565
  if (c.req.header("x-opencode-session")) {
3474
3566
  return openCodeAdapter;
@@ -3486,6 +3578,9 @@ function detectAdapter(c) {
3486
3578
  if (userAgent.startsWith("Charm-Crush/")) {
3487
3579
  return crushAdapter;
3488
3580
  }
3581
+ if (/^Polytoken(?:[\s/]|$)/.test(userAgent)) {
3582
+ return polytokenAdapter;
3583
+ }
3489
3584
  if (c.req.header("x-session-affinity")) {
3490
3585
  return openCodeAdapter;
3491
3586
  }
@@ -3499,9 +3594,9 @@ function detectAdapter(c) {
3499
3594
  if (isLiteLLMRequest(c)) {
3500
3595
  return passthroughAdapter;
3501
3596
  }
3502
- return defaultAdapter;
3597
+ return resolveDefaultAdapter();
3503
3598
  }
3504
- var ADAPTER_MAP, envDefault, defaultAdapter;
3599
+ var ADAPTER_MAP, envDefault;
3505
3600
  var init_detect = __esm(() => {
3506
3601
  init_opencode2();
3507
3602
  init_droid2();
@@ -3515,6 +3610,7 @@ var init_detect = __esm(() => {
3515
3610
  init_jcode();
3516
3611
  init_codex();
3517
3612
  init_cherry();
3613
+ init_polytoken2();
3518
3614
  init_adapterInstances();
3519
3615
  ADAPTER_MAP = {
3520
3616
  opencode: openCodeAdapter,
@@ -3529,6 +3625,7 @@ var init_detect = __esm(() => {
3529
3625
  claudecode: claudeCodeAdapter,
3530
3626
  cherry: cherryAdapter,
3531
3627
  cherrystudio: cherryAdapter,
3628
+ polytoken: polytokenAdapter,
3532
3629
  openai: openAiAdapter,
3533
3630
  jcode: jcodeAdapter,
3534
3631
  codex: codexAdapter
@@ -3537,7 +3634,6 @@ var init_detect = __esm(() => {
3537
3634
  if (envDefault && !ADAPTER_MAP[envDefault]) {
3538
3635
  console.warn(`[meridian] Unknown MERIDIAN_DEFAULT_AGENT="${envDefault}". ` + `Valid values: ${Object.keys(ADAPTER_MAP).join(", ")}. Falling back to opencode.`);
3539
3636
  }
3540
- defaultAdapter = ADAPTER_MAP[envDefault] ?? openCodeAdapter;
3541
3637
  });
3542
3638
 
3543
3639
  // src/proxy/sdkFeatures.ts
@@ -3693,6 +3789,14 @@ var init_sdkFeatures = __esm(() => {
3693
3789
  },
3694
3790
  codex: {
3695
3791
  codeSystemPrompt: false
3792
+ },
3793
+ polytoken: {
3794
+ codeSystemPrompt: false,
3795
+ clientSystemPrompt: true,
3796
+ claudeMd: "off",
3797
+ memory: false,
3798
+ dreaming: false,
3799
+ sharedMemory: false
3696
3800
  }
3697
3801
  };
3698
3802
  VALID_CLAUDE_MD_VALUES = new Set(["off", "project", "full"]);
@@ -23563,6 +23667,7 @@ var BILLING_SIGNALS = [
23563
23667
  /^\s*(?:(?:error|api error|claude code returned an error result):\s*)*credit balance is too low[.!]?\s*$/m,
23564
23668
  /^\s*(?:(?:error|api error|claude code returned an error result|subprocess stderr):\s*)*your (?:group|organization|org)(?:'|’)s usage limit is set to \$\d/m
23565
23669
  ];
23670
+ var SUBSCRIPTION_ACCESS_DISABLED = /^\s*(?:(?:error|api error|claude code returned an error result|subprocess stderr):\s*|failed to authenticate\.\s*)*(?:\d{3} )?your (?:organization|org) has disabled claude subscription access/m;
23566
23671
  var HIT_YOUR_LIMIT = /hit your (?:[\w-]+ )?limit/;
23567
23672
  var HIT_YOUR_SPEND_LIMIT = /^\s*(?:(?:error|api error|claude code returned an error result|subprocess stderr):\s*)*you(?:'|’)ve hit your (?:[\w'’-]+ ){0,4}(?:spend|usage) limit/m;
23568
23673
  var REACHED_YOUR_TIER_LIMIT = /^[ \t]*(?:(?:error|api error|claude code returned an error result|subprocess stderr):[ \t]*)*(?:\d{3}[ \t]+)?you(?:'|’)ve reached your (?:claude )?(?:fable|mythos|opus|sonnet|haiku)(?: \d+(?:\.\d+)*)? limit(?:(?:[.!][ \t]+|[ \t]+)(?:(?:run[ \t]+)?\/usage-credits(?:[ \t]+to[ \t]+continue)?(?:[ \t]+or[ \t]+switch[ \t]+models[ \t]+with[ \t]+\/model)?|\/model[ \t]+to[ \t]+switch[ \t]+models|switch[ \t]+to[ \t]+another[ \t]+model(?:[ \t]+to[ \t]+continue)?)\.?|[.!]?)[ \t\r]*$/m;
@@ -23591,6 +23696,13 @@ function classifyError(errMsg, model) {
23591
23696
  message: "Claude OAuth token has expired and could not be refreshed automatically. Run 'claude login' in your terminal to re-authenticate."
23592
23697
  };
23593
23698
  }
23699
+ if (SUBSCRIPTION_ACCESS_DISABLED.test(lower)) {
23700
+ return {
23701
+ status: 402,
23702
+ type: "billing_error",
23703
+ message: "This account's organization has disabled Claude subscription access for Claude Code. Ask the organization admin to re-enable it, or serve this request from an API-key profile — an identical retry on this account fails the same way."
23704
+ };
23705
+ }
23594
23706
  if (HTTP_401.test(lower) || lower.includes("authentication") || lower.includes("invalid auth") || lower.includes("credentials")) {
23595
23707
  return {
23596
23708
  status: 401,
@@ -31905,6 +32017,7 @@ var claudeCodeTransforms = [
31905
32017
  ];
31906
32018
 
31907
32019
  // src/proxy/transforms/registry.ts
32020
+ init_polytoken();
31908
32021
  var ADAPTER_TRANSFORMS = {
31909
32022
  opencode: openCodeTransforms,
31910
32023
  crush: crushTransforms,
@@ -31917,7 +32030,8 @@ var ADAPTER_TRANSFORMS = {
31917
32030
  "claude-code": claudeCodeTransforms,
31918
32031
  openai: openCodeTransforms,
31919
32032
  jcode: openCodeTransforms,
31920
- codex: [...openCodeTransforms, ...codexTransforms]
32033
+ codex: [...openCodeTransforms, ...codexTransforms],
32034
+ polytoken: polytokenTransforms
31921
32035
  };
31922
32036
  function getAdapterTransforms(adapterName) {
31923
32037
  return ADAPTER_TRANSFORMS[adapterName] ?? [];
@@ -37525,7 +37639,7 @@ data: ${JSON.stringify(lastError)}
37525
37639
  resolvedProfileId = profile.id;
37526
37640
  const authStatus = await getClaudeAuthStatusAsync(profile.id !== "default" ? profile.id : undefined, Object.keys(profile.env).length > 0 ? profile.env : undefined);
37527
37641
  const requestSource = c.req.header("x-meridian-source")?.slice(0, 64) || undefined;
37528
- const declaredAgentMode = adapter.getAgentMode?.(c, body) ?? c.req.header("x-opencode-agent-mode") ?? null;
37642
+ const declaredAgentMode = adapter.getAgentMode?.(c, body) ?? (adapter.baseName === "polytoken" || adapter.name === "polytoken" ? undefined : c.req.header("x-opencode-agent-mode")) ?? null;
37529
37643
  const isSubagentRequest = declaredAgentMode === "subagent" || requestSource?.startsWith("subagent-") === true;
37530
37644
  const agentMode = isSubagentRequest ? "subagent" : declaredAgentMode;
37531
37645
  const requestedModel = typeof body.model === "string" ? body.model : "sonnet";
@@ -37576,9 +37690,10 @@ data: ${JSON.stringify(lastError)}
37576
37690
  workingDirectory
37577
37691
  }), adapterBase);
37578
37692
  const stream3 = pipelineCtx.prefersStreaming !== undefined ? pipelineCtx.prefersStreaming : body.stream ?? false;
37579
- const effortHeader = c.req.header("x-opencode-effort");
37580
- const thinkingHeader = c.req.header("x-opencode-thinking");
37581
- const taskBudgetHeader = c.req.header("x-opencode-task-budget");
37693
+ const isPolytokenBase = adapterBase === "polytoken";
37694
+ const effortHeader = isPolytokenBase ? undefined : c.req.header("x-opencode-effort");
37695
+ const thinkingHeader = isPolytokenBase ? undefined : c.req.header("x-opencode-thinking");
37696
+ const taskBudgetHeader = isPolytokenBase ? undefined : c.req.header("x-opencode-task-budget");
37582
37697
  const rawBetaHeader = c.req.header("anthropic-beta");
37583
37698
  const betaFilter = filterBetasForProfile(rawBetaHeader, profile.type, getBetaPolicyFromEnv());
37584
37699
  if (betaFilter.stripped.length > 0) {
@@ -37733,7 +37848,7 @@ data: ${JSON.stringify(lastError)}
37733
37848
  const trailingSystemReminderOptions = adapterBase === "claude-code" ? { allowTrailingSystemReminder: true } : undefined;
37734
37849
  const durableCheckpointContinuation = durableCheckpointIds?.length && durableMappingAtTurn.status === "found" && matchesStoredLineagePrefix(durableMappingAtTurn.session, lineageMessages) ? coalesceCompleteToolResultContinuation((body.messages || []).slice(durableMappingAtTurn.session.messageCount), durableCheckpointIds, trailingSystemReminderOptions) : undefined;
37735
37850
  const advancesDurableCheckpoint = Boolean(durableCheckpointContinuation);
37736
- const passthrough = adapter.instancePassthrough !== undefined ? adapter.instancePassthrough : pipelineCtx.passthrough !== undefined ? pipelineCtx.passthrough : envBool("PASSTHROUGH");
37851
+ const passthrough = adapterBase === "polytoken" ? true : adapter.instancePassthrough !== undefined ? adapter.instancePassthrough : pipelineCtx.passthrough !== undefined ? pipelineCtx.passthrough : envBool("PASSTHROUGH");
37737
37852
  if (advancesDurableCheckpoint && lineageResult.type !== "continuation" && lineageResult.type !== "compaction" && durableMappingAtTurn.status === "found") {
37738
37853
  const checkpointSession = getSessionByClaudeId(durableMappingAtTurn.session.claudeSessionId);
37739
37854
  if (checkpointSession) {
@@ -38174,7 +38289,7 @@ data: ${JSON.stringify(lastError)}
38174
38289
  }
38175
38290
  const clientTool = requestTools.find((t) => t.name === toolName);
38176
38291
  let toolInput = normalizeToolInput(input.tool_input, clientTool?.input_schema);
38177
- if (toolName.toLowerCase() === "task" && toolInput?.subagent_type && typeof toolInput.subagent_type === "string") {
38292
+ if (adapterBase !== "polytoken" && toolName.toLowerCase() === "task" && toolInput?.subagent_type && typeof toolInput.subagent_type === "string") {
38178
38293
  toolInput = { ...toolInput, subagent_type: resolveAgentAlias(toolInput.subagent_type, validAgentNames) };
38179
38294
  }
38180
38295
  const signature = toolUseSignature(toolName, toolInput);
@@ -39086,7 +39201,7 @@ data: ${JSON.stringify({
39086
39201
  try {
39087
39202
  const clientTool = requestTools.find((tool2) => tool2.name === buffered.name);
39088
39203
  const parsed = normalizeToolInput(JSON.parse(buffered.json), clientTool?.input_schema);
39089
- if (buffered.name.toLowerCase() === "task" && typeof parsed?.subagent_type === "string") {
39204
+ if (adapterBase !== "polytoken" && buffered.name.toLowerCase() === "task" && typeof parsed?.subagent_type === "string") {
39090
39205
  parsed.subagent_type = resolveAgentAlias(parsed.subagent_type, validAgentNames);
39091
39206
  }
39092
39207
  fixed = JSON.stringify(parsed);
package/dist/cli.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  startProxyServer
4
- } from "./cli-x1sv3bqf.js";
4
+ } from "./cli-198xnjcn.js";
5
5
  import"./cli-5jxyma6z.js";
6
6
  import"./cli-sry5aqdj.js";
7
7
  import"./cli-8yp89fan.js";