@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.
@@ -1 +1 @@
1
- {"version":3,"file":"detect.d.ts","sourceRoot":"","sources":["../../../src/proxy/adapters/detect.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AACnC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AA4C9C;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,EAAE,CAE3C;AA2DD,wBAAgB,aAAa,CAAC,CAAC,EAAE,OAAO,GAAG,YAAY,CA2FtD"}
1
+ {"version":3,"file":"detect.d.ts","sourceRoot":"","sources":["../../../src/proxy/adapters/detect.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AACnC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAkD9C;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,EAAE,CAE3C;AAqED,wBAAgB,aAAa,CAAC,CAAC,EAAE,OAAO,GAAG,YAAY,CAkHtD"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Polytoken native adapter.
3
+ *
4
+ * Polytoken sends Anthropic Messages requests with a stable
5
+ * `X-Polytoken-Session` header and executes its own tools client-side — the
6
+ * client owns the tool loop, so the proxy must ALWAYS run in passthrough mode
7
+ * and never activate OpenCode-style agent behavior (subagent parsing, fuzzy
8
+ * aliasing, Task-tool routing, file-change tracking).
9
+ *
10
+ * Identity contract:
11
+ * - Session identity comes ONLY from X-Polytoken-Session, trimmed. No
12
+ * parent identity, no agent-mode scoping, no attestation, no OpenCode
13
+ * lineage normalization. A missing/blank header means "no identity": the
14
+ * request runs fingerprint-less and independent (never resumed) rather
15
+ * than being given an invented key.
16
+ * - The header is a session key, not an authentication credential — same
17
+ * trust model as every other adapter's headers.
18
+ *
19
+ * CWD contract: a network-hosted Polytoken may run its tools and environment
20
+ * far from the proxy, and the client does not advertise a machine-readable
21
+ * working directory, so extraction returns undefined (SDK cwd falls back to
22
+ * MERIDIAN_WORKDIR/process.cwd()) and `clientEnvironmentMayDifferFromProxy`
23
+ * keeps the environment distinction explicit.
24
+ */
25
+ import type { AgentAdapter } from "../adapter";
26
+ /**
27
+ * Normalize the native session id: trim surrounding whitespace; a nonempty
28
+ * trimmed string is returned unchanged. Missing/empty/whitespace-only →
29
+ * undefined. No charset restriction, fixed fallback, profile prefix, or
30
+ * affinity-header fallback — the client's value IS the identity.
31
+ */
32
+ export declare function normalizePolytokenSessionId(value: string | undefined): string | undefined;
33
+ export declare const polytokenAdapter: AgentAdapter;
34
+ import { polytokenTransforms } from "../transforms/polytoken";
35
+ export { polytokenTransforms };
36
+ //# sourceMappingURL=polytoken.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"polytoken.d.ts","sourceRoot":"","sources":["../../../src/proxy/adapters/polytoken.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAK9C;;;;;GAKG;AACH,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAGzF;AAED,eAAO,MAAM,gBAAgB,EAAE,YA8F9B,CAAA;AAED,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAA;AAC7D,OAAO,EAAE,mBAAmB,EAAE,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/proxy/errors.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;CAChB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAc1D;AAuID,2EAA2E;AAC3E,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,GAAG,OAAO,CAEpF;AAqFD;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,eAAe,CA2K7E;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAM3D;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,aAAa,GAAG,iBAAiB,CAAA;AAEtE;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS,CAahG;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAI3E;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAGxD;AAuBD;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,SAAS,IAAI,MAAM,CAEhG;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAE5E;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAGjE;AAED;;;;;GAKG;AACH,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,WAAW,GAAG,cAAc,GAAG,SAAS,GAAG,eAAe,GAAG,kBAAkB,GAAG,SAAS,CAAA;IACnG,sDAAsD;IACtD,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,wDAAwD;IACxD,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,uEAAuE;IACvE,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,wDAAwD;IACxD,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB;;wCAEoC;IACpC,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAuBD;;;;;;GAMG;AACH;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,0BAA0B,CAAC,KAAK,EAAE;IAChD,MAAM,EAAE,cAAc,CAAC,QAAQ,CAAC,CAAA;IAChC,WAAW,EAAE,OAAO,CAAA;IACpB,gBAAgB,EAAE,MAAM,CAAA;IACxB,WAAW,EAAE,OAAO,CAAA;CACrB,GAAG,OAAO,CAYV;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,cAAc,CAiEpE;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,CAAC,EAAE,cAAc,EACjB,GAAG,EAAE;IACH,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB,GACA,MAAM,CAYR"}
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/proxy/errors.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;CAChB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAc1D;AAoKD,2EAA2E;AAC3E,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,GAAG,OAAO,CAEpF;AAqFD;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,eAAe,CA0L7E;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAM3D;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,aAAa,GAAG,iBAAiB,CAAA;AAEtE;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS,CAahG;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAI3E;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAGxD;AAuBD;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,SAAS,IAAI,MAAM,CAEhG;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAE5E;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAGjE;AAED;;;;;GAKG;AACH,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,WAAW,GAAG,cAAc,GAAG,SAAS,GAAG,eAAe,GAAG,kBAAkB,GAAG,SAAS,CAAA;IACnG,sDAAsD;IACtD,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,wDAAwD;IACxD,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,uEAAuE;IACvE,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,wDAAwD;IACxD,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB;;wCAEoC;IACpC,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAuBD;;;;;;GAMG;AACH;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,0BAA0B,CAAC,KAAK,EAAE;IAChD,MAAM,EAAE,cAAc,CAAC,QAAQ,CAAC,CAAA;IAChC,WAAW,EAAE,OAAO,CAAA;IACpB,gBAAgB,EAAE,MAAM,CAAA;IACxB,WAAW,EAAE,OAAO,CAAA;CACrB,GAAG,OAAO,CAYV;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,cAAc,CAiEpE;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,CAAC,EAAE,cAAc,EACjB,GAAG,EAAE;IACH,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB,GACA,MAAM,CAYR"}
@@ -1 +1 @@
1
- {"version":3,"file":"sdkFeatures.d.ts","sourceRoot":"","sources":["../../src/proxy/sdkFeatures.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,MAAM,WAAW,eAAe;IAC9B,iFAAiF;IACjF,gBAAgB,EAAE,OAAO,CAAA;IACzB,kFAAkF;IAClF,kBAAkB,EAAE,OAAO,CAAA;IAC3B,4DAA4D;IAC5D,QAAQ,EAAE,KAAK,GAAG,SAAS,GAAG,MAAM,CAAA;IACpC,wDAAwD;IACxD,MAAM,EAAE,OAAO,CAAA;IACf,6CAA6C;IAC7C,QAAQ,EAAE,OAAO,CAAA;IACjB,0DAA0D;IAC1D,QAAQ,EAAE,UAAU,GAAG,SAAS,GAAG,UAAU,CAAA;IAC7C,4CAA4C;IAC5C,mBAAmB,EAAE,OAAO,CAAA;IAC5B,iFAAiF;IACjF,YAAY,EAAE,OAAO,CAAA;IACrB;;;;;OAKG;IACH,iBAAiB,EAAE,OAAO,CAAA;IAC1B;;;;;;OAMG;IACH,kBAAkB,EAAE,OAAO,CAAA;IAC3B,iDAAiD;IACjD,YAAY,EAAE,MAAM,CAAA;IACpB,2DAA2D;IAC3D,aAAa,EAAE,MAAM,CAAA;IACrB,+CAA+C;IAC/C,QAAQ,EAAE,OAAO,CAAA;IACjB,uEAAuE;IACvE,qBAAqB,EAAE,MAAM,CAAA;CAC9B;AAED,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,eAAe,CAAC,CAAC,CAAA;AA6HpE;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,MAAM,GAAG,eAAe,CAU1E;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,eAAe,CAAC,UAAU,CAAC,GAAG,SAAS,CAKhG;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAOtE;AAKD;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,eAAe,CAAC,CAgC5E;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,CAAC,eAAe,CAAC,GAAG,IAAI,CAInG;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAI9D"}
1
+ {"version":3,"file":"sdkFeatures.d.ts","sourceRoot":"","sources":["../../src/proxy/sdkFeatures.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,MAAM,WAAW,eAAe;IAC9B,iFAAiF;IACjF,gBAAgB,EAAE,OAAO,CAAA;IACzB,kFAAkF;IAClF,kBAAkB,EAAE,OAAO,CAAA;IAC3B,4DAA4D;IAC5D,QAAQ,EAAE,KAAK,GAAG,SAAS,GAAG,MAAM,CAAA;IACpC,wDAAwD;IACxD,MAAM,EAAE,OAAO,CAAA;IACf,6CAA6C;IAC7C,QAAQ,EAAE,OAAO,CAAA;IACjB,0DAA0D;IAC1D,QAAQ,EAAE,UAAU,GAAG,SAAS,GAAG,UAAU,CAAA;IAC7C,4CAA4C;IAC5C,mBAAmB,EAAE,OAAO,CAAA;IAC5B,iFAAiF;IACjF,YAAY,EAAE,OAAO,CAAA;IACrB;;;;;OAKG;IACH,iBAAiB,EAAE,OAAO,CAAA;IAC1B;;;;;;OAMG;IACH,kBAAkB,EAAE,OAAO,CAAA;IAC3B,iDAAiD;IACjD,YAAY,EAAE,MAAM,CAAA;IACpB,2DAA2D;IAC3D,aAAa,EAAE,MAAM,CAAA;IACrB,+CAA+C;IAC/C,QAAQ,EAAE,OAAO,CAAA;IACjB,uEAAuE;IACvE,qBAAqB,EAAE,MAAM,CAAA;CAC9B;AAED,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,eAAe,CAAC,CAAC,CAAA;AA8IpE;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,MAAM,GAAG,eAAe,CAU1E;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,eAAe,CAAC,UAAU,CAAC,GAAG,SAAS,CAKhG;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAOtE;AAKD;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,eAAe,CAAC,CAgC5E;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,CAAC,eAAe,CAAC,GAAG,IAAI,CAInG;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAI9D"}
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/proxy/server.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AACtE,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,WAAW,EAAE,CAAA;AAGvD,YAAY,EACV,SAAS,EACT,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,cAAc,EACd,cAAc,EACd,iBAAiB,EACjB,YAAY,EACZ,aAAa,EACb,WAAW,GACZ,MAAM,aAAa,CAAA;AAKpB,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA;AA4EnG,OAAO,EACL,kBAAkB,EAElB,WAAW,EACX,oBAAoB,EAMpB,KAAK,aAAa,EAGnB,MAAM,mBAAmB,CAAA;AAI1B,OAAO,EAKL,iBAAiB,EACjB,mBAAmB,EAKpB,MAAM,iBAAiB,CAAA;AA0CxB,OAAO,EAAE,kBAAkB,EAAE,WAAW,EAAE,oBAAoB,EAAE,CAAA;AAChE,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,CAAA;AACjD,YAAY,EAAE,aAAa,EAAE,CAAA;AAsY7B,wBAAgB,iBAAiB,CAAC,MAAM,GAAE,OAAO,CAAC,WAAW,CAAM,GAAG,WAAW,CAi6OhF;AAWD,wBAAgB,gCAAgC,IAAI,IAAI,CAavD;AAED,wBAAsB,gBAAgB,CAAC,MAAM,GAAE,OAAO,CAAC,WAAW,CAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CA8NhG"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/proxy/server.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AACtE,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,WAAW,EAAE,CAAA;AAGvD,YAAY,EACV,SAAS,EACT,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,cAAc,EACd,cAAc,EACd,iBAAiB,EACjB,YAAY,EACZ,aAAa,EACb,WAAW,GACZ,MAAM,aAAa,CAAA;AAKpB,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA;AA4EnG,OAAO,EACL,kBAAkB,EAElB,WAAW,EACX,oBAAoB,EAMpB,KAAK,aAAa,EAGnB,MAAM,mBAAmB,CAAA;AAI1B,OAAO,EAKL,iBAAiB,EACjB,mBAAmB,EAKpB,MAAM,iBAAiB,CAAA;AA0CxB,OAAO,EAAE,kBAAkB,EAAE,WAAW,EAAE,oBAAoB,EAAE,CAAA;AAChE,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,CAAA;AACjD,YAAY,EAAE,aAAa,EAAE,CAAA;AAsY7B,wBAAgB,iBAAiB,CAAC,MAAM,GAAE,OAAO,CAAC,WAAW,CAAM,GAAG,WAAW,CAs8OhF;AAWD,wBAAgB,gCAAgC,IAAI,IAAI,CAavD;AAED,wBAAsB,gBAAgB,CAAC,MAAM,GAAE,OAAO,CAAC,WAAW,CAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CA8NhG"}
@@ -0,0 +1,18 @@
1
+ import type { Transform } from "../transform";
2
+ /**
3
+ * Polytoken native transforms.
4
+ *
5
+ * Scoped to adapter base `polytoken` ONLY — deliberately not spread onto
6
+ * openai/jcode/codex, whose tool configs differ. The client owns the tool
7
+ * loop, so this is pure passthrough plumbing:
8
+ * - passthrough forced true (mandatory client-owned tool execution);
9
+ * - signed/redacted thinking preserved (supportsThinking true);
10
+ * - body/system/tools and the client's stream preference preserved;
11
+ * - empty SDK agents/hooks — no Task/task parsing, no fuzzy aliases;
12
+ * - no file-change tracking or core-tool rewriting;
13
+ * - empty blocked/incompatible/allowed MCP lists and coreToolNames: the
14
+ * generated client-passthrough MCP names are the only allowed tools, and
15
+ * an OpenCode-style allowlist would collide with client tool names.
16
+ */
17
+ export declare const polytokenTransforms: Transform[];
18
+ //# sourceMappingURL=polytoken.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"polytoken.d.ts","sourceRoot":"","sources":["../../../src/proxy/transforms/polytoken.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAkB,MAAM,cAAc,CAAA;AAE7D;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,mBAAmB,EAAE,SAAS,EAqB1C,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../src/proxy/transforms/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AAyC7C,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,SAAS,EAAE,CAE9E"}
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../src/proxy/transforms/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AA8C7C,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,SAAS,EAAE,CAE9E"}
package/dist/server.js CHANGED
@@ -11,7 +11,7 @@ import {
11
11
  runObserveHook,
12
12
  runTransformHook,
13
13
  startProxyServer
14
- } from "./cli-x1sv3bqf.js";
14
+ } from "./cli-198xnjcn.js";
15
15
  import"./cli-5jxyma6z.js";
16
16
  import"./cli-sry5aqdj.js";
17
17
  import"./cli-8yp89fan.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rynfar/meridian",
3
- "version": "1.69.0",
3
+ "version": "1.70.0",
4
4
  "description": "Local Anthropic API powered by your Claude Max subscription. One subscription, every agent.",
5
5
  "type": "module",
6
6
  "main": "./dist/server.js",
@@ -16,6 +16,8 @@
16
16
  */
17
17
 
18
18
  import * as Plugin from "@opencode-ai/plugin/promise/plugin"
19
+ import { Model } from "@opencode-ai/schema/model"
20
+ import type { CatalogDraft } from "@opencode-ai/plugin/promise/catalog"
19
21
  import {
20
22
  PRIORITY_ATTESTATION_HEADER,
21
23
  createPriorityAttestation,
@@ -29,8 +31,18 @@ import {
29
31
  export const SUPPORTED_OPENCODE_V2_VERSION = "0.0.0-beta-18314"
30
32
 
31
33
  const MERIDIAN_PROVIDERS = new Set(["anthropic", "meridian"])
34
+ const MERIDIAN_CATALOG_PROVIDER = "meridian"
32
35
  const PARENT_SESSION_ONE_SHOTS = new Set(["title", "summary"])
33
36
  const ATTACHED_COMPACTION_AGENT = "compaction"
37
+ const MODEL_DISCOVERY_TIMEOUT_MS = 3_000
38
+ const PROVIDER_READY_POLL_MS = 25
39
+ // The plugin tree does not import from src/, so this mirrors VALID_EFFORTS in
40
+ // src/proxy/effort.ts. A test asserts the two stay identical. Filtering in this
41
+ // order also gives every model its variants low -> max regardless of the order
42
+ // the proxy happens to serialise its capability object in.
43
+ const MERIDIAN_EFFORTS = ["low", "medium", "high", "xhigh", "max"] as const
44
+
45
+ export const MERIDIAN_V2_EFFORTS: readonly string[] = MERIDIAN_EFFORTS
34
46
 
35
47
  const SESSION_AFFINITY_HEADERS = [
36
48
  "x-opencode-session",
@@ -131,6 +143,186 @@ function isRecord(value: unknown): value is Record<string, unknown> {
131
143
  return typeof value === "object" && value !== null && !Array.isArray(value)
132
144
  }
133
145
 
146
+ export interface MeridianModel {
147
+ id: string
148
+ name: string
149
+ contextWindow: number
150
+ efforts: string[]
151
+ }
152
+
153
+ export interface MeridianProviderModels {
154
+ providerID: string
155
+ models: MeridianModel[]
156
+ }
157
+
158
+ type MeridianCatalogClient = {
159
+ provider: {
160
+ get(input: { providerID: string }): Promise<unknown>
161
+ }
162
+ reload(): Promise<void>
163
+ }
164
+
165
+ type ModelFetcher = (input: string | URL | Request, init?: RequestInit) => Promise<Response>
166
+
167
+ export function meridianModelsURL(baseURL: unknown): string | undefined {
168
+ if (typeof baseURL !== "string" || baseURL.length === 0) return undefined
169
+ try {
170
+ const url = new URL(baseURL)
171
+ if (url.protocol !== "http:" && url.protocol !== "https:") return undefined
172
+ url.search = ""
173
+ url.hash = ""
174
+ if (!url.pathname.endsWith("/")) url.pathname += "/"
175
+ // OpenCode's Anthropic provider carries the API version in the base URL
176
+ // (`http://127.0.0.1:3456/v1`), which is also the shape the V2 package gate
177
+ // configures. Appending `v1/models` there requests `/v1/v1/models`, a 404
178
+ // that silently disables discovery, so resolve `models` against an existing
179
+ // version segment instead.
180
+ const endpoint = /(?:^|\/)v1\/$/.test(url.pathname) ? "models" : "v1/models"
181
+ return new URL(endpoint, url).toString()
182
+ } catch {
183
+ return undefined
184
+ }
185
+ }
186
+
187
+ export function parseMeridianModels(value: unknown): MeridianModel[] | undefined {
188
+ if (!isRecord(value) || !Array.isArray(value.data)) return undefined
189
+
190
+ const models: MeridianModel[] = []
191
+ const ids = new Set<string>()
192
+ for (const item of value.data) {
193
+ if (!isRecord(item)) return undefined
194
+ const id = item.id
195
+ const name = item.display_name
196
+ const contextWindow = item.context_window
197
+ if (
198
+ typeof id !== "string"
199
+ || id.length === 0
200
+ || id.length > 256
201
+ || /[^\x21-\x7E]/.test(id)
202
+ || ids.has(id)
203
+ || typeof name !== "string"
204
+ || name.trim().length === 0
205
+ || name.length > 256
206
+ || typeof contextWindow !== "number"
207
+ || !Number.isSafeInteger(contextWindow)
208
+ || contextWindow <= 0
209
+ ) {
210
+ return undefined
211
+ }
212
+ const capabilities = isRecord(item.capabilities) ? item.capabilities : undefined
213
+ const effort = capabilities && isRecord(capabilities.effort) ? capabilities.effort : undefined
214
+ const efforts = MERIDIAN_EFFORTS.filter((level) => isRecord(effort?.[level]) && effort[level].supported === true)
215
+ ids.add(id)
216
+ models.push({ id, name, contextWindow, efforts })
217
+ }
218
+ return models
219
+ }
220
+
221
+ export async function fetchMeridianModels(
222
+ baseURL: unknown,
223
+ signal: AbortSignal,
224
+ fetcher: ModelFetcher = globalThis.fetch,
225
+ ): Promise<MeridianModel[] | undefined> {
226
+ const url = meridianModelsURL(baseURL)
227
+ if (!url || signal.aborted) return undefined
228
+
229
+ const controller = new AbortController()
230
+ const abort = () => controller.abort()
231
+ const timeout = setTimeout(abort, MODEL_DISCOVERY_TIMEOUT_MS)
232
+ timeout.unref?.()
233
+ signal.addEventListener("abort", abort, { once: true })
234
+ try {
235
+ const response = await fetcher(url, { signal: controller.signal })
236
+ if (!response.ok) return undefined
237
+ return parseMeridianModels(await response.json())
238
+ } catch {
239
+ return undefined
240
+ } finally {
241
+ clearTimeout(timeout)
242
+ signal.removeEventListener("abort", abort)
243
+ }
244
+ }
245
+
246
+ function meridianProviderBaseURL(value: unknown): unknown {
247
+ if (!isRecord(value)) return undefined
248
+ const provider = isRecord(value.data) ? value.data : value
249
+ if (!isRecord(provider.settings)) return undefined
250
+ return provider.settings.baseURL
251
+ }
252
+
253
+ function isLegacyMeridianBaseURL(baseURL: unknown): boolean {
254
+ if (typeof baseURL !== "string") return false
255
+ try {
256
+ const { hostname } = new URL(baseURL)
257
+ return hostname === "localhost" || hostname === "127.0.0.1" || hostname === "[::1]"
258
+ } catch {
259
+ return false
260
+ }
261
+ }
262
+
263
+ export async function loadMeridianModels(
264
+ catalog: MeridianCatalogClient,
265
+ signal: AbortSignal,
266
+ fetcher: ModelFetcher = globalThis.fetch,
267
+ ): Promise<MeridianProviderModels[]> {
268
+ const deadline = Date.now() + MODEL_DISCOVERY_TIMEOUT_MS
269
+ while (!signal.aborted) {
270
+ const providers = await Promise.all([...MERIDIAN_PROVIDERS].map(async (providerID) => {
271
+ try {
272
+ const baseURL = meridianProviderBaseURL(await catalog.provider.get({ providerID }))
273
+ if (providerID === MERIDIAN_CATALOG_PROVIDER && meridianModelsURL(baseURL) === undefined) return undefined
274
+ if (providerID !== MERIDIAN_CATALOG_PROVIDER && !isLegacyMeridianBaseURL(baseURL)) return undefined
275
+ return { providerID, baseURL }
276
+ } catch {
277
+ return undefined
278
+ }
279
+ }))
280
+ const configured = providers.flatMap(provider => provider ? [provider] : [])
281
+ if (configured.length > 0) {
282
+ const discovered = await Promise.all(configured.map(async ({ providerID, baseURL }) => {
283
+ const models = await fetchMeridianModels(baseURL, signal, fetcher)
284
+ return models ? { providerID, models } : undefined
285
+ }))
286
+ return discovered.flatMap(result => result ? [result] : [])
287
+ }
288
+ if (Date.now() >= deadline) return []
289
+ await new Promise<void>((resolve) => setTimeout(resolve, PROVIDER_READY_POLL_MS))
290
+ }
291
+ return []
292
+ }
293
+
294
+ /**
295
+ * Write Meridian's advertised models over the assembled V2 catalog.
296
+ *
297
+ * Meridian is authoritative for what it will actually serve: the context window
298
+ * follows the signed-in subscription (Sonnet stays 200k so a 1M turn is not
299
+ * billed as Extra Usage), and the effort levels are the ones the proxy accepts.
300
+ * OpenCode's built-in models.dev entries disagree — beta-18866 advertises a 1M
301
+ * Sonnet — so an entry that already exists must be corrected, not skipped.
302
+ *
303
+ * This does not overwrite user configuration. V2 layers `providers.<id>.models`
304
+ * on top of plugin transforms, verified live on beta-18866: a configured
305
+ * `claude-opus-5` override survived a transform that wrote a different name and
306
+ * context to the same model.
307
+ */
308
+ export function applyMeridianModels(
309
+ catalog: CatalogDraft,
310
+ providerID: string,
311
+ models: readonly MeridianModel[],
312
+ ): void {
313
+ for (const model of models) {
314
+ catalog.model.update(providerID, model.id, (entry) => {
315
+ entry.name = model.name
316
+ entry.limit.context = model.contextWindow
317
+ entry.variants = model.efforts.map((effort) => ({
318
+ id: Model.VariantID.make(effort),
319
+ headers: {},
320
+ body: { effort },
321
+ }))
322
+ })
323
+ }
324
+ }
325
+
134
326
  async function withTimeout<T>(pending: Promise<T>, timeoutMs: number): Promise<T | undefined> {
135
327
  let timer: ReturnType<typeof setTimeout> | undefined
136
328
  const timedOut = new Promise<undefined>((resolve) => {
@@ -196,6 +388,33 @@ const MeridianV2Plugin = Plugin.define({
196
388
  pending: Promise<ResolvedAgentMetadata>
197
389
  }>()
198
390
  const registered: Array<{ dispose: () => Promise<void> }> = []
391
+ const modelDiscoveryController = new AbortController()
392
+ let discoveredModels: MeridianProviderModels[] = []
393
+ let discoveryStarted = false
394
+
395
+ registered.push(await context.catalog.transform((catalog) => {
396
+ for (const discovered of discoveredModels) {
397
+ applyMeridianModels(catalog, discovered.providerID, discovered.models)
398
+ }
399
+ }))
400
+
401
+ const discoverModels = async () => {
402
+ if (discoveryStarted || modelDiscoveryController.signal.aborted) return false
403
+ const models = await loadMeridianModels(context.catalog, modelDiscoveryController.signal).catch(() => [])
404
+ if (models.length === 0 || modelDiscoveryController.signal.aborted) return false
405
+ discoveryStarted = true
406
+ discoveredModels = models
407
+ await context.catalog.reload()
408
+ return true
409
+ }
410
+
411
+ const catalogEvents = context.event.subscribe({ signal: modelDiscoveryController.signal })
412
+ void (async () => {
413
+ for await (const event of catalogEvents) {
414
+ if (event.type !== "catalog.updated") continue
415
+ if (await discoverModels()) return
416
+ }
417
+ })().catch(() => {})
199
418
 
200
419
  const resolveAgentTraits = (agent: string, refresh = false): Promise<ResolvedAgentMetadata> => {
201
420
  const cached = traitsByAgent.get(agent)
@@ -320,11 +539,15 @@ const MeridianV2Plugin = Plugin.define({
320
539
  }, { providerID }))
321
540
  }
322
541
  } catch (error) {
542
+ // Setup never returns its cleanup on this path, so the discovery
543
+ // subscription and its poll loop would otherwise outlive the failure.
544
+ modelDiscoveryController.abort()
323
545
  await Promise.allSettled(registered.map(({ dispose }) => dispose()))
324
546
  throw error
325
547
  }
326
548
 
327
549
  return async () => {
550
+ modelDiscoveryController.abort()
328
551
  const results = await Promise.allSettled(registered.map(({ dispose }) => dispose()))
329
552
  const failures = results.flatMap(result => result.status === "rejected" ? [result.reason] : [])
330
553
  if (failures.length > 0) throw new AggregateError(failures, "Failed to dispose Meridian V2 hooks")