@arnilo/prism 0.1.1 → 0.1.2

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/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.1.2] - 2026-08-10
4
+
5
+ ### Changed
6
+ - **Release 0.1.2 (plan 014)** is the Alibaba Cloud provider enrichment patch on the frozen 0.1.x line, additive-only vs 0.1.1 (freeze manifest `scripts/phase14-freeze-manifest.json`): (1) **embeddings** — `createAlibabaEmbedder` in `@arnilo/prism-provider-alibaba` over the OpenAI-compatible `POST {base}/embeddings` (text-embedding-v3/v4), a structural `Embedder` assignable to `@arnilo/prism-memory`'s without a dependency; inputs chunked at the DashScope cap (10/request), vectors in input order, dimensions 64–2048 (default 1024) + `encoding_format` passthrough, key resolved per call and redacted from errors; (2) **video input** — `file` blocks with `video/*` media types serialize to compatible-mode `video_url` content parts on Qwen-VL models, gated on the `file` input capability (`mapAlibabaModel` advertises `["text", "image", "file"]` for the qwen-vl family); (3) **documented deferrals** — document input (compatible path is the OpenAI Files API `file-extract` + `fileid://` reference, an upload/status lifecycle) and rerank (only workspace-dedicated `compatible-api/v1/reranks` exists, not on the public presets) are recorded in the verified decision table in [docs/providers/alibaba.md](docs/providers/alibaba.md) as demand-gated follow-ups; (4) **opt-in live probe** — `PRISM_LIVE_DASHSCOPE_KEY`-gated `test:live` script (skips when absent, never in CI). Store compatibility with 0.1.1: **compatible, no migration**; declaration surface additive-only vs the frozen 0.1.x contract.
7
+
3
8
  ## [0.1.1] - 2026-08-10
4
9
 
5
10
  ### Changed
