Skip to content

tmp: CI run for history rewrite (do not merge) - #14

Closed
Goldokpa wants to merge 15 commits into
mainfrom
tmp/history-rewrite-ci
Closed

Goldokpa wants to merge 15 commits into
mainfrom
tmp/history-rewrite-ci

Conversation

@Goldokpa

@Goldokpa Goldokpa commented Oct 9, 2026

Copy link
Copy Markdown
Contributor

Temporary PR to run required checks on the rewritten main commit. Will be closed and the branch deleted.

obielin and others added 15 commits July 24, 2026 21:05
… junk

CI failed at setup-node/npm ci because package-lock.json was gitignored
and never committed; npm ci and npm's cache both require it.

- .gitignore: stop ignoring package-lock.json (CI uses npm ci); ignore
  vitest.config.ts.timestamp-*.mjs
- add @vitest/coverage-v8 devDep (test:coverage failed: missing provider)
- test:coverage now 'vitest run --coverage' (deterministic, no watch)
- remove 5 stray committed vitest timestamp files
- commit package-lock.json

Verified locally on Node 22: npm ci, lint, typecheck, test:coverage
(51 tests pass), build all green.
Aligns the TypeScript SDK with the Python package so the install
commands match across languages:

  pip install identark
  npm install identark

Previously the npm name was @identark/sdk while PyPI was identark, which
read as two unrelated products. The unscoped name was still available.

Subpath imports follow the same rename (identark/integrations/langchain,
identark/integrations/vercel); the exports map is subpath-relative so it
needed no change. Adds repository/homepage/bugs fields pointing at the
renamed identArk/identark-js repo — npm surfaces these on the package
page and they are required for build provenance.

Typecheck clean, 51/51 tests passing.
….0.1)

1.0.0 was unusable for ESM consumers. src/index.ts re-exported the
LangChain integration from the main barrel, and because ESM resolves
imports eagerly, `import { DirectGateway } from "identark"` — the first
example in the README — threw ERR_MODULE_NOT_FOUND for @langchain/core
unless the user happened to have LangChain installed. @langchain/core was
only ever a devDependency, so essentially no consumer had it.

Integrations are no longer re-exported from the barrel; they are reached
through their existing subpaths, which is what the README already
documents.

Also corrects the packaging metadata, which advertised things that were
not true:

  - exports listed .cjs files for both integration subpaths that were
    never built, so `require("identark/integrations/langchain")` failed
    outright. dist/index.cjs was a CommonJS shim that require()d ESM
    files, which only works on Node >=22.12. The package is ESM; the
    exports map now says so rather than promising a CJS build that does
    not exist. The build:cjs script is removed — it emitted CommonJS over
    the ESM output and never produced nested .cjs at all.
  - "peerDependenciesOptional" is not an npm field and was silently
    ignored, so openai and @anthropic-ai/sdk were required peers. They
    are now optional via peerDependenciesMeta, alongside @langchain/core
    (^1.0.0, matching what is actually tested). "ai" is not declared —
    the Vercel integration only appears to use it in a JSDoc example.
  - ./package.json is exported, which bundlers and tooling expect.

Verified by installing the packed tarball into a clean project with zero
peers present: the previously failing import resolves, both subpaths
load, typecheck clean, 51/51 tests passing.
Switches the release workflow off NODE_AUTH_TOKEN/secrets.NPM_TOKEN and
onto npm's OIDC trusted publishing, so nothing secret is stored in the
repo at all — no token to leak, rotate, or be caught by npm's ongoing
restrictions on 2FA-bypassing tokens.

Three changes were needed:
  - drop the NODE_AUTH_TOKEN env (auth now comes from the OIDC token)
  - upgrade npm in CI: trusted publishing needs >= 11.5.1 and the npm
    bundled with Node predates it, which would fail with ENEEDAUTH
  - move Node 20.x -> 22.x (20 reached end of life in April 2026)

id-token: write was already present. Provenance is attached automatically
when publishing this way, so the explicit --provenance flag is redundant.

Requires the matching Trusted Publisher entry on npmjs.com for the
`identark` package (repo identArk/identark-js, workflow publish.yml).
Until that is registered, tagged releases will fail at the publish step.
src/index.ts hardcoded `export const version`, and `npm version patch`
only ever rewrites package.json — so 1.0.2 shipped to npm while still
reporting version === "1.0.1" to anyone who read it. An SDK that
misreports its own version is a bad thing to hand a debugging user.

Adds scripts/sync-version.mjs, wired to npm's `version` lifecycle hook so
it runs after the bump and before the release commit, and git-adds the
result — the corrected source lands in the same commit and tag. The
script exits non-zero if the constant is ever renamed rather than
silently doing nothing.

Corrects the current value to 1.0.2.
Carries the brand mark in the repo itself rather than hotlinking the
landing site, which is now a private repository — a raw URL pointing
there would 404 for anyone reading this README on GitHub or npm.

Uses an absolute raw.githubusercontent URL because npm does not reliably
resolve relative image paths on the package page. The asset stays out of
the published tarball; it is fetched by URL, not bundled.
)

Port identark/validation.py to src/validation.ts:
- validateToolDefinitions: OpenAI function-calling schema checks,
  throws ConfigurationError on malformed tools
