@securecoms/agent-bridge 0.31.0 → 0.32.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 +43 -0
- package/dist/bin.js +29 -28
- package/dist/index.js +29 -28
- package/dist/service/runtime-config-dir.d.ts +8 -2
- package/dist/version.d.ts +1 -1
- package/dist/voice/persona.d.ts +4 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -767,6 +767,38 @@ including its key). Each proxied call is metered server-side
|
|
|
767
767
|
`fast_voice_tokens_in`, `fast_voice_tokens_out`), capped at
|
|
768
768
|
`VOICE_FAST_CALLS_PER_MINUTE` (default 60) per agent.
|
|
769
769
|
|
|
770
|
+
### Calling your own provider directly (`route: "direct"`)
|
|
771
|
+
|
|
772
|
+
To keep the fast-path call off the SecureComs proxy entirely, add
|
|
773
|
+
`"route": "direct"` to the credential file's `fast_path` block:
|
|
774
|
+
|
|
775
|
+
```json
|
|
776
|
+
"fast_path": { "enabled": true, "route": "direct", "base_url": "https://api.openai.com/v1",
|
|
777
|
+
"model": "gpt-4o-mini", "api_key_env": "SECURECOMS_VOICE_LLM_KEY" }
|
|
778
|
+
```
|
|
779
|
+
|
|
780
|
+
- With `route: "direct"` the daemon calls `base_url` with the file's own
|
|
781
|
+
`api_key`/`api_key_env`, and never calls `POST /api/v1/voice/fast-complete`,
|
|
782
|
+
even when the settings fetch succeeds. The backend voice settings (persona,
|
|
783
|
+
dials, voice, pace) still apply; only the fast-path provider and key come from
|
|
784
|
+
the file. A later `voice_settings_changed` refetch keeps the direct route.
|
|
785
|
+
- Opt-in lives only in this file. There is no web or backend setting for it,
|
|
786
|
+
and only the exact value `"direct"` counts: a block without `route` (or with
|
|
787
|
+
any other value) behaves as described above, so an old `fast_path` block does
|
|
788
|
+
not switch to direct on upgrade.
|
|
789
|
+
- If the direct provider fails (timeout, HTTP error, bad response), nothing is
|
|
790
|
+
spoken by the fast path and your full agent answers the turn. The daemon never
|
|
791
|
+
retries through the SecureComs proxy.
|
|
792
|
+
- `route: "direct"` without a resolvable key is a configuration error: the
|
|
793
|
+
daemon logs `voice.fast_path_direct_no_key` once at start and runs with no
|
|
794
|
+
fast path (full agent only). It does not fall back to the proxy.
|
|
795
|
+
- The prompt sent to your provider is the same call-scoped prompt the proxy
|
|
796
|
+
would get: the call's own spoken turns only, no typed chat, notes or memory.
|
|
797
|
+
The `x-securecoms-bridge-caps` header is never sent to your provider.
|
|
798
|
+
- Call summaries use the same client: with `route: "direct"` they are also
|
|
799
|
+
generated by your provider, never the SecureComs proxy. With no usable key,
|
|
800
|
+
call summaries are unavailable (as is the fast path).
|
|
801
|
+
|
|
770
802
|
---
|
|
771
803
|
|
|
772
804
|
## Unified memory (0.29.0)
|
|
@@ -931,6 +963,17 @@ copied after the owner's next typed message.
|
|
|
931
963
|
|
|
932
964
|
---
|
|
933
965
|
|
|
966
|
+
## Release notes: 0.32.0
|
|
967
|
+
|
|
968
|
+
<!-- [COPY, approved by Eric 2026-10-20 ("Notes ok")] -->
|
|
969
|
+
|
|
970
|
+
- Privacy: the agent no longer sends its memory file, persona file text or old memory text to the SecureComs server. It sends only the persona file names and sizes. The server already removed the text it had stored.
|
|
971
|
+
- Optional: an agent's quick spoken replies on calls can go straight from the agent's machine to the owner's own model provider, using a key in the agent's credential file (`voice.fast_path.route: "direct"`). It is off unless you turn it on; with it on, call summaries also use your provider, and without a usable key they are not available.
|
|
972
|
+
|
|
973
|
+
Upgrade: `npm install -g @securecoms/agent-bridge@0.32.0`, then restart the agent.
|
|
974
|
+
|
|
975
|
+
---
|
|
976
|
+
|
|
934
977
|
## Release notes: 0.31.0
|
|
935
978
|
|
|
936
979
|
<!-- [COPY, approved by Eric 2026-10-18 (voice-scope release notes)] -->
|
package/dist/bin.js
CHANGED
|
@@ -7765,6 +7765,8 @@ var schema = z2.object({
|
|
|
7765
7765
|
model: z2.string().min(1),
|
|
7766
7766
|
api_key: z2.string().min(1).optional(),
|
|
7767
7767
|
api_key_env: z2.string().min(1).optional(),
|
|
7768
|
+
// E.2: only the exact string "direct" opts in; any other value is ignored (today's proxy behavior), never an error.
|
|
7769
|
+
route: z2.unknown().optional(),
|
|
7768
7770
|
timeout_ms: z2.number().int().min(500).max(1e4).default(2500),
|
|
7769
7771
|
max_tokens: z2.number().int().min(16).max(400).default(80)
|
|
7770
7772
|
})
|
|
@@ -7789,7 +7791,8 @@ function parseVoiceConfig(raw, env) {
|
|
|
7789
7791
|
model: v.fast_path.model,
|
|
7790
7792
|
apiKey,
|
|
7791
7793
|
timeoutMs: v.fast_path.timeout_ms,
|
|
7792
|
-
maxTokens: v.fast_path.max_tokens
|
|
7794
|
+
maxTokens: v.fast_path.max_tokens,
|
|
7795
|
+
...v.fast_path.route === "direct" ? { route: "direct" } : {}
|
|
7793
7796
|
}
|
|
7794
7797
|
};
|
|
7795
7798
|
}
|
|
@@ -34662,6 +34665,7 @@ function lineHash(line) {
|
|
|
34662
34665
|
return createHash5("sha256").update(line.trim(), "utf8").digest("hex");
|
|
34663
34666
|
}
|
|
34664
34667
|
var LOCAL_REPORT_FILE = "local-config.json";
|
|
34668
|
+
var LOCAL_PERSONA_FILE_NAMES = ["IDENTITY.md", "SOUL.md", "AGENTS.md"];
|
|
34665
34669
|
var SECRET_PATH_COUNT_MAX = 1e4;
|
|
34666
34670
|
var isCount = (v) => typeof v === "number" && Number.isSafeInteger(v) && v >= 0 && v <= SECRET_PATH_COUNT_MAX;
|
|
34667
34671
|
function parseSecretPathsReport(raw) {
|
|
@@ -34743,18 +34747,23 @@ function readLocalReport(home, identityId) {
|
|
|
34743
34747
|
const hasSearchKey = doc.has_search_key === true;
|
|
34744
34748
|
const hasLlmKey = doc.has_llm_key === true;
|
|
34745
34749
|
const raw = doc.persona;
|
|
34746
|
-
const persona = raw && typeof raw === "object" && !Array.isArray(raw) ?
|
|
34747
|
-
|
|
34748
|
-
)
|
|
34750
|
+
const persona = raw && typeof raw === "object" && !Array.isArray(raw) ? raw : {};
|
|
34751
|
+
const personaFiles = [];
|
|
34752
|
+
for (const name of LOCAL_PERSONA_FILE_NAMES) {
|
|
34753
|
+
const text = persona[name];
|
|
34754
|
+
if (typeof text === "string" && text.trim() !== "") {
|
|
34755
|
+
personaFiles.push({ name, bytes: Buffer.byteLength(text, "utf8") });
|
|
34756
|
+
}
|
|
34757
|
+
}
|
|
34749
34758
|
const capRaw = doc.owner_dm_search_cap_effective;
|
|
34750
34759
|
const ownerDmCap = typeof capRaw === "number" && Number.isInteger(capRaw) && capRaw >= 0 && capRaw <= OWNER_DM_SEARCH_DAILY_CAP_MAX ? capRaw : void 0;
|
|
34751
34760
|
return {
|
|
34752
|
-
|
|
34761
|
+
local_persona_files: personaFiles,
|
|
34753
34762
|
has_search_key: hasSearchKey,
|
|
34754
34763
|
has_llm_key: hasLlmKey,
|
|
34755
34764
|
has_extract_provider: doc.has_extract_provider === true,
|
|
34756
34765
|
...ownerDmCap !== void 0 ? { owner_dm_search_cap_effective: ownerDmCap } : {},
|
|
34757
|
-
legacy_memory: localLegacySources(doc).map(({ path: _path, ...source }) => source),
|
|
34766
|
+
legacy_memory: localLegacySources(doc).map(({ path: _path, content: _content, ...source }) => source),
|
|
34758
34767
|
secret_paths: parseSecretPathsReport(doc.secret_paths)
|
|
34759
34768
|
};
|
|
34760
34769
|
}
|
|
@@ -34839,16 +34848,6 @@ async function applyLegacyMemoryFactDecisions(home, identityId, rawDecisions, re
|
|
|
34839
34848
|
}
|
|
34840
34849
|
return { sourcesDeleted, factsAssigned };
|
|
34841
34850
|
}
|
|
34842
|
-
function readManagedMemory(home, identityId) {
|
|
34843
|
-
const p = join18(runtimeConfigDir(home, identityId), MEMORY_FILE);
|
|
34844
|
-
if (!existsSync4(p)) return null;
|
|
34845
|
-
try {
|
|
34846
|
-
const body = readFileSync10(p, "utf8").trim();
|
|
34847
|
-
return body || null;
|
|
34848
|
-
} catch {
|
|
34849
|
-
return null;
|
|
34850
|
-
}
|
|
34851
|
-
}
|
|
34852
34851
|
function pruneManagedMemory(home, identityId, hashes, deps = REAL_FS) {
|
|
34853
34852
|
const dir = runtimeConfigDir(home, identityId);
|
|
34854
34853
|
const path = join18(dir, MEMORY_FILE);
|
|
@@ -36057,6 +36056,9 @@ var BridgeAgent = class _BridgeAgent {
|
|
|
36057
36056
|
this.injectedFastLlm = !!deps.fastLlm;
|
|
36058
36057
|
this.fileVoiceConfig = cfg.voice;
|
|
36059
36058
|
this.fastLlm = deps.fastLlm ?? (cfg.voice?.fastPath.enabled ? new FastLlmClient(cfg.voice.fastPath, this.fetchImpl) : void 0);
|
|
36059
|
+
if (this.fileVoiceConfig?.fastPath.route === "direct" && !this.fileVoiceConfig.fastPath.apiKey) {
|
|
36060
|
+
writeServiceLog("warn", "voice.fast_path_direct_no_key");
|
|
36061
|
+
}
|
|
36060
36062
|
this.voiceSettingsSource = cfg.voice ? "file" : "none";
|
|
36061
36063
|
this.latency = deps.latency ?? new LatencyRecorder();
|
|
36062
36064
|
this.voiceCoalesceWindowMs = Math.max(0, deps.voiceCoalesceWindowMs ?? voiceCoalesceWindowFromEnv());
|
|
@@ -36856,6 +36858,7 @@ var BridgeAgent = class _BridgeAgent {
|
|
|
36856
36858
|
const s = parseVoiceSettings(await res.json());
|
|
36857
36859
|
if (s.identityDisplayName) this.lastOwnDisplayName = s.identityDisplayName;
|
|
36858
36860
|
const proxy = settingsToVoiceConfig(s, { baseUrl: this.cfg.apiBase, apiKey: this.cfg.apiKey });
|
|
36861
|
+
const direct = this.fileVoiceConfig?.fastPath.route === "direct" ? this.fileVoiceConfig.fastPath : void 0;
|
|
36859
36862
|
if (s.version === 0 && this.fileVoiceConfig) {
|
|
36860
36863
|
const merged = {
|
|
36861
36864
|
...s,
|
|
@@ -36864,16 +36867,16 @@ var BridgeAgent = class _BridgeAgent {
|
|
|
36864
36867
|
quirks: this.fileVoiceConfig.persona.quirks
|
|
36865
36868
|
};
|
|
36866
36869
|
this.voiceSettings = merged;
|
|
36867
|
-
this.cfg.voice = { persona: this.fileVoiceConfig.persona, fastPath: proxy.fastPath, settings: merged };
|
|
36870
|
+
this.cfg.voice = { persona: this.fileVoiceConfig.persona, fastPath: direct ?? proxy.fastPath, settings: merged };
|
|
36868
36871
|
this.voiceSettingsVersion = 0;
|
|
36869
36872
|
this.voiceSettingsSource = "file";
|
|
36870
36873
|
} else {
|
|
36871
36874
|
this.voiceSettings = s;
|
|
36872
|
-
this.cfg.voice = proxy;
|
|
36875
|
+
this.cfg.voice = direct ? { ...proxy, fastPath: direct } : proxy;
|
|
36873
36876
|
this.voiceSettingsVersion = s.version;
|
|
36874
36877
|
this.voiceSettingsSource = "backend";
|
|
36875
36878
|
}
|
|
36876
|
-
if (!this.injectedFastLlm) {
|
|
36879
|
+
if (!this.injectedFastLlm && !direct) {
|
|
36877
36880
|
this.fastLlm = new FastLlmClient(this.cfg.voice.fastPath, this.fetchImpl);
|
|
36878
36881
|
}
|
|
36879
36882
|
writeServiceLog("info", "voice.settings_loaded", {
|
|
@@ -37102,12 +37105,10 @@ var BridgeAgent = class _BridgeAgent {
|
|
|
37102
37105
|
const report = {
|
|
37103
37106
|
applied_version: version,
|
|
37104
37107
|
paths: checkConfiguredPaths(skillsJson),
|
|
37105
|
-
//
|
|
37106
|
-
//
|
|
37107
|
-
|
|
37108
|
-
|
|
37109
|
-
// interpret any of it.
|
|
37110
|
-
local_persona: local?.persona ?? null,
|
|
37108
|
+
// F-0 (G-5): the report carries no content. No MEMORY.md text, no persona text, no legacy
|
|
37109
|
+
// text. E13 needs only to know which of the runtime's own persona files hold something, so
|
|
37110
|
+
// this is [{name, bytes}] for each non-blank file and nothing else.
|
|
37111
|
+
local_persona_files: local?.local_persona_files ?? [],
|
|
37111
37112
|
// Only the runtime knows whether a search key file is configured — it
|
|
37112
37113
|
// is an environment value on that process, invisible to the daemon and
|
|
37113
37114
|
// to the backend. The backend needs it to generate a truthful tool
|
|
@@ -37140,9 +37141,9 @@ var BridgeAgent = class _BridgeAgent {
|
|
|
37140
37141
|
...this.reportedClearGeneration(),
|
|
37141
37142
|
// 7b spec §9.2 (Task 19): capability versus state. Read-only: the report never starts the embedder.
|
|
37142
37143
|
...this.reportedRecall(),
|
|
37143
|
-
// Inert legacy files only. `readLocalReport` revalidates the current
|
|
37144
|
-
// regular-file bytes and strips every local path before this
|
|
37145
|
-
// machine.
|
|
37144
|
+
// Inert legacy files only, metadata only. `readLocalReport` revalidates the current
|
|
37145
|
+
// regular-file bytes and strips every local path and every `content` before this
|
|
37146
|
+
// leaves the machine.
|
|
37146
37147
|
legacy_memory: local?.legacy_memory ?? [],
|
|
37147
37148
|
// §B.4: counts of server-named secret paths inside / allowlisted /
|
|
37148
37149
|
// outside the secrets directory, and the runtime's mode. Numbers and
|
package/dist/index.js
CHANGED
|
@@ -33659,6 +33659,8 @@ var schema = z2.object({
|
|
|
33659
33659
|
model: z2.string().min(1),
|
|
33660
33660
|
api_key: z2.string().min(1).optional(),
|
|
33661
33661
|
api_key_env: z2.string().min(1).optional(),
|
|
33662
|
+
// E.2: only the exact string "direct" opts in; any other value is ignored (today's proxy behavior), never an error.
|
|
33663
|
+
route: z2.unknown().optional(),
|
|
33662
33664
|
timeout_ms: z2.number().int().min(500).max(1e4).default(2500),
|
|
33663
33665
|
max_tokens: z2.number().int().min(16).max(400).default(80)
|
|
33664
33666
|
})
|
|
@@ -33683,7 +33685,8 @@ function parseVoiceConfig(raw, env) {
|
|
|
33683
33685
|
model: v.fast_path.model,
|
|
33684
33686
|
apiKey,
|
|
33685
33687
|
timeoutMs: v.fast_path.timeout_ms,
|
|
33686
|
-
maxTokens: v.fast_path.max_tokens
|
|
33688
|
+
maxTokens: v.fast_path.max_tokens,
|
|
33689
|
+
...v.fast_path.route === "direct" ? { route: "direct" } : {}
|
|
33687
33690
|
}
|
|
33688
33691
|
};
|
|
33689
33692
|
}
|
|
@@ -34297,6 +34300,7 @@ function lineHash(line) {
|
|
|
34297
34300
|
return createHash5("sha256").update(line.trim(), "utf8").digest("hex");
|
|
34298
34301
|
}
|
|
34299
34302
|
var LOCAL_REPORT_FILE = "local-config.json";
|
|
34303
|
+
var LOCAL_PERSONA_FILE_NAMES = ["IDENTITY.md", "SOUL.md", "AGENTS.md"];
|
|
34300
34304
|
var SECRET_PATH_COUNT_MAX = 1e4;
|
|
34301
34305
|
var isCount = (v) => typeof v === "number" && Number.isSafeInteger(v) && v >= 0 && v <= SECRET_PATH_COUNT_MAX;
|
|
34302
34306
|
function parseSecretPathsReport(raw) {
|
|
@@ -34378,18 +34382,23 @@ function readLocalReport(home, identityId) {
|
|
|
34378
34382
|
const hasSearchKey = doc.has_search_key === true;
|
|
34379
34383
|
const hasLlmKey = doc.has_llm_key === true;
|
|
34380
34384
|
const raw = doc.persona;
|
|
34381
|
-
const persona = raw && typeof raw === "object" && !Array.isArray(raw) ?
|
|
34382
|
-
|
|
34383
|
-
)
|
|
34385
|
+
const persona = raw && typeof raw === "object" && !Array.isArray(raw) ? raw : {};
|
|
34386
|
+
const personaFiles = [];
|
|
34387
|
+
for (const name of LOCAL_PERSONA_FILE_NAMES) {
|
|
34388
|
+
const text = persona[name];
|
|
34389
|
+
if (typeof text === "string" && text.trim() !== "") {
|
|
34390
|
+
personaFiles.push({ name, bytes: Buffer.byteLength(text, "utf8") });
|
|
34391
|
+
}
|
|
34392
|
+
}
|
|
34384
34393
|
const capRaw = doc.owner_dm_search_cap_effective;
|
|
34385
34394
|
const ownerDmCap = typeof capRaw === "number" && Number.isInteger(capRaw) && capRaw >= 0 && capRaw <= OWNER_DM_SEARCH_DAILY_CAP_MAX ? capRaw : void 0;
|
|
34386
34395
|
return {
|
|
34387
|
-
|
|
34396
|
+
local_persona_files: personaFiles,
|
|
34388
34397
|
has_search_key: hasSearchKey,
|
|
34389
34398
|
has_llm_key: hasLlmKey,
|
|
34390
34399
|
has_extract_provider: doc.has_extract_provider === true,
|
|
34391
34400
|
...ownerDmCap !== void 0 ? { owner_dm_search_cap_effective: ownerDmCap } : {},
|
|
34392
|
-
legacy_memory: localLegacySources(doc).map(({ path: _path, ...source }) => source),
|
|
34401
|
+
legacy_memory: localLegacySources(doc).map(({ path: _path, content: _content, ...source }) => source),
|
|
34393
34402
|
secret_paths: parseSecretPathsReport(doc.secret_paths)
|
|
34394
34403
|
};
|
|
34395
34404
|
}
|
|
@@ -34474,16 +34483,6 @@ async function applyLegacyMemoryFactDecisions(home, identityId, rawDecisions, re
|
|
|
34474
34483
|
}
|
|
34475
34484
|
return { sourcesDeleted, factsAssigned };
|
|
34476
34485
|
}
|
|
34477
|
-
function readManagedMemory(home, identityId) {
|
|
34478
|
-
const p = join15(runtimeConfigDir(home, identityId), MEMORY_FILE);
|
|
34479
|
-
if (!existsSync4(p)) return null;
|
|
34480
|
-
try {
|
|
34481
|
-
const body = readFileSync8(p, "utf8").trim();
|
|
34482
|
-
return body || null;
|
|
34483
|
-
} catch {
|
|
34484
|
-
return null;
|
|
34485
|
-
}
|
|
34486
|
-
}
|
|
34487
34486
|
function pruneManagedMemory(home, identityId, hashes, deps = REAL_FS) {
|
|
34488
34487
|
const dir = runtimeConfigDir(home, identityId);
|
|
34489
34488
|
const path = join15(dir, MEMORY_FILE);
|
|
@@ -35773,6 +35772,9 @@ var BridgeAgent = class _BridgeAgent {
|
|
|
35773
35772
|
this.injectedFastLlm = !!deps.fastLlm;
|
|
35774
35773
|
this.fileVoiceConfig = cfg.voice;
|
|
35775
35774
|
this.fastLlm = deps.fastLlm ?? (cfg.voice?.fastPath.enabled ? new FastLlmClient(cfg.voice.fastPath, this.fetchImpl) : void 0);
|
|
35775
|
+
if (this.fileVoiceConfig?.fastPath.route === "direct" && !this.fileVoiceConfig.fastPath.apiKey) {
|
|
35776
|
+
writeServiceLog2("warn", "voice.fast_path_direct_no_key");
|
|
35777
|
+
}
|
|
35776
35778
|
this.voiceSettingsSource = cfg.voice ? "file" : "none";
|
|
35777
35779
|
this.latency = deps.latency ?? new LatencyRecorder();
|
|
35778
35780
|
this.voiceCoalesceWindowMs = Math.max(0, deps.voiceCoalesceWindowMs ?? voiceCoalesceWindowFromEnv());
|
|
@@ -36572,6 +36574,7 @@ var BridgeAgent = class _BridgeAgent {
|
|
|
36572
36574
|
const s = parseVoiceSettings(await res.json());
|
|
36573
36575
|
if (s.identityDisplayName) this.lastOwnDisplayName = s.identityDisplayName;
|
|
36574
36576
|
const proxy = settingsToVoiceConfig(s, { baseUrl: this.cfg.apiBase, apiKey: this.cfg.apiKey });
|
|
36577
|
+
const direct = this.fileVoiceConfig?.fastPath.route === "direct" ? this.fileVoiceConfig.fastPath : void 0;
|
|
36575
36578
|
if (s.version === 0 && this.fileVoiceConfig) {
|
|
36576
36579
|
const merged = {
|
|
36577
36580
|
...s,
|
|
@@ -36580,16 +36583,16 @@ var BridgeAgent = class _BridgeAgent {
|
|
|
36580
36583
|
quirks: this.fileVoiceConfig.persona.quirks
|
|
36581
36584
|
};
|
|
36582
36585
|
this.voiceSettings = merged;
|
|
36583
|
-
this.cfg.voice = { persona: this.fileVoiceConfig.persona, fastPath: proxy.fastPath, settings: merged };
|
|
36586
|
+
this.cfg.voice = { persona: this.fileVoiceConfig.persona, fastPath: direct ?? proxy.fastPath, settings: merged };
|
|
36584
36587
|
this.voiceSettingsVersion = 0;
|
|
36585
36588
|
this.voiceSettingsSource = "file";
|
|
36586
36589
|
} else {
|
|
36587
36590
|
this.voiceSettings = s;
|
|
36588
|
-
this.cfg.voice = proxy;
|
|
36591
|
+
this.cfg.voice = direct ? { ...proxy, fastPath: direct } : proxy;
|
|
36589
36592
|
this.voiceSettingsVersion = s.version;
|
|
36590
36593
|
this.voiceSettingsSource = "backend";
|
|
36591
36594
|
}
|
|
36592
|
-
if (!this.injectedFastLlm) {
|
|
36595
|
+
if (!this.injectedFastLlm && !direct) {
|
|
36593
36596
|
this.fastLlm = new FastLlmClient(this.cfg.voice.fastPath, this.fetchImpl);
|
|
36594
36597
|
}
|
|
36595
36598
|
writeServiceLog2("info", "voice.settings_loaded", {
|
|
@@ -36818,12 +36821,10 @@ var BridgeAgent = class _BridgeAgent {
|
|
|
36818
36821
|
const report = {
|
|
36819
36822
|
applied_version: version,
|
|
36820
36823
|
paths: checkConfiguredPaths(skillsJson),
|
|
36821
|
-
//
|
|
36822
|
-
//
|
|
36823
|
-
|
|
36824
|
-
|
|
36825
|
-
// interpret any of it.
|
|
36826
|
-
local_persona: local?.persona ?? null,
|
|
36824
|
+
// F-0 (G-5): the report carries no content. No MEMORY.md text, no persona text, no legacy
|
|
36825
|
+
// text. E13 needs only to know which of the runtime's own persona files hold something, so
|
|
36826
|
+
// this is [{name, bytes}] for each non-blank file and nothing else.
|
|
36827
|
+
local_persona_files: local?.local_persona_files ?? [],
|
|
36827
36828
|
// Only the runtime knows whether a search key file is configured — it
|
|
36828
36829
|
// is an environment value on that process, invisible to the daemon and
|
|
36829
36830
|
// to the backend. The backend needs it to generate a truthful tool
|
|
@@ -36856,9 +36857,9 @@ var BridgeAgent = class _BridgeAgent {
|
|
|
36856
36857
|
...this.reportedClearGeneration(),
|
|
36857
36858
|
// 7b spec §9.2 (Task 19): capability versus state. Read-only: the report never starts the embedder.
|
|
36858
36859
|
...this.reportedRecall(),
|
|
36859
|
-
// Inert legacy files only. `readLocalReport` revalidates the current
|
|
36860
|
-
// regular-file bytes and strips every local path before this
|
|
36861
|
-
// machine.
|
|
36860
|
+
// Inert legacy files only, metadata only. `readLocalReport` revalidates the current
|
|
36861
|
+
// regular-file bytes and strips every local path and every `content` before this
|
|
36862
|
+
// leaves the machine.
|
|
36862
36863
|
legacy_memory: local?.legacy_memory ?? [],
|
|
36863
36864
|
// §B.4: counts of server-named secret paths inside / allowlisted /
|
|
36864
36865
|
// outside the secrets directory, and the runtime's mode. Numbers and
|
|
@@ -46,7 +46,8 @@ export declare const LOCAL_REPORT_FILE = "local-config.json";
|
|
|
46
46
|
* and it never affects which file the runtime actually reads.
|
|
47
47
|
*/
|
|
48
48
|
export interface LocalReport {
|
|
49
|
-
|
|
49
|
+
/** F-0 (spec D-3): name and UTF-8 size of each non-blank persona file. The text never leaves readLocalReport. */
|
|
50
|
+
local_persona_files: LocalPersonaFileReport[];
|
|
50
51
|
has_search_key: boolean;
|
|
51
52
|
has_llm_key: boolean;
|
|
52
53
|
/** L-2 (spec §7.9): a readable key for an extract-capable provider. Only a real true counts; absent is false. */
|
|
@@ -64,6 +65,11 @@ export interface LocalReport {
|
|
|
64
65
|
* so no path (the owner's `allowed_secret_paths` sits in the same file) can
|
|
65
66
|
* ride along to the backend.
|
|
66
67
|
*/
|
|
68
|
+
export declare const LOCAL_PERSONA_FILE_NAMES: readonly ["IDENTITY.md", "SOUL.md", "AGENTS.md"];
|
|
69
|
+
export interface LocalPersonaFileReport {
|
|
70
|
+
name: (typeof LOCAL_PERSONA_FILE_NAMES)[number];
|
|
71
|
+
bytes: number;
|
|
72
|
+
}
|
|
67
73
|
export interface SecretPathsReport {
|
|
68
74
|
mode: "report" | "enforce";
|
|
69
75
|
inside: number;
|
|
@@ -80,11 +86,11 @@ export interface SecretPathsReport {
|
|
|
80
86
|
export type LegacyMemoryKind = "global-memory" | "conversation-history" | "captured-memory";
|
|
81
87
|
export declare const LEGACY_MEMORY_FACT_MAX_BYTES = 1024;
|
|
82
88
|
export declare const LEGACY_MEMORY_FACT_DECISION_MAX = 500;
|
|
89
|
+
/** What leaves the machine for one legacy source: metadata only (F-0 G-5). Never `content`, never `path`. */
|
|
83
90
|
export interface LegacyMemoryReport {
|
|
84
91
|
id: string;
|
|
85
92
|
kind: LegacyMemoryKind;
|
|
86
93
|
channel_id?: string;
|
|
87
|
-
content: string | null;
|
|
88
94
|
bytes: number;
|
|
89
95
|
exportable: boolean;
|
|
90
96
|
}
|
package/dist/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const BRIDGE_VERSION = "0.
|
|
1
|
+
export declare const BRIDGE_VERSION = "0.32.0";
|
package/dist/voice/persona.d.ts
CHANGED
|
@@ -28,6 +28,10 @@ export interface FastPathConfig {
|
|
|
28
28
|
maxTokens: number;
|
|
29
29
|
/** Extra request headers. Set only by settingsToVoiceConfig (the SecureComs proxy); never by parseVoiceConfig. */
|
|
30
30
|
headers?: Readonly<Record<string, string>>;
|
|
31
|
+
/** E.2 (spec §6, OQ-4): the credential file's explicit opt-in to call this provider directly from the agent's
|
|
32
|
+
* machine. Set only by parseVoiceConfig, only for `route: "direct"`; a backend settings fetch then never replaces
|
|
33
|
+
* this config with the SecureComs proxy's. */
|
|
34
|
+
route?: "direct";
|
|
31
35
|
}
|
|
32
36
|
export interface VoiceConfig {
|
|
33
37
|
persona: VoicePersona;
|