package/dist/index.d.ts CHANGED
@@ -105,5 +105,5 @@ export { createToolParameterValidator, createToolRegistry, dispatchToolCall, fil
105
105
  export type { ResolvedUseCaseModel, ResolveUseCaseModelInput, UseCaseModelBinding, } from "./use-case-model.js";
106
106
  export { resolveUseCaseModel, resolveUseCaseModelBinding, useCaseCredentialProviderId, } from "./use-case-model.js";
107
107
  export declare const name = "prism";
108
- export declare const version = "0.1.1";
108
+ export declare const version = "0.1.2";
109
109
  export declare const description = "Agent harness for AI providers, agents, sessions, and tools.";
package/dist/index.js CHANGED
@@ -57,6 +57,6 @@ export { DEFAULT_TOOL_RESULT_FOLD_MAX_SUMMARY_BYTES, DEFAULT_TOOL_RESULT_FOLD_MI
57
57
  export { createToolParameterValidator, createToolRegistry, dispatchToolCall, filterTools } from "./tools.js";
58
58
  export { resolveUseCaseModel, resolveUseCaseModelBinding, useCaseCredentialProviderId, } from "./use-case-model.js";
59
59
  export const name = "prism";
60
- export const version = "0.1.1";
60
+ export const version = "0.1.2";
61
61
  export const description = "Agent harness for AI providers, agents, sessions, and tools.";
62
62
  //# sourceMappingURL=index.js.map
package/docs/index.md CHANGED
@@ -129,7 +129,7 @@ Prism is a TypeScript/Node.js agent harness. Host apps and extension packages ow
129
129
  - [Ponytail behavior integration](ponytail.md): optional `@arnilo/prism-ponytail` — upstream Ponytail skills/commands, `ponytail-mode` injector, session `ponytail-mode` persistence; resolves peer `@dietrichgebert/ponytail` or `upstreamPath`; opt-in (not in code/sdk profiles).
130
130
 
131
131
  ## Release and install
132
- - [Release and install](release-and-install.md): current **0.1.1** 49-package graph (root + 48 workspace packages; plan 013 post-release hardening on the frozen 0.1.x line — build single-flight, MCP SSE relay test, combined coverage summary, canonical manifest-count narrative, ACP modes/config persistence guidance; Phase 12 release-candidate hardening; plan 012 — freeze manifest, compatibility matrix, upgrade matrix, packed-install e2e journeys, restart-recovery evidence, capacity envelopes, security policy), exact-peer/install/tarball rules, deterministic resumable publication and publish dry-run, frozen 0.1.x compatibility and support matrix (Node/PostgreSQL/platform/provider/protocol pins and unsupported combinations, machine-checked against `scripts/phase12-freeze-manifest.json`), protected PostgreSQL gate, pinned supply-chain gates, offline tests, the 0.0.15 provider/AI-SDK/RAG/memory protected live-canary matrix, and sandbox-browser Docker/Playwright gates.
132
+ - [Release and install](release-and-install.md): current **0.1.2** 49-package graph (root + 48 workspace packages; plan 014 Alibaba provider enrichment on the frozen 0.1.x line — embeddings, video input, verified compatible-mode surface decision table; plan 013 post-release hardening — build single-flight, MCP SSE relay test, combined coverage summary, canonical manifest-count narrative, ACP modes/config persistence guidance; Phase 12 release-candidate hardening; plan 012 — freeze manifest, compatibility matrix, upgrade matrix, packed-install e2e journeys, restart-recovery evidence, capacity envelopes, security policy), exact-peer/install/tarball rules, deterministic resumable publication and publish dry-run, frozen 0.1.x compatibility and support matrix (Node/PostgreSQL/platform/provider/protocol pins and unsupported combinations, machine-checked against `scripts/phase12-freeze-manifest.json`), protected PostgreSQL gate, pinned supply-chain gates, offline tests, the 0.0.15 provider/AI-SDK/RAG/memory protected live-canary matrix, and sandbox-browser Docker/Playwright gates.
133
133
  - [0.1.0 / 1.0 readiness gates](0.1.0-readiness.md): command-per-gate 1.0 readiness table — frozen API surface + compat gate, migration/docs tripwires, budget table, live-suite matrix, security matrix, current-line status (**0.0.23** published target), signed-publication/live-canary prerequisites for 1.0, and Phase 12 demand-evidence entry criteria.
134
134
  - [Review coverage (2026-07-26 Phase 11)](review-coverage-2026-07-26-phase-11.md): Plan 079 evidence freeze — baseline size/startup/benchmark budgets, hotspot domain extraction table, confirmed duplication survivors (redactor/cleanJson/row-codecs/checkpoints/exec-runner/approval/ownership), profile adoption recommendations, and tarball artifact-diet findings for 0.0.16.
135
135
  - [Review coverage (2026-07-26 Phase 10)](review-coverage-2026-07-26-phase-10.md): Plan 078 evidence freeze — OpenAI hosted tools/continuation/realtime, AI SDK version matrix, remaining provider metadata parity, RAG replaceSource/loaders/parsers/reranker/provenance/ingestion-status, memory export/rebuild/conformance, and 0.0.15 (43 → 43 manifests; no new package) release gates.
@@ -29,12 +29,38 @@ serialization, dynamic model discovery, and explicit/implicit cache accounting.
29
29
  Do not use it for automatic credential discovery, setup-time catalog fetches, or
30
30
  real-network tests (live tests stay opt-in).
31
31
 
32
+ ## Compatible-mode surface (verified 2026-08-10)
33
+
34
+ Decision record for which DashScope / Model Studio surfaces are reachable through
35
+ OpenAI-compatible endpoints on the package's public presets. Sources retrieved
36
+ 2026-08-10; links in the table. This table is the authority for what the package
37
+ implements vs defers (plan 014 Task 1).
38
+
39
+ | Surface | OpenAI-compatible? | Verified route | Decision |
40
+ | --- | --- | --- | --- |
41
+ | Embeddings | Yes | `POST {base}/embeddings` on all public presets (intl/beijing/us); `text-embedding-v3`/`v4`; dimensions 64–2048 (default 1024); max 10 inputs per request, 8,192 tokens each | Implemented in 0.1.2 (`createAlibabaEmbedder`) |
42
+ | Video input | Yes | Chat content part `{"type":"video_url","video_url":{"url":…},"fps":2}` on Qwen-VL models; URL must be publicly reachable with correct `Content-Length`/`Content-Type`; `fps` 0.1–10 (default 2) | Implemented in 0.1.2 (video `file` blocks → `video_url`) |
43
+ | Document input | Partial | OpenAI Files API `POST {base}/files` (`purpose: "file-extract"`, ≤150 MB) then reference `fileid://<id>` as a system message (qwen-long, ≤100 files); no document content part exists in compatible mode; `doc_url` parts are native-only (qwen-doc-turbo) | Deferred — upload + status lifecycle, not a serialization mapping; demand-gated follow-up |
44
+ | Rerank | Partial | `POST {workspaceId}.{region}.maas.aliyuncs.com/compatible-api/v1/reranks` (`qwen3-rerank`, ≤500 documents, 4,000 tokens/item) — workspace-dedicated only, base path `compatible-api/v1` (not `compatible-mode/v1`); no rerank route on the public presets | Deferred — no route on public presets; workspace-dedicated route recorded for a future `baseUrl`-supplied reranker |
45
+ | Text-to-SQL | n/a | No dedicated endpoint; SQL generation is a chat prompt use case on `chat/completions` | Nothing to implement — covered by the existing chat provider |
46
+ | Async task polling | No | `X-DashScope-Async: enable` + `GET /api/v1/tasks/{id}` — native-only | Deferred (documented) |
47
+
48
+ Sources:
49
+
50
+ - OpenAI compatibility overview: <https://help.aliyun.com/en/model-studio/compatibility-of-openai-with-dashscope>
51
+ - Embeddings (models, dimensions): <https://www.alibabacloud.com/help/en/model-studio/models>; batch limits: <https://docs.qwencloud.com/resources/faq-embedding-reranking>
52
+ - Video input (`video_url` part): <https://help.aliyun.com/en/model-studio/qwen-api-via-openai-chat-completions>
53
+ - Document input (file-extract): <https://help.aliyun.com/en/model-studio/long-context-qwen-long> and <https://help.aliyun.com/en/model-studio/openai-file-interface>; native `doc_url`: <https://help.aliyun.com/en/model-studio/data-mining-qwen-doc>
54
+ - Rerank (`compatible-api/v1/reranks`): <https://www.alibabacloud.com/help/en/model-studio/rerank>
55
+ - Async task polling (native): <https://help.aliyun.com/en/model-studio/asynchronous-call-api-reference>
56
+
32
57
  ## Inputs / request
33
58
 
34
59
  ```ts
35
60
  import {
36
61
  createAlibabaProviderPackage,
37
62
  createAlibabaProvider,
63
+ createAlibabaEmbedder,
38
64
  listAlibabaModels,
39
65
  defineAlibabaModel,
40
66
  alibabaBaseUrl,
@@ -42,6 +68,7 @@ import {
42
68
 
43
69
  createAlibabaProviderPackage(options: AlibabaProviderPackageOptions): ProviderPackage
44
70
  createAlibabaProvider(options?: AlibabaProviderOptions): AIProvider
71
+ createAlibabaEmbedder(options: AlibabaEmbedderOptions): AlibabaEmbedder
45
72
  listAlibabaModels(options?: ListAlibabaModelsOptions): Promise<ModelConfig[]>
46
73
  defineAlibabaModel(config: AlibabaModelConfig): ModelConfig
47
74
  alibabaBaseUrl(options?: { baseUrl?: string; preset?: AlibabaBasePreset }): string
@@ -69,6 +96,70 @@ Workspace-dedicated endpoints
69
96
  (`https://{workspaceId}.{region}.maas.aliyuncs.com/compatible-mode/v1`) are supplied
70
97
  verbatim via `baseUrl`.
71
98
 
99
+ ## Embeddings
100
+
101
+ `createAlibabaEmbedder()` calls the OpenAI-compatible `POST {base}/embeddings`
102
+ (text-embedding-v3/v4) and returns a structural `Embedder` — assignable to
103
+ `@arnilo/prism-memory`'s `Embedder` without importing it (the package stays
104
+ dependency-free).
105
+
106
+ ```ts
107
+ import { createAlibabaEmbedder } from "@arnilo/prism-provider-alibaba";
108
+
109
+ const embedder = createAlibabaEmbedder({
110
+ apiKey: process.env.DASHSCOPE_API_KEY,
111
+ model: "text-embedding-v4",
112
+ dimensions: 1024, // 64–2048, default 1024
113
+ });
114
+
115
+ const vectors = await embedder.embed(["hello", "world"]); // number[2][1024]
116
+ ```
117
+
118
+ - Inputs are chunked at `ALIBABA_EMBEDDING_BATCH_SIZE` (10) per request — the
119
+ DashScope cap (8,192 tokens per text) — and vectors are returned in input order.
120
+ Empty input returns `[]` without a fetch.
121
+ - `dimensions` (64–2048, default 1024) and `encoding_format` (default `float`)
122
+ pass through on the wire; `baseUrl`/`preset`/`fetch`/`headers` mirror the
123
+ provider options.
124
+ - Caller-gated like discovery: construction never fetches; the key is resolved per
125
+ call and redacted from all thrown errors; provider-owned headers
126
+ (`authorization`, `content-type`) cannot be overridden by caller headers.
127
+
128
+ ## Multimodal input
129
+
130
+ Video input (0.1.2): a `file` content block with a `video/*` media type serializes
131
+ to the compatible-mode `video_url` content part on Qwen-VL models:
132
+
133
+ ```ts
134
+ // host side
135
+ { type: "file", mediaType: "video/mp4", url: "https://example.com/clip.mp4" }
136
+ // wire shape emitted by serializeAlibabaMessage
137
+ { "type": "video_url", "video_url": { "url": "https://example.com/clip.mp4" } }
138
+ ```
139
+
140
+ - Gated on the `file` input capability (no core `"video"` capability in 0.1.2);
141
+ `mapAlibabaModel()` advertises `["text", "image", "file"]` for the qwen-vl
142
+ family; `defineAlibabaModel` capability overrides still win.
143
+ - `url` (publicly reachable, correct `Content-Length`/`Content-Type`) or base64
144
+ `data:` URL pass through; `resourceUri`-only blocks throw before fetch (the
145
+ provider never fetches). `fps` defaults upstream to 2.0.
146
+ - Document input is **deferred**: compatible-mode chat has no document content
147
+ part — the compatible path is the OpenAI Files API (`purpose: file-extract`,
148
+ ≤150 MB) plus a `fileid://<id>` system-message reference (qwen-long, ≤100
149
+ files), an upload/status lifecycle outside serialization. `document` and
150
+ non-video `file` blocks keep failing before fetch.
151
+
152
+ ## Rerank (deferred)
153
+
154
+ No OpenAI-compatible rerank route exists on the public presets, so 0.1.2 ships no
155
+ reranker. The verified compatible route is workspace-dedicated only:
156
+ `POST {workspaceId}.{region}.maas.aliyuncs.com/compatible-api/v1/reranks`
157
+ (`qwen3-rerank`, ≤500 documents, 4,000 tokens/item; base path `compatible-api/v1`,
158
+ not `compatible-mode/v1`). A future `createAlibabaReranker` over that route is
159
+ demand-gated: implement when a caller supplies a workspace-dedicated `baseUrl` and
160
+ needs rerank (structural `Reranker` shape from `@arnilo/prism-rag`, no new
161
+ dependency). Multimodal rerank (`qwen3-vl-rerank`) is native-only and stays out.
162
+
72
163
  ## Outputs / response / events
73
164
 
74
165
  | Surface | Behavior |
@@ -163,6 +254,10 @@ await kernel.load([
163
254
  - The API key is resolved per request via `resolveCredentialValue` and sent only as
164
255
  `Authorization: Bearer`; keys are redacted from all thrown errors (including
165
256
  discovery failures). No local filesystem paths enter request payloads.
257
+ - Opt-in live probe (never part of `npm test`/CI):
258
+ `PRISM_LIVE_DASHSCOPE_KEY=… npm run test:live --workspace @arnilo/prism-provider-alibaba`
259
+ exercises an embeddings round-trip against the real endpoint (model override via
260
+ `PRISM_LIVE_DASHSCOPE_MODEL`); absent env = documented skip, never a failure.
166
261
  - Caller-supplied `ProviderRequest.options.headers` can add non-owned headers, but
167
262
  provider-owned headers (`content-type`, `authorization`) are applied last and
168
263
  cannot be overridden.
@@ -241,6 +241,38 @@ git push origin v0.1.1 # tag push triggers release.yml publish job (prove
241
241
 
242
242
  **Rollback notes.** `release:publish --version 0.1.1 --resume --report release-artifacts/publish-report.json` resumes an interrupted publication and skips only registry versions whose internal dependency fingerprint matches the local manifest. A failed package aborts the run with its status written to the report; re-run after fixing the cause. npm cannot unpublish the `0.1.1` line after 72 hours — a post-publication defect ships as a `0.1.x` patch (additive-only compat promise, `release:gate` enforced), or as a documented break in the next line with a `docs/migration.md` entry. `0.1.1` is store-compatible with `0.1.0` in **both directions** (no migration ran — same checksum-protected contract), so an operator may defer or roll back the patch without a database rollback.
243
243
 
244
+ ### 0.1.2 publish handoff (plan 014 Task 6)
245
+
246
+ **Decision: GO when the operator prerequisites below are recorded.** Release **0.1.2** (plan 014) is the Alibaba Cloud provider enrichment patch on the frozen 0.1.x line: `createAlibabaEmbedder` over the OpenAI-compatible `POST {base}/embeddings` (structural `Embedder`, no new dependency), video input via `video_url` content parts on Qwen-VL models (gated on the `file` input capability), a verified compatible-mode surface decision table in [providers/alibaba.md](providers/alibaba.md) (document input and rerank deferred as demand-gated follow-ups), and an opt-in `PRISM_LIVE_DASHSCOPE_KEY` live probe. Publishable graph stays **49** manifests (root + 48 workspace) at exact **0.1.2**. Store compatibility with 0.1.1: **compatible, no migration**; declaration surface additive-only vs the frozen 0.1.x contract (`scripts/compat-baseline` regenerated at 0.1.2 with zero breaking deltas).
247
+
248
+ ```bash
249
+ # Operator prerequisites (each a named blocked gate — none may be skipped):
250
+ # 1. protected live-canary matrix green (live-canaries.yml, canary-report.json retained)
251
+ # 2. PostgreSQL + keychain protected suites green (test:postgres, keychain suite)
252
+ # 3. CodeQL SAST green on the release commit (security.yml / release.yml codeql-release)
253
+ # 4. npm OIDC trusted publishing identity authenticated (NPM_TOKEN with id-token, provenance)
254
+
255
+ git diff --check
256
+ npm ci
257
+ npm run sdk:ready # includes typecheck, lint, format, full test, coverage, pack, release:gate
258
+ npm run security:threat-suites
259
+ PRISM_TEST_POSTGRES_URL="$DATABASE_URL" npm run test:postgres # Phase 7 + Phase 12 restart-recovery
260
+ npm audit --audit-level=moderate
261
+ npm run release:check -- --version 0.1.2 --report /tmp/prism-0.1.2-preflight.json
262
+ npm run release:publish -- --version 0.1.2 --dry-run --allow-dirty --allow-untagged --report /tmp/prism-0.1.2-dry-run.json
263
+ # run the dry-run twice and diff the reports: deterministic, byte-identical
264
+
265
+ # Sign the release on the clean tagged tree (operator GPG key):
266
+ git tag -s v0.1.2 -m "Prism 0.1.2"
267
+ git verify-tag v0.1.2
268
+ git push origin v0.1.2 # tag push triggers release.yml publish job (provenance, attestations)
269
+
270
+ # Real publication never bypasses the gates: release.mjs refuses
271
+ # --allow-dirty/--allow-untagged without --dry-run.
272
+ ```
273
+
274
+ **Rollback notes.** `release:publish --version 0.1.2 --resume --report release-artifacts/publish-report.json` resumes an interrupted publication and skips only registry versions whose internal dependency fingerprint matches the local manifest. A failed package aborts the run with its status written to the report; re-run after fixing the cause. npm cannot unpublish the `0.1.2` line after 72 hours — a post-publication defect ships as a `0.1.x` patch (additive-only compat promise, `release:gate` enforced), or as a documented break in the next line with a `docs/migration.md` entry. `0.1.2` is store-compatible with `0.1.1` in **both directions** (no migration ran — same checksum-protected contract), so an operator may defer or roll back the patch without a database rollback.
275
+
244
276
  ### 0.0.28 publish handoff (historical)
245
277
 
246
278
  **Decision: GO after protected operator prerequisites below.** Release **0.0.28** (Phase 11, plan 011) ships the optional enterprise adapter seams: OIDC/JWKS identity verification (`@arnilo/prism-credentials-node/oidc`), OPA policy evaluation into the durable ledger (`@arnilo/prism-policy/opa`), MCP OAuth client/server support (`@arnilo/prism-mcp`), host-selected OpenAPI operations as effect-gated tools (`@arnilo/prism-openapi-tools`), and an S3-compatible artifact body store behind the new core body contract (`@arnilo/prism-server/artifact-bodies`). Every seam is opt-in and fail-closed; hosts that wire none keep exact prior behavior. Publishable graph stays **49** publishable manifests (root + 48 workspace packages; `prism-openapi-tools` joined the graph in this release). See [migration](migration.md) `0.0.27 → 0.0.28`.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arnilo/prism",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "Agent harness for AI providers, agents, sessions, and tools.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -141,7 +141,7 @@
141
141
  "clean": "rm -rf dist packages/*/dist",
142
142
  "build": "npm run build:core && npm run build --workspaces --if-present",
143
143
  "typecheck": "npm run build && npm run typecheck --workspaces --if-present && tsc -p examples --noEmit",
144
- "test": "npm run build && node --test dist/__tests__/*.test.js && node --test scripts/release-gate.test.mjs scripts/tooling-gate.test.mjs scripts/budget-gate.test.mjs scripts/phase8-conformance.test.mjs scripts/phase9-conformance.test.mjs scripts/phase10-conformance.test.mjs scripts/phase11-conformance.test.mjs scripts/phase11-freeze.test.mjs scripts/phase12-freeze.test.mjs scripts/phase13-freeze.test.mjs scripts/benchmark-0.1.0.test.mjs scripts/e2e-enterprise-journey.test.mjs scripts/e2e-coding-journey.test.mjs && npm run test --workspaces --if-present",
144
+ "test": "npm run build && node --test dist/__tests__/*.test.js && node --test scripts/release-gate.test.mjs scripts/tooling-gate.test.mjs scripts/budget-gate.test.mjs scripts/phase8-conformance.test.mjs scripts/phase9-conformance.test.mjs scripts/phase10-conformance.test.mjs scripts/phase11-conformance.test.mjs scripts/phase11-freeze.test.mjs scripts/phase12-freeze.test.mjs scripts/phase13-freeze.test.mjs scripts/phase14-freeze.test.mjs scripts/benchmark-0.1.0.test.mjs scripts/e2e-enterprise-journey.test.mjs scripts/e2e-coding-journey.test.mjs && npm run test --workspaces --if-present",
145
145
  "test:coverage": "node --test --experimental-test-coverage --test-coverage-lines=60 --test-coverage-functions=70 --test-coverage-branches=75 --test-coverage-exclude='**/__tests__/**' --test-coverage-exclude='**/node_modules/**' --test-coverage-exclude='**/scripts/**' --test-coverage-exclude='**/packages/**' --test-coverage-exclude='**/examples/**' dist/__tests__/*.test.js && node scripts/coverage-summary.mjs",
146
146
  "coverage:summary": "node scripts/coverage-summary.mjs",
147
147
  "lint": "biome lint .",