@omnicross/daemon 0.2.0 → 0.3.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/dist/index.cjs CHANGED
@@ -65,17 +65,17 @@ var import_billing_types = require("@omnicross/contracts/billing-types");
65
65
  var import_core4 = require("@omnicross/core");
66
66
  var import_GeminiCodeAssistProjectResolver = require("@omnicross/core/auth/GeminiCodeAssistProjectResolver");
67
67
  var import_ApiKeyPoolService = require("@omnicross/core/completion/ApiKeyPoolService");
68
- var import_outbound_api9 = require("@omnicross/core/outbound-api");
68
+ var import_outbound_api10 = require("@omnicross/core/outbound-api");
69
69
  var import_subscriptionRegistryPort = require("@omnicross/core/outbound-api/subscriptionRegistryPort");
70
70
  var import_SubscriptionAccountHealth4 = require("@omnicross/core/pipeline/SubscriptionAccountHealth");
71
71
  var import_AccountAllowanceStore4 = require("@omnicross/core/pipeline/AccountAllowanceStore");
72
72
  var import_AccountAllowanceScheduling5 = require("@omnicross/core/pipeline/AccountAllowanceScheduling");
73
- var import_upstreamFetch8 = require("@omnicross/core/pipeline/upstreamFetch");
73
+ var import_upstreamFetch9 = require("@omnicross/core/pipeline/upstreamFetch");
74
74
  var import_SubscriptionIdentityStore3 = require("@omnicross/core/provider-proxy/identity/SubscriptionIdentityStore");
75
75
  var import_gemini_code_assist_resolver = require("@omnicross/core/ports/gemini-code-assist-resolver");
76
76
  var import_provider_proxy4 = require("@omnicross/core/provider-proxy");
77
77
  var import_cli_launcher2 = require("@omnicross/cli-launcher");
78
- var import_outbound_api10 = require("@omnicross/core/outbound-api");
78
+ var import_outbound_api11 = require("@omnicross/core/outbound-api");
79
79
  var import_usage2 = require("@omnicross/core/usage");
80
80
  var import_subscriptions6 = require("@omnicross/subscriptions");
81
81
 
@@ -879,11 +879,11 @@ async function handleRouteLeaseApi(req, res, path2, deps) {
879
879
 
880
880
  // src/admin/adminApi.ts
881
881
  var import_node_http = __toESM(require("http"), 1);
882
- var import_outbound_api4 = require("@omnicross/core/outbound-api");
882
+ var import_outbound_api5 = require("@omnicross/core/outbound-api");
883
883
  var import_image_generation_types = require("@omnicross/contracts/image-generation-types");
884
884
  var import_AccountAllowanceScheduling2 = require("@omnicross/core/pipeline/AccountAllowanceScheduling");
885
885
  var import_SubscriptionAccountHealth = require("@omnicross/core/pipeline/SubscriptionAccountHealth");
886
- var import_upstreamFetch3 = require("@omnicross/core/pipeline/upstreamFetch");
886
+ var import_upstreamFetch4 = require("@omnicross/core/pipeline/upstreamFetch");
887
887
 
888
888
  // src/image-generation/imagesConfigValidation.ts
889
889
  var import_outbound_api = require("@omnicross/core/outbound-api");
@@ -3739,6 +3739,488 @@ async function handleDashboard(deps) {
3739
3739
  return { status: 200, body: summary };
3740
3740
  }
3741
3741
 
3742
+ // src/admin/searchAdminApi.ts
3743
+ var import_outbound_api2 = require("@omnicross/core/outbound-api");
3744
+ var import_api3 = require("@omnicross/core/search/api");
3745
+ var import_http3 = require("@omnicross/core/search/http");
3746
+ var import_search2 = require("@omnicross/core/search");
3747
+
3748
+ // src/search/searchDoctorProjection.ts
3749
+ var import_search_types = require("@omnicross/contracts/search-types");
3750
+ var import_api = require("@omnicross/core/search/api");
3751
+ var import_http = require("@omnicross/core/search/http");
3752
+ var API_DOCTOR_PROVIDERS = [
3753
+ {
3754
+ id: "tavily",
3755
+ capabilities: import_api.TAVILY_CAPABILITIES,
3756
+ configured: (configs) => configs.tavily !== void 0,
3757
+ missingReason: "no API key configured"
3758
+ },
3759
+ {
3760
+ id: "jina",
3761
+ capabilities: import_api.JINA_CAPABILITIES,
3762
+ configured: (configs) => configs.jina !== void 0,
3763
+ // Honest about the asymmetry: Jina CAN run keyless, but a provider nobody
3764
+ // asked for is still not enabled.
3765
+ missingReason: "not configured (Jina can run without a key, but must be enabled explicitly)"
3766
+ },
3767
+ {
3768
+ id: "searxng",
3769
+ capabilities: import_api.SEARXNG_CAPABILITIES,
3770
+ configured: (configs) => configs.searxng !== void 0,
3771
+ missingReason: "no API host configured"
3772
+ },
3773
+ {
3774
+ id: "zhipu",
3775
+ capabilities: import_api.ZHIPU_CAPABILITIES,
3776
+ configured: (configs) => configs.zhipu !== void 0,
3777
+ missingReason: "no API key configured"
3778
+ },
3779
+ {
3780
+ id: "z.ai",
3781
+ capabilities: import_api.ZHIPU_CAPABILITIES,
3782
+ configured: (configs) => configs["z.ai"] !== void 0,
3783
+ missingReason: "no API key configured"
3784
+ }
3785
+ ];
3786
+ function buildSearchDoctorSnapshot(contributions = (0, import_http.builtinHttpSearchContributions)(), apiConfigs) {
3787
+ const rows = contributions.map((contribution) => ({
3788
+ providerId: contribution.id,
3789
+ source: contribution.source,
3790
+ kind: contribution.kind,
3791
+ capabilities: contribution.capabilities
3792
+ }));
3793
+ if (apiConfigs === void 0) return rows;
3794
+ for (const provider of API_DOCTOR_PROVIDERS) {
3795
+ if (provider.configured(apiConfigs)) continue;
3796
+ rows.push({
3797
+ providerId: provider.id,
3798
+ source: "builtin",
3799
+ kind: "api",
3800
+ capabilities: provider.capabilities,
3801
+ status: "unconfigured",
3802
+ reason: provider.missingReason
3803
+ });
3804
+ }
3805
+ return rows;
3806
+ }
3807
+ var SEARCH_DOCTOR_QUERY = "MDN HTTP headers documentation";
3808
+ function classifyLiveSearchOutcome(providerId, outcome, checkedAt) {
3809
+ if (outcome.kind === "results") {
3810
+ if (outcome.count > 0) return { providerId, status: "healthy", checkedAt };
3811
+ return {
3812
+ providerId,
3813
+ status: "degraded",
3814
+ checkedAt,
3815
+ reason: "reachable, but the engine returned no usable results (possible partial drift)"
3816
+ };
3817
+ }
3818
+ const error = (0, import_search_types.toSearchErrorShape)(outcome.error);
3819
+ const stage = error.details?.stage;
3820
+ const { status, reason } = classifySearchFailure(stage, error.code);
3821
+ return { providerId, status, checkedAt, reason, error };
3822
+ }
3823
+ function classifySearchFailure(stage, code) {
3824
+ if (stage === "challenge") {
3825
+ return { status: "blocked", reason: "the engine served a bot challenge instead of results" };
3826
+ }
3827
+ if (stage === "trust") {
3828
+ return {
3829
+ status: "blocked",
3830
+ reason: "the engine served a page that failed the anti-decoy trust check"
3831
+ };
3832
+ }
3833
+ if (code === "policy_denied") {
3834
+ return {
3835
+ status: "blocked",
3836
+ reason: "the egress policy refused the request target"
3837
+ };
3838
+ }
3839
+ if (code === "parse_failed") {
3840
+ return {
3841
+ status: "failed",
3842
+ reason: "the response was not recognizable as a search result page (parser drift suspected)"
3843
+ };
3844
+ }
3845
+ if (code === "timeout") {
3846
+ return { status: "failed", reason: "the request exceeded its time budget" };
3847
+ }
3848
+ return { status: "failed", reason: `the request failed (${code})` };
3849
+ }
3850
+
3851
+ // src/search/SearchAssembly.ts
3852
+ var import_upstreamFetch3 = require("@omnicross/core/pipeline/upstreamFetch");
3853
+ var import_search = require("@omnicross/core/search");
3854
+ var import_api2 = require("@omnicross/core/search/api");
3855
+ var import_http2 = require("@omnicross/core/search/http");
3856
+ function searchEgressPolicyFrom(config) {
3857
+ const hosts = config.egress.allowedPrivateHosts;
3858
+ return hosts.length > 0 ? { allowedPrivateHosts: [...hosts] } : {};
3859
+ }
3860
+ function searchPolicyFrom(config) {
3861
+ const { preferred, allowed, fallbackEnabled, maxAttempts } = config.policy;
3862
+ return {
3863
+ ...preferred !== void 0 ? { preferred } : {},
3864
+ ...allowed !== void 0 ? { allowed: [...allowed] } : {},
3865
+ fallbackEnabled,
3866
+ ...maxAttempts !== void 0 ? { maxAttempts } : {}
3867
+ };
3868
+ }
3869
+ function resolveSearchUpstreamDispatcher(url) {
3870
+ return (0, import_upstreamFetch3.resolveUpstreamDispatcher)({ url });
3871
+ }
3872
+ var searchUpstreamProxyConfig = createUpstreamProxyResolver();
3873
+ function resolveSearchUpstreamProxyConfig(url) {
3874
+ return searchUpstreamProxyConfig({ url });
3875
+ }
3876
+ function searchContributionsFrom(config) {
3877
+ return [
3878
+ ...(0, import_http2.builtinHttpSearchContributions)(
3879
+ (0, import_http2.createSearchHttpTransport)({
3880
+ resolveProxyDispatcher: resolveSearchUpstreamDispatcher,
3881
+ resolveProxyConfig: resolveSearchUpstreamProxyConfig
3882
+ })
3883
+ ),
3884
+ ...(0, import_api2.apiSearchContributions)(config.providers, {
3885
+ egressPolicy: searchEgressPolicyFrom(config),
3886
+ resolveProxyDispatcher: resolveSearchUpstreamDispatcher
3887
+ })
3888
+ ];
3889
+ }
3890
+ function buildSearchRuntime(config, options = {}) {
3891
+ const logger = options.logger ?? null;
3892
+ return (0, import_search.createSearchRuntime)({
3893
+ contributions: options.contributions ?? searchContributionsFrom(config),
3894
+ policy: searchPolicyFrom(config),
3895
+ ...logger ? {
3896
+ onEvent: (event) => {
3897
+ logger.debug(`[search] ${formatSearchEvent(event)}`);
3898
+ }
3899
+ } : {}
3900
+ });
3901
+ }
3902
+ function formatSearchEvent(event) {
3903
+ const parts = [
3904
+ `type=${event.type}`,
3905
+ `request=${event.requestId}`,
3906
+ `queryHash=${event.queryHash}`,
3907
+ `durationMs=${event.durationMs}`
3908
+ ];
3909
+ if ("providerId" in event && event.providerId !== void 0) {
3910
+ parts.push(`provider=${event.providerId}`);
3911
+ }
3912
+ if ("outcome" in event && event.outcome !== void 0) parts.push(`outcome=${event.outcome}`);
3913
+ if ("errorCode" in event && event.errorCode !== void 0) parts.push(`error=${event.errorCode}`);
3914
+ if ("resultCount" in event && event.resultCount !== void 0) {
3915
+ parts.push(`results=${event.resultCount}`);
3916
+ }
3917
+ if ("fallbackCount" in event && event.fallbackCount !== void 0) {
3918
+ parts.push(`fallbacks=${event.fallbackCount}`);
3919
+ }
3920
+ return parts.join(" ");
3921
+ }
3922
+
3923
+ // src/admin/searchAdminApi.ts
3924
+ var KEYLESS_HTTP_PROVIDER_IDS = /* @__PURE__ */ new Set(["http-bing", "http-duckduckgo"]);
3925
+ var API_PROVIDER_IDS = /* @__PURE__ */ new Set([
3926
+ "tavily",
3927
+ "jina",
3928
+ "searxng",
3929
+ "zhipu",
3930
+ "z.ai"
3931
+ ]);
3932
+ var SEARCH_QUERY_MAX_CODE_UNITS = 256;
3933
+ var QUERY_CONTROL_CHARS = /[\u0000-\u001f\u007f]/u;
3934
+ var SEARCH_RESULT_FIELD_CAPS = { title: 512, url: 2048, content: 1024 };
3935
+ var SEARCH_QUERY_MAX_RESULTS = 5;
3936
+ function sanitizeResultField(value, cap) {
3937
+ const text = typeof value === "string" ? value : value === null || value === void 0 ? "" : String(value);
3938
+ return text.replace(/[\u0000-\u001f\u007f]/gu, "").slice(0, cap);
3939
+ }
3940
+ function writeJson(res, status, body) {
3941
+ res.writeHead(status, { "Content-Type": "application/json" });
3942
+ res.end(JSON.stringify(body));
3943
+ }
3944
+ function writeErr(res, status, message) {
3945
+ writeJson(res, status, { error: { type: "admin_api_error", message } });
3946
+ }
3947
+ var SEARCH_MAX_BODY_BYTES = 64 * 1024;
3948
+ var SearchBodyTooLargeError = class extends Error {
3949
+ };
3950
+ async function readJsonBody2(req) {
3951
+ const chunks = [];
3952
+ let bytes = 0;
3953
+ for await (const chunk of req) {
3954
+ const buffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
3955
+ bytes += buffer.length;
3956
+ if (bytes > SEARCH_MAX_BODY_BYTES) throw new SearchBodyTooLargeError("request body is too large");
3957
+ chunks.push(buffer);
3958
+ }
3959
+ const raw = Buffer.concat(chunks).toString("utf8");
3960
+ if (!raw.trim()) return {};
3961
+ try {
3962
+ const parsed = JSON.parse(raw);
3963
+ return parsed !== null && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
3964
+ } catch {
3965
+ return {};
3966
+ }
3967
+ }
3968
+ async function readBodyOrReject(req, res) {
3969
+ try {
3970
+ return await readJsonBody2(req);
3971
+ } catch (error) {
3972
+ if (error instanceof SearchBodyTooLargeError) {
3973
+ writeErr(res, 400, error.message);
3974
+ return void 0;
3975
+ }
3976
+ throw error;
3977
+ }
3978
+ }
3979
+ async function handleSearchAdmin(req, res, method, rest, deps) {
3980
+ if (rest.length === 1 && rest[0] === "diagnostics") {
3981
+ if (!deps.searchStatus) {
3982
+ return writeErr(res, 501, "Search status is not available in this build");
3983
+ }
3984
+ if (method !== "GET") {
3985
+ return writeErr(res, 405, `method ${method} not allowed on search diagnostics`);
3986
+ }
3987
+ return handleSearchDiagnostics(res, deps);
3988
+ }
3989
+ if (rest.length === 1 && rest[0] === "test") {
3990
+ if (!deps.searchStatus) {
3991
+ return writeErr(res, 501, "Search status is not available in this build");
3992
+ }
3993
+ if (method !== "POST") {
3994
+ return writeErr(res, 405, `method ${method} not allowed on search test`);
3995
+ }
3996
+ return handleSearchTest(req, res, deps);
3997
+ }
3998
+ if (rest.length === 1 && rest[0] === "query") {
3999
+ if (!deps.searchStatus) {
4000
+ return writeErr(res, 501, "Search status is not available in this build");
4001
+ }
4002
+ if (method !== "POST") {
4003
+ return writeErr(res, 405, `method ${method} not allowed on search query`);
4004
+ }
4005
+ return handleSearchQuery(req, res, deps);
4006
+ }
4007
+ return writeErr(res, 404, `unknown search route '/${rest.join("/")}'`);
4008
+ }
4009
+ async function handleSearchDiagnostics(res, deps) {
4010
+ const status = deps.searchStatus;
4011
+ const persisted = await (0, import_outbound_api2.loadServerConfig)(deps.settingsStore);
4012
+ const search = persisted.search ?? import_outbound_api2.DEFAULT_SEARCH_SERVER_CONFIG;
4013
+ const rows = buildSearchDoctorSnapshot(
4014
+ status.runtime.listProviders(),
4015
+ search.providers
4016
+ );
4017
+ const snapshot = {
4018
+ rows,
4019
+ modes: {
4020
+ // codex is read from the LIVE config per request — an admin PUT has
4021
+ // already applied. responses/anthropic were captured at bootstrap.
4022
+ codex: search.modes.codex,
4023
+ responses: status.modes.responses,
4024
+ anthropic: status.modes.anthropic
4025
+ },
4026
+ applySemantics: { codex: "immediate", rest: "restart" }
4027
+ };
4028
+ return writeJson(res, 200, { diagnostics: snapshot });
4029
+ }
4030
+ function persistedSearchContributions(search, fetchImpl) {
4031
+ if (fetchImpl) {
4032
+ const egressPolicy = searchEgressPolicyFrom(search);
4033
+ return [
4034
+ ...(0, import_http3.builtinHttpSearchContributions)(
4035
+ (0, import_http3.createSearchHttpTransport)({ fetch: fetchImpl, egressPolicy })
4036
+ ),
4037
+ ...(0, import_api3.apiSearchContributions)(search.providers, { egressPolicy, fetchImpl })
4038
+ ];
4039
+ }
4040
+ return searchContributionsFrom(search);
4041
+ }
4042
+ async function handleSearchTest(req, res, deps) {
4043
+ const status = deps.searchStatus;
4044
+ const body = await readBodyOrReject(req, res);
4045
+ if (body === void 0) return;
4046
+ const providerId = body["providerId"];
4047
+ if (typeof providerId !== "string" || providerId.length === 0) {
4048
+ return writeErr(res, 400, "providerId must be a non-empty string");
4049
+ }
4050
+ if (!KEYLESS_HTTP_PROVIDER_IDS.has(providerId) && !API_PROVIDER_IDS.has(providerId)) {
4051
+ return writeErr(res, 404, `unknown search provider '${providerId}'`);
4052
+ }
4053
+ const persisted = await (0, import_outbound_api2.loadServerConfig)(deps.settingsStore);
4054
+ const search = persisted.search ?? import_outbound_api2.DEFAULT_SEARCH_SERVER_CONFIG;
4055
+ const providers = search.providers;
4056
+ if (!KEYLESS_HTTP_PROVIDER_IDS.has(providerId) && providers[providerId] === void 0) {
4057
+ return writeErr(res, 400, `search provider '${providerId}' is not configured`);
4058
+ }
4059
+ const fetchImpl = status.testFetch;
4060
+ const contributions = persistedSearchContributions(search, fetchImpl);
4061
+ const contribution = contributions.find((c) => c.id === providerId);
4062
+ if (!contribution) {
4063
+ return writeErr(res, 400, `search provider '${providerId}' is not configured`);
4064
+ }
4065
+ const checkedAt = (/* @__PURE__ */ new Date()).toISOString();
4066
+ try {
4067
+ const results = await contribution.provider.search(SEARCH_DOCTOR_QUERY, { maxResults: 5 });
4068
+ const diagnostic = classifyLiveSearchOutcome(
4069
+ contribution.id,
4070
+ { kind: "results", count: results.length },
4071
+ checkedAt
4072
+ );
4073
+ const response = { diagnostic, resultCount: results.length };
4074
+ return writeJson(res, 200, { result: response });
4075
+ } catch (error) {
4076
+ const diagnostic = classifyLiveSearchOutcome(contribution.id, { kind: "failure", error }, checkedAt);
4077
+ const response = { diagnostic };
4078
+ return writeJson(res, 200, { result: response });
4079
+ }
4080
+ }
4081
+ async function handleSearchQuery(req, res, deps) {
4082
+ const status = deps.searchStatus;
4083
+ const body = await readBodyOrReject(req, res);
4084
+ if (body === void 0) return;
4085
+ const providerId = body["providerId"];
4086
+ if (typeof providerId !== "string" || providerId.length === 0) {
4087
+ return writeErr(res, 400, "providerId must be a non-empty string");
4088
+ }
4089
+ if (!KEYLESS_HTTP_PROVIDER_IDS.has(providerId) && !API_PROVIDER_IDS.has(providerId)) {
4090
+ return writeErr(res, 404, `unknown search provider '${providerId}'`);
4091
+ }
4092
+ const query2 = body["query"];
4093
+ if (typeof query2 !== "string" || query2.trim().length === 0) {
4094
+ return writeErr(res, 400, "query must be a non-empty string");
4095
+ }
4096
+ if (query2.length > SEARCH_QUERY_MAX_CODE_UNITS) {
4097
+ return writeErr(res, 400, `query must be at most ${SEARCH_QUERY_MAX_CODE_UNITS} characters`);
4098
+ }
4099
+ if (QUERY_CONTROL_CHARS.test(query2)) {
4100
+ return writeErr(res, 400, "query must not contain control characters");
4101
+ }
4102
+ const persisted = await (0, import_outbound_api2.loadServerConfig)(deps.settingsStore);
4103
+ const search = persisted.search ?? import_outbound_api2.DEFAULT_SEARCH_SERVER_CONFIG;
4104
+ const providers = search.providers;
4105
+ if (!KEYLESS_HTTP_PROVIDER_IDS.has(providerId) && providers[providerId] === void 0) {
4106
+ return writeErr(res, 400, `search provider '${providerId}' is not configured`);
4107
+ }
4108
+ const fetchImpl = status.testFetch;
4109
+ const runtime = (0, import_search2.createSearchRuntime)({
4110
+ contributions: persistedSearchContributions(search, fetchImpl),
4111
+ policy: {
4112
+ ...searchPolicyFrom(search),
4113
+ // The panel always walks: it answers "does a search WORK for this
4114
+ // operator", not "does this one provider behave" — that is `/test`'s
4115
+ // job. The persisted policy's allowlist still bounds the walk.
4116
+ fallbackEnabled: true,
4117
+ preferred: providerId
4118
+ }
4119
+ });
4120
+ const checkedAt = (/* @__PURE__ */ new Date()).toISOString();
4121
+ try {
4122
+ const orchestrated = await runtime.search({ query: query2, options: { maxResults: 5 } });
4123
+ const results = orchestrated.results;
4124
+ const sanitized = results.slice(0, SEARCH_QUERY_MAX_RESULTS).map((result) => ({
4125
+ title: sanitizeResultField(result.title, SEARCH_RESULT_FIELD_CAPS.title),
4126
+ url: sanitizeResultField(result.url, SEARCH_RESULT_FIELD_CAPS.url),
4127
+ content: sanitizeResultField(result.content, SEARCH_RESULT_FIELD_CAPS.content)
4128
+ }));
4129
+ const diagnostic = sanitized.length === 0 ? { providerId: orchestrated.providerId, status: "healthy", checkedAt } : classifyLiveSearchOutcome(
4130
+ orchestrated.providerId,
4131
+ { kind: "results", count: sanitized.length },
4132
+ checkedAt
4133
+ );
4134
+ const response = {
4135
+ diagnostic,
4136
+ providerUsed: orchestrated.providerId,
4137
+ fallbackCount: orchestrated.fallbackCount,
4138
+ resultCount: sanitized.length,
4139
+ results: sanitized
4140
+ };
4141
+ return writeJson(res, 200, { result: response });
4142
+ } catch (error) {
4143
+ const diagnostic = classifyLiveSearchOutcome(providerId, { kind: "failure", error }, checkedAt);
4144
+ const response = { diagnostic };
4145
+ return writeJson(res, 200, { result: response });
4146
+ }
4147
+ }
4148
+
4149
+ // src/admin/searchAdminView.ts
4150
+ var API_KEY_PROVIDERS = /* @__PURE__ */ new Set(["tavily", "jina", "zhipu", "z.ai"]);
4151
+ var BASIC_AUTH_PROVIDERS = /* @__PURE__ */ new Set(["searxng"]);
4152
+ function isRecord(value) {
4153
+ return value !== null && typeof value === "object" && !Array.isArray(value);
4154
+ }
4155
+ function redactSearchServerConfig(search) {
4156
+ const providers = {};
4157
+ for (const [id, raw] of Object.entries(search.providers)) {
4158
+ const entry = raw;
4159
+ const view = {};
4160
+ if (entry.apiHost !== void 0) view.apiHost = entry.apiHost;
4161
+ if (entry.basicAuthUsername !== void 0) view.basicAuthUsername = entry.basicAuthUsername;
4162
+ if (API_KEY_PROVIDERS.has(id)) {
4163
+ view.apiKeyConfigured = typeof entry.apiKey === "string" && entry.apiKey.length > 0;
4164
+ }
4165
+ if (BASIC_AUTH_PROVIDERS.has(id)) {
4166
+ view.basicAuthPasswordConfigured = typeof entry.basicAuthPassword === "string" && entry.basicAuthPassword.length > 0;
4167
+ }
4168
+ providers[id] = view;
4169
+ }
4170
+ return {
4171
+ modes: search.modes,
4172
+ providers,
4173
+ egress: { allowedPrivateHosts: [...search.egress.allowedPrivateHosts] },
4174
+ policy: { ...search.policy, ...search.policy.allowed ? { allowed: [...search.policy.allowed] } : {} }
4175
+ };
4176
+ }
4177
+ function storedSecrets(current, id) {
4178
+ const entry = current.providers[id];
4179
+ if (!entry) return {};
4180
+ const out = {};
4181
+ if (typeof entry.apiKey === "string" && entry.apiKey.length > 0) out.apiKey = entry.apiKey;
4182
+ if (typeof entry.basicAuthPassword === "string" && entry.basicAuthPassword.length > 0) {
4183
+ out.basicAuthPassword = entry.basicAuthPassword;
4184
+ }
4185
+ return out;
4186
+ }
4187
+ function resolveSecretField(entry, field, stored) {
4188
+ if (!(field in entry)) {
4189
+ if (stored !== void 0) entry[field] = stored;
4190
+ return;
4191
+ }
4192
+ const value = entry[field];
4193
+ if (value === null) {
4194
+ delete entry[field];
4195
+ return;
4196
+ }
4197
+ if (typeof value === "string" && value.trim().length > 0) return;
4198
+ if (stored !== void 0) entry[field] = stored;
4199
+ else delete entry[field];
4200
+ }
4201
+ function preserveSearchSecrets(incoming, current) {
4202
+ if (!isRecord(incoming)) return incoming;
4203
+ const section = { ...incoming };
4204
+ const providersValue = section["providers"];
4205
+ if (!isRecord(providersValue)) return section;
4206
+ const providers = {};
4207
+ for (const [id, entryValue] of Object.entries(providersValue)) {
4208
+ if (!isRecord(entryValue)) {
4209
+ providers[id] = entryValue;
4210
+ continue;
4211
+ }
4212
+ const entry = { ...entryValue };
4213
+ delete entry["apiKeyConfigured"];
4214
+ delete entry["basicAuthPasswordConfigured"];
4215
+ const stored = storedSecrets(current, id);
4216
+ resolveSecretField(entry, "apiKey", stored.apiKey);
4217
+ resolveSecretField(entry, "basicAuthPassword", stored.basicAuthPassword);
4218
+ providers[id] = entry;
4219
+ }
4220
+ section["providers"] = providers;
4221
+ return section;
4222
+ }
4223
+
3742
4224
  // src/admin/keyPolicyBody.ts
3743
4225
  function parseKeyPolicyBody(body) {
3744
4226
  const policy = {};
@@ -3801,7 +4283,7 @@ function parseKeyPolicyBody(body) {
3801
4283
  var ENDPOINTS = /* @__PURE__ */ new Set(["chat", "responses", "messages", "gemini"]);
3802
4284
  var TARGET_KINDS = /* @__PURE__ */ new Set(["account", "account-group", "account-pool", "provider"]);
3803
4285
  var FALLBACKS = /* @__PURE__ */ new Set(["next", "fail", "global"]);
3804
- function isRecord(value) {
4286
+ function isRecord2(value) {
3805
4287
  return !!value && typeof value === "object" && !Array.isArray(value);
3806
4288
  }
3807
4289
  function nonBlank(value) {
@@ -3821,7 +4303,7 @@ function validateGatewayBindingsSegment(patch) {
3821
4303
  const ids = /* @__PURE__ */ new Set();
3822
4304
  raw.forEach((entry, index) => {
3823
4305
  const path2 = `bindings[${index}]`;
3824
- if (!isRecord(entry)) {
4306
+ if (!isRecord2(entry)) {
3825
4307
  errors.push(`${path2} must be an object`);
3826
4308
  return;
3827
4309
  }
@@ -3850,12 +4332,12 @@ function validateGatewayBindingsSegment(patch) {
3850
4332
  } else if (entry.modelMappings.length > 100) {
3851
4333
  errors.push(`${path2}.modelMappings cannot contain more than 100 entries`);
3852
4334
  } else if (entry.modelMappings.some(
3853
- (mapping) => !isRecord(mapping) || !nonBlank(mapping.source) || !nonBlank(mapping.target)
4335
+ (mapping) => !isRecord2(mapping) || !nonBlank(mapping.source) || !nonBlank(mapping.target)
3854
4336
  )) {
3855
4337
  errors.push(`${path2}.modelMappings must contain non-empty source and target strings`);
3856
4338
  }
3857
4339
  }
3858
- if (!isRecord(entry.target) || !TARGET_KINDS.has(String(entry.target.kind))) {
4340
+ if (!isRecord2(entry.target) || !TARGET_KINDS.has(String(entry.target.kind))) {
3859
4341
  errors.push(`${path2}.target is invalid`);
3860
4342
  } else {
3861
4343
  if (!nonBlank(entry.target.providerId)) errors.push(`${path2}.target.providerId is required`);
@@ -3870,7 +4352,7 @@ function validateGatewayBindingsSegment(patch) {
3870
4352
  }
3871
4353
  }
3872
4354
  if (entry.modelMap !== void 0) {
3873
- if (!isRecord(entry.modelMap) || Object.values(entry.modelMap).some((value) => typeof value !== "string")) {
4355
+ if (!isRecord2(entry.modelMap) || Object.values(entry.modelMap).some((value) => typeof value !== "string")) {
3874
4356
  errors.push(`${path2}.modelMap must contain string values`);
3875
4357
  }
3876
4358
  }
@@ -3888,15 +4370,15 @@ function validateGatewayBindingsSegment(patch) {
3888
4370
  }
3889
4371
 
3890
4372
  // src/admin/voucherAdmin.ts
3891
- var import_outbound_api2 = require("@omnicross/core/outbound-api");
3892
- function writeJson(res, status, body) {
4373
+ var import_outbound_api3 = require("@omnicross/core/outbound-api");
4374
+ function writeJson2(res, status, body) {
3893
4375
  res.writeHead(status, { "Content-Type": "application/json" });
3894
4376
  res.end(JSON.stringify(body));
3895
4377
  }
3896
- function writeErr(res, status, message) {
3897
- writeJson(res, status, { error: { type: "voucher_error", message } });
4378
+ function writeErr2(res, status, message) {
4379
+ writeJson2(res, status, { error: { type: "voucher_error", message } });
3898
4380
  }
3899
- function readJsonBody2(req) {
4381
+ function readJsonBody3(req) {
3900
4382
  return new Promise((resolve10, reject) => {
3901
4383
  const chunks = [];
3902
4384
  req.on("data", (c) => chunks.push(c));
@@ -3947,34 +4429,34 @@ function parseVoucherCreateBody(body) {
3947
4429
  return { ok: true, input };
3948
4430
  }
3949
4431
  async function voucherEnabled(deps) {
3950
- const config = await (0, import_outbound_api2.loadServerConfig)(deps.settingsStore);
4432
+ const config = await (0, import_outbound_api3.loadServerConfig)(deps.settingsStore);
3951
4433
  return config.voucher?.enabled === true;
3952
4434
  }
3953
4435
  async function handleVoucher(req, res, method, rest, deps) {
3954
4436
  const voucherDb = deps.voucherDb;
3955
- if (!voucherDb) return writeErr(res, 501, "Voucher feature is not available");
4437
+ if (!voucherDb) return writeErr2(res, 501, "Voucher feature is not available");
3956
4438
  if (method === "GET" && rest.length === 0) {
3957
4439
  const rows = await voucherDb.voucherList();
3958
- return writeJson(res, 200, { vouchers: rows.map(import_outbound_api2.toVoucherInfo) });
4440
+ return writeJson2(res, 200, { vouchers: rows.map(import_outbound_api3.toVoucherInfo) });
3959
4441
  }
3960
4442
  if (method === "POST" && rest.length === 0) {
3961
- if (!await voucherEnabled(deps)) return writeErr(res, 403, "Voucher feature is disabled");
4443
+ if (!await voucherEnabled(deps)) return writeErr2(res, 403, "Voucher feature is disabled");
3962
4444
  let body;
3963
4445
  try {
3964
- body = await readJsonBody2(req);
4446
+ body = await readJsonBody3(req);
3965
4447
  } catch {
3966
- return writeErr(res, 400, "Invalid JSON in request body");
4448
+ return writeErr2(res, 400, "Invalid JSON in request body");
3967
4449
  }
3968
4450
  const parsed = parseVoucherCreateBody(body);
3969
- if (!parsed.ok) return writeErr(res, 400, parsed.message);
3970
- const code = (0, import_outbound_api2.generateVoucherCode)();
4451
+ if (!parsed.ok) return writeErr2(res, 400, parsed.message);
4452
+ const code = (0, import_outbound_api3.generateVoucherCode)();
3971
4453
  const created = await voucherDb.voucherCreate({
3972
- id: (0, import_outbound_api2.newVoucherId)(),
3973
- codeHash: (0, import_outbound_api2.hashVoucherCode)(code),
3974
- codePrefix: (0, import_outbound_api2.voucherCodePrefix)(code),
4454
+ id: (0, import_outbound_api3.newVoucherId)(),
4455
+ codeHash: (0, import_outbound_api3.hashVoucherCode)(code),
4456
+ codePrefix: (0, import_outbound_api3.voucherCodePrefix)(code),
3975
4457
  ...parsed.input
3976
4458
  });
3977
- return writeJson(res, 201, {
4459
+ return writeJson2(res, 201, {
3978
4460
  id: created.id,
3979
4461
  codePrefix: created.codePrefix,
3980
4462
  type: created.type,
@@ -3985,11 +4467,11 @@ async function handleVoucher(req, res, method, rest, deps) {
3985
4467
  }
3986
4468
  const id = rest[0];
3987
4469
  if (method === "POST" && id && rest[1] === "revoke") {
3988
- if (!await voucherEnabled(deps)) return writeErr(res, 403, "Voucher feature is disabled");
4470
+ if (!await voucherEnabled(deps)) return writeErr2(res, 403, "Voucher feature is disabled");
3989
4471
  const ok = await voucherDb.voucherRevokeCas(id, Date.now());
3990
- return writeJson(res, ok ? 200 : 409, { ok });
4472
+ return writeJson2(res, ok ? 200 : 409, { ok });
3991
4473
  }
3992
- return writeErr(res, 405, `method ${method} not allowed on voucher`);
4474
+ return writeErr2(res, 405, `method ${method} not allowed on voucher`);
3993
4475
  }
3994
4476
 
3995
4477
  // src/admin/webhookConfigBody.ts
@@ -4156,7 +4638,7 @@ function resetBillingRuntimeForTests() {
4156
4638
  }
4157
4639
 
4158
4640
  // src/migration/migration.ts
4159
- var import_outbound_api3 = require("@omnicross/core/outbound-api");
4641
+ var import_outbound_api4 = require("@omnicross/core/outbound-api");
4160
4642
 
4161
4643
  // src/ports/account-multi.ts
4162
4644
  var import_node_crypto8 = require("crypto");
@@ -4584,7 +5066,7 @@ async function gatherExport(deps, passphrase) {
4584
5066
  v: BUNDLE_VERSION,
4585
5067
  providers: cfg.providers,
4586
5068
  tokens,
4587
- server: (0, import_outbound_api3.normalizeServerConfig)(cfg.server)
5069
+ server: (0, import_outbound_api4.normalizeServerConfig)(cfg.server)
4588
5070
  };
4589
5071
  return sealPack(JSON.stringify(bundle), passphrase);
4590
5072
  }
@@ -4633,7 +5115,7 @@ async function applyImport(packString, passphrase, mode, deps, parseProviderInpu
4633
5115
  const imageErrors = validateImagesAdminConfig(rawServer["images"]);
4634
5116
  if (imageErrors.length > 0) throw new Error("migration pack has an invalid Images config");
4635
5117
  }
4636
- validatedServer = (0, import_outbound_api3.normalizeServerConfig)(bundle.server);
5118
+ validatedServer = (0, import_outbound_api4.normalizeServerConfig)(bundle.server);
4637
5119
  }
4638
5120
  const validatedProviders = [];
4639
5121
  for (const raw of rawProviders) {
@@ -4914,12 +5396,12 @@ async function handlePricingResolveConflicts(body, deps) {
4914
5396
  }
4915
5397
 
4916
5398
  // src/admin/accountAllowanceApi.ts
4917
- function writeJson2(res, status, body) {
5399
+ function writeJson3(res, status, body) {
4918
5400
  res.writeHead(status, { "Content-Type": "application/json" });
4919
5401
  res.end(JSON.stringify(body));
4920
5402
  }
4921
5403
  function writeError2(res, status, message) {
4922
- writeJson2(res, status, { error: { type: "account_allowance_error", message } });
5404
+ writeJson3(res, status, { error: { type: "account_allowance_error", message } });
4923
5405
  }
4924
5406
  function readJson2(req) {
4925
5407
  return new Promise((resolve10, reject) => {
@@ -4952,7 +5434,7 @@ async function handleAccountAllowanceApi(req, res, method, rest, service) {
4952
5434
  if (!service.getSchedulingStatus) {
4953
5435
  return writeError2(res, 501, "allowance scheduling diagnostics are not available");
4954
5436
  }
4955
- return writeJson2(res, 200, { scheduling: service.getSchedulingStatus() });
5437
+ return writeJson3(res, 200, { scheduling: service.getSchedulingStatus() });
4956
5438
  }
4957
5439
  if (method === "GET") {
4958
5440
  const params = query(req);
@@ -4961,7 +5443,7 @@ async function handleAccountAllowanceApi(req, res, method, rest, service) {
4961
5443
  if (providerId === null) return writeError2(res, 400, "providerId must be claude or codex");
4962
5444
  const accountId = rest.length >= 2 ? rest[1] : params.get("accountId") ?? void 0;
4963
5445
  const allowances = await service.list({ providerId, accountId });
4964
- return writeJson2(res, 200, { allowances });
5446
+ return writeJson3(res, 200, { allowances });
4965
5447
  }
4966
5448
  if (method === "POST" && rest[0] === "refresh") {
4967
5449
  const body = await readJson2(req);
@@ -4976,7 +5458,7 @@ async function handleAccountAllowanceApi(req, res, method, rest, service) {
4976
5458
  if (accountId && allowances.length === 0) {
4977
5459
  return writeError2(res, 404, `Claude account '${accountId}' not found`);
4978
5460
  }
4979
- return writeJson2(res, 200, { allowances });
5461
+ return writeJson3(res, 200, { allowances });
4980
5462
  }
4981
5463
  return writeError2(res, 405, `method ${method} not allowed on account allowances`);
4982
5464
  }
@@ -4992,7 +5474,7 @@ function readBody(req) {
4992
5474
  req.on("error", reject);
4993
5475
  });
4994
5476
  }
4995
- async function readJsonBody3(req) {
5477
+ async function readJsonBody4(req) {
4996
5478
  const raw = await readBody(req);
4997
5479
  if (!raw.trim()) return {};
4998
5480
  try {
@@ -5002,12 +5484,12 @@ async function readJsonBody3(req) {
5002
5484
  return {};
5003
5485
  }
5004
5486
  }
5005
- function writeJson3(res, status, body) {
5487
+ function writeJson4(res, status, body) {
5006
5488
  res.writeHead(status, { "Content-Type": "application/json" });
5007
5489
  res.end(JSON.stringify(body));
5008
5490
  }
5009
5491
  function writeJsonError(res, status, message) {
5010
- writeJson3(res, status, { error: { type: "admin_api_error", message } });
5492
+ writeJson4(res, status, { error: { type: "admin_api_error", message } });
5011
5493
  }
5012
5494
  function maskProviderApiKey(apiKey) {
5013
5495
  if (!apiKey) return "";
@@ -5028,7 +5510,7 @@ function toKeyInfo(row) {
5028
5510
  lastUsedAt: row.lastUsedAt,
5029
5511
  revoked: row.revokedAt !== null,
5030
5512
  kind: row.kind,
5031
- allowedEndpoints: [...(0, import_outbound_api4.effectiveOutboundPermissions)(row.allowedEndpoints)],
5513
+ allowedEndpoints: [...(0, import_outbound_api5.effectiveOutboundPermissions)(row.allowedEndpoints)],
5032
5514
  legacyPermissions: row.allowedEndpoints === void 0,
5033
5515
  loopbackOnly: row.loopbackOnly,
5034
5516
  maxConcurrency: row.maxConcurrency,
@@ -5114,6 +5596,8 @@ async function handleAdminApi(req, res, path2, deps) {
5114
5596
  return await handleServer(req, res, method, deps);
5115
5597
  case "images":
5116
5598
  return await handleImages(res, method, rest, deps);
5599
+ case "search":
5600
+ return await handleSearchAdmin(req, res, method, rest, deps);
5117
5601
  case "accounts":
5118
5602
  return await handleAccounts(req, res, method, rest, deps);
5119
5603
  case "cli":
@@ -5147,7 +5631,7 @@ function requestQuery(req) {
5147
5631
  return new URLSearchParams(qIdx >= 0 ? raw.slice(qIdx + 1) : "");
5148
5632
  }
5149
5633
  function writeResult(res, result) {
5150
- writeJson3(res, result.status, result.body);
5634
+ writeJson4(res, result.status, result.body);
5151
5635
  }
5152
5636
  async function handleUsage(req, res, method, rest, deps) {
5153
5637
  if (method !== "GET") return writeJsonError(res, 405, `method ${method} not allowed on usage`);
@@ -5156,13 +5640,13 @@ async function handleUsage(req, res, method, rest, deps) {
5156
5640
  async function handleDashboardRoute(res, method, deps) {
5157
5641
  if (method !== "GET") return writeJsonError(res, 405, `method ${method} not allowed on dashboard`);
5158
5642
  const result = await handleDashboard(deps);
5159
- return writeJson3(res, result.status, result.body);
5643
+ return writeJson4(res, result.status, result.body);
5160
5644
  }
5161
5645
  async function handlePricing(req, res, method, rest, deps) {
5162
5646
  if (rest.length === 0) {
5163
5647
  if (method === "GET") return writeResult(res, await handlePricingList(deps));
5164
5648
  if (method === "PUT") {
5165
- return writeResult(res, await handlePricingUpsert(await readJsonBody3(req), deps));
5649
+ return writeResult(res, await handlePricingUpsert(await readJsonBody4(req), deps));
5166
5650
  }
5167
5651
  if (method === "DELETE") {
5168
5652
  return writeResult(res, await handlePricingDelete(requestQuery(req), deps));
@@ -5173,7 +5657,7 @@ async function handlePricing(req, res, method, rest, deps) {
5173
5657
  return writeResult(res, await handlePricingFetchLatest(deps));
5174
5658
  }
5175
5659
  if (method === "POST" && rest.length === 1 && rest[0] === "resolve-conflicts") {
5176
- return writeResult(res, await handlePricingResolveConflicts(await readJsonBody3(req), deps));
5660
+ return writeResult(res, await handlePricingResolveConflicts(await readJsonBody4(req), deps));
5177
5661
  }
5178
5662
  return writeJsonError(res, 404, `unknown pricing route '${rest.join("/")}'`);
5179
5663
  }
@@ -5187,15 +5671,15 @@ function migrationDeps(deps) {
5187
5671
  }
5188
5672
  async function handleMigrationExport(req, res, method, deps) {
5189
5673
  if (method !== "POST") return writeJsonError(res, 405, `method ${method} not allowed on export`);
5190
- const body = await readJsonBody3(req);
5674
+ const body = await readJsonBody4(req);
5191
5675
  const result = await handleExport(body, migrationDeps(deps));
5192
- return writeJson3(res, result.status, result.body);
5676
+ return writeJson4(res, result.status, result.body);
5193
5677
  }
5194
5678
  async function handleMigrationImport(req, res, method, deps) {
5195
5679
  if (method !== "POST") return writeJsonError(res, 405, `method ${method} not allowed on import`);
5196
- const body = await readJsonBody3(req);
5680
+ const body = await readJsonBody4(req);
5197
5681
  const result = await handleImport(body, migrationDeps(deps));
5198
- return writeJson3(res, result.status, result.body);
5682
+ return writeJson4(res, result.status, result.body);
5199
5683
  }
5200
5684
  async function handleProviders(req, res, method, rest, deps) {
5201
5685
  const cfg = loadConfig(deps.configPath);
@@ -5226,13 +5710,13 @@ async function handleProviders(req, res, method, rest, deps) {
5226
5710
  if (method === "GET" && rest.length === 2 && rest[1] === "reveal-key") {
5227
5711
  const row = cfg.providers.find((p) => p.id === rest[0]);
5228
5712
  if (!row) return writeJsonError(res, 404, `provider '${rest[0]}' not found`);
5229
- return writeJson3(res, 200, { apiKey: row.apiKey ?? "" });
5713
+ return writeJson4(res, 200, { apiKey: row.apiKey ?? "" });
5230
5714
  }
5231
5715
  if (method === "GET") {
5232
- return writeJson3(res, 200, { providers: cfg.providers.map(toProviderView) });
5716
+ return writeJson4(res, 200, { providers: cfg.providers.map(toProviderView) });
5233
5717
  }
5234
5718
  if (method === "POST") {
5235
- const body = await readJsonBody3(req);
5719
+ const body = await readJsonBody4(req);
5236
5720
  const provider = parseProviderInput(body, void 0);
5237
5721
  if (!provider) return writeJsonError(res, 400, "invalid provider (id, apiFormat, baseUrl required)");
5238
5722
  if (cfg.providers.some((p) => p.id === provider.id)) {
@@ -5240,25 +5724,25 @@ async function handleProviders(req, res, method, rest, deps) {
5240
5724
  }
5241
5725
  cfg.providers.push(provider);
5242
5726
  persistProviders(cfg, deps);
5243
- return writeJson3(res, 201, { provider: toProviderView(provider) });
5727
+ return writeJson4(res, 201, { provider: toProviderView(provider) });
5244
5728
  }
5245
5729
  const id = rest[0];
5246
5730
  if (!id) return writeJsonError(res, 400, "provider id required in path");
5247
5731
  const idx = cfg.providers.findIndex((p) => p.id === id);
5248
5732
  if (idx < 0) return writeJsonError(res, 404, `provider '${id}' not found`);
5249
5733
  if (method === "PUT") {
5250
- const body = await readJsonBody3(req);
5734
+ const body = await readJsonBody4(req);
5251
5735
  const existing = cfg.providers[idx];
5252
5736
  const updated = parseProviderInput(body, existing);
5253
5737
  if (!updated) return writeJsonError(res, 400, "invalid provider (apiFormat, baseUrl required)");
5254
5738
  cfg.providers[idx] = updated;
5255
5739
  persistProviders(cfg, deps);
5256
- return writeJson3(res, 200, { provider: toProviderView(updated) });
5740
+ return writeJson4(res, 200, { provider: toProviderView(updated) });
5257
5741
  }
5258
5742
  if (method === "DELETE") {
5259
5743
  cfg.providers.splice(idx, 1);
5260
5744
  persistProviders(cfg, deps);
5261
- return writeJson3(res, 200, { ok: true });
5745
+ return writeJson4(res, 200, { ok: true });
5262
5746
  }
5263
5747
  return writeJsonError(res, 405, `method ${method} not allowed on providers`);
5264
5748
  }
@@ -5267,7 +5751,7 @@ function persistProviders(cfg, deps) {
5267
5751
  deps.llmConfig.reload(cfg);
5268
5752
  }
5269
5753
  async function handleProviderReorder(req, res, cfg, deps) {
5270
- const body = await readJsonBody3(req);
5754
+ const body = await readJsonBody4(req);
5271
5755
  const rawOrder = body["order"];
5272
5756
  if (!Array.isArray(rawOrder)) {
5273
5757
  return writeJsonError(res, 400, "reorder requires { order: string[] }");
@@ -5291,14 +5775,14 @@ async function handleProviderReorder(req, res, cfg, deps) {
5291
5775
  }
5292
5776
  cfg.providers = reordered;
5293
5777
  persistProviders(cfg, deps);
5294
- return writeJson3(res, 200, { ok: true, providers: cfg.providers.map(toProviderView) });
5778
+ return writeJson4(res, 200, { ok: true, providers: cfg.providers.map(toProviderView) });
5295
5779
  }
5296
5780
  async function handleDiscoverModels(res, id, cfg) {
5297
5781
  if (!id) return writeJsonError(res, 400, "provider id required in path");
5298
5782
  const row = cfg.providers.find((p) => p.id === id);
5299
5783
  if (!row) return writeJsonError(res, 404, `provider '${id}' not found`);
5300
5784
  if (row.apiFormat !== "openai" && row.apiFormat !== "openai-response") {
5301
- return writeJson3(res, 200, { models: [], unsupportedFormat: true });
5785
+ return writeJson4(res, 200, { models: [], unsupportedFormat: true });
5302
5786
  }
5303
5787
  const resolvedKey = resolveEnvKey(row.apiKey);
5304
5788
  const base = row.baseUrl.replace(/\/+$/, "");
@@ -5306,7 +5790,7 @@ async function handleDiscoverModels(res, id, cfg) {
5306
5790
  try {
5307
5791
  const headers = { Accept: "application/json" };
5308
5792
  if (resolvedKey) headers["Authorization"] = `Bearer ${resolvedKey}`;
5309
- const response = await (0, import_upstreamFetch3.fetchUpstream)(url, { method: "GET", headers }, { providerId: "byo" });
5793
+ const response = await (0, import_upstreamFetch4.fetchUpstream)(url, { method: "GET", headers }, { providerId: "byo" });
5310
5794
  if (!response.ok) {
5311
5795
  const text = await response.text().catch(() => "");
5312
5796
  let message = text.slice(0, 300);
@@ -5315,32 +5799,32 @@ async function handleDiscoverModels(res, id, cfg) {
5315
5799
  message = parsed?.error?.message || parsed?.message || message;
5316
5800
  } catch {
5317
5801
  }
5318
- return writeJson3(res, 200, {
5802
+ return writeJson4(res, 200, {
5319
5803
  models: [],
5320
5804
  error: `discovery failed (${response.status})${message ? `: ${message}` : ""}`
5321
5805
  });
5322
5806
  }
5323
5807
  const data = await response.json();
5324
5808
  const models = Array.isArray(data?.data) ? data.data.map((m) => typeof m?.id === "string" ? m.id : "").filter((m) => m.length > 0) : [];
5325
- return writeJson3(res, 200, { models });
5809
+ return writeJson4(res, 200, { models });
5326
5810
  } catch (err5) {
5327
5811
  const message = err5 instanceof Error ? err5.message : String(err5);
5328
- return writeJson3(res, 200, { models: [], error: `discovery failed: ${message}` });
5812
+ return writeJson4(res, 200, { models: [], error: `discovery failed: ${message}` });
5329
5813
  }
5330
5814
  }
5331
5815
  async function handleTestModel(req, res, id, cfg) {
5332
5816
  if (!id) return writeJsonError(res, 400, "provider id required in path");
5333
5817
  const row = cfg.providers.find((p) => p.id === id);
5334
5818
  if (!row) return writeJsonError(res, 404, `provider '${id}' not found`);
5335
- const body = await readJsonBody3(req);
5819
+ const body = await readJsonBody4(req);
5336
5820
  const model = typeof body["model"] === "string" ? body["model"].trim() : "";
5337
5821
  if (!model) return writeJsonError(res, 400, "test requires a { model } string");
5338
5822
  if (row.apiFormat === "gemini") {
5339
- return writeJson3(res, 200, { ok: false, unsupportedFormat: true });
5823
+ return writeJson4(res, 200, { ok: false, unsupportedFormat: true });
5340
5824
  }
5341
5825
  const resolvedKey = resolveEnvKey(row.apiKey);
5342
5826
  if (!resolvedKey) {
5343
- return writeJson3(res, 200, { ok: false, message: "no API key configured for this provider" });
5827
+ return writeJson4(res, 200, { ok: false, message: "no API key configured for this provider" });
5344
5828
  }
5345
5829
  let url = row.baseUrl.replace(/\/+$/, "");
5346
5830
  const prompt = "Reply with the single word: OK.";
@@ -5365,7 +5849,7 @@ async function handleTestModel(req, res, id, cfg) {
5365
5849
  }
5366
5850
  const startedAt = Date.now();
5367
5851
  try {
5368
- const response = await (0, import_upstreamFetch3.fetchUpstream)(
5852
+ const response = await (0, import_upstreamFetch4.fetchUpstream)(
5369
5853
  url,
5370
5854
  { method: "POST", headers, body: JSON.stringify(payload) },
5371
5855
  { providerId: "byo" }
@@ -5379,9 +5863,9 @@ async function handleTestModel(req, res, id, cfg) {
5379
5863
  message = parsed?.error?.message || parsed?.message || message;
5380
5864
  } catch {
5381
5865
  }
5382
- return writeJson3(res, 200, { ok: false, status: response.status, latencyMs, message });
5866
+ return writeJson4(res, 200, { ok: false, status: response.status, latencyMs, message });
5383
5867
  }
5384
- return writeJson3(res, 200, {
5868
+ return writeJson4(res, 200, {
5385
5869
  ok: true,
5386
5870
  status: response.status,
5387
5871
  latencyMs,
@@ -5389,7 +5873,7 @@ async function handleTestModel(req, res, id, cfg) {
5389
5873
  });
5390
5874
  } catch (err5) {
5391
5875
  const message = err5 instanceof Error ? err5.message : String(err5);
5392
- return writeJson3(res, 200, { ok: false, latencyMs: Date.now() - startedAt, message });
5876
+ return writeJson4(res, 200, { ok: false, latencyMs: Date.now() - startedAt, message });
5393
5877
  }
5394
5878
  }
5395
5879
  function extractSampleText(text, apiFormat) {
@@ -5430,7 +5914,7 @@ async function handleProviderKeys(res, id, cfg, deps) {
5430
5914
  const row = cfg.providers.find((p) => p.id === id);
5431
5915
  if (!row) return writeJsonError(res, 404, `provider '${id}' not found`);
5432
5916
  const cooldown = await deps.apiKeyPool.getKeyHealth(id);
5433
- return writeJson3(res, 200, { keys: toPoolKeyView(row, cooldown, deps) });
5917
+ return writeJson4(res, 200, { keys: toPoolKeyView(row, cooldown, deps) });
5434
5918
  }
5435
5919
  function parsePoolKeyInput(body, existing) {
5436
5920
  const out = {};
@@ -5449,7 +5933,7 @@ async function handleAddProviderKey(req, res, id, cfg, deps) {
5449
5933
  if (!id) return writeJsonError(res, 400, "provider id required in path");
5450
5934
  const idx = cfg.providers.findIndex((p) => p.id === id);
5451
5935
  if (idx < 0) return writeJsonError(res, 404, `provider '${id}' not found`);
5452
- const body = await readJsonBody3(req);
5936
+ const body = await readJsonBody4(req);
5453
5937
  const parsed = parsePoolKeyInput(body);
5454
5938
  if (!parsed.apiKey) return writeJsonError(res, 400, "add requires a non-empty apiKey");
5455
5939
  const keyId = `key-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;
@@ -5461,7 +5945,7 @@ async function handleAddProviderKey(req, res, id, cfg, deps) {
5461
5945
  row.apiKeys = [...row.apiKeys ?? [], entry];
5462
5946
  persistProviders(cfg, deps);
5463
5947
  const cooldown = await deps.apiKeyPool.getKeyHealth(id);
5464
- return writeJson3(res, 201, { keys: toPoolKeyView(row, cooldown, deps) });
5948
+ return writeJson4(res, 201, { keys: toPoolKeyView(row, cooldown, deps) });
5465
5949
  }
5466
5950
  async function handleUpdateProviderKey(req, res, id, keyId, cfg, deps) {
5467
5951
  if (!id) return writeJsonError(res, 400, "provider id required in path");
@@ -5471,7 +5955,7 @@ async function handleUpdateProviderKey(req, res, id, keyId, cfg, deps) {
5471
5955
  const row = cfg.providers[idx];
5472
5956
  const keyIdx = (row.apiKeys ?? []).findIndex((k) => k.id === keyId);
5473
5957
  if (keyIdx < 0) return writeJsonError(res, 404, `pool key '${keyId}' not found`);
5474
- const body = await readJsonBody3(req);
5958
+ const body = await readJsonBody4(req);
5475
5959
  const existing = row.apiKeys[keyIdx];
5476
5960
  const parsed = parsePoolKeyInput(body, existing);
5477
5961
  const entry = { id: keyId, apiKey: parsed.apiKey || existing.apiKey };
@@ -5481,7 +5965,7 @@ async function handleUpdateProviderKey(req, res, id, keyId, cfg, deps) {
5481
5965
  row.apiKeys[keyIdx] = entry;
5482
5966
  persistProviders(cfg, deps);
5483
5967
  const cooldown = await deps.apiKeyPool.getKeyHealth(id);
5484
- return writeJson3(res, 200, { keys: toPoolKeyView(row, cooldown, deps) });
5968
+ return writeJson4(res, 200, { keys: toPoolKeyView(row, cooldown, deps) });
5485
5969
  }
5486
5970
  async function handleDeleteProviderKey(res, id, keyId, cfg, deps) {
5487
5971
  if (!id) return writeJsonError(res, 400, "provider id required in path");
@@ -5495,7 +5979,7 @@ async function handleDeleteProviderKey(res, id, keyId, cfg, deps) {
5495
5979
  if (row.apiKeys.length === 0) row.apiKeys = void 0;
5496
5980
  persistProviders(cfg, deps);
5497
5981
  const cooldown = await deps.apiKeyPool.getKeyHealth(id);
5498
- return writeJson3(res, 200, { keys: toPoolKeyView(row, cooldown, deps) });
5982
+ return writeJson4(res, 200, { keys: toPoolKeyView(row, cooldown, deps) });
5499
5983
  }
5500
5984
  async function handleToggleProviderKey(req, res, id, keyId, cfg, deps) {
5501
5985
  if (!id) return writeJsonError(res, 400, "provider id required in path");
@@ -5505,11 +5989,11 @@ async function handleToggleProviderKey(req, res, id, keyId, cfg, deps) {
5505
5989
  const row = cfg.providers[idx];
5506
5990
  const keyIdx = (row.apiKeys ?? []).findIndex((k) => k.id === keyId);
5507
5991
  if (keyIdx < 0) return writeJsonError(res, 404, `pool key '${keyId}' not found`);
5508
- const body = await readJsonBody3(req);
5992
+ const body = await readJsonBody4(req);
5509
5993
  row.apiKeys[keyIdx].enabled = Boolean(body["enabled"]);
5510
5994
  persistProviders(cfg, deps);
5511
5995
  const cooldown = await deps.apiKeyPool.getKeyHealth(id);
5512
- return writeJson3(res, 200, { keys: toPoolKeyView(row, cooldown, deps) });
5996
+ return writeJson4(res, 200, { keys: toPoolKeyView(row, cooldown, deps) });
5513
5997
  }
5514
5998
  function parseApiKeysInput(raw, existing) {
5515
5999
  if (!Array.isArray(raw)) return existing;
@@ -5695,13 +6179,13 @@ function handlePresets(res, method) {
5695
6179
  website: p.website,
5696
6180
  modelsEndpoint: p.modelsEndpoint
5697
6181
  }));
5698
- return writeJson3(res, 200, { presets, excluded });
6182
+ return writeJson4(res, 200, { presets, excluded });
5699
6183
  }
5700
6184
  async function handleKeys(req, res, method, rest, deps) {
5701
6185
  if (method === "GET" && rest.length === 0) {
5702
6186
  const rows = await deps.keyDb.outboundApiKeysList();
5703
6187
  const reader = deps.keySpendReader;
5704
- if (!reader) return writeJson3(res, 200, { keys: rows.map(toKeyInfo) });
6188
+ if (!reader) return writeJson4(res, 200, { keys: rows.map(toKeyInfo) });
5705
6189
  const now = Date.now();
5706
6190
  const keys = await Promise.all(
5707
6191
  rows.map(async (row) => {
@@ -5713,13 +6197,13 @@ async function handleKeys(req, res, method, rest, deps) {
5713
6197
  return info;
5714
6198
  })
5715
6199
  );
5716
- return writeJson3(res, 200, { keys });
6200
+ return writeJson4(res, 200, { keys });
5717
6201
  }
5718
6202
  if (method === "POST" && rest.length === 0) {
5719
- const body = await readJsonBody3(req);
6203
+ const body = await readJsonBody4(req);
5720
6204
  const name = typeof body["name"] === "string" && body["name"].trim() ? body["name"].trim() : "key";
5721
- const created = await (0, import_outbound_api4.createNamedKey)(deps.keyDb, name);
5722
- return writeJson3(res, 201, {
6205
+ const created = await (0, import_outbound_api5.createNamedKey)(deps.keyDb, name);
6206
+ return writeJson4(res, 201, {
5723
6207
  id: created.id,
5724
6208
  name: created.name,
5725
6209
  keyPrefix: created.keyPrefix,
@@ -5730,7 +6214,7 @@ async function handleKeys(req, res, method, rest, deps) {
5730
6214
  }
5731
6215
  if (method === "GET" && rest.length === 2 && rest[1] === "reveal") {
5732
6216
  const revealed = await deps.keyDb.outboundApiKeysReveal(rest[0]);
5733
- if (revealed !== null) return writeJson3(res, 200, { key: revealed });
6217
+ if (revealed !== null) return writeJson4(res, 200, { key: revealed });
5734
6218
  const exists = (await deps.keyDb.outboundApiKeysList()).some((r) => r.id === rest[0]);
5735
6219
  if (!exists) return writeJsonError(res, 404, `key '${rest[0]}' not found`);
5736
6220
  return writeJsonError(
@@ -5745,32 +6229,32 @@ async function handleKeys(req, res, method, rest, deps) {
5745
6229
  const bound = await integrationKeyRequirement(deps, id);
5746
6230
  if (bound) return writeJsonError(res, 409, bound);
5747
6231
  const ok = await deps.keyDb.outboundApiKeysRevoke(id);
5748
- return writeJson3(res, ok ? 200 : 404, { ok });
6232
+ return writeJson4(res, ok ? 200 : 404, { ok });
5749
6233
  }
5750
6234
  if (method === "DELETE" && id && !action) {
5751
6235
  const bound = await integrationKeyRequirement(deps, id);
5752
6236
  if (bound) return writeJsonError(res, 409, bound);
5753
6237
  const ok = await deps.keyDb.outboundApiKeysDelete(id);
5754
- return writeJson3(res, ok ? 200 : 404, { ok });
6238
+ return writeJson4(res, ok ? 200 : 404, { ok });
5755
6239
  }
5756
6240
  if (method === "POST" && id && action === "enabled") {
5757
- const body = await readJsonBody3(req);
6241
+ const body = await readJsonBody4(req);
5758
6242
  const enabled = body["enabled"] === true;
5759
6243
  if (!enabled) {
5760
6244
  const bound = await integrationKeyRequirement(deps, id);
5761
6245
  if (bound) return writeJsonError(res, 409, bound);
5762
6246
  }
5763
6247
  const ok = await deps.keyDb.outboundApiKeysSetEnabled(id, enabled);
5764
- return writeJson3(res, ok ? 200 : 404, { ok, enabled });
6248
+ return writeJson4(res, ok ? 200 : 404, { ok, enabled });
5765
6249
  }
5766
6250
  if (method === "POST" && id && action === "permissions") {
5767
- const body = await readJsonBody3(req);
6251
+ const body = await readJsonBody4(req);
5768
6252
  if (Object.keys(body).length !== 1 || !Object.prototype.hasOwnProperty.call(body, "permissions")) {
5769
6253
  return writeJsonError(res, 400, "body must contain only permissions");
5770
6254
  }
5771
6255
  let permissions;
5772
6256
  try {
5773
- permissions = (0, import_outbound_api4.validateOutboundPermissions)(body["permissions"]);
6257
+ permissions = (0, import_outbound_api5.validateOutboundPermissions)(body["permissions"]);
5774
6258
  } catch {
5775
6259
  return writeJsonError(
5776
6260
  res,
@@ -5779,19 +6263,19 @@ async function handleKeys(req, res, method, rest, deps) {
5779
6263
  );
5780
6264
  }
5781
6265
  const before = (await deps.keyDb.outboundApiKeysList()).find((row) => row.id === id);
5782
- if (!before) return writeJson3(res, 404, { ok: false });
5783
- if (before.revokedAt !== null) return writeJson3(res, 409, { ok: false });
6266
+ if (!before) return writeJson4(res, 404, { ok: false });
6267
+ if (before.revokedAt !== null) return writeJson4(res, 409, { ok: false });
5784
6268
  const required = await integrationKeyRequirement(deps, id, permissions);
5785
6269
  if (required) return writeJsonError(res, 409, required);
5786
6270
  const ok = await deps.keyDb.outboundApiKeysSetPermissions(id, permissions);
5787
6271
  if (!ok) {
5788
6272
  const current = (await deps.keyDb.outboundApiKeysList()).find((row) => row.id === id);
5789
- return writeJson3(res, current?.revokedAt !== null ? 409 : 404, { ok: false });
6273
+ return writeJson4(res, current?.revokedAt !== null ? 409 : 404, { ok: false });
5790
6274
  }
5791
- return writeJson3(res, 200, { ok: true, allowedEndpoints: permissions });
6275
+ return writeJson4(res, 200, { ok: true, allowedEndpoints: permissions });
5792
6276
  }
5793
6277
  if (method === "POST" && id && action === "max-concurrency") {
5794
- const body = await readJsonBody3(req);
6278
+ const body = await readJsonBody4(req);
5795
6279
  const raw = body["maxConcurrency"];
5796
6280
  let value;
5797
6281
  if (raw === null) {
@@ -5806,14 +6290,14 @@ async function handleKeys(req, res, method, rest, deps) {
5806
6290
  );
5807
6291
  }
5808
6292
  const ok = await deps.keyDb.outboundApiKeysSetMaxConcurrency(id, value);
5809
- return writeJson3(res, ok ? 200 : 404, { ok, maxConcurrency: value });
6293
+ return writeJson4(res, ok ? 200 : 404, { ok, maxConcurrency: value });
5810
6294
  }
5811
6295
  if (method === "POST" && id && action === "policy") {
5812
- const body = await readJsonBody3(req);
6296
+ const body = await readJsonBody4(req);
5813
6297
  const parsed = parseKeyPolicyBody(body);
5814
6298
  if (!parsed.ok) return writeJsonError(res, 400, parsed.message);
5815
6299
  const ok = await deps.keyDb.outboundApiKeysSetPolicy(id, parsed.policy);
5816
- return writeJson3(res, ok ? 200 : 404, { ok });
6300
+ return writeJson4(res, ok ? 200 : 404, { ok });
5817
6301
  }
5818
6302
  return writeJsonError(res, 405, `method ${method} not allowed on keys`);
5819
6303
  }
@@ -5904,7 +6388,8 @@ function outboundServerConfigInput(config) {
5904
6388
  userMessageQueue: config.userMessageQueue,
5905
6389
  concurrencyQueue: config.concurrencyQueue,
5906
6390
  voucher: config.voucher,
5907
- anthropic: config.anthropic
6391
+ anthropic: config.anthropic,
6392
+ search: config.search
5908
6393
  };
5909
6394
  }
5910
6395
  function projectImagesConfigForAdmin(config) {
@@ -5940,8 +6425,8 @@ function sameConfigValue(left, right) {
5940
6425
  return JSON.stringify(left) === JSON.stringify(right);
5941
6426
  }
5942
6427
  function imageConfigurationAuditFields(previous, next) {
5943
- const before = previous ?? import_outbound_api4.DEFAULT_IMAGES_SERVER_CONFIG;
5944
- const after = next ?? import_outbound_api4.DEFAULT_IMAGES_SERVER_CONFIG;
6428
+ const before = previous ?? import_outbound_api5.DEFAULT_IMAGES_SERVER_CONFIG;
6429
+ const after = next ?? import_outbound_api5.DEFAULT_IMAGES_SERVER_CONFIG;
5945
6430
  const fields = [];
5946
6431
  if (before.enabled !== after.enabled) fields.push("enablement");
5947
6432
  if (before.provider !== after.provider) fields.push("provider");
@@ -5967,15 +6452,21 @@ function currentImageGenerationId(deps) {
5967
6452
  }
5968
6453
  async function handleServer(req, res, method, deps) {
5969
6454
  if (method === "GET") {
5970
- const config = await (0, import_outbound_api4.loadServerConfig)(deps.settingsStore);
6455
+ const config = await (0, import_outbound_api5.loadServerConfig)(deps.settingsStore);
5971
6456
  let server = config;
5972
6457
  if (config.proxy) server = { ...server, proxy: redactOutboundProxy(config.proxy) };
5973
6458
  if (config.webhook) server = { ...server, webhook: redactWebhookConfig(config.webhook) };
5974
6459
  if (config.billing) server = { ...server, billing: redactBillingConfig(config.billing) };
5975
- return writeJson3(res, 200, { server: projectImagesConfigForAdmin(server) });
6460
+ if (config.search) {
6461
+ server = {
6462
+ ...server,
6463
+ search: redactSearchServerConfig(config.search)
6464
+ };
6465
+ }
6466
+ return writeJson4(res, 200, { server: projectImagesConfigForAdmin(server) });
5976
6467
  }
5977
6468
  if (method === "PUT") {
5978
- const patch = await readJsonBody3(req);
6469
+ const patch = await readJsonBody4(req);
5979
6470
  const queueErrors = validateQueueSegments(patch);
5980
6471
  if (queueErrors.length > 0) {
5981
6472
  return writeJsonError(res, 400, `invalid queue config: ${queueErrors.join("; ")}`);
@@ -6004,7 +6495,7 @@ async function handleServer(req, res, method, deps) {
6004
6495
  if (billingErrors.length > 0) {
6005
6496
  return writeJsonError(res, 400, `invalid billing config: ${billingErrors.join("; ")}`);
6006
6497
  }
6007
- const current = await (0, import_outbound_api4.loadServerConfig)(deps.settingsStore);
6498
+ const current = await (0, import_outbound_api5.loadServerConfig)(deps.settingsStore);
6008
6499
  let effectivePatch = patch;
6009
6500
  if (patch.proxy) {
6010
6501
  effectivePatch = { ...effectivePatch, proxy: preserveOutboundProxySecrets(patch.proxy, current.proxy) };
@@ -6025,7 +6516,21 @@ async function handleServer(req, res, method, deps) {
6025
6516
  }
6026
6517
  effectivePatch = { ...effectivePatch, images };
6027
6518
  }
6028
- const merged = (0, import_outbound_api4.mergeServerConfig)(current, effectivePatch);
6519
+ if (patch.search !== void 0) {
6520
+ const searchPatch = preserveSearchSecrets(
6521
+ patch.search,
6522
+ current.search ?? import_outbound_api5.DEFAULT_SEARCH_SERVER_CONFIG
6523
+ );
6524
+ const searchErrors = (0, import_outbound_api5.validateSearchServerConfig)(searchPatch);
6525
+ if (searchErrors.length > 0) {
6526
+ return writeJsonError(res, 400, `invalid search config: ${searchErrors.join("; ")}`);
6527
+ }
6528
+ effectivePatch = {
6529
+ ...effectivePatch,
6530
+ search: searchPatch
6531
+ };
6532
+ }
6533
+ const merged = (0, import_outbound_api5.mergeServerConfig)(current, effectivePatch);
6029
6534
  const priorImageGenerationId = currentImageGenerationId(deps);
6030
6535
  try {
6031
6536
  await applyServerConfigTransaction(current, merged, {
@@ -6055,7 +6560,7 @@ async function handleServer(req, res, method, deps) {
6055
6560
  throw error;
6056
6561
  }
6057
6562
  },
6058
- persist: (next) => (0, import_outbound_api4.saveServerConfig)(deps.settingsStore, next),
6563
+ persist: (next) => (0, import_outbound_api5.saveServerConfig)(deps.settingsStore, next),
6059
6564
  restorePersisted: (snapshot) => deps.settingsStore.restoreDocumentSnapshot(snapshot)
6060
6565
  });
6061
6566
  } catch (error) {
@@ -6077,7 +6582,11 @@ async function handleServer(req, res, method, deps) {
6077
6582
  } catch {
6078
6583
  }
6079
6584
  }
6080
- return writeJson3(res, 200, { server: projectImagesConfigForAdmin(merged) });
6585
+ const mergedForAdmin = merged.search ? {
6586
+ ...merged,
6587
+ search: redactSearchServerConfig(merged.search)
6588
+ } : merged;
6589
+ return writeJson4(res, 200, { server: projectImagesConfigForAdmin(mergedForAdmin) });
6081
6590
  }
6082
6591
  return writeJsonError(res, 405, `method ${method} not allowed on server`);
6083
6592
  }
@@ -6094,7 +6603,7 @@ async function handleAccounts(req, res, method, rest, deps) {
6094
6603
  sessionKey: query2.get("sessionKey") ?? void 0,
6095
6604
  limit: Number.isFinite(parsedLimit) ? parsedLimit : 100
6096
6605
  });
6097
- return writeJson3(res, 200, {
6606
+ return writeJson4(res, 200, {
6098
6607
  available: true,
6099
6608
  records,
6100
6609
  capacity: import_AccountRouteActivity.ACCOUNT_ROUTE_ACTIVITY_LIMIT,
@@ -6110,7 +6619,7 @@ async function handleAccounts(req, res, method, rest, deps) {
6110
6619
  providerId: query2.get("providerId") ?? void 0,
6111
6620
  accountId: query2.get("accountId") ?? void 0
6112
6621
  });
6113
- return writeJson3(res, 200, {
6622
+ return writeJson4(res, 200, {
6114
6623
  available: true,
6115
6624
  entries,
6116
6625
  collectedAt: Date.now()
@@ -6129,10 +6638,10 @@ async function handleAccounts(req, res, method, rest, deps) {
6129
6638
  const accounts = await deps.subscriptionAccounts.listAll();
6130
6639
  const providerAccounts = await deps.subscriptionTokenWriter.listSanitizedAccounts();
6131
6640
  const externalCli = await deps.subscriptionTokenWriter.listExternalCliAvailability();
6132
- return writeJson3(res, 200, { accounts, providerAccounts, externalCli });
6641
+ return writeJson4(res, 200, { accounts, providerAccounts, externalCli });
6133
6642
  }
6134
6643
  if (method === "POST" && rest[0] === "batch" && rest.length === 1) {
6135
- const body = await readJsonBody3(req);
6644
+ const body = await readJsonBody4(req);
6136
6645
  const parsed = validateAccountBatchBody(body);
6137
6646
  if (!parsed) return writeJsonError(res, 400, "invalid account batch request");
6138
6647
  const result = await deps.subscriptionTokenWriter.batchManageAccounts(parsed.refs, parsed.mutation);
@@ -6148,15 +6657,15 @@ async function handleAccounts(req, res, method, rest, deps) {
6148
6657
  deps.accountAllowanceService?.removeAccountSnapshot?.(ref.providerId, ref.accountId);
6149
6658
  }
6150
6659
  }
6151
- return writeJson3(res, 200, { ok: true, affected: result.affected });
6660
+ return writeJson4(res, 200, { ok: true, affected: result.affected });
6152
6661
  }
6153
6662
  if (method === "GET" && rest[0] === "codex" && rest[1] === "oauth" && rest[3] === "status") {
6154
6663
  const result = handleCodexOAuthStatus(rest[2], deps);
6155
- return writeJson3(res, result.status, result.body);
6664
+ return writeJson4(res, result.status, result.body);
6156
6665
  }
6157
6666
  if (method === "DELETE" && rest[0] === "codex" && rest[1] === "oauth" && rest[2]) {
6158
6667
  const result = handleCodexOAuthCancel(rest[2], deps);
6159
- return writeJson3(res, result.status, result.body);
6668
+ return writeJson4(res, result.status, result.body);
6160
6669
  }
6161
6670
  if (method === "GET" && rest.length === 3 && rest[2] === "diagnostics") {
6162
6671
  const providerId = asSubscriptionProviderId(rest[0]);
@@ -6178,7 +6687,7 @@ async function handleAccounts(req, res, method, rest, deps) {
6178
6687
  resumeAt: entry.resumeAt
6179
6688
  })) ?? [];
6180
6689
  const diagnostics = [...health2, ...allowance].sort((left, right) => right.at - left.at).slice(0, 200);
6181
- return writeJson3(res, 200, { diagnostics });
6690
+ return writeJson4(res, 200, { diagnostics });
6182
6691
  }
6183
6692
  if (method === "GET" && rest.length === 3 && rest[2] === "events") {
6184
6693
  const providerId = asSubscriptionProviderId(rest[0]);
@@ -6190,17 +6699,17 @@ async function handleAccounts(req, res, method, rest, deps) {
6190
6699
  }
6191
6700
  const snapshot = deps.accountProbeService?.getAllHistory().find((entry) => entry.providerId === providerId && entry.accountId === accountId);
6192
6701
  const diagnostics = (0, import_SubscriptionAccountHealth.getSharedAccountHealth)().getDiagnostics({ providerId, accountId });
6193
- return writeJson3(res, 200, { events: snapshot?.records ?? [], diagnostics });
6702
+ return writeJson4(res, 200, { events: snapshot?.records ?? [], diagnostics });
6194
6703
  }
6195
6704
  if (method === "PATCH" && rest.length === 2) {
6196
6705
  const providerId = asSubscriptionProviderId(rest[0]);
6197
6706
  if (!providerId) return writeJsonError(res, 400, `unknown subscription provider '${rest[0] ?? ""}'`);
6198
- const body = await readJsonBody3(req);
6707
+ const body = await readJsonBody4(req);
6199
6708
  const patch = validateAccountMetadataPatch(body);
6200
6709
  if (!patch) return writeJsonError(res, 400, "invalid account metadata patch");
6201
6710
  const result = await deps.subscriptionTokenWriter.patchAccountMetadata(providerId, rest[1], patch);
6202
6711
  if (!result.ok) return writeJsonError(res, 404, `account '${rest[1]}' not found`);
6203
- return writeJson3(res, 200, { ok: true });
6712
+ return writeJson4(res, 200, { ok: true });
6204
6713
  }
6205
6714
  if (method === "PUT" || method === "POST" || method === "DELETE") {
6206
6715
  const providerId = asSubscriptionProviderId(rest[0]);
@@ -6209,15 +6718,15 @@ async function handleAccounts(req, res, method, rest, deps) {
6209
6718
  }
6210
6719
  if (method === "POST" && rest[1] === "oauth" && rest[2] === "start") {
6211
6720
  const result = providerId === "codex" ? handleCodexOAuthStart(deps) : handleOAuthStart(providerId, deps);
6212
- return writeJson3(res, result.status, result.body);
6721
+ return writeJson4(res, result.status, result.body);
6213
6722
  }
6214
6723
  if (method === "POST" && rest[1] === "oauth" && rest[2] === "complete") {
6215
- const body2 = await readJsonBody3(req);
6724
+ const body2 = await readJsonBody4(req);
6216
6725
  const result = await handleOAuthComplete(providerId, body2, deps);
6217
- return writeJson3(res, result.status, result.body);
6726
+ return writeJson4(res, result.status, result.body);
6218
6727
  }
6219
6728
  if (method === "POST" && rest[1] === "accounts") {
6220
- const body2 = await readJsonBody3(req);
6729
+ const body2 = await readJsonBody4(req);
6221
6730
  const block = validateTokenBody(providerId, body2);
6222
6731
  if (!block) {
6223
6732
  return writeJsonError(res, 400, `malformed token body for provider '${providerId}'`);
@@ -6225,20 +6734,20 @@ async function handleAccounts(req, res, method, rest, deps) {
6225
6734
  const label = typeof body2["label"] === "string" && body2["label"].trim() ? body2["label"].trim() : void 0;
6226
6735
  await deps.subscriptionAccountAppender.appendProviderAccount(providerId, block, label);
6227
6736
  const status2 = await statusEntryFor(deps.subscriptionAccounts, providerId);
6228
- return writeJson3(res, 200, status2 ? { account: status2 } : { ok: true });
6737
+ return writeJson4(res, 200, status2 ? { account: status2 } : { ok: true });
6229
6738
  }
6230
6739
  if (method === "POST" && rest[1] === "import-external") {
6231
6740
  if (providerId !== "claude" && providerId !== "codex") {
6232
6741
  return writeJsonError(res, 400, `provider '${providerId}' has no external CLI store`);
6233
6742
  }
6234
- const body2 = await readJsonBody3(req);
6743
+ const body2 = await readJsonBody4(req);
6235
6744
  const label = typeof body2["label"] === "string" && body2["label"].trim() ? body2["label"].trim() : void 0;
6236
6745
  const result = await deps.subscriptionTokenWriter.importExternalCliAccount(providerId, label);
6237
6746
  if (!result.ok) {
6238
6747
  return writeJsonError(res, 409, `no usable external ${providerId} CLI credential found`);
6239
6748
  }
6240
6749
  const status2 = await statusEntryFor(deps.subscriptionAccounts, providerId);
6241
- return writeJson3(res, 200, {
6750
+ return writeJson4(res, 200, {
6242
6751
  ok: true,
6243
6752
  account: status2 ?? void 0,
6244
6753
  nativeCredentialMode: result.nativeCredentialMode,
@@ -6253,7 +6762,7 @@ async function handleAccounts(req, res, method, rest, deps) {
6253
6762
  const writer2 = deps.subscriptionTokenWriter;
6254
6763
  const ok = providerId === "claude" ? await writer2.refreshClaudeToken() : providerId === "codex" ? await writer2.refreshCodexToken() : await writer2.refreshGeminiToken();
6255
6764
  const status2 = await statusEntryFor(deps.subscriptionAccounts, providerId);
6256
- return writeJson3(res, 200, { ok, account: status2 ?? void 0 });
6765
+ return writeJson4(res, 200, { ok, account: status2 ?? void 0 });
6257
6766
  }
6258
6767
  if (method === "POST" && rest.length === 3 && rest[2] === "test") {
6259
6768
  const accountId = rest[1];
@@ -6263,7 +6772,7 @@ async function handleAccounts(req, res, method, rest, deps) {
6263
6772
  return writeJsonError(res, 404, `account '${accountId}' not found`);
6264
6773
  }
6265
6774
  const result = await deps.accountProbeService.testAccountConnection(providerId, accountId);
6266
- return writeJson3(res, 200, {
6775
+ return writeJson4(res, 200, {
6267
6776
  ok: result.ok,
6268
6777
  marked: result.marked,
6269
6778
  tier: result.tier,
@@ -6272,15 +6781,15 @@ async function handleAccounts(req, res, method, rest, deps) {
6272
6781
  }
6273
6782
  if (method === "POST" && rest[2] === "label") {
6274
6783
  const accountId = rest[1];
6275
- const body2 = await readJsonBody3(req);
6784
+ const body2 = await readJsonBody4(req);
6276
6785
  const label = typeof body2["label"] === "string" ? body2["label"].trim() : "";
6277
6786
  const result = await deps.subscriptionTokenWriter.renameAccount(providerId, accountId, label);
6278
6787
  if (!result.ok) return writeJsonError(res, 404, `account '${accountId}' not found`);
6279
- return writeJson3(res, 200, { ok: true });
6788
+ return writeJson4(res, 200, { ok: true });
6280
6789
  }
6281
6790
  if (method === "POST" && rest[2] === "priority") {
6282
6791
  const accountId = rest[1];
6283
- const body2 = await readJsonBody3(req);
6792
+ const body2 = await readJsonBody4(req);
6284
6793
  const raw = body2["priority"];
6285
6794
  const priority = typeof raw === "number" ? raw : Number(raw);
6286
6795
  if (!Number.isFinite(priority)) {
@@ -6288,76 +6797,76 @@ async function handleAccounts(req, res, method, rest, deps) {
6288
6797
  }
6289
6798
  const result = await deps.subscriptionTokenWriter.setAccountPriority(providerId, accountId, priority);
6290
6799
  if (!result.ok) return writeJsonError(res, 404, `account '${accountId}' not found`);
6291
- return writeJson3(res, 200, { ok: true });
6800
+ return writeJson4(res, 200, { ok: true });
6292
6801
  }
6293
6802
  if (method === "POST" && rest[2] === "proxy") {
6294
6803
  const accountId = rest[1];
6295
- const body2 = await readJsonBody3(req);
6804
+ const body2 = await readJsonBody4(req);
6296
6805
  const rawProxy = body2["proxy"];
6297
6806
  let proxy;
6298
6807
  if (rawProxy !== null && rawProxy !== void 0) {
6299
- proxy = (0, import_outbound_api4.normalizeProxyConfig)(rawProxy);
6808
+ proxy = (0, import_outbound_api5.normalizeProxyConfig)(rawProxy);
6300
6809
  if (!proxy) return writeJsonError(res, 400, "invalid proxy config");
6301
6810
  }
6302
6811
  const result = await deps.subscriptionTokenWriter.setAccountProxy(providerId, accountId, proxy);
6303
6812
  if (!result.ok) return writeJsonError(res, 404, `account '${accountId}' not found`);
6304
- return writeJson3(res, 200, { ok: true });
6813
+ return writeJson4(res, 200, { ok: true });
6305
6814
  }
6306
6815
  if (method === "POST" && rest[2] === "supported-models") {
6307
6816
  const accountId = rest[1];
6308
- const body2 = await readJsonBody3(req);
6817
+ const body2 = await readJsonBody4(req);
6309
6818
  const parsed = validateSupportedModelsBody(body2["supportedModels"]);
6310
6819
  if (!parsed.ok) return writeJsonError(res, 400, "invalid supportedModels");
6311
6820
  const result = await deps.subscriptionTokenWriter.setAccountSupportedModels(providerId, accountId, parsed.value);
6312
6821
  if (!result.ok) return writeJsonError(res, 404, `account '${accountId}' not found`);
6313
- return writeJson3(res, 200, { ok: true });
6822
+ return writeJson4(res, 200, { ok: true });
6314
6823
  }
6315
6824
  if (method === "PUT" && rest[1] === "active") {
6316
- const body2 = await readJsonBody3(req);
6825
+ const body2 = await readJsonBody4(req);
6317
6826
  const id = typeof body2["id"] === "string" ? body2["id"] : "";
6318
6827
  if (!id) return writeJsonError(res, 400, "active switch requires { id }");
6319
6828
  const result = await deps.subscriptionTokenWriter.setActiveAccount(providerId, id);
6320
6829
  if (!result.ok) return writeJsonError(res, 404, `account '${id}' not found`);
6321
- return writeJson3(res, 200, { ok: true });
6830
+ return writeJson4(res, 200, { ok: true });
6322
6831
  }
6323
6832
  if (method === "DELETE" && rest.length === 2) {
6324
6833
  const accountId = rest[1];
6325
6834
  const result = await deps.subscriptionTokenWriter.removeAccount(providerId, accountId);
6326
6835
  if (!result.removed) return writeJsonError(res, 404, `account '${accountId}' not found`);
6327
6836
  deps.accountAllowanceService?.removeAccountSnapshot?.(providerId, accountId);
6328
- return writeJson3(res, 200, { ok: true });
6837
+ return writeJson4(res, 200, { ok: true });
6329
6838
  }
6330
6839
  if (method === "DELETE" && rest.length === 1) {
6331
6840
  await deps.subscriptionTokenWriter.clearProvider(providerId);
6332
6841
  deps.accountAllowanceService?.removeProviderSnapshots?.(providerId);
6333
- return writeJson3(res, 200, { ok: true });
6842
+ return writeJson4(res, 200, { ok: true });
6334
6843
  }
6335
6844
  if (method === "DELETE") {
6336
6845
  return writeJsonError(res, 405, "method DELETE not allowed on this accounts path");
6337
6846
  }
6338
- const body = await readJsonBody3(req);
6847
+ const body = await readJsonBody4(req);
6339
6848
  const config = validateTokenBody(providerId, body);
6340
6849
  if (!config) {
6341
6850
  return writeJsonError(res, 400, `malformed token body for provider '${providerId}'`);
6342
6851
  }
6343
6852
  await deps.subscriptionTokenWriter.writeProviderTokens(providerId, config);
6344
6853
  const status = await statusEntryFor(deps.subscriptionAccounts, providerId);
6345
- return writeJson3(res, 200, status ? { account: status } : { ok: true });
6854
+ return writeJson4(res, 200, status ? { account: status } : { ok: true });
6346
6855
  }
6347
6856
  return writeJsonError(res, 405, `method ${method} not allowed on accounts`);
6348
6857
  }
6349
6858
  async function handleCli(req, res, method, rest, deps) {
6350
6859
  if (method === "GET" && rest.length === 0) {
6351
6860
  const result = handleCliList(process.platform, deps.cliPathProbe);
6352
- return writeJson3(res, result.status, result.body);
6861
+ return writeJson4(res, result.status, result.body);
6353
6862
  }
6354
6863
  if (method === "GET" && rest[0] === "sessions") {
6355
6864
  const result = handleCliSessions();
6356
- return writeJson3(res, result.status, result.body);
6865
+ return writeJson4(res, result.status, result.body);
6357
6866
  }
6358
6867
  if (method === "DELETE" && rest[0] === "sessions" && rest[1]) {
6359
6868
  const result = handleCliStop(rest[1]);
6360
- return writeJson3(res, result.status, result.body);
6869
+ return writeJson4(res, result.status, result.body);
6361
6870
  }
6362
6871
  if (method === "POST" && rest[1] === "install") {
6363
6872
  const cli = rest[0];
@@ -6365,14 +6874,14 @@ async function handleCli(req, res, method, rest, deps) {
6365
6874
  return writeJsonError(res, 400, `unknown cli '${cli ?? ""}'`);
6366
6875
  }
6367
6876
  const result = await handleCliInstall(cli, deps.cliCommandRunner);
6368
- return writeJson3(res, result.status, result.body);
6877
+ return writeJson4(res, result.status, result.body);
6369
6878
  }
6370
6879
  if (method === "POST" && rest[1] === "launch") {
6371
6880
  const cli = rest[0];
6372
6881
  if (!isLaunchCliId(cli)) {
6373
6882
  return writeJsonError(res, 400, `unknown cli '${cli ?? ""}'`);
6374
6883
  }
6375
- const body = await readJsonBody3(req);
6884
+ const body = await readJsonBody4(req);
6376
6885
  const providers = loadConfig(deps.configPath).providers ?? [];
6377
6886
  const result = await handleCliLaunch(cli, body, {
6378
6887
  llmConfig: deps.llmConfig,
@@ -6381,7 +6890,7 @@ async function handleCli(req, res, method, rest, deps) {
6381
6890
  opener: deps.cliTerminalOpener,
6382
6891
  probe: deps.cliPathProbe
6383
6892
  });
6384
- return writeJson3(res, result.status, result.body);
6893
+ return writeJson4(res, result.status, result.body);
6385
6894
  }
6386
6895
  return writeJsonError(res, 405, `method ${method} not allowed on cli`);
6387
6896
  }
@@ -6391,52 +6900,52 @@ async function handleIntegrations(req, res, method, rest, deps) {
6391
6900
  const manager = factory();
6392
6901
  try {
6393
6902
  if (method === "GET" && rest.length === 0) {
6394
- return writeJson3(res, 200, {
6903
+ return writeJson4(res, 200, {
6395
6904
  integrations: await manager.listStatus(),
6396
6905
  gateway: deps.outboundApiServer.getStatus()
6397
6906
  });
6398
6907
  }
6399
6908
  if (method === "POST" && rest.length === 1 && rest[0] === "rotate") {
6400
6909
  await manager.rotateGatewayKey();
6401
- return writeJson3(res, 200, { ok: true, integrations: await manager.listStatus() });
6910
+ return writeJson4(res, 200, { ok: true, integrations: await manager.listStatus() });
6402
6911
  }
6403
6912
  const client = rest[0];
6404
6913
  if (!isIntegrationClient(client)) {
6405
6914
  return writeJsonError(res, 400, `unknown integration client '${client ?? ""}'`);
6406
6915
  }
6407
6916
  if (method === "POST" && rest[1] === "key") {
6408
- const body = await readJsonBody3(req);
6917
+ const body = await readJsonBody4(req);
6409
6918
  if (Object.keys(body).length !== 1 || typeof body.keyId !== "string" || !body.keyId.trim()) {
6410
6919
  return writeJsonError(res, 400, "body must contain a non-empty keyId string");
6411
6920
  }
6412
6921
  const status = await manager.bindIntegrationKey(client, body.keyId.trim());
6413
- return writeJson3(res, 200, { integration: status });
6922
+ return writeJson4(res, 200, { integration: status });
6414
6923
  }
6415
6924
  if (method === "POST" && rest[1] === "plan") {
6416
- const body = await readJsonBody3(req);
6925
+ const body = await readJsonBody4(req);
6417
6926
  const configPath = body.configPath;
6418
6927
  if (configPath !== void 0 && typeof configPath !== "string") {
6419
6928
  return writeJsonError(res, 400, "configPath must be a string");
6420
6929
  }
6421
6930
  const plan = await manager.plan(client, configPath);
6422
- return writeJson3(res, 200, { plan });
6931
+ return writeJson4(res, 200, { plan });
6423
6932
  }
6424
6933
  if (method === "POST" && (rest[1] === "install" || rest[1] === "apply")) {
6425
- const body = await readJsonBody3(req);
6934
+ const body = await readJsonBody4(req);
6426
6935
  const configPath = body.configPath;
6427
6936
  if (configPath !== void 0 && typeof configPath !== "string") {
6428
6937
  return writeJsonError(res, 400, "configPath must be a string");
6429
6938
  }
6430
6939
  const status = await manager.install(client, configPath);
6431
- return writeJson3(res, 200, { integration: status });
6940
+ return writeJson4(res, 200, { integration: status });
6432
6941
  }
6433
6942
  if (method === "POST" && rest[1] === "repair") {
6434
6943
  const status = await manager.repair(client);
6435
- return writeJson3(res, 200, { integration: status });
6944
+ return writeJson4(res, 200, { integration: status });
6436
6945
  }
6437
6946
  if (method === "DELETE" && rest.length === 1 || method === "POST" && rest[1] === "remove") {
6438
6947
  const status = await manager.remove(client);
6439
- return writeJson3(res, 200, { integration: status });
6948
+ return writeJson4(res, 200, { integration: status });
6440
6949
  }
6441
6950
  return writeJsonError(res, 405, `method ${method} not allowed on integrations`);
6442
6951
  } catch (error) {
@@ -6579,8 +7088,8 @@ async function handleImages(res, method, rest, deps) {
6579
7088
  }
6580
7089
  const reader = deps.imageRuntimeStatus;
6581
7090
  if (!reader) return writeJsonError(res, 501, "Images runtime status is not available");
6582
- const serverConfig = await (0, import_outbound_api4.loadServerConfig)(deps.settingsStore);
6583
- const images = serverConfig.images ?? import_outbound_api4.DEFAULT_IMAGES_SERVER_CONFIG;
7091
+ const serverConfig = await (0, import_outbound_api5.loadServerConfig)(deps.settingsStore);
7092
+ const images = serverConfig.images ?? import_outbound_api5.DEFAULT_IMAGES_SERVER_CONFIG;
6584
7093
  const lifecycle = reader.status();
6585
7094
  const capability = await reader.inspectCapability(IMAGE_ADMIN_STATUS_TENANT);
6586
7095
  const resources = safeRuntimeResources(reader.resourceStatus());
@@ -6599,7 +7108,7 @@ async function handleImages(res, method, rest, deps) {
6599
7108
  httpLeases: safeStatusCount(generation.httpLeases),
6600
7109
  hostedLeases: safeStatusCount(generation.hostedLeases)
6601
7110
  }));
6602
- return writeJson3(res, 200, {
7111
+ return writeJson4(res, 200, {
6603
7112
  configured: {
6604
7113
  enabled: images.enabled,
6605
7114
  provider: images.provider,
@@ -6627,11 +7136,11 @@ async function handleImages(res, method, rest, deps) {
6627
7136
  async function handleStatus(res, method, deps) {
6628
7137
  if (method !== "GET") return writeJsonError(res, 405, `method ${method} not allowed on status`);
6629
7138
  const status = deps.outboundApiServer.getStatus();
6630
- const serverConfig = await (0, import_outbound_api4.loadServerConfig)(deps.settingsStore);
7139
+ const serverConfig = await (0, import_outbound_api5.loadServerConfig)(deps.settingsStore);
6631
7140
  const endpoints = ["chat", "responses", "messages", "gemini"].map((endpoint) => {
6632
- const routes = (serverConfig.bindings ?? []).filter((binding) => binding.enabled && binding.endpoint === endpoint).map((binding) => (0, import_outbound_api4.gatewayBindingToEndpointConfig)(binding));
7141
+ const routes = (serverConfig.bindings ?? []).filter((binding) => binding.enabled && binding.endpoint === endpoint).map((binding) => (0, import_outbound_api5.gatewayBindingToEndpointConfig)(binding));
6633
7142
  const useSubscription = routes.some((route) => route.useSubscription);
6634
- if ((0, import_outbound_api4.isKindMappedEndpoint)(endpoint)) {
7143
+ if ((0, import_outbound_api5.isKindMappedEndpoint)(endpoint)) {
6635
7144
  const kinds = {};
6636
7145
  for (const route of routes) {
6637
7146
  for (const [kind, ref] of Object.entries(route.modelMap ?? {})) {
@@ -6665,14 +7174,14 @@ async function handleStatus(res, method, deps) {
6665
7174
  })() : void 0;
6666
7175
  if (status.running) {
6667
7176
  const queueStatus = deps.outboundApiServer.getQueueStatus();
6668
- return writeJson3(res, 200, {
7177
+ return writeJson4(res, 200, {
6669
7178
  ...status,
6670
7179
  endpoints,
6671
7180
  queueStatus,
6672
7181
  ...imageRuntime ? { imageRuntime } : {}
6673
7182
  });
6674
7183
  }
6675
- return writeJson3(res, 200, {
7184
+ return writeJson4(res, 200, {
6676
7185
  ...status,
6677
7186
  endpoints,
6678
7187
  ...imageRuntime ? { imageRuntime } : {}
@@ -6696,18 +7205,18 @@ function resolvePlaygroundPath(endpoint, body) {
6696
7205
  }
6697
7206
  async function handlePlayground(req, res, method, deps) {
6698
7207
  if (method !== "POST") return writeJsonError(res, 405, `method ${method} not allowed on playground`);
6699
- const body = await readJsonBody3(req);
7208
+ const body = await readJsonBody4(req);
6700
7209
  const endpoint = typeof body["endpoint"] === "string" ? body["endpoint"] : "";
6701
7210
  const key = typeof body["key"] === "string" ? body["key"] : "";
6702
7211
  const payload = body["body"];
6703
7212
  const status = deps.outboundApiServer.getStatus();
6704
7213
  if (!status.running || !status.port) return writeJsonError(res, 503, "outbound server not running");
6705
- const path2 = resolvePlaygroundPath(endpoint, isRecord2(payload) ? payload : {});
7214
+ const path2 = resolvePlaygroundPath(endpoint, isRecord3(payload) ? payload : {});
6706
7215
  if (!path2) return writeJsonError(res, 400, `unknown endpoint '${endpoint}'`);
6707
7216
  const upstreamBody = typeof payload === "string" ? payload : JSON.stringify(payload ?? {});
6708
7217
  await proxyToOutbound(res, status.port, path2, key, upstreamBody);
6709
7218
  }
6710
- function isRecord2(v) {
7219
+ function isRecord3(v) {
6711
7220
  return !!v && typeof v === "object" && !Array.isArray(v);
6712
7221
  }
6713
7222
  function proxyToOutbound(res, outboundPort, path2, key, body) {
@@ -6843,7 +7352,7 @@ async function handleUiStatic(req, res, urlPath, uiDist) {
6843
7352
  }
6844
7353
 
6845
7354
  // src/admin/version.ts
6846
- var DAEMON_VERSION = true ? "0.2.0" : "0.0.0-dev";
7355
+ var DAEMON_VERSION = true ? "0.3.0" : "0.0.0-dev";
6847
7356
 
6848
7357
  // src/admin/AdminServer.ts
6849
7358
  var LOOPBACK_ADDR = "127.0.0.1";
@@ -7296,14 +7805,14 @@ function defaultBillingDir(configPath) {
7296
7805
 
7297
7806
  // src/image-generation/ImageDoctorService.ts
7298
7807
  var import_image_generation = require("@omnicross/core/image-generation");
7299
- var import_outbound_api6 = require("@omnicross/core/outbound-api");
7808
+ var import_outbound_api7 = require("@omnicross/core/outbound-api");
7300
7809
  var import_subscriptions3 = require("@omnicross/subscriptions");
7301
7810
 
7302
7811
  // src/image-generation/FileCodexImageCapabilityEvidenceSource.ts
7303
7812
  var import_node_crypto13 = require("crypto");
7304
7813
  var import_node_fs10 = require("fs");
7305
7814
  var import_node_path11 = require("path");
7306
- var import_outbound_api5 = require("@omnicross/core/outbound-api");
7815
+ var import_outbound_api6 = require("@omnicross/core/outbound-api");
7307
7816
 
7308
7817
  // src/image-generation/imageTenantHmac.ts
7309
7818
  var import_node_crypto12 = require("crypto");
@@ -7376,7 +7885,7 @@ var ACCOUNT_DOMAIN = Buffer.from("omnicross:codex-image-evidence:account:v1\0",
7376
7885
  var ACCOUNT_KEY = /^[a-f0-9]{64}$/u;
7377
7886
  var SIZE = /^(?:auto|[1-9][0-9]{1,4}x[1-9][0-9]{1,4})$/u;
7378
7887
  var MAX_MANIFEST_BYTES = 4 * 1024 * 1024;
7379
- var PHYSICAL_RETENTION_TTL_MS = import_outbound_api5.IMAGE_SERVER_HARD_CEILINGS.evidenceTtlMs;
7888
+ var PHYSICAL_RETENTION_TTL_MS = import_outbound_api6.IMAGE_SERVER_HARD_CEILINGS.evidenceTtlMs;
7380
7889
  function exactKeys(value, allowed) {
7381
7890
  const allow = new Set(allowed);
7382
7891
  return Object.keys(value).every((key) => allow.has(key));
@@ -7750,7 +8259,7 @@ function createImageDoctorService(options) {
7750
8259
  const activePaths = () => options.storageCatalog.active().resolver;
7751
8260
  return Object.freeze({
7752
8261
  inspectLocal: async (config) => {
7753
- const configErrors = (0, import_outbound_api6.validateImagesServerConfig)(config);
8262
+ const configErrors = (0, import_outbound_api7.validateImagesServerConfig)(config);
7754
8263
  let verifiedAreas = 0;
7755
8264
  try {
7756
8265
  const paths = activePaths();
@@ -7792,7 +8301,7 @@ function createImageDoctorService(options) {
7792
8301
  continue;
7793
8302
  }
7794
8303
  try {
7795
- const permissions = (0, import_outbound_api6.validateOutboundPermissions)(row.allowedEndpoints);
8304
+ const permissions = (0, import_outbound_api7.validateOutboundPermissions)(row.allowedEndpoints);
7796
8305
  if (permissions.includes("images")) imagesAuthorizedRows += 1;
7797
8306
  } catch {
7798
8307
  invalidRows += 1;
@@ -8096,7 +8605,7 @@ var ImageCleanupService = class {
8096
8605
  // src/image-generation/ImageRuntimeGenerationFactory.ts
8097
8606
  var import_node_crypto16 = require("crypto");
8098
8607
  var import_image_generation5 = require("@omnicross/core/image-generation");
8099
- var import_outbound_api7 = require("@omnicross/core/outbound-api");
8608
+ var import_outbound_api8 = require("@omnicross/core/outbound-api");
8100
8609
  var import_subscriptions4 = require("@omnicross/subscriptions");
8101
8610
 
8102
8611
  // src/image-generation/ImageApiRuntimeResolver.ts
@@ -8564,7 +9073,7 @@ function createImageRuntimeGeneration(options) {
8564
9073
  throw new TypeError("image runtime generation id is invalid");
8565
9074
  }
8566
9075
  const config = snapshotConfig(options.config);
8567
- const configErrors = (0, import_outbound_api7.validateImagesServerConfig)(config);
9076
+ const configErrors = (0, import_outbound_api8.validateImagesServerConfig)(config);
8568
9077
  if (configErrors.length > 0) {
8569
9078
  throw new TypeError(`image runtime configuration is invalid: ${configErrors[0]}`);
8570
9079
  }
@@ -12156,7 +12665,7 @@ function safeStringify(value) {
12156
12665
  var import_node_crypto20 = require("crypto");
12157
12666
  var import_node_fs16 = require("fs");
12158
12667
  var import_node_path17 = require("path");
12159
- var import_outbound_api8 = require("@omnicross/core/outbound-api");
12668
+ var import_outbound_api9 = require("@omnicross/core/outbound-api");
12160
12669
  function atomicReplaceDocument(targetPath, contents) {
12161
12670
  const tempPath = (0, import_node_path17.join)(
12162
12671
  (0, import_node_path17.dirname)(targetPath),
@@ -12204,13 +12713,13 @@ var JsonApiServerSettingsStore = class {
12204
12713
  box;
12205
12714
  atomicReplace;
12206
12715
  async get(key) {
12207
- if (key !== import_outbound_api8.OUTBOUND_API_SERVER_CONFIG_KEY) return void 0;
12716
+ if (key !== import_outbound_api9.OUTBOUND_API_SERVER_CONFIG_KEY) return void 0;
12208
12717
  const file = this.readFile();
12209
12718
  if (file.server === void 0) return void 0;
12210
12719
  return this.decryptSecrets(file.server);
12211
12720
  }
12212
12721
  async set(key, value) {
12213
- if (key !== import_outbound_api8.OUTBOUND_API_SERVER_CONFIG_KEY) return;
12722
+ if (key !== import_outbound_api9.OUTBOUND_API_SERVER_CONFIG_KEY) return;
12214
12723
  const file = this.readFile();
12215
12724
  file.server = this.encryptSecrets(value);
12216
12725
  this.atomicReplace(
@@ -13849,7 +14358,7 @@ var import_node_fs23 = require("fs");
13849
14358
  var import_node_path24 = require("path");
13850
14359
  var import_SubscriptionAccountHealth2 = require("@omnicross/core/pipeline/SubscriptionAccountHealth");
13851
14360
  var import_AccountAllowanceScheduling3 = require("@omnicross/core/pipeline/AccountAllowanceScheduling");
13852
- var import_upstreamFetch4 = require("@omnicross/core/pipeline/upstreamFetch");
14361
+ var import_upstreamFetch5 = require("@omnicross/core/pipeline/upstreamFetch");
13853
14362
  var import_SubscriptionIdentityStore2 = require("@omnicross/core/provider-proxy/identity/SubscriptionIdentityStore");
13854
14363
  var import_subscriptions5 = require("@omnicross/subscriptions");
13855
14364
 
@@ -13997,7 +14506,7 @@ var JsonSubscriptionCredentialStore = class {
13997
14506
  * a plaintext token pair into `upstream-trace.jsonl`.
13998
14507
  */
13999
14508
  buildRefreshFetch(providerId, accountId) {
14000
- return this.fetchImpl ?? ((url, init) => (0, import_upstreamFetch4.fetchUpstream)(url, init, { providerId, accountId, redactBodies: true }));
14509
+ return this.fetchImpl ?? ((url, init) => (0, import_upstreamFetch5.fetchUpstream)(url, init, { providerId, accountId, redactBodies: true }));
14001
14510
  }
14002
14511
  /**
14003
14512
  * In-flight refresh coalescing. OAuth refresh tokens are
@@ -14555,7 +15064,7 @@ var JsonSubscriptionCredentialStore = class {
14555
15064
  };
14556
15065
 
14557
15066
  // src/AccountHealthProbeScheduler.ts
14558
- var import_upstreamFetch5 = require("@omnicross/core/pipeline/upstreamFetch");
15067
+ var import_upstreamFetch6 = require("@omnicross/core/pipeline/upstreamFetch");
14559
15068
 
14560
15069
  // src/probe/CodexGenerationProbe.ts
14561
15070
  var import_codexCliHeaders = require("@omnicross/core/provider-proxy/identity/codexCliHeaders");
@@ -14716,7 +15225,7 @@ var AccountHealthProbeScheduler = class {
14716
15225
  this.logger = logger;
14717
15226
  this.config = config;
14718
15227
  this.now = opts.now ?? Date.now;
14719
- this.fetchImpl = opts.fetchImpl ?? import_upstreamFetch5.fetchUpstream;
15228
+ this.fetchImpl = opts.fetchImpl ?? import_upstreamFetch6.fetchUpstream;
14720
15229
  this.sleep = opts.sleep ?? ((ms) => new Promise((r) => setTimeout(r, ms)));
14721
15230
  this.planFor = opts.planFor ?? probePlanFor;
14722
15231
  }
@@ -16414,7 +16923,7 @@ var AuditWriter = class {
16414
16923
  var import_node_fs32 = require("fs");
16415
16924
  var import_node_crypto24 = require("crypto");
16416
16925
  var import_node_path33 = require("path");
16417
- var import_upstreamFetch6 = require("@omnicross/core/pipeline/upstreamFetch");
16926
+ var import_upstreamFetch7 = require("@omnicross/core/pipeline/upstreamFetch");
16418
16927
 
16419
16928
  // src/billing/billingFiles.ts
16420
16929
  var BILLING_FILE_RE = /^billing-(\d{4})-(\d{2})-(\d{2})\.jsonl$/;
@@ -16437,7 +16946,7 @@ var BillingPublisher = class {
16437
16946
  constructor(billingDir, logger, opts = {}) {
16438
16947
  this.billingDir = billingDir;
16439
16948
  this.logger = logger;
16440
- this.fetchImpl = opts.fetchImpl ?? ((url, init) => (0, import_upstreamFetch6.fetchUpstream)(url, init));
16949
+ this.fetchImpl = opts.fetchImpl ?? ((url, init) => (0, import_upstreamFetch7.fetchUpstream)(url, init));
16441
16950
  this.defer = opts.defer ?? ((fn) => setTimeout(fn, 0));
16442
16951
  this.timeoutMs = opts.timeoutMs ?? BILLING_POST_TIMEOUT_MS;
16443
16952
  this.now = opts.now ?? Date.now;
@@ -16846,7 +17355,7 @@ function createRouteLeaseSubscriptionPreflight(credentials) {
16846
17355
 
16847
17356
  // src/webhook/WebhookDispatcher.ts
16848
17357
  var import_node_crypto25 = require("crypto");
16849
- var import_upstreamFetch7 = require("@omnicross/core/pipeline/upstreamFetch");
17358
+ var import_upstreamFetch8 = require("@omnicross/core/pipeline/upstreamFetch");
16850
17359
  var WEBHOOK_MAX_ATTEMPTS = 3;
16851
17360
  var WEBHOOK_QUEUE_MAX = 1e3;
16852
17361
  var WEBHOOK_SEND_TIMEOUT_MS = 1e4;
@@ -16866,7 +17375,7 @@ var WebhookDispatcher = class {
16866
17375
  sleep;
16867
17376
  now;
16868
17377
  constructor(opts = {}) {
16869
- this.fetchImpl = opts.fetchImpl ?? ((url, init) => (0, import_upstreamFetch7.fetchUpstream)(url, init));
17378
+ this.fetchImpl = opts.fetchImpl ?? ((url, init) => (0, import_upstreamFetch8.fetchUpstream)(url, init));
16870
17379
  this.logger = opts.logger;
16871
17380
  this.maxAttempts = opts.maxAttempts ?? WEBHOOK_MAX_ATTEMPTS;
16872
17381
  this.queueMax = opts.queueMax ?? WEBHOOK_QUEUE_MAX;
@@ -17102,7 +17611,7 @@ function buildDaemon(config, paths) {
17102
17611
  );
17103
17612
  (0, import_AccountAllowanceStore4.setSharedAccountAllowanceStore)(accountAllowanceStore);
17104
17613
  (0, import_AccountAllowanceScheduling5.getSharedAccountAllowanceScheduling)().configure(
17105
- (0, import_outbound_api9.normalizeServerConfig)(decryptedConfig.server).allowanceScheduling
17614
+ (0, import_outbound_api10.normalizeServerConfig)(decryptedConfig.server).allowanceScheduling
17106
17615
  );
17107
17616
  const llmConfig = new ConfigFileProviderConfigSource(decryptedConfig);
17108
17617
  const keyDb = new JsonOutboundKeyDb(paths.keysPath, secretBox3);
@@ -17123,7 +17632,7 @@ function buildDaemon(config, paths) {
17123
17632
  logger
17124
17633
  );
17125
17634
  claudeAllowanceRefreshScheduler.configure(
17126
- (0, import_outbound_api9.normalizeServerConfig)(decryptedConfig.server).allowanceScheduling
17635
+ (0, import_outbound_api10.normalizeServerConfig)(decryptedConfig.server).allowanceScheduling
17127
17636
  );
17128
17637
  const subscriptionAccounts = new import_subscriptions6.SubscriptionAccountService(credentialStore);
17129
17638
  (0, import_subscriptions6.setSubscriptionAccountService)(subscriptionAccounts);
@@ -17133,7 +17642,7 @@ function buildDaemon(config, paths) {
17133
17642
  );
17134
17643
  (0, import_subscriptions6.setSubscriptionProviderRegistry)(subscriptionRegistry);
17135
17644
  setServerProxyConfig(decryptedConfig.server?.proxy);
17136
- (0, import_upstreamFetch8.setUpstreamProxyResolver)(
17645
+ (0, import_upstreamFetch9.setUpstreamProxyResolver)(
17137
17646
  createUpstreamProxyResolver({
17138
17647
  getAccountProxy: (providerId, accountId) => credentialStore.getAccountProxy(providerId, accountId)
17139
17648
  })
@@ -17156,7 +17665,7 @@ function buildDaemon(config, paths) {
17156
17665
  const pricingEngine = new import_usage2.PricingEngine(pricingStore, logger, {
17157
17666
  // Catalog egress follows the same global/env proxy policy as every other
17158
17667
  // daemon upstream call; no provider/account override applies here.
17159
- fetchImpl: ((input, init) => (0, import_upstreamFetch8.fetchUpstream)(String(input), init ?? {}))
17668
+ fetchImpl: ((input, init) => (0, import_upstreamFetch9.fetchUpstream)(String(input), init ?? {}))
17160
17669
  });
17161
17670
  const pricingRefreshScheduler = new PricingRefreshScheduler(
17162
17671
  pricingEngine,
@@ -17168,13 +17677,21 @@ function buildDaemon(config, paths) {
17168
17677
  defaultUsageEventsPath(paths.configPath),
17169
17678
  async (providerId, model) => await pricingEngine.getEntry(providerId, model) !== null
17170
17679
  );
17171
- const keySpendTracker = new import_outbound_api10.KeySpendTracker(usageEventStore);
17680
+ const keySpendTracker = new import_outbound_api11.KeySpendTracker(usageEventStore);
17172
17681
  const usageThroughput = (0, import_usage2.getSharedUsageThroughputTracker)();
17173
17682
  const usageRecorder = new import_usage2.UsageRecorder(usageEventStore, pricingEngine, logger, {
17174
17683
  onRecord: (apiKeyId, costUsd, at) => keySpendTracker.add(apiKeyId, costUsd, at),
17175
17684
  onEvent: (row, at) => usageThroughput.record(row, at)
17176
17685
  });
17177
- const initialImagesConfig = (0, import_outbound_api9.normalizeServerConfig)(decryptedConfig.server).images;
17686
+ const initialImagesConfig = (0, import_outbound_api10.normalizeServerConfig)(decryptedConfig.server).images;
17687
+ const initialSearchConfig = (0, import_outbound_api10.normalizeServerConfig)(decryptedConfig.server).search;
17688
+ for (const issue of (0, import_outbound_api10.validateSearchServerConfig)(
17689
+ decryptedConfig.server?.search
17690
+ )) {
17691
+ logger.warn("[search] ignoring invalid config: " + issue);
17692
+ }
17693
+ const searchRuntime = buildSearchRuntime(initialSearchConfig, { logger });
17694
+ const searchFrontendModes = initialSearchConfig.modes;
17178
17695
  const imageObservability = new ImageObservability();
17179
17696
  const imageRuntimeObservability = Object.freeze({
17180
17697
  telemetrySink: imageObservability.telemetrySink,
@@ -17304,7 +17821,9 @@ function buildDaemon(config, paths) {
17304
17821
  apiKeyPool,
17305
17822
  usageRecorder,
17306
17823
  openAIOperationRegistry,
17307
- responsesHostedImageIngress
17824
+ responsesHostedImageIngress,
17825
+ searchRuntime,
17826
+ searchFrontendModes
17308
17827
  });
17309
17828
  if (providerProxy.getDeps().openAIOperationRegistry !== openAIOperationRegistry) {
17310
17829
  throw new Error(
@@ -17338,7 +17857,7 @@ function buildDaemon(config, paths) {
17338
17857
  credentialStore,
17339
17858
  (0, import_SubscriptionAccountHealth4.getSharedAccountHealth)(),
17340
17859
  logger,
17341
- import_outbound_api9.DEFAULT_ACCOUNT_PROBE
17860
+ import_outbound_api10.DEFAULT_ACCOUNT_PROBE
17342
17861
  );
17343
17862
  const getHealthReport = () => buildHealthReport({
17344
17863
  version: DAEMON_VERSION,
@@ -17355,7 +17874,7 @@ function buildDaemon(config, paths) {
17355
17874
  // `/health` body stays byte-identical (zero regression).
17356
17875
  subscriptionAccountsHealthy: () => accountHealthProbeScheduler.enabled ? accountHealthProbeScheduler.probedAccountsHealthy() : void 0
17357
17876
  });
17358
- const outboundApiServer = (0, import_outbound_api9.getOutboundApiServer)({
17877
+ const outboundApiServer = (0, import_outbound_api10.getOutboundApiServer)({
17359
17878
  db: keyDb,
17360
17879
  // voucher-redemption #9: the key-authenticated `POST /redeem` endpoint redeems
17361
17880
  // cards against the presenting key (gated on `voucher.enabled`).
@@ -17369,7 +17888,9 @@ function buildDaemon(config, paths) {
17369
17888
  keySpendTracker,
17370
17889
  // configurable-logging: route the server's OWN lifecycle + relay dispatch-error
17371
17890
  // lines through the injected logger (honors level/format/file sink).
17372
- logger
17891
+ logger,
17892
+ // plan 阶段5: the same instance the managed frontends hold.
17893
+ searchRuntime
17373
17894
  });
17374
17895
  const auditDir = defaultAuditDir(paths.configPath);
17375
17896
  const billingDir = defaultBillingDir(paths.configPath);
@@ -17391,6 +17912,10 @@ function buildDaemon(config, paths) {
17391
17912
  }),
17392
17913
  routeLeaseManager,
17393
17914
  subscriptionAccounts,
17915
+ // search-settings-ui D3: the daemon's ONE search runtime + its
17916
+ // bootstrap-captured modes, for `GET /admin/api/search/diagnostics` and
17917
+ // `POST /admin/api/search/test` (501 when a light embedder omits it).
17918
+ searchStatus: { runtime: searchRuntime, modes: searchFrontendModes },
17394
17919
  accountAllowanceService,
17395
17920
  allowanceRefreshScheduler: claudeAllowanceRefreshScheduler,
17396
17921
  accountProbeService: accountHealthProbeScheduler,
@@ -17420,7 +17945,7 @@ function buildDaemon(config, paths) {
17420
17945
  // — `server.proxy.byProvider[...]` was silently skipped — and the call was
17421
17946
  // excluded from the upstream trace, so a failing login left no evidence.
17422
17947
  // `redactBodies` keeps the code/verifier + minted token out of that trace.
17423
- oauthExchangeFetch: paths.oauthExchangeFetch ? () => paths.oauthExchangeFetch : (providerId) => (url, init) => (0, import_upstreamFetch8.fetchUpstream)(url, init, { providerId, redactBodies: true }),
17948
+ oauthExchangeFetch: paths.oauthExchangeFetch ? () => paths.oauthExchangeFetch : (providerId) => (url, init) => (0, import_upstreamFetch9.fetchUpstream)(url, init, { providerId, redactBodies: true }),
17424
17949
  subscriptionAccountAppender: credentialStore,
17425
17950
  // Codex interactive OAuth (app-parity-2 child 5) — the async loopback flow store
17426
17951
  // + the one-shot 127.0.0.1:1455 listener. Token captured + persisted daemon-side;
@@ -17440,7 +17965,7 @@ function buildDaemon(config, paths) {
17440
17965
  cliCommandRunner: paths.cliCommandRunner,
17441
17966
  integrationManagerFactory: () => {
17442
17967
  const live = outboundApiServer.getStatus();
17443
- const port = live.port || decryptedConfig.server?.port || import_outbound_api9.DEFAULT_OUTBOUND_PORT;
17968
+ const port = live.port || decryptedConfig.server?.port || import_outbound_api10.DEFAULT_OUTBOUND_PORT;
17444
17969
  return new IntegrationManager({
17445
17970
  configPath: paths.configPath,
17446
17971
  gatewayBaseUrl: live.loopbackUrl ?? `http://127.0.0.1:${port}`,
@@ -17486,7 +18011,7 @@ function buildDaemon(config, paths) {
17486
18011
  });
17487
18012
  const webhookDispatcher = new WebhookDispatcher({
17488
18013
  logger,
17489
- fetchImpl: (url, init) => (0, import_upstreamFetch8.fetchUpstream)(url, init)
18014
+ fetchImpl: (url, init) => (0, import_upstreamFetch9.fetchUpstream)(url, init)
17490
18015
  });
17491
18016
  setWebhookRuntime(webhookDispatcher, (0, import_SubscriptionAccountHealth4.getSharedAccountHealth)());
17492
18017
  const auditWriter = new AuditWriter(auditDir, logger);
@@ -17527,6 +18052,8 @@ function buildDaemon(config, paths) {
17527
18052
  keyDb,
17528
18053
  settingsStore,
17529
18054
  openAIOperationRegistry,
18055
+ searchRuntime,
18056
+ searchFrontendModes,
17530
18057
  imageRuntimeManager,
17531
18058
  imageObservability,
17532
18059
  imageCleanupService,
@@ -17562,11 +18089,11 @@ function buildDaemon(config, paths) {
17562
18089
  function resetDaemonSingletonsForTests() {
17563
18090
  resetImageRuntimeBootstrapSession();
17564
18091
  (0, import_provider_proxy4.__resetProviderProxyForTests)();
17565
- (0, import_outbound_api9.__resetOutboundApiServerForTests)();
18092
+ (0, import_outbound_api10.__resetOutboundApiServerForTests)();
17566
18093
  (0, import_subscriptionRegistryPort.setSubscriptionRegistryForOutbound)(null);
17567
18094
  (0, import_subscriptions6.setSubscriptionProviderRegistry)(null);
17568
18095
  (0, import_subscriptions6.setSubscriptionAccountService)(null);
17569
- (0, import_upstreamFetch8.setUpstreamProxyResolver)(null);
18096
+ (0, import_upstreamFetch9.setUpstreamProxyResolver)(null);
17570
18097
  setServerProxyConfig(void 0);
17571
18098
  (0, import_gemini_code_assist_resolver.setGeminiCodeAssistResolver)(null);
17572
18099
  setSecretBox(null);