- validateToolResultJson: warns (console.warn) on non-JSON tool results
- validateMessageContent: string | content-block array | null

Wire validateToolDefinitions into DirectGateway invokeLlm/invokeLlmStream
(as Python's DirectGateway does) and export all three from the package
index. MockGateway is left unvalidated, matching the Python MockGateway.
ControlPlaneGateway wiring is deferred to PR #8.

Co-authored-by: Kem-Ada <283358351+Kem-Ada@users.noreply.github.com>
Brings src/pricing.ts to parity with the Python SDK's identark/pricing.py.

- Add the `ModelPricing` interface, replacing `Record<string, number>` values.
- Add the five bundled models the TS table was missing (`o1`, `o1-mini`,
  `claude-sonnet-4-20250514`, `claude-opus-4-20250514`) plus a new
  `GEMINI_PRICING` table, and compose them into `BUNDLED_PRICING`.
- Add `getPricing`, `setPricingTable` and `listKnownModels` over an active,
  override-aware pricing table.
- Support the same overrides as Python, at the same precedence:
  `IDENTARK_PRICING_URL` > `~/.identark/pricing.json` > bundled defaults.
  Node has no synchronous HTTP primitive, so the remote fetch is exposed as
  `await initPricing()`; the local-file and `setPricingTable` paths stay sync.
- Rewire `estimateCost` onto the active table so overrides reach the cost
  figures DirectGateway reports.

Two parity bugs in `estimateCost` fall out of the rewire. A model priced at
`{input: 0, output: 0}` was billed at the unknown-model fallback rate because
of a falsy check on the rates, and a model named after an `Object.prototype`
member resolved to the inherited value and produced a `NaN` cost. Python's
`dict.get` does neither.

The existing `OPENAI_PRICING` / `ANTHROPIC_PRICING` / `MISTRAL_PRICING`
exports are kept as-is for backwards compatibility.

Tests: 35 new cases in tests/pricing.test.ts covering the eight Python unit
tests in tests/unit/test_pricing.py plus negative cases for unknown models,
malformed and missing override files, failing and non-OK remote fetches,
override precedence, and zero-priced models.

Co-authored-by: Kem-Ada <283358351+Kem-Ada@users.noreply.github.com>
Co-authored-by: Gold okpa <Okpagold@gmail.com>
DirectGateway's OpenAI classifier only looked at the error class name and a
string fallback, and the Anthropic paths had no classifier at all — two
copies of an inline string check that could only ever produce
ContentPolicyError or a generic ProviderError.

Port the full detection ladder from the Python SDK's
_classify_openai_error / _classify_anthropic_error:

- class hierarchy (prototype-chain walk, the TS analogue of __mro__)
- HTTP status: 429 -> RateLimitError, 401 -> ProviderError("Authentication
  failed: ...")
- error code in (content_filter, content_policy_violation, output_blocked)
  -> ContentPolicyError; Anthropic matches on error type instead
- string fallback, unchanged

RateLimitError now carries retry_after_seconds read from the error's
retry-after header (Headers instance or plain record) or a retryAfter
property, defaulting to 60 as Python does. Anthropic errors route through a
new _classifyAnthropicError shared by the blocking and streaming paths.

Also narrows the try blocks to wrap only the provider API call, matching
Python — response parsing no longer gets laundered into a ProviderError.

Co-authored-by: Kem-Ada <283358351+Kem-Ada@users.noreply.github.com>
Co-authored-by: Gold okpa <Okpagold@gmail.com>
A sixth constructor argument, history: "client" (or IDENTARK_HISTORY_MODE=client),
keeps the conversation in the gateway and sends it in full with
store_history=false, so the control plane stores no prompts or responses.
Assistant tool calls are kept in OpenAI shape so tool loops replay. Default
stays "server". Exports the HistoryMode type.

Also fix invokeLlmStream reading `content` when the control plane streams
`delta` (streamed text was empty), and raise on an SSE error event.

Mirrors the Python SDK.

Signed-off-by: Gold Okpa <okpagold@gmail.com>
* feat(gemini): add GeminiGateway integration for Google Gemini

Port of identark/integrations/gemini.py: GeminiGateway (alias
IdentArkGeminiGateway) on the optional @google/generative-ai peer
dependency, with function calling, multimodal input, streaming, cost cap,
local file URLs and Gemini error classification. Exposed at
identark/integrations/gemini.


* fix(gemini): stop classifying every SDK error as a rate limit

The JS SDK prefixes every error with "[GoogleGenerativeAI Error]" and
includes the generativelanguage.googleapis.com URL, both of which contain
the substring "rate", so all failures became RateLimitError. Match
keywords at word starts and use the HTTP status when present.


---------

Co-authored-by: Kem-Ada <283358351+Kem-Ada@users.noreply.github.com>
@Goldokpa

Goldokpa commented Oct 9, 2026

Copy link
Copy Markdown
Contributor Author

Closing: temporary CI run for the history rewrite.

@Goldokpa Goldokpa closed this Oct 9, 2026
@Goldokpa
Goldokpa deleted the tmp/history-rewrite-ci branch October 9, 2026 11:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants