openmates 0.29.0-alpha.9 → 0.31.0-alpha.1
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 +77 -1
- package/README.md +30 -14
- package/dist/{chunk-QRCAXXAL.js → chunk-2RBBM2P4.js} +39 -3
- package/dist/{chunk-IXAKWPUK.js → chunk-3VYOE57W.js} +4263 -3159
- package/dist/{chunk-67U3XD2B.js → chunk-F5GPD6LA.js} +1 -5
- package/dist/{chunk-QVCMMBD4.js → chunk-JRV7KTSJ.js} +3234 -2195
- package/dist/chunk-QMP6PIS7.js +46 -0
- package/dist/{chunk-BYYH2YTS.js → chunk-WXUEJGB6.js} +1 -1
- package/dist/cli-internal-client.d.ts +6 -0
- package/dist/cli-internal-client.js +132 -0
- package/dist/cli.d.ts +1 -1
- package/dist/cli.js +5 -5
- package/dist/{client-CCQdkE5S.d.ts → client-Cf2BFZoY.d.ts} +28 -77
- package/dist/index.d.ts +29 -15
- package/dist/index.js +16 -32
- package/dist/{privacyScan-DJCR2FTA.js → privacyScan-BX4MPHS4.js} +1 -1
- package/dist/ruleDocuments-7IWMOMA6.js +160 -0
- package/dist/sdk-entry.d.ts +62 -4
- package/dist/sdk-entry.js +85 -3
- package/dist/sdk-session-v1-entry.d.ts +1 -1
- package/dist/{sdkApiKeyRust-BW-c6ZkZ.d.ts → sdkApiKeyRust-C2glWiFL.d.ts} +1 -1
- package/dist/{sdkTaskOrder-CJPmq9yh.d.ts → sdkTaskOrder-Dvh17s4r.d.ts} +1006 -132
- package/dist/{tasksCli-V2INK4CH.js → tasksCli-PSN2EWIU.js} +1 -1
- package/fixtures/privacy-runtime/linux-arm64/libggml-base.so +0 -0
- package/fixtures/privacy-runtime/linux-arm64/libggml-base.so.0 +0 -0
- package/fixtures/privacy-runtime/linux-arm64/libggml-base.so.0.15.1 +0 -0
- package/fixtures/privacy-runtime/linux-arm64/libggml-cpu.so +0 -0
- package/fixtures/privacy-runtime/linux-arm64/libggml-cpu.so.0 +0 -0
- package/fixtures/privacy-runtime/linux-arm64/libggml-cpu.so.0.15.1 +0 -0
- package/fixtures/privacy-runtime/linux-arm64/libggml.so +0 -0
- package/fixtures/privacy-runtime/linux-arm64/libggml.so.0 +0 -0
- package/fixtures/privacy-runtime/linux-arm64/libggml.so.0.15.1 +0 -0
- package/fixtures/privacy-runtime/linux-arm64/manifest.json +9 -9
- package/package.json +4 -4
- package/templates/core/docker-compose.selfhost.yml +69 -0
- package/dist/ruleDocuments-6VMP2CV5.js +0 -91
package/CHANGELOG.md
CHANGED
|
@@ -1,7 +1,83 @@
|
|
|
1
1
|
# Changelog — `openmates` npm package (CLI and SDK)
|
|
2
2
|
|
|
3
3
|
Only SDK-relevant compatibility notes are recorded here. Release versions follow
|
|
4
|
-
the product line (`0.29.x`
|
|
4
|
+
the product line (`0.29.x` prereleases from `dev`, stable from `main`).
|
|
5
|
+
|
|
6
|
+
## Unreleased
|
|
7
|
+
|
|
8
|
+
### Breaking
|
|
9
|
+
|
|
10
|
+
- Rust SDK: `Memories::create`, `update` and `types`, `MemoryInput`,
|
|
11
|
+
`hash_item_key` and `memory_plaintext` are removed, matching npm and Python
|
|
12
|
+
(removed 2026-11-07; the backend answers 410). `IdeaBucket::save_settings` now
|
|
13
|
+
returns the same refusal as npm/Python. `sdk.memories` is implemented in all
|
|
14
|
+
three SDKs.
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
|
|
18
|
+
- `billing.downloadInvoice`, `billing.downloadCreditNote` and
|
|
19
|
+
`billing.usageExport` now declare the exported `RawDownload` type
|
|
20
|
+
(`contentType`, optional `filename`, `data: ArrayBuffer`); the runtime shape is
|
|
21
|
+
unchanged. `filename` is now always the last path component of the
|
|
22
|
+
`Content-Disposition` name, and is omitted for `.`/`..` names or a malformed
|
|
23
|
+
`filename*` encoding (previously such a header threw a `URIError`). Rust and
|
|
24
|
+
Python follow the same filename contract.
|
|
25
|
+
|
|
26
|
+
Cross-language SDK alignment (npm, Python and Rust now behave the same; each case
|
|
27
|
+
is a shared conformance vector):
|
|
28
|
+
|
|
29
|
+
- **Malformed document slugs are refused locally.** `docs.show()` and
|
|
30
|
+
`docs.download()` throw the new `OpenMatesInvalidInputError`
|
|
31
|
+
(code `OPENMATES_SDK_INVALID_INPUT`) before any request for an empty slug,
|
|
32
|
+
`..`, a leading or trailing `/`, an empty or `.` segment, `\`, `:`, NUL or other
|
|
33
|
+
control characters, or a slug over 4096 bytes. Previously these reached the
|
|
34
|
+
server. Python raises the same error class, which is a `ValueError`.
|
|
35
|
+
- **An empty Wikipedia `language` means English.** `wikipedia.search()`,
|
|
36
|
+
`summary()`, `learning()` and `article()` send `language=en` for `""`, the same
|
|
37
|
+
as an omitted language. Previously npm sent `language=` and the backend
|
|
38
|
+
rejected the request.
|
|
39
|
+
- **Draft preview fallback counts Unicode characters.** When a draft has no saved
|
|
40
|
+
preview, `drafts.get()`/`list()` use the first 160 Unicode characters of the
|
|
41
|
+
markdown instead of 160 UTF-16 code units, so the preview never ends in half an
|
|
42
|
+
emoji. A saved but empty or undecryptable `encryptedDraftPreview` now gives
|
|
43
|
+
`preview: null` instead of falling back to the markdown.
|
|
44
|
+
|
|
45
|
+
### Added (Python)
|
|
46
|
+
|
|
47
|
+
- `OpenMatesClient(api_key=...)` mirrors the npm root client: a missing or blank
|
|
48
|
+
key raises `OpenMatesApiKeyRequiredError` (code `OPENMATES_SDK_API_KEY_REQUIRED`,
|
|
49
|
+
a subclass of `OpenMatesConfigError`) at construction, it never reads
|
|
50
|
+
`OPENMATES_API_KEY`, and it refuses the legacy `session`/`load_stored_session`
|
|
51
|
+
options. `OpenMates()` is unchanged.
|
|
52
|
+
- Python `embeds.add_to_project()`/`remove_from_project()` resolve a Project
|
|
53
|
+
slug, name or id prefix before routing, as npm does.
|
|
54
|
+
|
|
55
|
+
## 0.30.0
|
|
56
|
+
|
|
57
|
+
### Breaking
|
|
58
|
+
|
|
59
|
+
- **The SDK is API-key only and separate from the CLI login.** The root
|
|
60
|
+
`OpenMatesClient` export no longer loads the stored CLI login (the 0.29.x
|
|
61
|
+
`OPENMATES_SDK_CLI_SESSION` deprecation is complete). It is now the API-key
|
|
62
|
+
client: `new OpenMatesClient({ apiKey })`. Constructing it (or calling
|
|
63
|
+
`OpenMatesClient.load()`) without an `apiKey` throws
|
|
64
|
+
`OpenMatesApiKeyRequiredError` (code `OPENMATES_SDK_API_KEY_REQUIRED`), and the
|
|
65
|
+
`session` / `loadStoredSession` options are rejected. No SDK entrypoint reads
|
|
66
|
+
CLI state files or the keychain, so an SDK script can use a different account
|
|
67
|
+
from the logged-in CLI. `SDK_CLI_SESSION_DEPRECATION_CODE` is removed.
|
|
68
|
+
|
|
69
|
+
**Migration:** create an API key in Settings → Developers and pass it
|
|
70
|
+
explicitly (`new OpenMatesClient({ apiKey })` or `new OpenMates({ apiKey })`).
|
|
71
|
+
The key decrypts your chats locally with its own wrapped account key; nothing
|
|
72
|
+
else is needed. The `openmates` command line keeps its own login and is
|
|
73
|
+
unaffected.
|
|
74
|
+
|
|
75
|
+
### Deprecated
|
|
76
|
+
|
|
77
|
+
- `SessionClient.loginPassword()` / `importSession()` in `openmates/sdk/v1`. Public
|
|
78
|
+
SDKs are API-key only; these login modes are removed once every capability they
|
|
79
|
+
offer is available through API-key authentication (open work tracked in
|
|
80
|
+
`config/sdk-capabilities.json`).
|
|
5
81
|
|
|
6
82
|
## 0.29.x
|
|
7
83
|
|
package/README.md
CHANGED
|
@@ -62,7 +62,7 @@ openmates whoami --json
|
|
|
62
62
|
The CLI displays a QR code or pair PIN. Approve it in the OpenMates web app.
|
|
63
63
|
During login, the CLI never asks for your account password.
|
|
64
64
|
|
|
65
|
-
Switch to a dev account using an isolated profile; upgrading to
|
|
65
|
+
Switch to a dev account using an isolated profile; upgrading to a prerelease
|
|
66
66
|
preserves your existing login and does not change the API server:
|
|
67
67
|
|
|
68
68
|
```bash
|
|
@@ -157,6 +157,8 @@ openmates settings --help
|
|
|
157
157
|
openmates settings account export data --json
|
|
158
158
|
openmates settings memories list --json
|
|
159
159
|
openmates learning-mode status --json
|
|
160
|
+
openmates learning-mode enable --age-group 16_18 --passcode <passcode> --no-collaborative-build
|
|
161
|
+
openmates learning-mode collaborative on --passcode <passcode>
|
|
160
162
|
openmates docs search "API keys"
|
|
161
163
|
```
|
|
162
164
|
|
|
@@ -375,23 +377,37 @@ Use `chats.send()` for anonymous AI chat with automatic routing; `apps.ai.ask()`
|
|
|
375
377
|
requires an account. With an API key, use `saveToAccount: true` when you want the
|
|
376
378
|
chat saved to the OpenMates account.
|
|
377
379
|
|
|
378
|
-
###
|
|
380
|
+
### API keys only, never the CLI login
|
|
379
381
|
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
382
|
+
The SDK authenticates only with an API key you pass explicitly (or configure via
|
|
383
|
+
`OPENMATES_API_KEY`). It is completely separate from the `openmates` command
|
|
384
|
+
line: it never reads the CLI's `~/.openmates/session.json`, its state directory
|
|
385
|
+
or the OS keychain, so a script can use a different account than the one logged
|
|
386
|
+
in to the CLI. Create an API key in Settings → Developers. Each key carries its
|
|
387
|
+
own wrapped copy of your account key, so the SDK decrypts your chats locally,
|
|
388
|
+
in memory, with only that key.
|
|
389
|
+
|
|
390
|
+
Since 0.31.0 the root `OpenMatesClient` is the API-key client and requires
|
|
391
|
+
`apiKey`; constructing it without one throws `OpenMatesApiKeyRequiredError`
|
|
392
|
+
(code `OPENMATES_SDK_API_KEY_REQUIRED`). The former `session` and
|
|
393
|
+
`loadStoredSession` options are rejected.
|
|
394
|
+
|
|
395
|
+
```typescript
|
|
396
|
+
import { OpenMatesClient } from "openmates";
|
|
397
|
+
|
|
398
|
+
const om = new OpenMatesClient({ apiKey: process.env.MY_OPENMATES_KEY! });
|
|
399
|
+
```
|
|
387
400
|
|
|
388
401
|
### Native session SDK (preview)
|
|
389
402
|
|
|
390
403
|
`openmates/sdk/v1` exports `SessionClient`, `RustApiKeyClient` and related
|
|
391
404
|
types. Every operation runs in the shared OpenMates Rust core through a native
|
|
392
405
|
Node-API module loaded from `native/<platform>-<arch>.node`; the SDK never
|
|
393
|
-
launches the CLI and never reads CLI login state.
|
|
394
|
-
|
|
406
|
+
launches the CLI and never reads CLI login state. Its password/imported-session
|
|
407
|
+
login modes (`loginPassword()`, `importSession()`) are deprecated: public SDKs
|
|
408
|
+
are API-key only, and these modes are removed once every capability they offer
|
|
409
|
+
is available through API-key authentication (tracked in
|
|
410
|
+
`config/sdk-capabilities.json`). Use an API key for new integrations. If the native
|
|
395
411
|
module for your platform is missing or incompatible, construction throws
|
|
396
412
|
`SessionClientError` with code `native_binding_unavailable` (no TypeScript
|
|
397
413
|
fallback). The SDK is moving to one portable WebAssembly build of the core
|
|
@@ -402,12 +418,12 @@ artifacts are not yet published; from a source checkout run
|
|
|
402
418
|
|
|
403
419
|
## Versioning
|
|
404
420
|
|
|
405
|
-
OpenMates shows the short product line, for example `v0.
|
|
421
|
+
OpenMates shows the short product line, for example `v0.31`, in the web app.
|
|
406
422
|
The npm package uses exact artifact versions:
|
|
407
423
|
|
|
408
|
-
- `0.
|
|
424
|
+
- `0.31.0-alpha.N` is a prerelease from the `dev` branch published under the
|
|
409
425
|
`alpha` npm tag.
|
|
410
|
-
- `0.
|
|
426
|
+
- `0.31.0` is a stable release from `main` published under the `latest` npm tag.
|
|
411
427
|
|
|
412
428
|
Install stable releases with `npm install -g openmates`. Install prereleases with
|
|
413
429
|
`npm install -g openmates@alpha`.
|
|
@@ -18,6 +18,39 @@ function codingIdentifierRanges(text) {
|
|
|
18
18
|
return ranges;
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
+
// ../secret-scanner/src/embedReferenceRanges.ts
|
|
22
|
+
var EMBED_LINK_TARGET = /\(embed:[^\s)]+\)/g;
|
|
23
|
+
var JSON_FENCE_OPEN = "```json\n";
|
|
24
|
+
var JSON_BLOCK = /```json\n([\s\S]*?)\n```/g;
|
|
25
|
+
var EMBED_ID_MEMBER = /"embed_id"\s*:\s*"(?:\\.|[^"\\])*"|"embed_ids"\s*:\s*\[(?:\s*"(?:\\.|[^"\\])*"\s*,?)*\s*\]/g;
|
|
26
|
+
function isEmbedReferenceJson(body) {
|
|
27
|
+
let parsed;
|
|
28
|
+
try {
|
|
29
|
+
parsed = JSON.parse(body.trim());
|
|
30
|
+
} catch {
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
return typeof parsed === "object" && parsed !== null && ("embed_id" in parsed || "embed_ids" in parsed);
|
|
34
|
+
}
|
|
35
|
+
function embedReferenceRanges(text) {
|
|
36
|
+
if (!text.includes("embed")) return [];
|
|
37
|
+
const ranges = [];
|
|
38
|
+
for (const match of Array.from(text.matchAll(EMBED_LINK_TARGET))) {
|
|
39
|
+
ranges.push({ start: match.index, end: match.index + match[0].length });
|
|
40
|
+
}
|
|
41
|
+
for (const match of Array.from(text.matchAll(JSON_BLOCK))) {
|
|
42
|
+
if (!isEmbedReferenceJson(match[1])) continue;
|
|
43
|
+
const bodyStart = match.index + JSON_FENCE_OPEN.length;
|
|
44
|
+
for (const member of Array.from(match[1].matchAll(EMBED_ID_MEMBER))) {
|
|
45
|
+
ranges.push({ start: bodyStart + member.index, end: bodyStart + member.index + member[0].length });
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return ranges.sort((a, b) => a.start - b.start);
|
|
49
|
+
}
|
|
50
|
+
function overlapsAnyRange(start, end, ranges) {
|
|
51
|
+
return ranges.some((range) => start < range.end && end > range.start);
|
|
52
|
+
}
|
|
53
|
+
|
|
21
54
|
// ../ui/src/components/enter_message/services/piiDetectionService.ts
|
|
22
55
|
function luhnCheck(cardNumber) {
|
|
23
56
|
const digits = cardNumber.replace(/\D/g, "");
|
|
@@ -519,6 +552,7 @@ function detectPII(text, excludedIdsOrOptions = /* @__PURE__ */ new Set()) {
|
|
|
519
552
|
});
|
|
520
553
|
}
|
|
521
554
|
const hasUrlExclusions = urlExclusionZones.length > 0;
|
|
555
|
+
const embedZones = embedReferenceRanges(text);
|
|
522
556
|
if (text.length >= MIN_PII_TEXT_LENGTH) {
|
|
523
557
|
for (const pattern of PII_PATTERNS) {
|
|
524
558
|
if (hasDisabledCategories) {
|
|
@@ -532,6 +566,7 @@ function detectPII(text, excludedIdsOrOptions = /* @__PURE__ */ new Set()) {
|
|
|
532
566
|
const startIndex = regexMatch.index;
|
|
533
567
|
const endIndex = startIndex + matchText.length;
|
|
534
568
|
if (pattern.type === "PHONE" && identifierRanges.some((range) => startIndex < range.end && endIndex > range.start)) continue;
|
|
569
|
+
if (overlapsAnyRange(startIndex, endIndex, embedZones)) continue;
|
|
535
570
|
if (hasUrlExclusions) {
|
|
536
571
|
const insideUrl = urlExclusionZones.some(
|
|
537
572
|
(zone) => startIndex >= zone.start && endIndex <= zone.end
|
|
@@ -584,7 +619,7 @@ function detectPII(text, excludedIdsOrOptions = /* @__PURE__ */ new Set()) {
|
|
|
584
619
|
const overlaps = coveredRanges.some(
|
|
585
620
|
(range) => startIndex >= range.start && startIndex < range.end || endIndex > range.start && endIndex <= range.end || startIndex <= range.start && endIndex >= range.end
|
|
586
621
|
);
|
|
587
|
-
if (!overlaps) {
|
|
622
|
+
if (!overlaps && !overlapsAnyRange(startIndex, endIndex, embedZones)) {
|
|
588
623
|
const matchText = text.substring(startIndex, endIndex);
|
|
589
624
|
const matchId = `pii-PERSONAL_DATA-${entry.id}-${startIndex}`;
|
|
590
625
|
if (!hasExclusions || !excludedIds.has(matchId)) {
|
|
@@ -732,7 +767,8 @@ var ProjectFilePrivacy = class {
|
|
|
732
767
|
const literal = text.slice(range.start, range.end);
|
|
733
768
|
if (!(this.options.preserveMappedTokens && this.values.has(literal)) && (this.values.has(literal) || GENERATED_TOKEN.test(literal) || legacyToken(literal))) ranges.push(range);
|
|
734
769
|
}
|
|
735
|
-
const
|
|
770
|
+
const shields = [...tokens, ...embedReferenceRanges(text)];
|
|
771
|
+
const overlaps = (start, end) => [...shields, ...ranges].some((r) => start < r.end && end > r.start);
|
|
736
772
|
for (const mapping of Array.from(this.values.values()).sort((a, b) => b.original.length - a.original.length)) {
|
|
737
773
|
let start = text.indexOf(mapping.original);
|
|
738
774
|
while (start !== -1) {
|
|
@@ -748,7 +784,7 @@ var ProjectFilePrivacy = class {
|
|
|
748
784
|
for (const range of enhanced) {
|
|
749
785
|
if (!Number.isInteger(range.start) || !Number.isInteger(range.end) || range.start < 0 || range.end <= range.start || range.end > text.length) fail("pii_invalid_semantic_range");
|
|
750
786
|
let fragments = [{ ...range }];
|
|
751
|
-
for (const shield of [...
|
|
787
|
+
for (const shield of [...shields, ...ranges]) fragments = fragments.flatMap((part) => {
|
|
752
788
|
if (part.start >= shield.end || part.end <= shield.start) return [part];
|
|
753
789
|
return [
|
|
754
790
|
part.start < shield.start ? { ...part, end: shield.start } : null,
|